creatium 0.1.17 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -676
- package/README.md +6 -10
- package/dist/index.d.mts +881 -0
- package/dist/index.d.ts +881 -0
- package/dist/{main.mjs → index.mjs} +330 -1080
- package/dist/shared/creatium.v0AbQ44Q.mjs +5912 -0
- package/dist/utils.d.mts +1013 -0
- package/dist/utils.d.ts +1013 -0
- package/dist/utils.mjs +2 -0
- package/package.json +17 -29
- package/dist/main.cjs +0 -2061
- package/dist/main.d.cts +0 -1672
- package/dist/main.d.mts +0 -1672
- package/dist/main.d.ts +0 -1672
package/dist/main.cjs
DELETED
|
@@ -1,2061 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const deepmergeTs = require('deepmerge-ts');
|
|
4
|
-
const process$1 = require('node:process');
|
|
5
|
-
const node_child_process = require('node:child_process');
|
|
6
|
-
const yargs = require('yargs');
|
|
7
|
-
const helpers = require('yargs/helpers');
|
|
8
|
-
const p = require('@clack/prompts');
|
|
9
|
-
const core = require('@clack/core');
|
|
10
|
-
const gradientString = require('gradient-string');
|
|
11
|
-
const node_util = require('node:util');
|
|
12
|
-
const stringWidth = require('string-width');
|
|
13
|
-
const boxen = require('@visulima/boxen');
|
|
14
|
-
const Table = require('cli-table3');
|
|
15
|
-
const columnify = require('columnify');
|
|
16
|
-
const promises = require('node:fs/promises');
|
|
17
|
-
const node_path = require('node:path');
|
|
18
|
-
const node_url = require('node:url');
|
|
19
|
-
const glob = require('tiny-glob');
|
|
20
|
-
const node_os = require('node:os');
|
|
21
|
-
|
|
22
|
-
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
23
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
24
|
-
|
|
25
|
-
function _interopNamespaceCompat(e) {
|
|
26
|
-
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
27
|
-
const n = Object.create(null);
|
|
28
|
-
if (e) {
|
|
29
|
-
for (const k in e) {
|
|
30
|
-
n[k] = e[k];
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
n.default = e;
|
|
34
|
-
return n;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const process__default = /*#__PURE__*/_interopDefaultCompat(process$1);
|
|
38
|
-
const yargs__default = /*#__PURE__*/_interopDefaultCompat(yargs);
|
|
39
|
-
const p__namespace = /*#__PURE__*/_interopNamespaceCompat(p);
|
|
40
|
-
const gradientString__default = /*#__PURE__*/_interopDefaultCompat(gradientString);
|
|
41
|
-
const stringWidth__default = /*#__PURE__*/_interopDefaultCompat(stringWidth);
|
|
42
|
-
const Table__default = /*#__PURE__*/_interopDefaultCompat(Table);
|
|
43
|
-
const columnify__default = /*#__PURE__*/_interopDefaultCompat(columnify);
|
|
44
|
-
const glob__default = /*#__PURE__*/_interopDefaultCompat(glob);
|
|
45
|
-
|
|
46
|
-
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
47
|
-
const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
48
|
-
const isWebWorker = typeof self === "object" && self.constructor && self.constructor.name === "DedicatedWorkerGlobalScope";
|
|
49
|
-
const isJsDom = typeof window !== "undefined" && window.name === "nodejs" || typeof navigator !== "undefined" && "userAgent" in navigator && typeof navigator.userAgent === "string" && (navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom"));
|
|
50
|
-
const isDeno = typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined";
|
|
51
|
-
const isBun = typeof process !== "undefined" && process.versions != null && process.versions.bun != null;
|
|
52
|
-
const env$2 = {
|
|
53
|
-
isBrowser,
|
|
54
|
-
isWebWorker,
|
|
55
|
-
isNode,
|
|
56
|
-
isJsDom,
|
|
57
|
-
isDeno,
|
|
58
|
-
isBun
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const execChild = async (cmd) => {
|
|
62
|
-
return new Promise((resolve, reject) => {
|
|
63
|
-
const options = {
|
|
64
|
-
shell: true,
|
|
65
|
-
stdio: "pipe"
|
|
66
|
-
};
|
|
67
|
-
const childProcess = node_child_process.spawn(cmd, options);
|
|
68
|
-
let stdout = "", stderr = "";
|
|
69
|
-
childProcess.stdout?.on("data", (data) => {
|
|
70
|
-
stdout += data.toString();
|
|
71
|
-
});
|
|
72
|
-
childProcess.stderr?.on("data", (data) => {
|
|
73
|
-
stderr += data.toString();
|
|
74
|
-
});
|
|
75
|
-
childProcess.on("close", (code) => {
|
|
76
|
-
if (code === 0) {
|
|
77
|
-
resolve({
|
|
78
|
-
stdout,
|
|
79
|
-
stderr
|
|
80
|
-
});
|
|
81
|
-
} else {
|
|
82
|
-
const data = {
|
|
83
|
-
code,
|
|
84
|
-
stdout,
|
|
85
|
-
stderr
|
|
86
|
-
};
|
|
87
|
-
reject(data);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
childProcess.on("error", (err) => {
|
|
91
|
-
reject(err);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
};
|
|
95
|
-
const existsLocalBin = async (binName) => {
|
|
96
|
-
const command = process__default.platform === "win32" ? `where ${binName}` : `which ${binName}`;
|
|
97
|
-
try {
|
|
98
|
-
await execChild(command);
|
|
99
|
-
return true;
|
|
100
|
-
} catch (_e) {
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const hideBin = helpers.hideBin;
|
|
106
|
-
const createCli = async (options) => {
|
|
107
|
-
const {
|
|
108
|
-
args = process.argv,
|
|
109
|
-
fn
|
|
110
|
-
} = options;
|
|
111
|
-
const bin = yargs__default(args);
|
|
112
|
-
await fn(bin);
|
|
113
|
-
bin.help();
|
|
114
|
-
bin.parse();
|
|
115
|
-
return bin;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const cTypes = [
|
|
119
|
-
// ForegroundColors
|
|
120
|
-
"black",
|
|
121
|
-
"blackBright",
|
|
122
|
-
"blue",
|
|
123
|
-
"blueBright",
|
|
124
|
-
"cyan",
|
|
125
|
-
"cyanBright",
|
|
126
|
-
"gray",
|
|
127
|
-
"green",
|
|
128
|
-
"greenBright",
|
|
129
|
-
"grey",
|
|
130
|
-
"magenta",
|
|
131
|
-
"magentaBright",
|
|
132
|
-
"red",
|
|
133
|
-
"redBright",
|
|
134
|
-
"white",
|
|
135
|
-
"whiteBright",
|
|
136
|
-
"yellow",
|
|
137
|
-
"yellowBright",
|
|
138
|
-
// BackgroundColors
|
|
139
|
-
"bgBlack",
|
|
140
|
-
"bgBlackBright",
|
|
141
|
-
"bgBlue",
|
|
142
|
-
"bgBlueBright",
|
|
143
|
-
"bgCyan",
|
|
144
|
-
"bgCyanBright",
|
|
145
|
-
"bgGray",
|
|
146
|
-
"bgGreen",
|
|
147
|
-
"bgGreenBright",
|
|
148
|
-
"bgGrey",
|
|
149
|
-
"bgMagenta",
|
|
150
|
-
"bgMagentaBright",
|
|
151
|
-
"bgRed",
|
|
152
|
-
"bgRedBright",
|
|
153
|
-
"bgWhite",
|
|
154
|
-
"bgWhiteBright",
|
|
155
|
-
"bgYellow",
|
|
156
|
-
"bgYellowBright",
|
|
157
|
-
// Modifiers
|
|
158
|
-
"blink",
|
|
159
|
-
"bold",
|
|
160
|
-
"dim",
|
|
161
|
-
"doubleunderline",
|
|
162
|
-
"framed",
|
|
163
|
-
"hidden",
|
|
164
|
-
"inverse",
|
|
165
|
-
"italic",
|
|
166
|
-
"overlined",
|
|
167
|
-
"reset",
|
|
168
|
-
"strikethrough",
|
|
169
|
-
"underline"
|
|
170
|
-
];
|
|
171
|
-
const _color = (t, v) => node_util.styleText(t, v);
|
|
172
|
-
const _colorObj = cTypes.reduce((acc, t) => {
|
|
173
|
-
acc[t] = (v) => _color(t, v);
|
|
174
|
-
return acc;
|
|
175
|
-
}, {});
|
|
176
|
-
const color = _colorObj;
|
|
177
|
-
const gradient = (txt, colors, opts) => {
|
|
178
|
-
return gradientString__default(colors, opts).multiline(txt);
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
const line = ({
|
|
182
|
-
title,
|
|
183
|
-
lineChar = "\u23AF",
|
|
184
|
-
align = "center"
|
|
185
|
-
}) => {
|
|
186
|
-
const lineCharLength = stringWidth__default(lineChar);
|
|
187
|
-
const totalWidth = process.stdout.columns;
|
|
188
|
-
const textLength = title ? stringWidth__default(title) : 0;
|
|
189
|
-
const width = Math.floor((totalWidth - textLength) / (2 * lineCharLength));
|
|
190
|
-
const line2 = lineChar.repeat(width);
|
|
191
|
-
if (align === "left") return title + line2 + line2;
|
|
192
|
-
else if (align === "right") return line2 + line2 + title;
|
|
193
|
-
return line2 + title + line2;
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const table = (data, options) => {
|
|
197
|
-
const _table = new Table__default(options);
|
|
198
|
-
_table.push(...data);
|
|
199
|
-
return _table.toString();
|
|
200
|
-
};
|
|
201
|
-
const box = (text, options) => boxen.boxen(text, options);
|
|
202
|
-
const columns = (data, options) => columnify__default(data, options);
|
|
203
|
-
|
|
204
|
-
const style$1 = {
|
|
205
|
-
color,
|
|
206
|
-
gradient,
|
|
207
|
-
box,
|
|
208
|
-
columns,
|
|
209
|
-
table,
|
|
210
|
-
line
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const isUnicodeSupported = () => {
|
|
214
|
-
if (process__default.platform !== "win32") return process__default.env.TERM !== "linux";
|
|
215
|
-
return Boolean(process__default.env.WT_SESSION) || Boolean(process__default.env.TERMINUS_SUBLIME) || process__default.env.ConEmuTask === "{cmd::Cmder}" || process__default.env.TERM_PROGRAM === "Terminus-Sublime" || process__default.env.TERM_PROGRAM === "vscode" || process__default.env.TERM === "xterm-256color" || process__default.env.TERM === "alacritty" || process__default.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
216
|
-
};
|
|
217
|
-
const unicode = isUnicodeSupported();
|
|
218
|
-
const s = (c, fallback) => unicode ? c : fallback;
|
|
219
|
-
const symbols = {
|
|
220
|
-
STEP_ACTIVE: s("\u25C6", "*"),
|
|
221
|
-
STEP_CANCEL: s("\u25A0", "x"),
|
|
222
|
-
STEP_ERROR: s("\u25B2", "x"),
|
|
223
|
-
STEP_SUBMIT: s("\u25C7", "o"),
|
|
224
|
-
BAR: s("\u2502", "|"),
|
|
225
|
-
BAR_END: s("\u2514", "\u2014")
|
|
226
|
-
};
|
|
227
|
-
const symbol = (state) => {
|
|
228
|
-
if (state === "initial" || state === "active")
|
|
229
|
-
return color.cyan(symbols.STEP_ACTIVE);
|
|
230
|
-
else if (state === "cancel")
|
|
231
|
-
return color.red(symbols.STEP_CANCEL);
|
|
232
|
-
else if (state === "error")
|
|
233
|
-
return color.yellow(symbols.STEP_ERROR);
|
|
234
|
-
else if (state === "submit")
|
|
235
|
-
return color.green(symbols.STEP_SUBMIT);
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
async function number(opts) {
|
|
239
|
-
return new core.TextPrompt({
|
|
240
|
-
validate: (value) => {
|
|
241
|
-
const errorDefault = "Value must be a number without";
|
|
242
|
-
const spaces = /\s/.test(value);
|
|
243
|
-
const isNum = typeof Number(value) === "number" && !isNaN(Number(value));
|
|
244
|
-
if (!value || !isNum) return opts.errorText ? opts.errorText : errorDefault;
|
|
245
|
-
if (spaces) return opts.errorText ? opts.errorText : errorDefault;
|
|
246
|
-
if (opts.validate) return opts.validate(value);
|
|
247
|
-
},
|
|
248
|
-
placeholder: opts.placeholder,
|
|
249
|
-
defaultValue: opts.defaultValue,
|
|
250
|
-
initialValue: opts.initialValue,
|
|
251
|
-
render() {
|
|
252
|
-
const title = `${color.gray(symbols.BAR)}
|
|
253
|
-
${symbol(this.state)} ${opts.message}
|
|
254
|
-
`;
|
|
255
|
-
const placeholder = opts.placeholder ? color.inverse(opts.placeholder[0]) + color.dim(opts.placeholder.slice(1)) : color.inverse(color.hidden("_"));
|
|
256
|
-
const value = !this.value ? placeholder : this.valueWithCursor;
|
|
257
|
-
switch (this.state) {
|
|
258
|
-
case "error":
|
|
259
|
-
return `${title.trim()}
|
|
260
|
-
${color.yellow(symbols.BAR)} ${value}
|
|
261
|
-
${color.yellow(
|
|
262
|
-
symbols.BAR_END
|
|
263
|
-
)} ${color.yellow(this.error)}
|
|
264
|
-
`;
|
|
265
|
-
case "submit":
|
|
266
|
-
return `${title}${color.gray(symbols.BAR)} ${color.dim(this.value || opts.placeholder)}`;
|
|
267
|
-
case "cancel":
|
|
268
|
-
return `${title}${color.gray(symbols.BAR)} ${color.strikethrough(
|
|
269
|
-
color.dim(this.value ?? "")
|
|
270
|
-
)}${this.value?.trim() ? "\n" + color.gray(symbols.BAR) : ""}`;
|
|
271
|
-
default:
|
|
272
|
-
return `${title}${color.cyan(symbols.BAR)} ${value}
|
|
273
|
-
${color.cyan(symbols.BAR_END)}
|
|
274
|
-
`;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}).prompt();
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const promptLineMethods = {
|
|
281
|
-
message: "message"};
|
|
282
|
-
|
|
283
|
-
const clackPrompts = p__namespace;
|
|
284
|
-
const printOptions = {
|
|
285
|
-
/**
|
|
286
|
-
* Logs a table in the prompt line.
|
|
287
|
-
*/
|
|
288
|
-
table: ({
|
|
289
|
-
value,
|
|
290
|
-
opts,
|
|
291
|
-
type = promptLineMethods.message
|
|
292
|
-
}) => p__namespace.log[type](table(value, opts)),
|
|
293
|
-
/**
|
|
294
|
-
* Logs data formatted into aligned columns in the prompt line.
|
|
295
|
-
*/
|
|
296
|
-
columns: ({
|
|
297
|
-
value,
|
|
298
|
-
opts,
|
|
299
|
-
type = promptLineMethods.message
|
|
300
|
-
}) => p__namespace.log[type](columns(value, opts)),
|
|
301
|
-
/**
|
|
302
|
-
* Logs a styled box in the prompt line.
|
|
303
|
-
*/
|
|
304
|
-
box: ({
|
|
305
|
-
value,
|
|
306
|
-
opts,
|
|
307
|
-
type = promptLineMethods.message
|
|
308
|
-
}) => p__namespace.log[type](box(value, opts))
|
|
309
|
-
};
|
|
310
|
-
const corePromptLine = {
|
|
311
|
-
...clackPrompts,
|
|
312
|
-
number,
|
|
313
|
-
...printOptions
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
const replacePlaceholders = async (props) => {
|
|
317
|
-
const { content, params, transform, opts } = props;
|
|
318
|
-
const { prefix, suffix } = opts?.mark || {
|
|
319
|
-
prefix: "{{",
|
|
320
|
-
suffix: "}}"
|
|
321
|
-
};
|
|
322
|
-
const escapeRegExp = (v) => v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
323
|
-
const regex = new RegExp(
|
|
324
|
-
`${escapeRegExp(prefix)}\\s*([^}]+?)\\s*${escapeRegExp(suffix)}`,
|
|
325
|
-
"g"
|
|
326
|
-
);
|
|
327
|
-
const getValue = (obj, path) => {
|
|
328
|
-
const parts = path.split(".");
|
|
329
|
-
let result2 = obj;
|
|
330
|
-
for (const part of parts) {
|
|
331
|
-
if (result2 === void 0) return void 0;
|
|
332
|
-
if (part.includes("[") && part.includes("]")) {
|
|
333
|
-
const [arrayName, indexStr] = part.split("[");
|
|
334
|
-
const index = parseInt(indexStr.replace("]", ""), 10);
|
|
335
|
-
result2 = result2[arrayName]?.[index];
|
|
336
|
-
} else {
|
|
337
|
-
result2 = result2[part];
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return result2;
|
|
341
|
-
};
|
|
342
|
-
const replaceAsync = async (match, key) => {
|
|
343
|
-
if (transform) {
|
|
344
|
-
const transformed = await transform(key);
|
|
345
|
-
if (transformed !== key) return transformed;
|
|
346
|
-
}
|
|
347
|
-
const value = getValue(params, key);
|
|
348
|
-
if (value === void 0) {
|
|
349
|
-
if (opts?.throw) throw new Error(`Placeholder ${key} not found`);
|
|
350
|
-
return match;
|
|
351
|
-
}
|
|
352
|
-
return String(value);
|
|
353
|
-
};
|
|
354
|
-
let result = content;
|
|
355
|
-
const matches = [...content.matchAll(regex)];
|
|
356
|
-
for (const match of matches) {
|
|
357
|
-
const [fullMatch, key] = match;
|
|
358
|
-
const replacement = await replaceAsync(fullMatch, key);
|
|
359
|
-
result = result.replace(fullMatch, replacement);
|
|
360
|
-
}
|
|
361
|
-
return result;
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
const getHomeDir = node_os.homedir;
|
|
365
|
-
const getTempDir = () => node_os.tmpdir();
|
|
366
|
-
const getPlatform = async () => {
|
|
367
|
-
const p = node_os.platform();
|
|
368
|
-
switch (p) {
|
|
369
|
-
case "win32":
|
|
370
|
-
return "windows";
|
|
371
|
-
case "darwin":
|
|
372
|
-
return "macos";
|
|
373
|
-
case "linux":
|
|
374
|
-
return "linux";
|
|
375
|
-
default:
|
|
376
|
-
return "unknown";
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
function getArch() {
|
|
380
|
-
const architecture = node_os.arch();
|
|
381
|
-
switch (architecture) {
|
|
382
|
-
case "arm64":
|
|
383
|
-
return "arm64";
|
|
384
|
-
case "arm":
|
|
385
|
-
return "arm64";
|
|
386
|
-
// As 'arm' is also treated as 'arm64'.
|
|
387
|
-
case "x64":
|
|
388
|
-
return "x64";
|
|
389
|
-
default:
|
|
390
|
-
return "unknown";
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
const resolvePath = node_path.resolve;
|
|
395
|
-
const relativePath = node_path.relative;
|
|
396
|
-
const getExtName = node_path.extname;
|
|
397
|
-
const getDirName = node_path.dirname;
|
|
398
|
-
const getBaseName = node_path.basename;
|
|
399
|
-
const isAbsolutePath = node_path.isAbsolute;
|
|
400
|
-
const normalizePath = node_path.normalize;
|
|
401
|
-
const writeFile = promises.writeFile;
|
|
402
|
-
const getPaths = glob__default;
|
|
403
|
-
const arePathsEqual = (path1, path2) => {
|
|
404
|
-
const normalizedPath1 = resolvePath(path1);
|
|
405
|
-
const normalizedPath2 = resolvePath(path2);
|
|
406
|
-
return normalizedPath1 === normalizedPath2;
|
|
407
|
-
};
|
|
408
|
-
const isPath = (str) => {
|
|
409
|
-
if (node_path.isAbsolute(str) || /^(\.\/|\.\.\/|[A-Za-z]:\\|\/)/.test(str)) {
|
|
410
|
-
if (node_path.isAbsolute(str) || /^(\.\/|\.\.\/|[A-Za-z]:\\|\/)/.test(str)) {
|
|
411
|
-
if (/\s(?!\\)/.test(str) && !/\\\s/.test(str))
|
|
412
|
-
return false;
|
|
413
|
-
try {
|
|
414
|
-
const normalizedPath = node_path.join(str);
|
|
415
|
-
return normalizedPath !== "";
|
|
416
|
-
} catch {
|
|
417
|
-
return false;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
return false;
|
|
422
|
-
};
|
|
423
|
-
const ensureDir = async (path) => {
|
|
424
|
-
const exist = await existsDir(path);
|
|
425
|
-
if (!exist) await createDir(path);
|
|
426
|
-
};
|
|
427
|
-
const readDir = async (path) => {
|
|
428
|
-
path = validateHomeDir(path);
|
|
429
|
-
return await promises.readdir(path, { withFileTypes: true });
|
|
430
|
-
};
|
|
431
|
-
async function getFilteredFileNames({
|
|
432
|
-
path,
|
|
433
|
-
extensions = []
|
|
434
|
-
}) {
|
|
435
|
-
const files = await readDir(path);
|
|
436
|
-
const filteredFileNames = files.filter((file) => {
|
|
437
|
-
const ext = getExtName(file.name);
|
|
438
|
-
return extensions.includes(ext);
|
|
439
|
-
}).map((file) => getBaseName(file.name, getExtName(file.name)));
|
|
440
|
-
return filteredFileNames;
|
|
441
|
-
}
|
|
442
|
-
const getCurrentDir = (path = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('main.cjs', document.baseURI).href))) => getDirName(node_url.fileURLToPath(path));
|
|
443
|
-
function joinPath(...paths) {
|
|
444
|
-
return node_path.join(...paths);
|
|
445
|
-
}
|
|
446
|
-
const getAbsolutePath = node_path.resolve;
|
|
447
|
-
function validateHomeDir(path) {
|
|
448
|
-
let resolvedPath = path;
|
|
449
|
-
if (path.startsWith("~/")) {
|
|
450
|
-
resolvedPath = path.replace(/^~(?=$|\/|\\)/, getHomeDir());
|
|
451
|
-
}
|
|
452
|
-
return getAbsolutePath(resolvedPath);
|
|
453
|
-
}
|
|
454
|
-
const readFile = promises.readFile;
|
|
455
|
-
async function removeDir(path) {
|
|
456
|
-
try {
|
|
457
|
-
path = validateHomeDir(path);
|
|
458
|
-
await promises.rm(path, {
|
|
459
|
-
recursive: true,
|
|
460
|
-
force: true
|
|
461
|
-
});
|
|
462
|
-
} catch (error) {
|
|
463
|
-
throw new Error(`Error removing ${path}: ${error.message}`);
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
async function removeDirIfExist(path) {
|
|
467
|
-
path = validateHomeDir(path);
|
|
468
|
-
const exists = await existsDir(path);
|
|
469
|
-
if (exists) await removeDir(path);
|
|
470
|
-
}
|
|
471
|
-
async function removePathIfExist(path) {
|
|
472
|
-
path = validateHomeDir(path);
|
|
473
|
-
const isDir = await isDirectory(path);
|
|
474
|
-
if (isDir) await removeDirIfExist(path);
|
|
475
|
-
else await removeFileIfExist(path);
|
|
476
|
-
}
|
|
477
|
-
async function removeFileIfExist(path) {
|
|
478
|
-
path = validateHomeDir(path);
|
|
479
|
-
const exists = await existsFile(path);
|
|
480
|
-
if (exists) await promises.unlink(path);
|
|
481
|
-
}
|
|
482
|
-
async function removeFile(path) {
|
|
483
|
-
await promises.unlink(path);
|
|
484
|
-
}
|
|
485
|
-
async function isDirectory(path) {
|
|
486
|
-
path = validateHomeDir(path);
|
|
487
|
-
const stats = await promises.stat(path);
|
|
488
|
-
return stats.isDirectory();
|
|
489
|
-
}
|
|
490
|
-
async function createDir(path) {
|
|
491
|
-
try {
|
|
492
|
-
path = validateHomeDir(path);
|
|
493
|
-
await promises.mkdir(path, { recursive: true });
|
|
494
|
-
} catch (error) {
|
|
495
|
-
throw Error(`Error creating the directory: ${error}`);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
async function existsDir(path) {
|
|
499
|
-
try {
|
|
500
|
-
path = validateHomeDir(path);
|
|
501
|
-
await promises.access(path, promises.constants.F_OK);
|
|
502
|
-
const stats = await promises.stat(path);
|
|
503
|
-
return stats.isDirectory();
|
|
504
|
-
} catch (error) {
|
|
505
|
-
if (error.code === "ENOENT") {
|
|
506
|
-
return false;
|
|
507
|
-
} else {
|
|
508
|
-
throw error;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
async function existsFile(path) {
|
|
513
|
-
try {
|
|
514
|
-
path = validateHomeDir(path);
|
|
515
|
-
await promises.access(path);
|
|
516
|
-
const stats = await promises.stat(path);
|
|
517
|
-
return stats.isFile();
|
|
518
|
-
} catch (error) {
|
|
519
|
-
if (error.code === "ENOENT") {
|
|
520
|
-
return false;
|
|
521
|
-
} else {
|
|
522
|
-
throw error;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
async function writeFileContent(path, content) {
|
|
527
|
-
path = validateHomeDir(path);
|
|
528
|
-
await promises.writeFile(path, content);
|
|
529
|
-
}
|
|
530
|
-
async function existsPath(path) {
|
|
531
|
-
const isFile = await existsFile(path);
|
|
532
|
-
if (isFile) return true;
|
|
533
|
-
const isDir = await existsDir(path);
|
|
534
|
-
return isDir;
|
|
535
|
-
}
|
|
536
|
-
const copyFile = async ({
|
|
537
|
-
input,
|
|
538
|
-
output
|
|
539
|
-
}) => {
|
|
540
|
-
try {
|
|
541
|
-
await promises.copyFile(input, output);
|
|
542
|
-
} catch (error) {
|
|
543
|
-
console.error(error);
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
const copyDir = async ({
|
|
547
|
-
input,
|
|
548
|
-
output
|
|
549
|
-
}) => {
|
|
550
|
-
const _copyDir = async ({
|
|
551
|
-
input: input2,
|
|
552
|
-
output: output2
|
|
553
|
-
}) => {
|
|
554
|
-
if (!await existsDir(input2)) throw new Error(`Input directory does not exist`);
|
|
555
|
-
const entries = await readDir(input2);
|
|
556
|
-
const exist = await existsDir(output2);
|
|
557
|
-
if (!exist) await createDir(output2);
|
|
558
|
-
for (const entry of entries) {
|
|
559
|
-
const srcPath = node_path.join(input2, entry.name);
|
|
560
|
-
const destPath = node_path.join(output2, entry.name);
|
|
561
|
-
if (entry.isDirectory()) {
|
|
562
|
-
await _copyDir({
|
|
563
|
-
input: srcPath,
|
|
564
|
-
output: destPath
|
|
565
|
-
});
|
|
566
|
-
} else {
|
|
567
|
-
await copyFile({
|
|
568
|
-
input: srcPath,
|
|
569
|
-
output: destPath
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
};
|
|
574
|
-
try {
|
|
575
|
-
await _copyDir({
|
|
576
|
-
input,
|
|
577
|
-
output
|
|
578
|
-
});
|
|
579
|
-
} catch (error) {
|
|
580
|
-
if (error instanceof Error)
|
|
581
|
-
throw new Error(`Error copying directory "${input}" to "${output}": ${error.message}`);
|
|
582
|
-
throw new Error(`Error copying directory: ${error}`);
|
|
583
|
-
}
|
|
584
|
-
};
|
|
585
|
-
const createSymlink = async ({
|
|
586
|
-
input,
|
|
587
|
-
output
|
|
588
|
-
}) => {
|
|
589
|
-
try {
|
|
590
|
-
await promises.access(output);
|
|
591
|
-
} catch (error) {
|
|
592
|
-
if (error.code === "ENOENT") {
|
|
593
|
-
await promises.mkdir(output, { recursive: true });
|
|
594
|
-
} else {
|
|
595
|
-
throw `\u274C\u{1F517} ${error}`;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
const sourceStat = await promises.lstat(input);
|
|
599
|
-
const isWin = process__default.platform === "win32";
|
|
600
|
-
if (sourceStat.isDirectory()) {
|
|
601
|
-
if (isWin) {
|
|
602
|
-
await promises.symlink(input, node_path.join(output, node_path.basename(input)), "junction");
|
|
603
|
-
} else {
|
|
604
|
-
await promises.symlink(input, node_path.join(output, node_path.basename(input)), "dir");
|
|
605
|
-
}
|
|
606
|
-
} else if (sourceStat.isFile()) {
|
|
607
|
-
await promises.symlink(input, node_path.join(output, node_path.basename(input)));
|
|
608
|
-
}
|
|
609
|
-
console.log(`\u{1F517} symlink: "${input}" to "${output}".`);
|
|
610
|
-
};
|
|
611
|
-
|
|
612
|
-
const homedir = getHomeDir();
|
|
613
|
-
const tmpdir = getTempDir();
|
|
614
|
-
const { env: env$1 } = process__default;
|
|
615
|
-
const macos = (name) => {
|
|
616
|
-
const library = joinPath(homedir, "Library");
|
|
617
|
-
return {
|
|
618
|
-
data: joinPath(library, "Application Support", name),
|
|
619
|
-
config: joinPath(library, "Preferences", name),
|
|
620
|
-
cache: joinPath(library, "Caches", name),
|
|
621
|
-
log: joinPath(library, "Logs", name),
|
|
622
|
-
temp: joinPath(tmpdir, name)
|
|
623
|
-
};
|
|
624
|
-
};
|
|
625
|
-
const windows = (name) => {
|
|
626
|
-
const appData = env$1.APPDATA || joinPath(homedir, "AppData", "Roaming");
|
|
627
|
-
const localAppData = env$1.LOCALAPPDATA || joinPath(homedir, "AppData", "Local");
|
|
628
|
-
return {
|
|
629
|
-
// Data/config/cache/log are invented by me as Windows isn't opinionated about this
|
|
630
|
-
data: joinPath(localAppData, name, "Data"),
|
|
631
|
-
config: joinPath(appData, name, "Config"),
|
|
632
|
-
cache: joinPath(localAppData, name, "Cache"),
|
|
633
|
-
log: joinPath(localAppData, name, "Log"),
|
|
634
|
-
temp: joinPath(tmpdir, name)
|
|
635
|
-
};
|
|
636
|
-
};
|
|
637
|
-
const linux = (name) => {
|
|
638
|
-
const username = getBaseName(homedir);
|
|
639
|
-
return {
|
|
640
|
-
data: joinPath(env$1.XDG_DATA_HOME || joinPath(homedir, ".local", "share"), name),
|
|
641
|
-
config: joinPath(env$1.XDG_CONFIG_HOME || joinPath(homedir, ".config"), name),
|
|
642
|
-
cache: joinPath(env$1.XDG_CACHE_HOME || joinPath(homedir, ".cache"), name),
|
|
643
|
-
// https://wiki.debian.org/XDGBaseDirectorySpecification#state
|
|
644
|
-
log: joinPath(env$1.XDG_STATE_HOME || joinPath(homedir, ".local", "state"), name),
|
|
645
|
-
temp: joinPath(tmpdir, username, name)
|
|
646
|
-
};
|
|
647
|
-
};
|
|
648
|
-
const getSystemEnvPaths = ({
|
|
649
|
-
name,
|
|
650
|
-
suffix = "nodejs"
|
|
651
|
-
}) => {
|
|
652
|
-
if (typeof name !== "string")
|
|
653
|
-
throw new TypeError(`Expected a string, got ${typeof name}`);
|
|
654
|
-
if (suffix) name += `-${suffix}`;
|
|
655
|
-
if (process__default.platform === "darwin") return macos(name);
|
|
656
|
-
if (process__default.platform === "win32") return windows(name);
|
|
657
|
-
return linux(name);
|
|
658
|
-
};
|
|
659
|
-
|
|
660
|
-
const getFileContent = async (path) => {
|
|
661
|
-
path = validateHomeDir(path);
|
|
662
|
-
const fileContentBuffer = await readFile(path);
|
|
663
|
-
const fileContent = fileContentBuffer.toString("utf8");
|
|
664
|
-
return fileContent;
|
|
665
|
-
};
|
|
666
|
-
const getObjectFromJSONContent = async (content) => {
|
|
667
|
-
const r = JSON.parse(content);
|
|
668
|
-
return r;
|
|
669
|
-
};
|
|
670
|
-
const getObjectFromJSONFile = async (path) => {
|
|
671
|
-
try {
|
|
672
|
-
const fileContent = await getFileContent(path);
|
|
673
|
-
return await getObjectFromJSONContent(fileContent);
|
|
674
|
-
} catch (error) {
|
|
675
|
-
throw new Error(`Error reading JSON file ${path}: ${error.message}`);
|
|
676
|
-
}
|
|
677
|
-
};
|
|
678
|
-
|
|
679
|
-
const cache = async (opts) => {
|
|
680
|
-
const {
|
|
681
|
-
id,
|
|
682
|
-
values,
|
|
683
|
-
projectName,
|
|
684
|
-
cwd,
|
|
685
|
-
suffix
|
|
686
|
-
} = opts;
|
|
687
|
-
const dir = cwd || getSystemEnvPaths({
|
|
688
|
-
name: projectName,
|
|
689
|
-
suffix
|
|
690
|
-
}).config;
|
|
691
|
-
const path = joinPath(dir, `config.json`);
|
|
692
|
-
const exists = await existsFile(path);
|
|
693
|
-
const defaultValues = { [id]: values };
|
|
694
|
-
const merge = deepmergeTs.deepmergeCustom({ mergeArrays: false });
|
|
695
|
-
const getCachedDataFromFile = async () => {
|
|
696
|
-
try {
|
|
697
|
-
const data = await getObjectFromJSONFile(path);
|
|
698
|
-
return data;
|
|
699
|
-
} catch {
|
|
700
|
-
return defaultValues;
|
|
701
|
-
}
|
|
702
|
-
};
|
|
703
|
-
let cachedData = exists ? await getCachedDataFromFile() : defaultValues;
|
|
704
|
-
const set = async (obj) => {
|
|
705
|
-
const exists2 = await existsFile(path);
|
|
706
|
-
if (!exists2) await ensureDir(dir);
|
|
707
|
-
const updatedData = merge(cachedData, { [id]: obj });
|
|
708
|
-
await writeFile(path, JSON.stringify(updatedData, null, 2));
|
|
709
|
-
cachedData = updatedData;
|
|
710
|
-
};
|
|
711
|
-
const get = async (v) => {
|
|
712
|
-
if (typeof v === "string") {
|
|
713
|
-
if (!cachedData[id] || typeof cachedData[id][v] === "undefined") return void 0;
|
|
714
|
-
return cachedData[id][v];
|
|
715
|
-
}
|
|
716
|
-
return cachedData[id];
|
|
717
|
-
};
|
|
718
|
-
const reset = async () => await set(values);
|
|
719
|
-
if (!exists) await set(values);
|
|
720
|
-
else {
|
|
721
|
-
const updatedData = merge({ [id]: values }, cachedData);
|
|
722
|
-
await set(updatedData[id]);
|
|
723
|
-
}
|
|
724
|
-
return {
|
|
725
|
-
/**
|
|
726
|
-
* The default values for the cache.
|
|
727
|
-
*/
|
|
728
|
-
defaultValues: values,
|
|
729
|
-
/**
|
|
730
|
-
* Retrieve a value from the cache.
|
|
731
|
-
*
|
|
732
|
-
* @example
|
|
733
|
-
* const theme = get('theme');
|
|
734
|
-
* console.log(theme); // Output: 'light'
|
|
735
|
-
*/
|
|
736
|
-
get,
|
|
737
|
-
/**
|
|
738
|
-
* Updates the cache with the provided values.
|
|
739
|
-
*
|
|
740
|
-
* Merges the existing cached values with the new partial values and updates the cache.
|
|
741
|
-
*/
|
|
742
|
-
set,
|
|
743
|
-
/**
|
|
744
|
-
* Resets the cache to its default values.
|
|
745
|
-
*
|
|
746
|
-
* @example
|
|
747
|
-
* reset();
|
|
748
|
-
*/
|
|
749
|
-
reset,
|
|
750
|
-
/**
|
|
751
|
-
* The path to the cache file.
|
|
752
|
-
*/
|
|
753
|
-
path
|
|
754
|
-
};
|
|
755
|
-
};
|
|
756
|
-
|
|
757
|
-
const getClosestPackageJson = async (startDir = process__default.cwd()) => {
|
|
758
|
-
let currentDir = resolvePath(startDir);
|
|
759
|
-
while (true) {
|
|
760
|
-
const pkgPath = joinPath(currentDir, "package.json");
|
|
761
|
-
if (await existsFile(pkgPath)) return pkgPath;
|
|
762
|
-
const parentDir = getDirName(currentDir);
|
|
763
|
-
if (parentDir === currentDir)
|
|
764
|
-
throw new Error("No package.json found in any parent directory.");
|
|
765
|
-
currentDir = parentDir;
|
|
766
|
-
}
|
|
767
|
-
};
|
|
768
|
-
const getClosestPackageDir = async (startDir = process__default.cwd()) => {
|
|
769
|
-
const pkgPath = await getClosestPackageJson(startDir);
|
|
770
|
-
return getDirName(pkgPath);
|
|
771
|
-
};
|
|
772
|
-
|
|
773
|
-
const _sys = {
|
|
774
|
-
__proto__: null,
|
|
775
|
-
arePathsEqual: arePathsEqual,
|
|
776
|
-
cache: cache,
|
|
777
|
-
copyDir: copyDir,
|
|
778
|
-
copyFile: copyFile,
|
|
779
|
-
createDir: createDir,
|
|
780
|
-
createSymlink: createSymlink,
|
|
781
|
-
ensureDir: ensureDir,
|
|
782
|
-
existsDir: existsDir,
|
|
783
|
-
existsFile: existsFile,
|
|
784
|
-
existsPath: existsPath,
|
|
785
|
-
fileURLToPath: node_url.fileURLToPath,
|
|
786
|
-
getAbsolutePath: getAbsolutePath,
|
|
787
|
-
getArch: getArch,
|
|
788
|
-
getBaseName: getBaseName,
|
|
789
|
-
getClosestPackageDir: getClosestPackageDir,
|
|
790
|
-
getClosestPackageJson: getClosestPackageJson,
|
|
791
|
-
getCurrentDir: getCurrentDir,
|
|
792
|
-
getDirName: getDirName,
|
|
793
|
-
getExtName: getExtName,
|
|
794
|
-
getFilteredFileNames: getFilteredFileNames,
|
|
795
|
-
getHomeDir: getHomeDir,
|
|
796
|
-
getObjectFromJSONFile: getObjectFromJSONFile,
|
|
797
|
-
getPaths: getPaths,
|
|
798
|
-
getPlatform: getPlatform,
|
|
799
|
-
getSystemEnvPaths: getSystemEnvPaths,
|
|
800
|
-
getTempDir: getTempDir,
|
|
801
|
-
isAbsolutePath: isAbsolutePath,
|
|
802
|
-
isDirectory: isDirectory,
|
|
803
|
-
isPath: isPath,
|
|
804
|
-
joinPath: joinPath,
|
|
805
|
-
normalizePath: normalizePath,
|
|
806
|
-
readDir: readDir,
|
|
807
|
-
readFile: readFile,
|
|
808
|
-
relativePath: relativePath,
|
|
809
|
-
removeDir: removeDir,
|
|
810
|
-
removeDirIfExist: removeDirIfExist,
|
|
811
|
-
removeFile: removeFile,
|
|
812
|
-
removeFileIfExist: removeFileIfExist,
|
|
813
|
-
removePathIfExist: removePathIfExist,
|
|
814
|
-
resolvePath: resolvePath,
|
|
815
|
-
validateHomeDir: validateHomeDir,
|
|
816
|
-
writeFile: writeFile,
|
|
817
|
-
writeFileContent: writeFileContent
|
|
818
|
-
};
|
|
819
|
-
|
|
820
|
-
const SELECT_BASE_OPTS = { NONE: "none" };
|
|
821
|
-
const mergeSelectBaseOptions = (config, defaultOptions) => {
|
|
822
|
-
const options = deepmergeTs.deepmerge(defaultOptions || {}, config.options || {});
|
|
823
|
-
const filteredOptions = config.onlyOptions && config.onlyOptions.length > 1 ? Object.entries(options).reduce((acc, [key, value]) => {
|
|
824
|
-
if (key === SELECT_BASE_OPTS.NONE || config.onlyOptions.includes(key))
|
|
825
|
-
acc[key] = value;
|
|
826
|
-
return acc;
|
|
827
|
-
}, {}) : options;
|
|
828
|
-
return {
|
|
829
|
-
...config,
|
|
830
|
-
options: Object.keys(filteredOptions).length > 1 ? filteredOptions : options
|
|
831
|
-
};
|
|
832
|
-
};
|
|
833
|
-
|
|
834
|
-
const sys = _sys;
|
|
835
|
-
const prompt = corePromptLine;
|
|
836
|
-
const env = env$2;
|
|
837
|
-
const style = style$1;
|
|
838
|
-
|
|
839
|
-
const utils = {
|
|
840
|
-
__proto__: null,
|
|
841
|
-
env: env,
|
|
842
|
-
prompt: prompt,
|
|
843
|
-
style: style,
|
|
844
|
-
sys: sys
|
|
845
|
-
};
|
|
846
|
-
|
|
847
|
-
const coreUtils = utils;
|
|
848
|
-
let Core$1 = class Core {
|
|
849
|
-
constructor(config) {
|
|
850
|
-
this.config = config;
|
|
851
|
-
}
|
|
852
|
-
// for use outside
|
|
853
|
-
_utils = utils;
|
|
854
|
-
/** On cancel callback */
|
|
855
|
-
_onCancel = async () => {
|
|
856
|
-
};
|
|
857
|
-
/** After the prompt is set */
|
|
858
|
-
afterPrompt;
|
|
859
|
-
/** Enable debug MODE */
|
|
860
|
-
debugMode = false;
|
|
861
|
-
/**
|
|
862
|
-
* Set initial value.
|
|
863
|
-
* For example if you want to prioritize a cli flag.
|
|
864
|
-
*
|
|
865
|
-
* @default undefined
|
|
866
|
-
*/
|
|
867
|
-
initialValue;
|
|
868
|
-
_type = {
|
|
869
|
-
string: "string",
|
|
870
|
-
number: "number",
|
|
871
|
-
boolean: "boolean",
|
|
872
|
-
array: "array"
|
|
873
|
-
};
|
|
874
|
-
_text = {
|
|
875
|
-
initialValueSuccess: (t, v) => `${t}
|
|
876
|
-
${this._utils.style.color.dim(this._utils.style.color.gray(v))}`,
|
|
877
|
-
initialValueError: (v) => `Initial value ${this._utils.style.color.yellow(v || "")} is not valid`
|
|
878
|
-
};
|
|
879
|
-
async getPromptHooked() {
|
|
880
|
-
if (!("prompt" in this && typeof this.prompt === "function")) return;
|
|
881
|
-
try {
|
|
882
|
-
if (this.initialValue && "validateInitialValue" in this && typeof this.validateInitialValue === "function") {
|
|
883
|
-
const validateValue = await this.validateInitialValue();
|
|
884
|
-
if (validateValue) return validateValue;
|
|
885
|
-
}
|
|
886
|
-
const res = await this.prompt();
|
|
887
|
-
if (this.afterPrompt) await this.afterPrompt(res);
|
|
888
|
-
return res;
|
|
889
|
-
} catch (error) {
|
|
890
|
-
if (error instanceof Error)
|
|
891
|
-
this._utils.prompt.log.error("Unexpected error:" + error?.message);
|
|
892
|
-
return await this.prompt();
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
};
|
|
896
|
-
|
|
897
|
-
class Select extends Core$1 {
|
|
898
|
-
async cmd() {
|
|
899
|
-
return {
|
|
900
|
-
desc: this.config.desc,
|
|
901
|
-
type: this._type.string,
|
|
902
|
-
alias: this.config.alias,
|
|
903
|
-
choices: Object.keys(this.config.options)
|
|
904
|
-
};
|
|
905
|
-
}
|
|
906
|
-
async validateInitialValue(data) {
|
|
907
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
908
|
-
if (typeof this.initialValue === "number" || typeof this.initialValue === "string") {
|
|
909
|
-
if (data?.showSuccess !== false)
|
|
910
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(message, this.initialValue.toString()));
|
|
911
|
-
return this.initialValue;
|
|
912
|
-
}
|
|
913
|
-
if (data?.showError !== false)
|
|
914
|
-
this._utils.prompt.log.warn(this._text.initialValueError(this.initialValue));
|
|
915
|
-
return void 0;
|
|
916
|
-
}
|
|
917
|
-
async prompt() {
|
|
918
|
-
const value = await this._utils.prompt.select({
|
|
919
|
-
message: this.config.promptMsg || this.config.desc,
|
|
920
|
-
options: Object.entries(this.config.options).map(([key, value2]) => ({
|
|
921
|
-
value: key,
|
|
922
|
-
label: value2?.name || key,
|
|
923
|
-
hint: value2?.desc
|
|
924
|
-
})),
|
|
925
|
-
initialValue: this.config.placeholderValue?.toString()
|
|
926
|
-
});
|
|
927
|
-
if (this._utils.prompt.isCancel(value)) {
|
|
928
|
-
await this._onCancel();
|
|
929
|
-
throw "";
|
|
930
|
-
}
|
|
931
|
-
return value;
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
const TEXT_EDITOR = {
|
|
936
|
-
...SELECT_BASE_OPTS,
|
|
937
|
-
VSCODE: "code",
|
|
938
|
-
SUBLIME: "subl",
|
|
939
|
-
WEBSTORM: "webstorm"
|
|
940
|
-
};
|
|
941
|
-
class Editor extends Select {
|
|
942
|
-
constructor(config) {
|
|
943
|
-
const defaultOptions = {
|
|
944
|
-
[TEXT_EDITOR.SUBLIME]: { name: "Sublime Text" },
|
|
945
|
-
[TEXT_EDITOR.VSCODE]: { name: "Visual Studio Code" },
|
|
946
|
-
[TEXT_EDITOR.WEBSTORM]: { name: "WebStorm" },
|
|
947
|
-
[TEXT_EDITOR.NONE]: {
|
|
948
|
-
name: "None",
|
|
949
|
-
desc: "Do not open the project with any text editor"
|
|
950
|
-
}
|
|
951
|
-
};
|
|
952
|
-
if (!config.desc) config.desc = "Select the text editor to open the project";
|
|
953
|
-
const finalConfig = mergeSelectBaseOptions(config, defaultOptions);
|
|
954
|
-
super(finalConfig);
|
|
955
|
-
this.config = finalConfig;
|
|
956
|
-
}
|
|
957
|
-
async validateInitialValue(data) {
|
|
958
|
-
const validateValue = await super.validateInitialValue({ showSuccess: false });
|
|
959
|
-
if (!validateValue) return void 0;
|
|
960
|
-
if (validateValue && await existsLocalBin(validateValue)) {
|
|
961
|
-
if (data?.showSuccess !== false)
|
|
962
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(this.config.promptMsg || this.config.desc, validateValue));
|
|
963
|
-
return validateValue;
|
|
964
|
-
}
|
|
965
|
-
if (data?.showError !== false)
|
|
966
|
-
this._utils.prompt.log.warn(this._text.initialValueError(this.initialValue));
|
|
967
|
-
return void 0;
|
|
968
|
-
}
|
|
969
|
-
async prompt() {
|
|
970
|
-
let value = await super.prompt();
|
|
971
|
-
if (value === TEXT_EDITOR.NONE) return value;
|
|
972
|
-
const exists = await existsLocalBin(value);
|
|
973
|
-
if (!exists) {
|
|
974
|
-
this.config.options = Object.fromEntries(
|
|
975
|
-
Object.entries(this.config.options).filter(([key]) => key !== value)
|
|
976
|
-
);
|
|
977
|
-
const badge = (txt) => this._utils.style.color.red(this._utils.style.color.inverse(" " + txt + " "));
|
|
978
|
-
this._utils.prompt.log.error(`Binary ${badge(value)} not found in system`);
|
|
979
|
-
value = await this.prompt();
|
|
980
|
-
}
|
|
981
|
-
return value;
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
const INSTALLER = {
|
|
986
|
-
DENO: "deno",
|
|
987
|
-
BUN: "bun",
|
|
988
|
-
NPM: "npm",
|
|
989
|
-
PNPM: "pnpm",
|
|
990
|
-
YARN: "yarn",
|
|
991
|
-
...SELECT_BASE_OPTS
|
|
992
|
-
};
|
|
993
|
-
class Install extends Select {
|
|
994
|
-
constructor(config) {
|
|
995
|
-
const defaultOptions = {
|
|
996
|
-
[INSTALLER.NPM]: { name: "npm" },
|
|
997
|
-
[INSTALLER.PNPM]: { name: "pnpm" },
|
|
998
|
-
[INSTALLER.YARN]: { name: "yarn" },
|
|
999
|
-
[INSTALLER.DENO]: { name: "deno" },
|
|
1000
|
-
[INSTALLER.NONE]: {
|
|
1001
|
-
name: "None",
|
|
1002
|
-
desc: "Do not install project dependencies"
|
|
1003
|
-
}
|
|
1004
|
-
};
|
|
1005
|
-
if (!config.desc) config.desc = "Select the package manager to install the dependencies.";
|
|
1006
|
-
const finalConfig = mergeSelectBaseOptions(config, defaultOptions);
|
|
1007
|
-
super(finalConfig);
|
|
1008
|
-
this.config = finalConfig;
|
|
1009
|
-
}
|
|
1010
|
-
async validateInitialValue(data) {
|
|
1011
|
-
const validateValue = await super.validateInitialValue({ showSuccess: false });
|
|
1012
|
-
if (!validateValue) return void 0;
|
|
1013
|
-
if (validateValue && await existsLocalBin(validateValue)) {
|
|
1014
|
-
if (data?.showSuccess !== false)
|
|
1015
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(this.config.promptMsg || this.config.desc, validateValue));
|
|
1016
|
-
return validateValue;
|
|
1017
|
-
}
|
|
1018
|
-
if (data?.showError !== false)
|
|
1019
|
-
this._utils.prompt.log.warn(this._text.initialValueError(this.initialValue));
|
|
1020
|
-
return void 0;
|
|
1021
|
-
}
|
|
1022
|
-
async prompt() {
|
|
1023
|
-
let value = await super.prompt();
|
|
1024
|
-
if (value === INSTALLER.NONE) return value;
|
|
1025
|
-
const exists = await existsLocalBin(value);
|
|
1026
|
-
if (!exists) {
|
|
1027
|
-
this.config.options = Object.fromEntries(
|
|
1028
|
-
Object.entries(this.config.options).filter(([key]) => key !== value)
|
|
1029
|
-
);
|
|
1030
|
-
const badge = (txt) => this._utils.style.color.red(this._utils.style.color.inverse(" " + txt + " "));
|
|
1031
|
-
this._utils.prompt.log.error(`Binary ${badge(value)} not found in system`);
|
|
1032
|
-
value = await this.prompt();
|
|
1033
|
-
}
|
|
1034
|
-
return value;
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
const OPTION = {
|
|
1039
|
-
array: "array",
|
|
1040
|
-
select: "select",
|
|
1041
|
-
multiselect: "multiselect",
|
|
1042
|
-
boolean: "boolean",
|
|
1043
|
-
number: "number",
|
|
1044
|
-
text: "text",
|
|
1045
|
-
void: "void",
|
|
1046
|
-
// customs
|
|
1047
|
-
output: "output",
|
|
1048
|
-
name: "name",
|
|
1049
|
-
template: "template",
|
|
1050
|
-
install: "install",
|
|
1051
|
-
openEditor: "openEditor",
|
|
1052
|
-
path: "path"
|
|
1053
|
-
};
|
|
1054
|
-
|
|
1055
|
-
let Array$1 = class Array extends Core$1 {
|
|
1056
|
-
#defaultSeparator = ",";
|
|
1057
|
-
async cmd() {
|
|
1058
|
-
return {
|
|
1059
|
-
desc: this.config.desc,
|
|
1060
|
-
type: this._type.array,
|
|
1061
|
-
alias: this.config.alias
|
|
1062
|
-
};
|
|
1063
|
-
}
|
|
1064
|
-
async validateInitialValue(data) {
|
|
1065
|
-
const separator = this.config.separator || this.#defaultSeparator;
|
|
1066
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1067
|
-
const value = this.initialValue;
|
|
1068
|
-
if (value && globalThis.Array.isArray(value)) {
|
|
1069
|
-
if (data?.showSuccess !== false)
|
|
1070
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(message, value.join(separator)));
|
|
1071
|
-
return value;
|
|
1072
|
-
} else if (value && typeof value === "string") {
|
|
1073
|
-
if (data?.showSuccess !== false)
|
|
1074
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(message, value));
|
|
1075
|
-
return value.split(separator).map((v) => v.trim());
|
|
1076
|
-
}
|
|
1077
|
-
if (data?.showError !== false)
|
|
1078
|
-
this._utils.prompt.log.warn(this._text.initialValueError(value));
|
|
1079
|
-
return void 0;
|
|
1080
|
-
}
|
|
1081
|
-
async prompt() {
|
|
1082
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1083
|
-
const separator = this.config.separator || this.#defaultSeparator;
|
|
1084
|
-
const value = await this._utils.prompt.text({
|
|
1085
|
-
message,
|
|
1086
|
-
initialValue: this.config.placeholderValue?.join(separator),
|
|
1087
|
-
validate: (v) => {
|
|
1088
|
-
if (!v) return "Value is required";
|
|
1089
|
-
if (v.trim().length === 0) return "Value is required";
|
|
1090
|
-
}
|
|
1091
|
-
});
|
|
1092
|
-
if (this._utils.prompt.isCancel(value)) {
|
|
1093
|
-
await this._onCancel();
|
|
1094
|
-
throw "";
|
|
1095
|
-
}
|
|
1096
|
-
const res = value.includes(separator) ? value.split(separator).map((v) => v.trim()) : [value];
|
|
1097
|
-
return res;
|
|
1098
|
-
}
|
|
1099
|
-
};
|
|
1100
|
-
|
|
1101
|
-
let Boolean$1 = class Boolean extends Core$1 {
|
|
1102
|
-
async cmd() {
|
|
1103
|
-
return {
|
|
1104
|
-
desc: this.config.desc,
|
|
1105
|
-
type: this._type.boolean,
|
|
1106
|
-
alias: this.config.alias
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
async validateInitialValue(data) {
|
|
1110
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1111
|
-
if (typeof this.initialValue === "boolean") {
|
|
1112
|
-
if (data?.showSuccess !== false)
|
|
1113
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(message, this.initialValue.toString()));
|
|
1114
|
-
return this.initialValue;
|
|
1115
|
-
}
|
|
1116
|
-
if (data?.showError !== false)
|
|
1117
|
-
this._utils.prompt.log.warn(this._text.initialValueError(this.initialValue));
|
|
1118
|
-
return void 0;
|
|
1119
|
-
}
|
|
1120
|
-
async prompt() {
|
|
1121
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1122
|
-
const value = await this._utils.prompt.confirm({
|
|
1123
|
-
message,
|
|
1124
|
-
initialValue: this.config.placeholderValue
|
|
1125
|
-
});
|
|
1126
|
-
if (this._utils.prompt.isCancel(value)) {
|
|
1127
|
-
await this._onCancel();
|
|
1128
|
-
throw "";
|
|
1129
|
-
}
|
|
1130
|
-
return value;
|
|
1131
|
-
}
|
|
1132
|
-
};
|
|
1133
|
-
|
|
1134
|
-
class Multiselect extends Core$1 {
|
|
1135
|
-
async cmd() {
|
|
1136
|
-
return {
|
|
1137
|
-
desc: this.config.desc,
|
|
1138
|
-
type: this._type.array,
|
|
1139
|
-
alias: this.config.alias,
|
|
1140
|
-
choices: Object.keys(this.config.options)
|
|
1141
|
-
};
|
|
1142
|
-
}
|
|
1143
|
-
async validateInitialValue(data) {
|
|
1144
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1145
|
-
if (this.initialValue && Array.isArray(this.initialValue) && Object.keys(this.config.options).every((v) => this.initialValue?.includes(v))) {
|
|
1146
|
-
if (data?.showSuccess !== false)
|
|
1147
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(message, this.initialValue.join(", ")));
|
|
1148
|
-
return this.initialValue;
|
|
1149
|
-
}
|
|
1150
|
-
if (data?.showError !== false)
|
|
1151
|
-
this._utils.prompt.log.warn(this._text.initialValueError(this.initialValue?.join(", ")));
|
|
1152
|
-
return void 0;
|
|
1153
|
-
}
|
|
1154
|
-
// @ts-ignore
|
|
1155
|
-
async prompt() {
|
|
1156
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1157
|
-
const value = await this._utils.prompt.multiselect({
|
|
1158
|
-
message,
|
|
1159
|
-
initialValues: this.config.placeholderValue,
|
|
1160
|
-
options: Object.entries(this.config.options).map(([key, value2]) => ({
|
|
1161
|
-
value: key,
|
|
1162
|
-
label: value2?.name || key,
|
|
1163
|
-
hint: value2?.desc
|
|
1164
|
-
}))
|
|
1165
|
-
});
|
|
1166
|
-
if (this._utils.prompt.isCancel(value)) {
|
|
1167
|
-
await this._onCancel();
|
|
1168
|
-
throw "";
|
|
1169
|
-
}
|
|
1170
|
-
return value;
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
let Number$1 = class Number extends Core$1 {
|
|
1175
|
-
async cmd() {
|
|
1176
|
-
return {
|
|
1177
|
-
desc: this.config.desc,
|
|
1178
|
-
type: this._type.number,
|
|
1179
|
-
alias: this.config.alias
|
|
1180
|
-
};
|
|
1181
|
-
}
|
|
1182
|
-
async validateInitialValue(data) {
|
|
1183
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1184
|
-
const value = this.initialValue;
|
|
1185
|
-
if (typeof value === "number") {
|
|
1186
|
-
if (data?.showSuccess !== false)
|
|
1187
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(message, value.toString()));
|
|
1188
|
-
return value;
|
|
1189
|
-
} else if (typeof value === "string") {
|
|
1190
|
-
if (data?.showSuccess !== false)
|
|
1191
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(message, value));
|
|
1192
|
-
return globalThis.Number(value);
|
|
1193
|
-
}
|
|
1194
|
-
if (data?.showError !== false)
|
|
1195
|
-
this._utils.prompt.log.warn(this._text.initialValueError(value));
|
|
1196
|
-
return void 0;
|
|
1197
|
-
}
|
|
1198
|
-
async prompt() {
|
|
1199
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1200
|
-
const value = await this._utils.prompt.number({
|
|
1201
|
-
message,
|
|
1202
|
-
initialValue: this.config.placeholderValue?.toString(),
|
|
1203
|
-
placeholder: this.config.placeholderValue?.toString()
|
|
1204
|
-
// validate : v => {
|
|
1205
|
-
// if ( !v ) return 'Value is required'
|
|
1206
|
-
// if ( v.trim().length === 0 ) return 'Value is required'
|
|
1207
|
-
// },
|
|
1208
|
-
});
|
|
1209
|
-
if (this._utils.prompt.isCancel(value)) {
|
|
1210
|
-
await this._onCancel();
|
|
1211
|
-
throw "";
|
|
1212
|
-
}
|
|
1213
|
-
return value;
|
|
1214
|
-
}
|
|
1215
|
-
};
|
|
1216
|
-
|
|
1217
|
-
class Text extends Core$1 {
|
|
1218
|
-
async cmd() {
|
|
1219
|
-
return {
|
|
1220
|
-
desc: this.config.desc,
|
|
1221
|
-
type: this._type.string,
|
|
1222
|
-
alias: this.config.alias
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
1225
|
-
async validateInitialValue(data) {
|
|
1226
|
-
const message = this.config.promptMsg || this.config.desc;
|
|
1227
|
-
if (typeof this.initialValue === "string") {
|
|
1228
|
-
if (data?.showSuccess !== false)
|
|
1229
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(message, this.initialValue));
|
|
1230
|
-
return this.initialValue;
|
|
1231
|
-
}
|
|
1232
|
-
if (data?.showError !== false)
|
|
1233
|
-
this._utils.prompt.log.warn(this._text.initialValueError(this.initialValue));
|
|
1234
|
-
return void 0;
|
|
1235
|
-
}
|
|
1236
|
-
async prompt() {
|
|
1237
|
-
const value = await this._utils.prompt.text({
|
|
1238
|
-
message: this.config.promptMsg || this.config.desc,
|
|
1239
|
-
// initialValue : this.config.initialValue,
|
|
1240
|
-
placeholder: this.config.placeholderValue,
|
|
1241
|
-
validate: (v) => {
|
|
1242
|
-
if (!v) return "Value is required";
|
|
1243
|
-
if (v.trim().length === 0) return "Value is required";
|
|
1244
|
-
}
|
|
1245
|
-
});
|
|
1246
|
-
if (this._utils.prompt.isCancel(value)) {
|
|
1247
|
-
await this._onCancel();
|
|
1248
|
-
throw "";
|
|
1249
|
-
}
|
|
1250
|
-
return value;
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
class Void extends Core$1 {
|
|
1255
|
-
async cmd() {
|
|
1256
|
-
return void 0;
|
|
1257
|
-
}
|
|
1258
|
-
async validateInitialValue() {
|
|
1259
|
-
return void 0;
|
|
1260
|
-
}
|
|
1261
|
-
async prompt() {
|
|
1262
|
-
if (this.config.fn)
|
|
1263
|
-
await this.config.fn();
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
class Name extends Text {
|
|
1268
|
-
constructor(config) {
|
|
1269
|
-
const finalConfig = {
|
|
1270
|
-
desc: config.desc ?? "Set the name of the project",
|
|
1271
|
-
...config
|
|
1272
|
-
};
|
|
1273
|
-
super(finalConfig);
|
|
1274
|
-
this.config = finalConfig;
|
|
1275
|
-
}
|
|
1276
|
-
async validateInitialValue(data) {
|
|
1277
|
-
const validateValue = await super.validateInitialValue({ showSuccess: false });
|
|
1278
|
-
if (!validateValue) return void 0;
|
|
1279
|
-
const hasSpaces = /\s/.test(validateValue);
|
|
1280
|
-
if (validateValue && !hasSpaces) {
|
|
1281
|
-
if (data?.showSuccess !== false)
|
|
1282
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(this.config.promptMsg || this.config.desc, validateValue));
|
|
1283
|
-
return validateValue;
|
|
1284
|
-
}
|
|
1285
|
-
if (data?.showError !== false)
|
|
1286
|
-
this._utils.prompt.log.warn(this._text.initialValueError(this.initialValue));
|
|
1287
|
-
return void 0;
|
|
1288
|
-
}
|
|
1289
|
-
async prompt() {
|
|
1290
|
-
const value = await this._utils.prompt.text({
|
|
1291
|
-
message: this.config.promptMsg || this.config.desc,
|
|
1292
|
-
// initialValue : this.config.initialValue,
|
|
1293
|
-
placeholder: this.config.placeholderValue,
|
|
1294
|
-
validate: (v) => {
|
|
1295
|
-
if (!v) return "Value is required";
|
|
1296
|
-
if (v.trim().length === 0) return "Value is required";
|
|
1297
|
-
if (/\s/.test(v)) return "Spaces are not allowed";
|
|
1298
|
-
}
|
|
1299
|
-
});
|
|
1300
|
-
if (this._utils.prompt.isCancel(value)) {
|
|
1301
|
-
await this._onCancel();
|
|
1302
|
-
throw "";
|
|
1303
|
-
}
|
|
1304
|
-
return value;
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
const PATH_TYPE = {
|
|
1309
|
-
folder: "folder",
|
|
1310
|
-
file: "file"
|
|
1311
|
-
};
|
|
1312
|
-
class Path extends Text {
|
|
1313
|
-
#existsPath;
|
|
1314
|
-
#pathType;
|
|
1315
|
-
constructor(config) {
|
|
1316
|
-
if (!config.pathType) config.pathType = PATH_TYPE.file;
|
|
1317
|
-
if (!config.exists) config.exists = false;
|
|
1318
|
-
const finalConfig = {
|
|
1319
|
-
desc: config.desc ?? `Set input ${config.exists ? "existing" : "new"} ${config.pathType}`,
|
|
1320
|
-
...config
|
|
1321
|
-
};
|
|
1322
|
-
super(finalConfig);
|
|
1323
|
-
this.config = finalConfig;
|
|
1324
|
-
this.#existsPath = config.exists;
|
|
1325
|
-
this.#pathType = config.pathType;
|
|
1326
|
-
}
|
|
1327
|
-
async #validatePath(path) {
|
|
1328
|
-
const mustExists = this.#existsPath;
|
|
1329
|
-
const type = this.#pathType;
|
|
1330
|
-
const existsPath = type === PATH_TYPE.file ? await existsFile(path) : await existsDir(path);
|
|
1331
|
-
const validation = mustExists === existsPath;
|
|
1332
|
-
console.debug({ pathValueData: {
|
|
1333
|
-
validatePath: path,
|
|
1334
|
-
existsPath,
|
|
1335
|
-
mustExists,
|
|
1336
|
-
type,
|
|
1337
|
-
validation
|
|
1338
|
-
} });
|
|
1339
|
-
if (validation) return path;
|
|
1340
|
-
this._utils.prompt.log.error(`${type === PATH_TYPE.file ? "File" : "Folder"} [${path}] ${mustExists ? "not exists. Set path that exists" : "already exists. Set path that not exists"}`);
|
|
1341
|
-
return void 0;
|
|
1342
|
-
}
|
|
1343
|
-
async validateInitialValue(data) {
|
|
1344
|
-
const validateValue = await super.validateInitialValue({ showSuccess: false });
|
|
1345
|
-
if (!validateValue) return void 0;
|
|
1346
|
-
if (validateValue && await this.#validatePath(validateValue)) {
|
|
1347
|
-
if (data?.showSuccess !== false)
|
|
1348
|
-
this._utils.prompt.log.success(this._text.initialValueSuccess(this.config.promptMsg || this.config.desc, validateValue));
|
|
1349
|
-
return validateValue;
|
|
1350
|
-
}
|
|
1351
|
-
if (data?.showError !== false)
|
|
1352
|
-
this._utils.prompt.log.warn(this._text.initialValueError(this.initialValue));
|
|
1353
|
-
return void 0;
|
|
1354
|
-
}
|
|
1355
|
-
async prompt() {
|
|
1356
|
-
let value = await this._utils.prompt.text({
|
|
1357
|
-
message: this.config.promptMsg || this.config.desc,
|
|
1358
|
-
// initialValue : this.config.initialValue,
|
|
1359
|
-
placeholder: this.config.placeholderValue,
|
|
1360
|
-
validate: (v) => {
|
|
1361
|
-
if (!v) return "Value is required";
|
|
1362
|
-
if (v.trim().length === 0) return "Value is required";
|
|
1363
|
-
}
|
|
1364
|
-
});
|
|
1365
|
-
if (this._utils.prompt.isCancel(value)) {
|
|
1366
|
-
await this._onCancel();
|
|
1367
|
-
throw "";
|
|
1368
|
-
}
|
|
1369
|
-
const exists = await this.#validatePath(value);
|
|
1370
|
-
if (!exists) value = await this.prompt();
|
|
1371
|
-
return value;
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
class Output extends Path {
|
|
1376
|
-
constructor(config) {
|
|
1377
|
-
const finalConfig = {
|
|
1378
|
-
desc: config.desc ?? "Set the path where you want to create your project",
|
|
1379
|
-
promptMsg: config.promptMsg ?? "Where do you want to create your project?",
|
|
1380
|
-
...config
|
|
1381
|
-
};
|
|
1382
|
-
super({
|
|
1383
|
-
...finalConfig,
|
|
1384
|
-
pathType: PATH_TYPE.folder,
|
|
1385
|
-
exists: false
|
|
1386
|
-
});
|
|
1387
|
-
this.config = finalConfig;
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
|
-
class Template extends Select {
|
|
1392
|
-
constructor(config) {
|
|
1393
|
-
const {
|
|
1394
|
-
options: _options,
|
|
1395
|
-
...rest
|
|
1396
|
-
} = config;
|
|
1397
|
-
const options = Object.fromEntries(
|
|
1398
|
-
Object.entries(_options).map(([key, value]) => [
|
|
1399
|
-
key,
|
|
1400
|
-
{
|
|
1401
|
-
name: value.name || key,
|
|
1402
|
-
desc: value.desc
|
|
1403
|
-
}
|
|
1404
|
-
])
|
|
1405
|
-
);
|
|
1406
|
-
const finalConfig = {
|
|
1407
|
-
desc: config.desc ?? "Select project template",
|
|
1408
|
-
options,
|
|
1409
|
-
...rest
|
|
1410
|
-
// Propiedades opcionales adicionales
|
|
1411
|
-
};
|
|
1412
|
-
super(finalConfig);
|
|
1413
|
-
this.config = finalConfig;
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
const name = "creatium";
|
|
1418
|
-
|
|
1419
|
-
class Core {
|
|
1420
|
-
constructor(config) {
|
|
1421
|
-
this.config = config;
|
|
1422
|
-
this.utils = coreUtils;
|
|
1423
|
-
this.onCancel = async () => {
|
|
1424
|
-
};
|
|
1425
|
-
}
|
|
1426
|
-
utils;
|
|
1427
|
-
onCancel;
|
|
1428
|
-
/** Enable cache */
|
|
1429
|
-
cache = false;
|
|
1430
|
-
/**
|
|
1431
|
-
* Project name.
|
|
1432
|
-
* Used for cache
|
|
1433
|
-
*/
|
|
1434
|
-
projectName = name;
|
|
1435
|
-
/** Debug mode */
|
|
1436
|
-
set debugMode(value) {
|
|
1437
|
-
if (value === true) {
|
|
1438
|
-
const dim = (txt) => this.utils.style.color.gray(this.utils.style.color.dim(txt));
|
|
1439
|
-
console.debug = (...args) => {
|
|
1440
|
-
console.log();
|
|
1441
|
-
const TITLE = dim(this.utils.style.line({
|
|
1442
|
-
title: "DEBUG",
|
|
1443
|
-
lineChar: " ",
|
|
1444
|
-
align: "left"
|
|
1445
|
-
}));
|
|
1446
|
-
const LINE = dim(this.utils.style.line({ title: "" }));
|
|
1447
|
-
console.log(TITLE);
|
|
1448
|
-
console.log(LINE);
|
|
1449
|
-
console.log(...args);
|
|
1450
|
-
console.log(LINE);
|
|
1451
|
-
console.log();
|
|
1452
|
-
};
|
|
1453
|
-
} else console.debug = () => {
|
|
1454
|
-
};
|
|
1455
|
-
}
|
|
1456
|
-
async #getCache() {
|
|
1457
|
-
const resetObjectValues = (obj) => {
|
|
1458
|
-
return Object.keys(obj).reduce((acc, key) => {
|
|
1459
|
-
acc[key] = void 0;
|
|
1460
|
-
return acc;
|
|
1461
|
-
}, {});
|
|
1462
|
-
};
|
|
1463
|
-
if (!this.cache) return;
|
|
1464
|
-
return await cache({
|
|
1465
|
-
projectName: this.projectName,
|
|
1466
|
-
id: "create-prompts",
|
|
1467
|
-
values: resetObjectValues(this.config)
|
|
1468
|
-
});
|
|
1469
|
-
}
|
|
1470
|
-
#getClass() {
|
|
1471
|
-
return {
|
|
1472
|
-
array: Array$1,
|
|
1473
|
-
number: Number$1,
|
|
1474
|
-
boolean: Boolean$1,
|
|
1475
|
-
multiselect: Multiselect,
|
|
1476
|
-
select: Select,
|
|
1477
|
-
text: Text,
|
|
1478
|
-
void: Void,
|
|
1479
|
-
openEditor: Editor,
|
|
1480
|
-
output: Output,
|
|
1481
|
-
install: Install,
|
|
1482
|
-
name: Name,
|
|
1483
|
-
template: Template,
|
|
1484
|
-
path: Path
|
|
1485
|
-
};
|
|
1486
|
-
}
|
|
1487
|
-
async getCmds() {
|
|
1488
|
-
const res = {};
|
|
1489
|
-
const Klass = this.#getClass();
|
|
1490
|
-
await Promise.all(Object.entries(this.config).map(async ([key, value]) => {
|
|
1491
|
-
const {
|
|
1492
|
-
type,
|
|
1493
|
-
...props
|
|
1494
|
-
} = value;
|
|
1495
|
-
if (!(type in Klass)) return;
|
|
1496
|
-
const instance = new Klass[type](props);
|
|
1497
|
-
if ("cmd" in instance) {
|
|
1498
|
-
const cmd = await instance.cmd();
|
|
1499
|
-
if (cmd) res[key] = cmd;
|
|
1500
|
-
}
|
|
1501
|
-
}));
|
|
1502
|
-
return res;
|
|
1503
|
-
}
|
|
1504
|
-
async getPrompts(initialValues) {
|
|
1505
|
-
const res = {};
|
|
1506
|
-
const Klass = this.#getClass();
|
|
1507
|
-
const cached = await this.#getCache();
|
|
1508
|
-
const cachedValues = await cached?.get();
|
|
1509
|
-
console.debug({ cacheData: {
|
|
1510
|
-
active: this.cache,
|
|
1511
|
-
...cached,
|
|
1512
|
-
values: cachedValues
|
|
1513
|
-
} });
|
|
1514
|
-
await Promise.all(Object.entries(this.config).map(async ([key, value]) => {
|
|
1515
|
-
const {
|
|
1516
|
-
type,
|
|
1517
|
-
...props
|
|
1518
|
-
} = value;
|
|
1519
|
-
if (!(type in Klass)) return;
|
|
1520
|
-
const instance = new Klass[type](props);
|
|
1521
|
-
instance._onCancel = this.onCancel;
|
|
1522
|
-
instance.debugMode = this.debugMode;
|
|
1523
|
-
const initialValue = initialValues?.[key];
|
|
1524
|
-
if (initialValue) instance.initialValue = initialValue;
|
|
1525
|
-
const cachedValue = cachedValues?.[key];
|
|
1526
|
-
if (cachedValue) instance.config.placeholderValue = cachedValue;
|
|
1527
|
-
instance.afterPrompt = async (value2) => await cached?.set({ [key]: value2 });
|
|
1528
|
-
if ("prompt" in instance)
|
|
1529
|
-
res[key] = await instance.getPromptHooked.bind(instance);
|
|
1530
|
-
}));
|
|
1531
|
-
return res;
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
class CreatiumCore {
|
|
1536
|
-
#core;
|
|
1537
|
-
#data;
|
|
1538
|
-
utils;
|
|
1539
|
-
config;
|
|
1540
|
-
#style;
|
|
1541
|
-
#cwd = process__default.cwd();
|
|
1542
|
-
constructor(config) {
|
|
1543
|
-
this.#core = new Core(config.prompt);
|
|
1544
|
-
this.config = config;
|
|
1545
|
-
this.utils = this.#core.utils;
|
|
1546
|
-
this.#core.cache = this.config.cache === void 0 ? true : this.config.cache;
|
|
1547
|
-
this.#core.projectName = this.config.name;
|
|
1548
|
-
this.debugMode = false;
|
|
1549
|
-
this.#style = { tick: this.utils.style.color.green(this.utils.style.color.dim("\u2713")) };
|
|
1550
|
-
}
|
|
1551
|
-
#_spinnerFN;
|
|
1552
|
-
/** Force debug mode */
|
|
1553
|
-
set debugMode(value) {
|
|
1554
|
-
this.#core.debugMode = value;
|
|
1555
|
-
if (value === true) {
|
|
1556
|
-
this.#_spinnerFN = this.utils.prompt.spinner;
|
|
1557
|
-
this.utils.prompt.spinner = (_) => {
|
|
1558
|
-
return {
|
|
1559
|
-
start: (m) => this.utils.prompt.log.message(m),
|
|
1560
|
-
message: (m) => this.utils.prompt.log.message(m),
|
|
1561
|
-
stop: (m) => this.utils.prompt.log.message(m)
|
|
1562
|
-
};
|
|
1563
|
-
};
|
|
1564
|
-
} else {
|
|
1565
|
-
if (this.#_spinnerFN) this.utils.prompt.spinner = this.#_spinnerFN;
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
async #exec(values) {
|
|
1569
|
-
this.#data = { values };
|
|
1570
|
-
console.debug({ initData: this.#data });
|
|
1571
|
-
this.#core.onCancel = async () => await this.cancel();
|
|
1572
|
-
if (this.config.hooks?.beforePrompt)
|
|
1573
|
-
await this.config.hooks.beforePrompt(this.#data);
|
|
1574
|
-
console.debug({ beforePromptData: this.#data });
|
|
1575
|
-
await this.intro();
|
|
1576
|
-
const prompts = await this.#core.getPrompts(this.#data.values);
|
|
1577
|
-
const answers = await this.utils.prompt.group(prompts, { onCancel: this.#core.onCancel });
|
|
1578
|
-
this.#data.values = answers;
|
|
1579
|
-
console.debug({ promptData: this.#data });
|
|
1580
|
-
if (this.config.hooks?.afterPrompt)
|
|
1581
|
-
await this.config.hooks.afterPrompt(this.#data);
|
|
1582
|
-
console.debug({ afterPromptData: this.#data });
|
|
1583
|
-
return answers;
|
|
1584
|
-
}
|
|
1585
|
-
#getCliArgs(props) {
|
|
1586
|
-
return props?.args && props.hideBin ? hideBin(props.args) ? props.args : props?.args : hideBin(process__default.argv);
|
|
1587
|
-
}
|
|
1588
|
-
async #initCli(props) {
|
|
1589
|
-
if (this.config.updater) await this.updateNotify();
|
|
1590
|
-
const args = this.#getCliArgs(props);
|
|
1591
|
-
const instance = await createCli({
|
|
1592
|
-
args,
|
|
1593
|
-
fn: async (cli) => {
|
|
1594
|
-
cli.scriptName(this.config.name).version(this.config.version).usage("Usage: $0 [options]").locale("en").help(false).showHelpOnFail(false).alias("h", "help").alias("v", "version");
|
|
1595
|
-
if (this.config.prompt) {
|
|
1596
|
-
const props2 = await this.#core.getCmds();
|
|
1597
|
-
cli.options(props2);
|
|
1598
|
-
}
|
|
1599
|
-
cli.option("debug", {
|
|
1600
|
-
desc: "Set Debug mode",
|
|
1601
|
-
type: "boolean"
|
|
1602
|
-
});
|
|
1603
|
-
return cli;
|
|
1604
|
-
}
|
|
1605
|
-
});
|
|
1606
|
-
const argv = await instance.argv;
|
|
1607
|
-
if (!argv.debug) this.debugMode = false;
|
|
1608
|
-
else this.debugMode = true;
|
|
1609
|
-
const {
|
|
1610
|
-
_,
|
|
1611
|
-
$0,
|
|
1612
|
-
...values
|
|
1613
|
-
} = argv;
|
|
1614
|
-
return values;
|
|
1615
|
-
}
|
|
1616
|
-
/**
|
|
1617
|
-
* Shows a notification if the current package is outdated.
|
|
1618
|
-
*
|
|
1619
|
-
* **information**: If this 'custom' function is provided, the default
|
|
1620
|
-
* notification will not be shown.
|
|
1621
|
-
*
|
|
1622
|
-
* @returns {Promise<boolean>} - A promise that resolves when the notification has finished.
|
|
1623
|
-
*/
|
|
1624
|
-
async updateNotify() {
|
|
1625
|
-
const { default: up } = await import('tiny-updater');
|
|
1626
|
-
return await up({
|
|
1627
|
-
name: this.config.name,
|
|
1628
|
-
version: this.config.version,
|
|
1629
|
-
ttl: 864e5
|
|
1630
|
-
});
|
|
1631
|
-
}
|
|
1632
|
-
/**
|
|
1633
|
-
* Cancels the current process and exits with code 0.
|
|
1634
|
-
*
|
|
1635
|
-
* If a `message` is provided, it will be displayed in the console.
|
|
1636
|
-
* If `onCancel` is set in the config, it will be called with the current data.
|
|
1637
|
-
* If `onCancel` is not set, a default message will be displayed.
|
|
1638
|
-
*
|
|
1639
|
-
* @param {string} [message] - The message to display before exiting.
|
|
1640
|
-
*/
|
|
1641
|
-
async cancel(message) {
|
|
1642
|
-
if (message) {
|
|
1643
|
-
this.utils.prompt.log.step("");
|
|
1644
|
-
this.utils.prompt.cancel(message);
|
|
1645
|
-
process__default.exit(0);
|
|
1646
|
-
} else if (this.config.onCancel && this.#data)
|
|
1647
|
-
await this.config.onCancel(this.#data);
|
|
1648
|
-
else if (this.config.onCancel === void 0) {
|
|
1649
|
-
this.utils.prompt.log.step("");
|
|
1650
|
-
this.utils.prompt.cancel("Canceled \u{1F494}");
|
|
1651
|
-
process__default.exit(0);
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
/**
|
|
1655
|
-
* Intro prompt line.
|
|
1656
|
-
*
|
|
1657
|
-
* If the parameter `message` is provided, it will be used as the intro message.
|
|
1658
|
-
* If the `intro` option is a function, it will be called with the `this.#data` as the argument.
|
|
1659
|
-
* If the `intro` option is undefined, the default intro message will be used.
|
|
1660
|
-
*
|
|
1661
|
-
* @param {string} [message] - The intro message.
|
|
1662
|
-
*/
|
|
1663
|
-
async intro(message) {
|
|
1664
|
-
if (message)
|
|
1665
|
-
this.utils.prompt.intro(message);
|
|
1666
|
-
else if (typeof this.config.intro === "function")
|
|
1667
|
-
await this.config.intro(this.#data || {});
|
|
1668
|
-
else if (this.config.intro === void 0) {
|
|
1669
|
-
console.log();
|
|
1670
|
-
const badge = (txt) => this.utils.style.color.blue(this.utils.style.color.inverse(" " + this.utils.style.color.bold(txt) + " "));
|
|
1671
|
-
this.utils.prompt.intro(badge(this.config.name));
|
|
1672
|
-
this.utils.prompt.log.step("");
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
/**
|
|
1676
|
-
* Outro prompt line.
|
|
1677
|
-
*
|
|
1678
|
-
* If the parameter `message` is provided, it will be used as the outro message.
|
|
1679
|
-
* If the `outro` option is a function, it will be called with the `this.#data` as the argument.
|
|
1680
|
-
* If the `outro` option is undefined, the default outro message will be used.
|
|
1681
|
-
*
|
|
1682
|
-
* @param {string} [message] - The outro message.
|
|
1683
|
-
*/
|
|
1684
|
-
async outro(message) {
|
|
1685
|
-
this.utils.prompt.log.step("");
|
|
1686
|
-
if (message)
|
|
1687
|
-
this.utils.prompt.outro(message);
|
|
1688
|
-
else if (typeof this.config.outro === "function" && this.#data)
|
|
1689
|
-
await this.config.outro(this.#data);
|
|
1690
|
-
else if (this.config.outro === void 0) {
|
|
1691
|
-
this.utils.prompt.outro(this.utils.style.color.greenBright("Successfully completed \u{1F308}"));
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1694
|
-
/**
|
|
1695
|
-
* Copy a directory from input path to output path.
|
|
1696
|
-
*
|
|
1697
|
-
* @param {object} data - Options object with input and output paths.
|
|
1698
|
-
* @param {string} data.input - The path to the directory to copy.
|
|
1699
|
-
* @param {string} data.output - The path to the destination directory.
|
|
1700
|
-
* @returns {Promise<void>} - Resolves when the directory has been copied.
|
|
1701
|
-
* @example
|
|
1702
|
-
*
|
|
1703
|
-
* const copyResult = await core.copyDir({
|
|
1704
|
-
* input : '/path/to/sourceDir',
|
|
1705
|
-
* output: '/path/to/destinationDir',
|
|
1706
|
-
* })
|
|
1707
|
-
*/
|
|
1708
|
-
async copyDir(data) {
|
|
1709
|
-
console.debug({ copyDirData: data });
|
|
1710
|
-
return await copyDir(data);
|
|
1711
|
-
}
|
|
1712
|
-
/**
|
|
1713
|
-
* Installs the project with the given package manager.
|
|
1714
|
-
*
|
|
1715
|
-
* @param {object} [options] - The options to install.
|
|
1716
|
-
* @param {Installer} [options.installer] - The package manager to use for the installation.
|
|
1717
|
-
* @param {string} [options.input] - The path to the folder. If not provided, the current directory is used.
|
|
1718
|
-
* @returns {Promise<void>}
|
|
1719
|
-
* @example
|
|
1720
|
-
* await core.install( {
|
|
1721
|
-
* installer : 'pnpm',
|
|
1722
|
-
* input : 'my/project/path',
|
|
1723
|
-
* } )
|
|
1724
|
-
*/
|
|
1725
|
-
async install({
|
|
1726
|
-
installer,
|
|
1727
|
-
input
|
|
1728
|
-
} = {}) {
|
|
1729
|
-
console.debug({ installData: {
|
|
1730
|
-
installer,
|
|
1731
|
-
input: input || this.#cwd
|
|
1732
|
-
} });
|
|
1733
|
-
if (!installer || installer === "none") return;
|
|
1734
|
-
const s = this.utils.prompt.spinner();
|
|
1735
|
-
const command = {
|
|
1736
|
-
[INSTALLER.PNPM]: `pnpm install${input ? ` --dir ${input}` : ""}`,
|
|
1737
|
-
[INSTALLER.NPM]: `npm install${input ? ` --prefix ${input}` : ""}`,
|
|
1738
|
-
[INSTALLER.YARN]: `yarn install${input ? ` --cwd ${input}` : ""}`,
|
|
1739
|
-
[INSTALLER.DENO]: `deno install${input ? ` --root ${input}` : ""}`,
|
|
1740
|
-
[INSTALLER.BUN]: `bun install${input ? ` --cwd ${input}` : ""}`
|
|
1741
|
-
};
|
|
1742
|
-
try {
|
|
1743
|
-
s.start(`Installing with ${installer}`);
|
|
1744
|
-
await execChild(command[installer]);
|
|
1745
|
-
s.stop(`${this.#style.tick} Package installed with [${installer}] successfully`);
|
|
1746
|
-
} catch (_e) {
|
|
1747
|
-
if (this.debugMode)
|
|
1748
|
-
s.stop(`Error in installation with [${installer}]: ${_e?.toString()}`);
|
|
1749
|
-
else
|
|
1750
|
-
s.stop(`Error in installation with [${installer}]`);
|
|
1751
|
-
}
|
|
1752
|
-
}
|
|
1753
|
-
/**
|
|
1754
|
-
* Open the project in the given editor.
|
|
1755
|
-
*
|
|
1756
|
-
* @param {object} params - The parameters for opening the editor.
|
|
1757
|
-
* @param {TextEditor} params.editor - The editor to open the project in.
|
|
1758
|
-
* @param {string} params.input - The input path. If not provided, the current directory is used.
|
|
1759
|
-
* @returns {Promise<void>}
|
|
1760
|
-
* @example
|
|
1761
|
-
* await core.openEditor( {
|
|
1762
|
-
* editor : 'vscode',
|
|
1763
|
-
* input : 'my/project/path',
|
|
1764
|
-
* })
|
|
1765
|
-
*/
|
|
1766
|
-
async openEditor({
|
|
1767
|
-
editor,
|
|
1768
|
-
input
|
|
1769
|
-
} = {}) {
|
|
1770
|
-
if (!input) input = this.#cwd;
|
|
1771
|
-
console.debug({ openEditorData: {
|
|
1772
|
-
editor,
|
|
1773
|
-
input
|
|
1774
|
-
} });
|
|
1775
|
-
if (!editor || editor === "none") return;
|
|
1776
|
-
const s = this.utils.prompt.spinner();
|
|
1777
|
-
try {
|
|
1778
|
-
s.start(`Opening in ${editor}`);
|
|
1779
|
-
await execChild(`${editor} ${input}`);
|
|
1780
|
-
s.stop(`${this.#style.tick} Text editor [${editor}] opened successfully`);
|
|
1781
|
-
} catch (_e) {
|
|
1782
|
-
if (this.debugMode)
|
|
1783
|
-
s.stop(`Error opening [${editor}] text editor: ${_e?.toString()}`);
|
|
1784
|
-
else
|
|
1785
|
-
s.stop(`Error opening [${editor}] text editor`);
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
/**
|
|
1789
|
-
* Replaces placeholders in files within the specified directory.
|
|
1790
|
-
*
|
|
1791
|
-
* This function searches for files in the provided input directory and replaces
|
|
1792
|
-
* placeholders within those files using the specified parameters. The placeholders
|
|
1793
|
-
* in the content are replaced with values from the `params` object.
|
|
1794
|
-
*
|
|
1795
|
-
* @param {object} args - The arguments object.
|
|
1796
|
-
* @param {string} [args.input] - The directory path containing files with placeholders.
|
|
1797
|
-
* @param {object} [args.params] - An object containing key-value pairs for replacing placeholders.
|
|
1798
|
-
* @returns {Promise<void>} A Promise that resolves once all placeholders have been replaced.
|
|
1799
|
-
* @example
|
|
1800
|
-
* await core.replacePlaceholders( {
|
|
1801
|
-
* input : 'my/project/path',
|
|
1802
|
-
* params : { consts: { version: '1.0.0' }, prompt: { name: 'My Project' } },
|
|
1803
|
-
* })
|
|
1804
|
-
*/
|
|
1805
|
-
async replacePlaceholders({
|
|
1806
|
-
input,
|
|
1807
|
-
params,
|
|
1808
|
-
inputOpts
|
|
1809
|
-
} = {}) {
|
|
1810
|
-
if (!input) input = this.#cwd;
|
|
1811
|
-
if (this.debugMode) console.dir({ replacePlaceholdersData: {
|
|
1812
|
-
params,
|
|
1813
|
-
input
|
|
1814
|
-
} }, { depth: null });
|
|
1815
|
-
if (!params) return;
|
|
1816
|
-
const getContent = async (filePath) => {
|
|
1817
|
-
try {
|
|
1818
|
-
const content = await readFile(filePath, "utf-8");
|
|
1819
|
-
return typeof content === "string" && content.trim().length > 0 ? content : void 0;
|
|
1820
|
-
} catch (_e) {
|
|
1821
|
-
return void 0;
|
|
1822
|
-
}
|
|
1823
|
-
};
|
|
1824
|
-
const paths = await getPaths("**", {
|
|
1825
|
-
filesOnly: true,
|
|
1826
|
-
cwd: input,
|
|
1827
|
-
absolute: true,
|
|
1828
|
-
dot: true,
|
|
1829
|
-
...inputOpts || {}
|
|
1830
|
-
});
|
|
1831
|
-
console.debug({
|
|
1832
|
-
templatePaths: paths,
|
|
1833
|
-
input
|
|
1834
|
-
});
|
|
1835
|
-
await Promise.all(paths.map(async (path) => {
|
|
1836
|
-
const content = await getContent(path);
|
|
1837
|
-
if (!content) return;
|
|
1838
|
-
const res = await replacePlaceholders({
|
|
1839
|
-
content,
|
|
1840
|
-
params
|
|
1841
|
-
});
|
|
1842
|
-
await writeFile(path, res, "utf-8");
|
|
1843
|
-
}));
|
|
1844
|
-
}
|
|
1845
|
-
/**
|
|
1846
|
-
* Return the input path of a template by name or path.
|
|
1847
|
-
*
|
|
1848
|
-
* @param {string} [input] - The name of the template or the path to the template.
|
|
1849
|
-
* @returns {Promise<string | undefined>} The input path of the template or undefined if not found.
|
|
1850
|
-
* @example
|
|
1851
|
-
* // with template path
|
|
1852
|
-
* const input = await core.getTemplateInput( { input : 'my/template/path' } )
|
|
1853
|
-
* @example
|
|
1854
|
-
* // With template key
|
|
1855
|
-
* // template key must be specified in the config prompt secction.
|
|
1856
|
-
* const input = await core.getTemplateInput( { input : 'templateKey' )
|
|
1857
|
-
*/
|
|
1858
|
-
async getTemplateInput({ input } = {}) {
|
|
1859
|
-
const templates = Object.entries(this.config.prompt).reduce((acc, [_key, value]) => {
|
|
1860
|
-
if (value.type === OPTION.template && value.options)
|
|
1861
|
-
Object.assign(acc, value.options);
|
|
1862
|
-
return acc;
|
|
1863
|
-
}, {});
|
|
1864
|
-
console.debug({ getTemplateInputData: {
|
|
1865
|
-
input,
|
|
1866
|
-
templates
|
|
1867
|
-
} });
|
|
1868
|
-
if (input && templates[input].input) return templates[input].input;
|
|
1869
|
-
if (input && await existsDir(input)) return input;
|
|
1870
|
-
this.utils.prompt.log.error(`Error creating Template: template input "${input}" not found`);
|
|
1871
|
-
return;
|
|
1872
|
-
}
|
|
1873
|
-
/**
|
|
1874
|
-
* Create a new project template.
|
|
1875
|
-
*
|
|
1876
|
-
* @param {CreateTemplateOpts} values - The values to create the template.
|
|
1877
|
-
* @returns {Promise<void>} - A promise that resolves when the template is created.
|
|
1878
|
-
* @example
|
|
1879
|
-
* // basic usage
|
|
1880
|
-
* await core.createTemplate( { input : 'my/template/path', output : 'my/project/path' } )
|
|
1881
|
-
* @example
|
|
1882
|
-
* // custom usage
|
|
1883
|
-
* await core.createTemplate( {
|
|
1884
|
-
* input : 'my/template/path',
|
|
1885
|
-
* output : 'my/project/path',
|
|
1886
|
-
* install : 'pnpm',
|
|
1887
|
-
* open : 'vscode',
|
|
1888
|
-
* consts : {
|
|
1889
|
-
* version : '1.0.0',
|
|
1890
|
-
* header : '// Template generated by Creatium. a project from PigeonPosse',
|
|
1891
|
-
* },
|
|
1892
|
-
* } )
|
|
1893
|
-
*/
|
|
1894
|
-
async createTemplate(values) {
|
|
1895
|
-
try {
|
|
1896
|
-
const {
|
|
1897
|
-
openEditor,
|
|
1898
|
-
input,
|
|
1899
|
-
output,
|
|
1900
|
-
install,
|
|
1901
|
-
consts,
|
|
1902
|
-
...prompt
|
|
1903
|
-
} = values;
|
|
1904
|
-
const data = {
|
|
1905
|
-
input: await this.getTemplateInput({ input }),
|
|
1906
|
-
output: output ? resolvePath(output) : void 0
|
|
1907
|
-
};
|
|
1908
|
-
console.debug({ createTemplate: {
|
|
1909
|
-
values,
|
|
1910
|
-
data
|
|
1911
|
-
} });
|
|
1912
|
-
this.utils.prompt.log.step("");
|
|
1913
|
-
if (!(data.input && data.output))
|
|
1914
|
-
throw new Error("Invalid input or output template");
|
|
1915
|
-
await this.copyDir({
|
|
1916
|
-
input: data.input,
|
|
1917
|
-
output: data.output
|
|
1918
|
-
});
|
|
1919
|
-
await this.replacePlaceholders({
|
|
1920
|
-
input: data.output,
|
|
1921
|
-
params: {
|
|
1922
|
-
name: this.config.name,
|
|
1923
|
-
version: this.config.version,
|
|
1924
|
-
consts,
|
|
1925
|
-
prompt
|
|
1926
|
-
}
|
|
1927
|
-
});
|
|
1928
|
-
await this.install({
|
|
1929
|
-
input: data.output,
|
|
1930
|
-
installer: install
|
|
1931
|
-
});
|
|
1932
|
-
await this.openEditor({
|
|
1933
|
-
input: data.output,
|
|
1934
|
-
editor: openEditor
|
|
1935
|
-
});
|
|
1936
|
-
await this.outro();
|
|
1937
|
-
} catch (e) {
|
|
1938
|
-
const error = e instanceof Error ? e.message : e?.toString();
|
|
1939
|
-
this.utils.prompt.log.error(`Unexpected error creating template:
|
|
1940
|
-
${error}
|
|
1941
|
-
|
|
1942
|
-
`);
|
|
1943
|
-
await this.#core.onCancel();
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
/**
|
|
1947
|
-
* Initialize the CLI and executes the callback function passed in the config.
|
|
1948
|
-
*
|
|
1949
|
-
* @param {GetPromptValues<C>} [values] - The values to override the CLI prompts. If not set, the CLI prompts will be executed.
|
|
1950
|
-
* @param {CreateOpts} [opts] - The options to pass to the CLI.
|
|
1951
|
-
* @returns The result of the callback function.
|
|
1952
|
-
*/
|
|
1953
|
-
async build(values, opts) {
|
|
1954
|
-
const cliValues = opts?.activeCli !== false ? await this.#initCli(opts) : {};
|
|
1955
|
-
const config = values ? deepmergeTs.deepmergeCustom({})(values, cliValues) : cliValues;
|
|
1956
|
-
return await this.#exec(config);
|
|
1957
|
-
}
|
|
1958
|
-
/**
|
|
1959
|
-
* Initializes and executes the command-line interface (CLI) process.
|
|
1960
|
-
*
|
|
1961
|
-
* @param {CliOpts} [props] - Optional CLI options to configure the initialization process.
|
|
1962
|
-
* @returns A promise resolving to the prompt values obtained after executing the CLI.
|
|
1963
|
-
* @example
|
|
1964
|
-
* // simple usage
|
|
1965
|
-
* await core.cli()
|
|
1966
|
-
* @example
|
|
1967
|
-
* // custom usage
|
|
1968
|
-
* await core.cli( { args : process.argv.slice( 4), hideBin : false } )
|
|
1969
|
-
*/
|
|
1970
|
-
async cli(props) {
|
|
1971
|
-
const values = await this.#initCli(props);
|
|
1972
|
-
return await this.#exec(values);
|
|
1973
|
-
}
|
|
1974
|
-
}
|
|
1975
|
-
|
|
1976
|
-
class Creatium {
|
|
1977
|
-
#core;
|
|
1978
|
-
options;
|
|
1979
|
-
config;
|
|
1980
|
-
constructor(options) {
|
|
1981
|
-
const {
|
|
1982
|
-
templates,
|
|
1983
|
-
opts,
|
|
1984
|
-
consts,
|
|
1985
|
-
...restConf
|
|
1986
|
-
} = options;
|
|
1987
|
-
this.options = options;
|
|
1988
|
-
this.config = {
|
|
1989
|
-
...restConf,
|
|
1990
|
-
prompt: {
|
|
1991
|
-
[OPTION.output]: { type: OPTION.output },
|
|
1992
|
-
...opts?.name !== false ? { [OPTION.name]: { type: OPTION.name } } : {},
|
|
1993
|
-
input: {
|
|
1994
|
-
type: OPTION.template,
|
|
1995
|
-
options: templates
|
|
1996
|
-
},
|
|
1997
|
-
...opts?.install !== false ? { [OPTION.install]: {
|
|
1998
|
-
type: OPTION.install,
|
|
1999
|
-
onlyOptions: typeof opts?.install !== "boolean" ? opts?.install : void 0
|
|
2000
|
-
} } : {},
|
|
2001
|
-
...opts?.openEditor !== false ? { [OPTION.openEditor]: {
|
|
2002
|
-
type: OPTION.openEditor,
|
|
2003
|
-
onlyOptions: typeof opts?.openEditor !== "boolean" ? opts?.openEditor : void 0
|
|
2004
|
-
} } : {}
|
|
2005
|
-
}
|
|
2006
|
-
};
|
|
2007
|
-
this.#core = new CreatiumCore(this.config);
|
|
2008
|
-
}
|
|
2009
|
-
/**
|
|
2010
|
-
* A simplified version of the `build` method from the main class.
|
|
2011
|
-
*
|
|
2012
|
-
* @param {ValuesSimple} [values] - The values to override the CLI prompts. If not set, the CLI prompts will be executed.
|
|
2013
|
-
* @param {CreateOpts} [opts] - The options to pass to the CLI.
|
|
2014
|
-
* @returns {Promise<ValuesSimple>} A promise resolving to the prompt values obtained after executing the CLI.
|
|
2015
|
-
* @example
|
|
2016
|
-
* // simple usage
|
|
2017
|
-
* await core.build()
|
|
2018
|
-
* @example
|
|
2019
|
-
* // custom usage
|
|
2020
|
-
* await core.build( { args : process.argv.slice(4), hideBin : false } )
|
|
2021
|
-
*/
|
|
2022
|
-
async build(values, opts) {
|
|
2023
|
-
const data = await this.#core.build(values, opts);
|
|
2024
|
-
await this.#core.createTemplate({
|
|
2025
|
-
...data,
|
|
2026
|
-
consts: this.options.consts
|
|
2027
|
-
});
|
|
2028
|
-
return data;
|
|
2029
|
-
}
|
|
2030
|
-
/**
|
|
2031
|
-
* A simplified version of the `cli` method from the main class.
|
|
2032
|
-
* Initializes and executes the command-line interface (CLI) process.
|
|
2033
|
-
*
|
|
2034
|
-
* @param {CliOpts} [props] - Optional CLI options to configure the initialization process.
|
|
2035
|
-
* @returns {Promise<ValuesSimple>} A promise resolving to the prompt values obtained after executing the CLI.
|
|
2036
|
-
* @example
|
|
2037
|
-
* // simple usage
|
|
2038
|
-
* await core.cli()
|
|
2039
|
-
* @example
|
|
2040
|
-
* // custom usage
|
|
2041
|
-
* await core.cli( { args : process.argv.slice(4), hideBin : false } )
|
|
2042
|
-
*/
|
|
2043
|
-
async cli(props) {
|
|
2044
|
-
const data = await this.#core.cli(props);
|
|
2045
|
-
await this.#core.createTemplate({
|
|
2046
|
-
...data,
|
|
2047
|
-
consts: this.options.consts
|
|
2048
|
-
});
|
|
2049
|
-
return data;
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
|
|
2053
|
-
exports.Creatium = Creatium;
|
|
2054
|
-
exports.CreatiumCore = CreatiumCore;
|
|
2055
|
-
exports.INSTALLER = INSTALLER;
|
|
2056
|
-
exports.OPTION = OPTION;
|
|
2057
|
-
exports.TEXT_EDITOR = TEXT_EDITOR;
|
|
2058
|
-
exports.env = env;
|
|
2059
|
-
exports.prompt = prompt;
|
|
2060
|
-
exports.style = style;
|
|
2061
|
-
exports.sys = sys;
|