UNPKG

9.48 kBJavaScriptView Raw
1(function (factory) {
2 if (typeof module === "object" && typeof module.exports === "object") {
3 var v = factory(require, exports);
4 if (v !== undefined) module.exports = v;
5 }
6 else if (typeof define === "function" && define.amd) {
7 define(["require", "exports", "chalk", "child_process", "commander", "deepmerge", "fs", "path", "prettier"], factory);
8 }
9})(function (require, exports) {
10 "use strict";
11 Object.defineProperty(exports, "__esModule", { value: true });
12 exports.AbstractCLI = exports.getProjectName = void 0;
13 const chalk = require("chalk");
14 const child_process_1 = require("child_process");
15 const commander = require("commander");
16 const deepmerge = require("deepmerge");
17 const fs = require("fs");
18 const path = require("path");
19 const prettier = require("prettier");
20 function getProjectName(namespace = '') {
21 let projectName = path
22 .resolve(process.cwd())
23 .split('')
24 .reverse()
25 .join('')
26 .replace(/(\\|\/).+/g, '')
27 .split('')
28 .reverse()
29 .join('')
30 .toLowerCase();
31 if (typeof namespace === 'string' && namespace.length > 0) {
32 projectName = `@${namespace}/${projectName}`;
33 }
34 return projectName;
35 }
36 exports.getProjectName = getProjectName;
37 const START = Date.now();
38 const PROJECT_NAME_REG_EXP = new RegExp(`@template/[a-z0-9]+`, 'g');
39 class AbstractCLI {
40 constructor(name, version) {
41 this.program = new commander.Command();
42 this.commands = new Map();
43 this.name = name;
44 this.version = version;
45 this.program.name(name).version(version, '-v, --version', 'output the current version');
46 }
47 parse() {
48 this.program.parse(process.argv);
49 }
50 consoleLog(message, silent = false) {
51 if (silent === false) {
52 console.log(message);
53 }
54 }
55 addCommand(name, description, options, action) {
56 const command = this.program.command(name);
57 const actions = [];
58 this.commands.set(name, {
59 command,
60 actions,
61 });
62 this.setDescriptionToCommand(name, description);
63 this.addOptionToCommand(name, options);
64 this.addActionToCommand(name, action);
65 command.action((options) => {
66 let spawnArgs = [];
67 actions.forEach((action) => {
68 spawnArgs = spawnArgs.concat(action(options));
69 });
70 this.spawnCommand(spawnArgs, options.silent);
71 });
72 }
73 setDescriptionToCommand(name, description) {
74 var _a;
75 (_a = this.commands.get(name)) === null || _a === void 0 ? void 0 : _a.command.description(description);
76 }
77 addOptionToCommand(name, options) {
78 const names = Array.isArray(name) ? name : [name];
79 names.forEach((name) => {
80 var _a;
81 const command = (_a = this.commands.get(name)) === null || _a === void 0 ? void 0 : _a.command;
82 options.forEach((option) => command.option(option.flags, option.description, option.default));
83 });
84 }
85 addActionToCommand(name, action) {
86 const names = Array.isArray(name) ? name : [name];
87 names.forEach((name) => {
88 var _a;
89 (_a = this.commands.get(name)) === null || _a === void 0 ? void 0 : _a.actions.push(action);
90 });
91 }
92 addFirstActionToCommand(name, action) {
93 const names = Array.isArray(name) ? name : [name];
94 names.forEach((name) => {
95 var _a;
96 (_a = this.commands.get(name)) === null || _a === void 0 ? void 0 : _a.actions.unshift(action);
97 });
98 }
99 spawnCommand(args, silent = false) {
100 console.log(`
101`, `${chalk.magenta.bold(`☀ ${chalk.underline(`@leanup/cli`)}${this.name != '' ? `-${this.name}` : ''}`)}`, `(v${this.version})`, chalk.italic.gray('execute the following pure command ...'), `
102 >`, chalk.bold('npx'), chalk.italic(...args), `
103`);
104 return child_process_1.spawn('npx', args, {
105 cwd: process.cwd(),
106 shell: true,
107 stdio: silent === false ? 'inherit' : undefined,
108 }).on('exit', (code) => {
109 if (code > 0) {
110 console.log(`
111`, chalk.red.bold(`✘ ${chalk.underline(`@leanup/cli`)}`), chalk.italic.gray('command execution ended with error'), chalk.white(`(in ${Date.now() - START} ms)`));
112 process.exit(code);
113 }
114 console.log(`
115`, chalk.green.bold(`✔ ${chalk.underline(`@leanup/cli`)}`), chalk.italic.gray('command execution successfully completed'), chalk.white(`(in ${Date.now() - START} ms)`));
116 });
117 }
118 copyAndPrint(folder, subfolder = '', options) {
119 const projectName = getProjectName(options.namespace);
120 options.onlyConfig = options.onlyConfig === true;
121 const currentDir = path.join(folder, subfolder);
122 let dirs;
123 try {
124 dirs = fs.readdirSync(currentDir);
125 }
126 catch (error) {
127 dirs = [];
128 }
129 dirs.forEach((dirent) => {
130 const stat = fs.lstatSync(path.join(currentDir, dirent));
131 const subDirent = `${subfolder}/${dirent}`.replace(/^\/+/, '');
132 const relPath = `${subfolder}/${dirent.replace(/^_+/, '')}`.replace(/^\/+/, '');
133 const dirPath = path.join(process.cwd(), relPath);
134 if (stat.isDirectory()) {
135 if (options.onlyConfig === false) {
136 if (fs.existsSync(dirPath) === false) {
137 fs.mkdirSync(dirPath);
138 this.consoleLog(`${chalk.yellow.bold(relPath)} folder created`, options.silent);
139 }
140 else {
141 this.consoleLog(`${chalk.blue.bold(relPath)} folder already exists`, options.silent);
142 }
143 this.copyAndPrint(folder, subDirent, options);
144 }
145 }
146 else if (stat.isFile()) {
147 if (fs.existsSync(dirPath) === false ||
148 relPath === 'package.json' ||
149 relPath === 'tsconfig.json' ||
150 options.overwrite === true) {
151 switch (path.extname(dirPath)) {
152 case '.tsx':
153 case '.ts':
154 case '.js':
155 case '.json':
156 case '.html':
157 case '.jsx':
158 case '.vue':
159 case '.svelte':
160 let data = '';
161 if (fs.existsSync(dirPath) === true && (relPath === 'package.json' || relPath === 'tsconfig.json')) {
162 const destJson = fs.readFileSync(dirPath, { encoding: 'utf8' });
163 const sourceJson = fs.readFileSync(path.join(folder, subDirent), { encoding: 'utf8' });
164 data = deepmerge(JSON.parse(destJson), JSON.parse(sourceJson), {
165 arrayMerge: (destArray, sourceArray, options) => {
166 const mergedArray = destArray.concat(sourceArray);
167 return mergedArray.filter((item, index) => mergedArray.indexOf(item) === index);
168 },
169 });
170 data = prettier.format(JSON.stringify(data), {
171 parser: 'json',
172 printWidth: 120,
173 singleQuote: true,
174 });
175 }
176 else {
177 data = fs.readFileSync(path.join(folder, subDirent), { encoding: 'utf8' });
178 }
179 data = data.replace(PROJECT_NAME_REG_EXP, projectName);
180 try {
181 fs.unlinkSync(dirPath);
182 }
183 catch (error) { }
184 fs.writeFileSync(dirPath, data, { encoding: 'utf8' });
185 break;
186 default:
187 fs.copyFileSync(path.join(folder, subDirent), dirPath);
188 }
189 this.consoleLog(`${chalk.green.bold(relPath)} file created`, options.silent);
190 }
191 else {
192 this.consoleLog(`${chalk.blue.bold(relPath)} file already exists`, options.silent);
193 }
194 }
195 });
196 }
197 }
198 exports.AbstractCLI = AbstractCLI;
199});
200//# sourceMappingURL=abstract-cli.js.map
\No newline at end of file