@leanup/cli
Version:
This CLI brings along all required tools to serve, test and build multi framework SPAs
200 lines • 9.48 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "chalk", "child_process", "commander", "deepmerge", "fs", "path", "prettier"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractCLI = exports.getProjectName = void 0;
const chalk = require("chalk");
const child_process_1 = require("child_process");
const commander = require("commander");
const deepmerge = require("deepmerge");
const fs = require("fs");
const path = require("path");
const prettier = require("prettier");
function getProjectName(namespace = '') {
let projectName = path
.resolve(process.cwd())
.split('')
.reverse()
.join('')
.replace(/(\\|\/).+/g, '')
.split('')
.reverse()
.join('')
.toLowerCase();
if (typeof namespace === 'string' && namespace.length > 0) {
projectName = `@${namespace}/${projectName}`;
}
return projectName;
}
exports.getProjectName = getProjectName;
const START = Date.now();
const PROJECT_NAME_REG_EXP = new RegExp(`@template/[a-z0-9]+`, 'g');
class AbstractCLI {
constructor(name, version) {
this.program = new commander.Command();
this.commands = new Map();
this.name = name;
this.version = version;
this.program.name(name).version(version, '-v, --version', 'output the current version');
}
parse() {
this.program.parse(process.argv);
}
consoleLog(message, silent = false) {
if (silent === false) {
console.log(message);
}
}
addCommand(name, description, options, action) {
const command = this.program.command(name);
const actions = [];
this.commands.set(name, {
command,
actions,
});
this.setDescriptionToCommand(name, description);
this.addOptionToCommand(name, options);
this.addActionToCommand(name, action);
command.action((options) => {
let spawnArgs = [];
actions.forEach((action) => {
spawnArgs = spawnArgs.concat(action(options));
});
this.spawnCommand(spawnArgs, options.silent);
});
}
setDescriptionToCommand(name, description) {
var _a;
(_a = this.commands.get(name)) === null || _a === void 0 ? void 0 : _a.command.description(description);
}
addOptionToCommand(name, options) {
const names = Array.isArray(name) ? name : [name];
names.forEach((name) => {
var _a;
const command = (_a = this.commands.get(name)) === null || _a === void 0 ? void 0 : _a.command;
options.forEach((option) => command.option(option.flags, option.description, option.default));
});
}
addActionToCommand(name, action) {
const names = Array.isArray(name) ? name : [name];
names.forEach((name) => {
var _a;
(_a = this.commands.get(name)) === null || _a === void 0 ? void 0 : _a.actions.push(action);
});
}
addFirstActionToCommand(name, action) {
const names = Array.isArray(name) ? name : [name];
names.forEach((name) => {
var _a;
(_a = this.commands.get(name)) === null || _a === void 0 ? void 0 : _a.actions.unshift(action);
});
}
spawnCommand(args, silent = false) {
console.log(`
`, `${chalk.magenta.bold(`☀ ${chalk.underline(`@leanup/cli`)}${this.name != '' ? `-${this.name}` : ''}`)}`, `(v${this.version})`, chalk.italic.gray('execute the following pure command ...'), `
>`, chalk.bold('npx'), chalk.italic(...args), `
`);
return (0, child_process_1.spawn)('npx', args, {
cwd: process.cwd(),
shell: true,
stdio: silent === false ? 'inherit' : undefined,
}).on('exit', (code) => {
if (code > 0) {
console.log(`
`, chalk.red.bold(`✘ ${chalk.underline(`@leanup/cli`)}`), chalk.italic.gray('command execution ended with error'), chalk.white(`(in ${Date.now() - START} ms)`));
process.exit(code);
}
console.log(`
`, chalk.green.bold(`✔ ${chalk.underline(`@leanup/cli`)}`), chalk.italic.gray('command execution successfully completed'), chalk.white(`(in ${Date.now() - START} ms)`));
});
}
copyAndPrint(folder, subfolder = '', options) {
const projectName = getProjectName(options.namespace);
options.onlyConfig = options.onlyConfig === true;
const currentDir = path.join(folder, subfolder);
let dirs;
try {
dirs = fs.readdirSync(currentDir);
}
catch (error) {
dirs = [];
}
dirs.forEach((dirent) => {
const stat = fs.lstatSync(path.join(currentDir, dirent));
const subDirent = `${subfolder}/${dirent}`.replace(/^\/+/, '');
const relPath = `${subfolder}/${dirent.replace(/^_+/, '')}`.replace(/^\/+/, '');
const dirPath = path.join(process.cwd(), relPath);
if (stat.isDirectory()) {
if (options.onlyConfig === false) {
if (fs.existsSync(dirPath) === false) {
fs.mkdirSync(dirPath);
this.consoleLog(`${chalk.yellow.bold(relPath)} folder created`, options.silent);
}
else {
this.consoleLog(`${chalk.blue.bold(relPath)} folder already exists`, options.silent);
}
this.copyAndPrint(folder, subDirent, options);
}
}
else if (stat.isFile()) {
if (fs.existsSync(dirPath) === false ||
relPath === 'package.json' ||
relPath === 'tsconfig.json' ||
options.overwrite === true) {
switch (path.extname(dirPath)) {
case '.tsx':
case '.ts':
case '.js':
case '.json':
case '.html':
case '.jsx':
case '.vue':
case '.svelte':
let data = '';
if (fs.existsSync(dirPath) === true && (relPath === 'package.json' || relPath === 'tsconfig.json')) {
const destJson = fs.readFileSync(dirPath, { encoding: 'utf8' });
const sourceJson = fs.readFileSync(path.join(folder, subDirent), { encoding: 'utf8' });
data = deepmerge(JSON.parse(destJson), JSON.parse(sourceJson), {
arrayMerge: (destArray, sourceArray, options) => {
const mergedArray = destArray.concat(sourceArray);
return mergedArray.filter((item, index) => mergedArray.indexOf(item) === index);
},
});
data = prettier.format(JSON.stringify(data), {
parser: 'json',
printWidth: 120,
singleQuote: true,
});
}
else {
data = fs.readFileSync(path.join(folder, subDirent), { encoding: 'utf8' });
}
data = data.replace(PROJECT_NAME_REG_EXP, projectName);
try {
fs.unlinkSync(dirPath);
}
catch (error) { }
fs.writeFileSync(dirPath, data, { encoding: 'utf8' });
break;
default:
fs.copyFileSync(path.join(folder, subDirent), dirPath);
}
this.consoleLog(`${chalk.green.bold(relPath)} file created`, options.silent);
}
else {
this.consoleLog(`${chalk.blue.bold(relPath)} file already exists`, options.silent);
}
}
});
}
}
exports.AbstractCLI = AbstractCLI;
});
//# sourceMappingURL=abstract-cli.js.map