You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
5.4 KiB
180 lines
5.4 KiB
#!/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 unzipper from "unzipper";
|
|
import {createTechnicalFiles, defaultGitRepo} from "./generators/block/index.js";
|
|
import {fileURLToPath} from 'url';
|
|
import config from 'config';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const isDev = process.env.NODE_ENV === 'development' || (config.has('isDev') && config.get('isDev')); // Check README file in case you get "missing files" error.
|
|
const blocksRegistry = isDev ? 'http://localhost:3020' : 'http://localhost:3020';
|
|
const blocksDirectory = isDev ? 'blocks/' : '';
|
|
|
|
console.log(__dirname);
|
|
|
|
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;
|
|
}
|
|
|
|
const zipFile = await downloadFile(responseData.downloadUrl, responseData.name + '.zip');
|
|
await fs.createReadStream(zipFile)
|
|
.pipe(unzipper.Extract({path: `${blocksDirectory}${responseData.name}/src`}))
|
|
.promise();
|
|
|
|
// Remove downloaded file.
|
|
try {
|
|
await fs.promises.access(zipFile, fs.constants.W_OK);
|
|
await fs.promises.unlink(zipFile);
|
|
} catch (e) {
|
|
console.log(e)
|
|
}
|
|
|
|
if (responseData.statusCode && responseData.statusCode !== 200) {
|
|
console.log(responseData);
|
|
console.log("⚠️ [ERROR]", responseData.message || "Server side error.");
|
|
return;
|
|
}
|
|
|
|
await createTechnicalFiles({
|
|
title: responseData.title,
|
|
name: responseData.name,
|
|
blockFilename: responseData.name,
|
|
blockGroupName: responseData.project,
|
|
version: responseData.version,
|
|
devToolSource: defaultGitRepo,
|
|
}, __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 downloadFile(preview_image.url, `${blocksDirectory}${blockName}/design/${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);
|
|
});
|
|
});
|
|
})
|
|
}
|
|
|