Browse Source

Remove unused files that were migrated to `create-block` package.

test-gpt-generated
Roman Axelrod 3 years ago
parent
commit
1d3aec4dff
  1. 238
      create-block.js
  2. 23
      generators/block/templates/.editorconfig
  3. 7
      generators/block/templates/.gitignore
  4. 167
      generators/block/templates/README.md
  5. 34
      generators/block/templates/block.json
  6. 7
      generators/block/templates/config/default.cjs
  7. 15
      generators/block/templates/data/advanced.json
  8. 7
      generators/block/templates/data/default.json
  9. 7
      generators/block/templates/gitignore
  10. 11
      generators/block/templates/package.json
  11. BIN
      generators/block/templates/src/images/demo.jpeg
  12. 7
      generators/block/templates/src/scripts/template.js
  13. 40
      generators/block/templates/src/styles/template.scss
  14. 68
      generators/block/templates/src/template.template.hbs
  15. 14
      helpers.js
  16. 25168
      package-lock.json
  17. 15
      package.json
  18. 16
      platforms/hubspot/hubspot-adapter.js

238
create-block.js

@ -1,238 +0,0 @@
#!/usr/bin/env node
import {Command} from 'commander';
import path from 'path';
import fetch from "node-fetch";
import fs from "fs";
import http from "http";
import https from "https";
import StreamZip from "node-stream-zip";
import {fileURLToPath} from 'url';
import memFs from 'mem-fs';
import editor from 'mem-fs-editor';
export const defaultGitRepo = 'git+https://git.devdevdev.life/axe-web-public/block-dev-tool.git#master';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const isDev = process.env.NODE_ENV === 'development'; // Check README file in case you get "missing files" error.
const blocksRegistry = isDev ? 'http://localhost:3020' : 'https://axe-web-blocks-registry.captain.devdevdev.life';
const blocksDirectory = isDev ? 'blocks/' : '';
if (isDev) {
console.log(`Development Mode Active`);
}
try {
const blockName = await init();
console.log(`🎉 Done! \n\nCheck the "${blocksDirectory}${blockName}" directory. \n`);
} catch (e) {
console.log(`❌ Fail.`);
}
async function init() {
const program = new Command();
program
.name('create-block')
.description('AXE-WEB Platform Blocks');
const promise = new Promise((resolve, reject) => {
program.command('pull')
.argument('<string>', 'Provide a full name of required block, for example: @axe-web/hero-block')
.action(async (blockName, options) => {
console.log('📦 Block to download:', blockName)
const status = await getBlockSourceFiles(blockName);
if (status) {
resolve(blockName);
} else {
reject();
}
});
});
program.parse();
return promise;
}
async function getBlockSourceFiles(blockName) {
const queryString = new URLSearchParams();
queryString.append('blockName', blockName);
queryString.append('includeDevConfig', 'true');
const response = await fetch(`${blocksRegistry}?${queryString.toString()}`);
const responseData = await response.json();
if (!responseData || !responseData.name) {
console.log("⚠️ Block not found, please contact administrator.");
return;
}
if (responseData.status && responseData.status !== 200) {
console.log("⚠️ [ERROR]", responseData.message || "Server side error.");
throw new Error("⚠️ [ERROR]", responseData.message || "Server side error.");
}
const data = {
title: responseData.title,
name: responseData.name,
preview_image: responseData.preview_image,
remToPx: responseData.config.remToPx ?? 16,
blockFilename: responseData.name,
blockClassName: responseData.name,
blockGroupName: responseData.project,
version: responseData.version,
devToolSource: defaultGitRepo,
};
if (responseData.downloadUrl) {
console.log(`⬇️ Downloading v${responseData.version}`);
const zipFile = await downloadFile(responseData.downloadUrl, responseData.name + '.zip');
// Download, Extract and Remove downloaded file.
try {
const zip = new StreamZip.async({file: zipFile});
await zip.extract(null, `${blocksDirectory}${responseData.name}/src`);
await zip.close();
await fs.promises.access(zipFile, fs.constants.W_OK);
await fs.promises.unlink(zipFile);
} catch (e) {
throw e;
}
} else {
await createSourceFiles(data, __dirname, `${blocksDirectory}${responseData.name}`);
}
await createTechnicalFiles(data, __dirname, `${blocksDirectory}${responseData.name}`);
if (responseData.config.design_files) {
await downloadDesignFiles(responseData.name, responseData.config.design_files);
}
await createDataFiles(responseData.name, responseData.config.data_sources);
await createConfigFile(responseData.name, responseData.config);
return true;
}
async function createConfigFile(blockName, config = {}) {
const obj = {
blockName,
baseView: config.baseView,
remToPx: config.remToPx,
};
const cssAssets = config.assets.filter(item => item.type === 'css').map(item => item.url);
if (cssAssets.length) {
obj.cssUrl = cssAssets;
}
const jsAssets = config.assets.filter(item => item.type === 'js').map(item => item.url);
if (jsAssets.length) {
obj.jsUrl = jsAssets;
}
await setupPath(`${blocksDirectory}${blockName}/config`);
await fs.promises.writeFile(`${blocksDirectory}${blockName}/config/default.json`, JSON.stringify(obj, null, 2));
}
async function downloadDesignFiles(blockName = '', files) {
for (let url of files) {
const fileName = url.split('/').pop();
await setupPath(`${blocksDirectory}${blockName}/design`);
await downloadFile(url, `${blocksDirectory}${blockName}/design/${fileName}`)
}
}
async function createDataFiles(blockName, dataSources = []) {
for (let source of dataSources) {
await setupPath(`${blocksDirectory}${blockName}/data`);
await fs.promises.writeFile(`${blocksDirectory}${blockName}/data/${source.name}.json`, JSON.stringify(source.data, null, 2));
if (typeof source.preview_images !== 'undefined' && source.preview_images.length) {
for (let preview_image of source.preview_images) {
await setupPath(`${blocksDirectory}${blockName}/design/preview`);
await downloadFile(preview_image.url, `${blocksDirectory}${blockName}/design/preview/${source.name}.${preview_image.width}.${preview_image.extension}`)
}
}
}
}
//
// Helpers
//
async function setupPath(path) {
if (!fs.existsSync(path)) {
await fs.promises.mkdir(path);
}
}
async function downloadFile(url, fileName) {
const file = fs.createWriteStream(fileName);
return new Promise((resolve, reject) => {
const protocol = url.startsWith('https://') ? https : http;
protocol.get(url, function (response) {
response.pipe(file);
// Loading Indicator.
const loadingInterval = setInterval(() => console.log('🕐 Download in progress...'), 3000);
// after download completed close filestream
file.on("finish", () => {
clearInterval(loadingInterval);
file.close();
resolve(fileName);
});
});
})
}
export async function createSourceFiles(data, baseDir, distPath) {
const pathDist = distPath + '/src'; //path.join(baseDir, distPath);
const generatorsPath = path.join(baseDir, 'generators/block/templates/src');
const store = memFs.create();
const filesystem = editor.create(store);
const files = [
{from: 'template.template.hbs', to: `${data.name}.template.hbs`},
{from: 'styles/template.scss', to: `styles/${data.name}.scss`},
{from: 'scripts/template.js', to: `scripts/${data.name}.js`},
'images/demo.jpeg',
];
for (let file of files) {
const from = typeof file !== 'string' ? `${generatorsPath}/${file.from}` : `${generatorsPath}/${file}`;
const to = typeof file !== 'string' ? `${pathDist}/${file.to}` : `${pathDist}/${file}`;
await filesystem.copyTplAsync(from, to, data);
}
return filesystem.commit(); // Promise
}
export async function createTechnicalFiles(data, baseDir, distPath) {
const pathDist = distPath; //path.join(baseDir, distPath);
const generatorsPath = path.join(baseDir, 'generators/block/templates');
const store = memFs.create();
const filesystem = editor.create(store);
const files = ['package.json', 'README.md', '.editorconfig', {from: 'gitignore', to: '.gitignore'}, 'block.json'];
for (let file of files) {
const from = typeof file !== 'string' ? `${generatorsPath}/${file.from}` : `${generatorsPath}/${file}`;
const to = typeof file !== 'string' ? `${pathDist}/${file.to}` : `${pathDist}/${file}`;
await filesystem.copyTplAsync(from, to, data);
}
return filesystem.commit(); // Promise
}

