#!/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('', '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); }); }); }) }