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/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;