23
generators/block/templates/.editorconfig

@ -1,23 +0,0 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
# WordPress Coding Standards
# https://make.wordpress.org/core/handbook/coding-standards/
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
[*.json]
indent_style = tab
indent_size = 4
[*.md]
trim_trailing_whitespace = false

7
generators/block/templates/.gitignore

@ -1,7 +0,0 @@
# Basic
.idea
.DS_Store
node_modules
vendor
# Custom

167
generators/block/templates/README.md

@ -1,167 +0,0 @@
# Development Setup
Install required modules:
```sh
npm install
```
Run development environment:
```sh
npm start
```
## How it works ⚙️
The project runs `gulp` and `browsersync` beyond the scenes.
Each change in template, styling or script files will reload the page. The idea is to have a comfortable development
environment.
# Block Structure
You will find all the block files in `/src` folder.
```
/src/images/
*.png, *jpg, *.svg
/src/scritps/
*.mjs, *js
/src/styles/
*.scss
/src/*.template.hbs
```
# Block rules
We have a “blocks system”, means you will have to follow strict rules and use listed technologies:
## Template Layout & Data
### Data
You will find multiple `*.json` files in `/data` folder after the first run of `npm start`.
These files are used as data sources in layout. By reviewing these files you can understand what parameters you have and
how the data is stored.
There are multiple data sources since the block can be reused in different situations with different data. We have to
make sure that the block is always rendered properly.
> Don't change or edit these files - use the data as it is!
### Handlebars
[Handlebars](https://handlebarsjs.com/guide/ "What is Handlebars") used as a template engine in the project.
All the template layout must be in a single `*.hbs` file that located in `/src` folder.
> Use the data that is available in `/data` folder.
> Avoid using any kind of "freestyle" input/content. Your template file must contain only HTML tags and Handlebars parameters.
### Static Media Files 🖼️
Use the `/src/images` folder in case you need to upload images or video files to the template.
These files will be available by the next URL: http://localhost:3000/images/${filename}
### Class Naming Convention
Use BEM naming system for class names: http://getbem.com/naming/
## Styling rules 🎨
### Mobile First 📱
Use Mobile First approach. Start with mobile device styling and then focus on other screen sizes by using @media (
min-width: ...px).
### CSS Units
Use `rem` units instead of pixels.
For example, `1rem = 16pixels` depends on project.
No need to use rem in situations of `1px`, `2px` or `3px`. (usually used for borders width).
It's important to mention that the block is "elastic". By using `rem` units we are able to scale the layout and keep the
aspect ratio.
### Global Styling
The development environment includes CSS rules of the original project. This is including fonts, CSS variables,
container logic etc...
The CSS file is already embedded in served HTML.
# JavaScript
## Sliders
For any kind of slides animations - use [SwiperJS](https://swiperjs.com/get-started).
The lib is included in the project and ready for use. Test with `window.Swiper` in browser console.
# Summary
## Short Video Review
Check the [Video Guide](https://www.loom.com/share/1c707a4ea14e48b7a35a49d7b0a6f1e0)
> PRO TIP
> Use x2 speed in the player 😜
## Testing ✅
### Development Toolbar ✔️
Use development toolbar to switch between data sources.
### Conditional Statements
Make sure the data is available in Handlebars template.
If there is a chance that some data/property will be missing - wrap the HTML layout with conditional verification:
Example:
Render the link only if URL exists
```
{{#if link_cta_url }}
<a href="{{link_cta_url}}">Click Here</a>
{{ endif }}
```
### Hover/Focus States ✔️
Make sure all "clickable" elements have `&:hover` & `&:focus` states in CSS rules.
This might be related to links, buttons or any other interactive elements.
### Responsiveness ✔️
Make sure the layout is rendered correctly on all standard breakpoint size:
1. 1920px in width...
2. 1680px
3. 1440px
4. 1360px
5. 1280px
6. 1024px
7. 980px
8. 768px
9. 600px
10. 414px
11. 375px
If you follow the rules of REM unit - your layout must be "elastic" and most of the breakpoints should be rendered
properly.
### Pixel Perfect Test ✔️
Compare the final result with provided screenshots.
You can use
available [Browser Extensions](https://chrome.google.com/webstore/detail/perfectpixel-by-welldonec/dkaagdgjmgdmbnecmcefdhjekcoceebi?hl=en)
or any other tool/approach that you're familiar with.
The idea is to have "pretty close" result to requested design.
## Delivery
Once you finished with the task, before letting me know - please review the next [Google Form link](https://forms.gle/w4sJjAyRDSSBRuGLA](https://forms.gle/w4sJjAyRDSSBRuGLA)
If everything is OK - send a Pull Request to the git project or share a ZIP file with me directly.

34
generators/block/templates/block.json

@ -1,34 +0,0 @@
{
"name": "<%= blockGroupName %>/<%= blockFilename %>",
"version": "<%= version %>",
"title": "<%= title %>",
"categories": [],
"icon": "shortcode",
"preview_image": "<%= preview_image %>",
"field_groups": [
{
"name": "content",
"label": "Content",
"fields": {
"title": {
"type": "text",
"label": "Title"
},
"content": {
"type": "wysiwyg",
"label": "Content"
},
"cta": {
"type": "link",
"label": "CTA"
}
}
},
{
"name": "styling",
"label": "Styling",
"fields": {
}
}
]
}

7
generators/block/templates/config/default.cjs

@ -1,7 +0,0 @@
module.exports = {
cssUrl: "https://",
jsUrl: "https://",
blockName: "<%= blockFilename %>",
baseView: "<%= baseView %>",
remToPx: <%= remToPx %>,
}

15
generators/block/templates/data/advanced.json

@ -1,15 +0,0 @@
{
"title": "Option Two",
"content": "<p><b>Delivering top results to industry leaders:</b></p>",
"image_url": "https://fakeimg.pl/400x400/",
"cta_text": "Our Success Stories",
"url": "https://google.com"
}
/**
* Tips for good data.json example:
* - Provide Short and Long version of text (title/content).
* - Put <a> and <strong> elements in content.
* - Upload different sizes and ratios of images.
* - Provide options with and without CTA to test conditional logic.
*/

7
generators/block/templates/data/default.json

@ -1,7 +0,0 @@
{
"title": "As a Global Salesforce Partner,\n we deliver Service Cloud solutions\n and complex Field Service Management\n in diverse industries worldwide",
"content": "<p><b>Delivering top results to industry leaders:</b></p>",
"image_url": "https://fakeimg.pl/400x400/",
"cta_text": "Our Success Stories",
"url": "https://google.com"
}

7
generators/block/templates/gitignore

@ -1,7 +0,0 @@
# Basic
.idea
.DS_Store
node_modules
vendor
# Custom

11
generators/block/templates/package.json

@ -1,11 +0,0 @@
{
"name": "<%= blockFilename %>",
"version": "<%= version %>",
"scripts": {
"start": "component-dev",
"build": "component-build"
},
"devDependencies": {
"create-block-dev-tool": "<%= devToolSource %>"
}
}

BIN
generators/block/templates/src/images/demo.jpeg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

7
generators/block/templates/src/scripts/template.js

@ -1,7 +0,0 @@
(function ($) {
console.log('Ready!');
console.log('jQuery =', $);
console.log('Swiper =', window.Swiper);
})(window.jQuery);

40
generators/block/templates/src/styles/template.scss

@ -1,40 +0,0 @@
/**
* Use "rem" instead of pixels. 1rem = <%= remToPx %>pixels
* No need to use rem in situations of "1px". (usually used for borders width).
*
* Use BEM naming system for class names: http://getbem.com/naming/
*
* Use Mobile First approach.
* Start with mobile device styling and then focus on other screen sizes by using @media (min-width: ...px).
*
*/
.<%= blockClassName %> {
&__header {
// Header Mobile.
@media (min-width: 1024px) {
// Header Desktop.
}
&-heading {
// Child Element.
}
}
&__visual {
&-image {
}
}
&__content {
}
&__footer {
}
}

68
generators/block/templates/src/template.template.hbs

@ -1,68 +0,0 @@
<section class="<%= blockClassName %> <%= blockClassName %>--{{ config.activeDataFile }}">
{{!
Remove Everything Below:
}}
<style>
code {
background-color: #eee;
color: #333;
padding: 1rem 1.5rem;
border: 2px solid #d8d8d8;
display: inline-block;
border-radius: 2px;
font-size: 14px;
white-space: pre-line;
}
</style>
<header class="<%= blockClassName %>__header">
<h1 class="<%= blockClassName %>__header-heading">Ready!</h1>
</header>
<div class="<%= blockClassName %>__content">
<p>
Review the `/data` folder with JSON data files.<br>
Don't change data JSON files - use the data as it is.
</p>
<p>Build the layout based on provided data structure.</p>
<br><br>
<hr>
<h2>Image Example</h2>
<div>
<img src="/images/demo.jpeg" alt="">
<br>
<code>&lt;img src=&quot;/images/demo.jpeg&quot; alt=&quot;&quot;&gt;
</code>
</div>
<br><br>
<hr>
<h2>Available Buttons Styling</h2>
<div>
<a href="#" class="btn btn--primary">Primary</a>
<br>
<code>&lt;a href=&quot;#&quot; class=&quot;btn btn--primary&quot;&gt;Primary&lt;/a&gt;
</code>
</div>
<br>
<div>
<a href="#" class="btn btn--secondary">Secondary</a>
<br>
<code>&lt;a href=&quot;#&quot; class=&quot;btn btn--secondary&quot;&gt;Secondary&lt;/a&gt;
</code>
</div>
</div>
{{!
Remove END
}}
</section>

14
helpers.js

@ -1,14 +0,0 @@
export function capitalize(str) {
if (typeof str !== 'string') {
return '';
}
return str
.toLowerCase()
.split(/[ -_]/g)
.filter((word) => !!word)
.map((word) => {
return word.charAt(0).toUpperCase() + word.slice(1);
})
.join(' ');
}

25168
package-lock.json

File diff suppressed because it is too large

15
package.json

@ -9,8 +9,6 @@
"scripts": {
"start": "component-dev",
"dev": "NODE_ENV=development node server.js",
"create-block": "node ./create-block.js pull",
"create-block-dev": "NODE_ENV=development node ./create-block.js pull",
"build": "rollup --config rollup.config.js",
"build-platform": "NODE_ENV=development node ./build.js",
"build-platform-cli": "component-build",
@ -22,7 +20,6 @@
"@braintree/sanitize-url": "^6.0.0",
"archiver": "^5.3.1",
"browser-sync": "^2.27.9",
"commander": "^9.4.1",
"config": "^3.3.7",
"escape-html": "^1.0.3",
"express": "^4.17.3",
@ -35,11 +32,7 @@
"gulp-sourcemaps": "^3.0.0",
"gulp-uglify": "^3.0.2",
"lodash-es": "^4.17.21",
"mem-fs": "^2.2.1",
"mem-fs-editor": "^9.5.0",
"mkdirp": "^1.0.4",
"node-fetch": "^3.2.10",
"node-stream-zip": "^1.15.0",
"open": "^8.4.0",
"sanitize-html": "^2.7.1",
"sass": "^1.50.1"
@ -61,14 +54,8 @@
"yeoman-generator": "^5.6.1"
},
"bin": {
"create-block": "./create-block.js",
"component-dev": "./server.js",
"component-build": "./build.js"
},
"files": [
"generators/block/templates/.gitignore",
"generators/block/**/*",
"layouts/**/*",
"helpers.js"
]
"files": []
}

16
platforms/hubspot/hubspot-adapter.js

@ -1,5 +1,4 @@
import {readFile, writeFile, mkdir, copyFile} from "fs/promises";
import {capitalize} from "../../helpers.js";
export async function buildHubspot(blockName) {
const distPath = `./exports/hubspot/${blockName}.module`;
@ -225,3 +224,18 @@ function convertToHubspotField(field = {}) {
});
}
}
export function capitalize(str) {
if (typeof str !== 'string') {
return '';
}
return str
.toLowerCase()
.split(/[ -_]/g)
.filter((word) => !!word)
.map((word) => {
return word.charAt(0).toUpperCase() + word.slice(1);
})
.join(' ');
}

Loading…
Cancel
Save