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 (0, 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 |
|
\ | No newline at end of file |