@retailcrm/embed-ui 0.9.22-alpha.1 → 0.9.22-alpha.3
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/CHANGELOG.md +14 -0
- package/README.md +3 -3
- package/bin/embed-ui.mjs +2249 -139
- package/package.json +7 -6
package/bin/embed-ui.mjs
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
3
|
import { execFileSync } from "node:child_process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
4
5
|
import fs from "node:fs";
|
|
5
6
|
import path from "node:path";
|
|
6
|
-
import
|
|
7
|
-
import process$1 from "node:process";
|
|
7
|
+
import process$2 from "node:process";
|
|
8
8
|
import yargs from "yargs";
|
|
9
9
|
import { randomUUID } from "node:crypto";
|
|
10
|
+
import * as readline$1 from "node:readline";
|
|
11
|
+
import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
|
|
12
|
+
import require$$0$1 from "stream";
|
|
13
|
+
import { styleText, stripVTControlCharacters } from "node:util";
|
|
14
|
+
import require$$0 from "tty";
|
|
10
15
|
const PACKAGE_MANAGERS = ["yarn", "npm", "pnpm", "bun"];
|
|
11
16
|
const HELP_TEXT = `Usage:
|
|
12
17
|
npx @retailcrm/embed-ui [target] [version] [options]
|
|
@@ -14,14 +19,14 @@ const HELP_TEXT = `Usage:
|
|
|
14
19
|
|
|
15
20
|
Options:
|
|
16
21
|
-t, --target <path> Target path (default: current directory)
|
|
17
|
-
-v, --version <ver> Target version.
|
|
22
|
+
-v, --version <ver> Target version. In init mode, defaults to the current CLI version
|
|
18
23
|
--exact Use exact version instead of range
|
|
19
24
|
--dry-run Show changes without writing package.json
|
|
20
25
|
--add Add selected embed-ui packages into one package.json
|
|
21
26
|
--packages <list> Comma-separated package ids or names for --add/init
|
|
22
27
|
--cwd <path> Project working directory for init
|
|
23
28
|
--package-manager Package manager for init installs
|
|
24
|
-
--interactive Ask init questions
|
|
29
|
+
--interactive Ask init questions with TTY selection prompts
|
|
25
30
|
--no-install Do not run package manager install in init mode
|
|
26
31
|
--no-configs Do not create root TypeScript, Vite, ESLint and env config files
|
|
27
32
|
--force-deps Replace incompatible existing init dependencies
|
|
@@ -59,7 +64,7 @@ const parseInitArgs = (argv) => {
|
|
|
59
64
|
"boolean-negation": true
|
|
60
65
|
}).option("cwd", {
|
|
61
66
|
type: "string",
|
|
62
|
-
default: process$
|
|
67
|
+
default: process$2.cwd(),
|
|
63
68
|
describe: "Project working directory"
|
|
64
69
|
}).option("help", {
|
|
65
70
|
alias: "h",
|
|
@@ -111,7 +116,7 @@ const parseInitArgs = (argv) => {
|
|
|
111
116
|
}).parseSync();
|
|
112
117
|
if (parsed.help || parsed.h) {
|
|
113
118
|
console.log(HELP_TEXT);
|
|
114
|
-
process$
|
|
119
|
+
process$2.exit(0);
|
|
115
120
|
}
|
|
116
121
|
const positionals = parsed._.map(String);
|
|
117
122
|
if (positionals.length > 1) {
|
|
@@ -122,7 +127,7 @@ const parseInitArgs = (argv) => {
|
|
|
122
127
|
}
|
|
123
128
|
return {
|
|
124
129
|
command: "init",
|
|
125
|
-
cwd: path.resolve(process$
|
|
130
|
+
cwd: path.resolve(process$2.cwd(), parsed.cwd),
|
|
126
131
|
target: parsed.target ?? positionals[0] ?? null,
|
|
127
132
|
version: parsed.version ?? null,
|
|
128
133
|
dryRun: parsed.dryRun,
|
|
@@ -159,7 +164,7 @@ const parseArgs = (argv) => {
|
|
|
159
164
|
const parsed = yargs(argv).scriptName("embed-ui").usage("Usage: $0 [target] [version] [options]").help(false).version(false).exitProcess(false).strictOptions().option("target", {
|
|
160
165
|
alias: "t",
|
|
161
166
|
type: "string",
|
|
162
|
-
default: process$
|
|
167
|
+
default: process$2.cwd()
|
|
163
168
|
}).option("help", {
|
|
164
169
|
alias: "h",
|
|
165
170
|
type: "boolean"
|
|
@@ -173,7 +178,7 @@ const parseArgs = (argv) => {
|
|
|
173
178
|
}).parseSync();
|
|
174
179
|
if (parsed.help || parsed.h) {
|
|
175
180
|
console.log(HELP_TEXT);
|
|
176
|
-
process$
|
|
181
|
+
process$2.exit(0);
|
|
177
182
|
}
|
|
178
183
|
const positionals = parsed._.map(String);
|
|
179
184
|
if (positionals.length > 2) {
|
|
@@ -181,7 +186,7 @@ const parseArgs = (argv) => {
|
|
|
181
186
|
}
|
|
182
187
|
const options = {
|
|
183
188
|
command: "update",
|
|
184
|
-
target: path.resolve(process$
|
|
189
|
+
target: path.resolve(process$2.cwd(), parsed.target),
|
|
185
190
|
version: parsed.version ?? null,
|
|
186
191
|
dryRun: parsed.dryRun,
|
|
187
192
|
exact: parsed.exact,
|
|
@@ -193,7 +198,7 @@ const parseArgs = (argv) => {
|
|
|
193
198
|
if (!options.version && isSemverLike(first)) {
|
|
194
199
|
options.version = stripLeadingV(first);
|
|
195
200
|
} else {
|
|
196
|
-
options.target = path.resolve(process$
|
|
201
|
+
options.target = path.resolve(process$2.cwd(), first);
|
|
197
202
|
}
|
|
198
203
|
}
|
|
199
204
|
if (positionals.length === 2) {
|
|
@@ -291,6 +296,24 @@ const resolveLatestVersion = () => {
|
|
|
291
296
|
}
|
|
292
297
|
return output;
|
|
293
298
|
};
|
|
299
|
+
const resolveCurrentPackageVersion = (startPath = fileURLToPath(import.meta.url)) => {
|
|
300
|
+
let currentDir = fs.existsSync(startPath) && fs.statSync(startPath).isDirectory() ? startPath : path.dirname(startPath);
|
|
301
|
+
while (true) {
|
|
302
|
+
const packageJsonPath = path.join(currentDir, "package.json");
|
|
303
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
304
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
305
|
+
if (packageJson.name === ROOT_PACKAGE && typeof packageJson.version === "string") {
|
|
306
|
+
return packageJson.version;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const parentDir = path.dirname(currentDir);
|
|
310
|
+
if (parentDir === currentDir) {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
currentDir = parentDir;
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
const resolveDefaultInitVersion = () => resolveCurrentPackageVersion() ?? resolveLatestVersion();
|
|
294
317
|
const isTargetPackage = (name) => name === ROOT_PACKAGE || name.startsWith(`${ROOT_PACKAGE}-`);
|
|
295
318
|
const createRange = (version, exact) => exact ? version : `^${version}`;
|
|
296
319
|
const formatRange = (currentRange, nextVersion, exact) => {
|
|
@@ -391,7 +414,7 @@ const installPackages = (packageJson, packages, version, exact) => {
|
|
|
391
414
|
return updates;
|
|
392
415
|
};
|
|
393
416
|
const promptForInstallSelection = async (packageJson) => {
|
|
394
|
-
if (!process$
|
|
417
|
+
if (!process$2.stdin.isTTY || !process$2.stdout.isTTY) {
|
|
395
418
|
throw new Error("Interactive add mode requires a TTY. Use --packages to select packages explicitly.");
|
|
396
419
|
}
|
|
397
420
|
console.log("Выберите пакеты для установки в текущий package.json:");
|
|
@@ -401,13 +424,13 @@ const promptForInstallSelection = async (packageJson) => {
|
|
|
401
424
|
console.log(` ${index + 1}. ${selectedPackage.name} (${selectedPackage.id})`);
|
|
402
425
|
console.log(` ${selectedPackage.description} Раздел по умолчанию: ${selectedPackage.section}.${installedHint}`);
|
|
403
426
|
}
|
|
404
|
-
const
|
|
405
|
-
input: process$
|
|
406
|
-
output: process$
|
|
427
|
+
const readline2 = createInterface({
|
|
428
|
+
input: process$2.stdin,
|
|
429
|
+
output: process$2.stdout
|
|
407
430
|
});
|
|
408
431
|
try {
|
|
409
432
|
while (true) {
|
|
410
|
-
const answer = await
|
|
433
|
+
const answer = await readline2.question(
|
|
411
434
|
"Введите номера, ids или имена пакетов через запятую (например: 1,3 или components,types): "
|
|
412
435
|
);
|
|
413
436
|
const tokens = parsePackageList(answer);
|
|
@@ -422,13 +445,14 @@ const promptForInstallSelection = async (packageJson) => {
|
|
|
422
445
|
}
|
|
423
446
|
}
|
|
424
447
|
} finally {
|
|
425
|
-
|
|
448
|
+
readline2.close();
|
|
426
449
|
}
|
|
427
450
|
};
|
|
428
451
|
const DEFAULT_INDENT = " ";
|
|
429
452
|
const DEFAULT_NEWLINE = "\n";
|
|
430
453
|
const INIT_RUNTIME_DEPENDENCIES = [
|
|
431
454
|
{ name: "@omnicajs/vue-remote", range: "^0.2.23" },
|
|
455
|
+
{ name: "@remote-ui/rpc", range: "^1.4.7" },
|
|
432
456
|
{ name: "pinia", range: "^2.2" },
|
|
433
457
|
{ name: "vue", range: "^3.5" },
|
|
434
458
|
{ name: "vue-i18n", range: "^11" }
|
|
@@ -444,12 +468,14 @@ const INIT_DEV_DEPENDENCIES = [
|
|
|
444
468
|
{ name: "eslint", range: "^9.39" },
|
|
445
469
|
{ name: "eslint-plugin-vue", range: "^10.9" },
|
|
446
470
|
{ name: "globals", range: "^16.5" },
|
|
471
|
+
{ name: "jsonc-eslint-parser", range: "^3.1" },
|
|
447
472
|
{ name: "less", range: "^4.6" },
|
|
448
473
|
{ name: "typescript", range: "^5.9" },
|
|
449
474
|
{ name: "typescript-eslint", range: "^8.59" },
|
|
450
475
|
{ name: "vite", range: "^7.3" },
|
|
451
476
|
{ name: "vite-svg-loader", range: "^5.1" },
|
|
452
|
-
{ name: "vue-eslint-parser", range: "^10.4" }
|
|
477
|
+
{ name: "vue-eslint-parser", range: "^10.4" },
|
|
478
|
+
{ name: "yaml-eslint-parser", range: "^2.0" }
|
|
453
479
|
];
|
|
454
480
|
const I18N_RUNTIME_DEPENDENCY = "vue-i18n";
|
|
455
481
|
const hasExistingDependency = (packageJson, name) => findDependencySection(packageJson, name) !== null;
|
|
@@ -586,18 +612,44 @@ const resolveLocalBinPath = (cwd, binName) => {
|
|
|
586
612
|
return fs.existsSync(binPath) ? binPath : null;
|
|
587
613
|
};
|
|
588
614
|
const hasLocalPackage = (cwd, packageName) => fs.existsSync(path.join(cwd, "node_modules", packageName, "package.json"));
|
|
589
|
-
const
|
|
615
|
+
const createPackageSpec = (packageName, version) => version && version !== "not used" ? `${packageName}@${version}` : packageName;
|
|
616
|
+
const resolvePackageManagerVersion$1 = (packageManager) => {
|
|
617
|
+
try {
|
|
618
|
+
return execFileSync(packageManager, ["--version"], {
|
|
619
|
+
encoding: "utf8",
|
|
620
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
621
|
+
}).trim();
|
|
622
|
+
} catch {
|
|
623
|
+
return null;
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
const resolveMajorVersion = (version) => {
|
|
627
|
+
const major = version?.match(/^\d+/u)?.[0];
|
|
628
|
+
return major ? Number(major) : null;
|
|
629
|
+
};
|
|
630
|
+
const resolveDownloadCommand = (packageName, binName, packageManager, args, packageVersion, versionResolver) => {
|
|
631
|
+
const packageSpec = createPackageSpec(packageName, packageVersion);
|
|
590
632
|
if (packageManager === "yarn") {
|
|
591
|
-
const
|
|
633
|
+
const yarnMajor = resolveMajorVersion(versionResolver("yarn"));
|
|
634
|
+
if (yarnMajor !== null && yarnMajor >= 2) {
|
|
635
|
+
const commandArgs3 = ["dlx", "-p", packageSpec, binName, ...args];
|
|
636
|
+
return {
|
|
637
|
+
command: "yarn",
|
|
638
|
+
args: commandArgs3,
|
|
639
|
+
display: `yarn ${commandArgs3.join(" ")}`,
|
|
640
|
+
source: "transient"
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
const commandArgs2 = ["-y", "-p", packageSpec, binName, ...args];
|
|
592
644
|
return {
|
|
593
|
-
command: "
|
|
645
|
+
command: "npx",
|
|
594
646
|
args: commandArgs2,
|
|
595
|
-
display: `
|
|
647
|
+
display: `npx ${commandArgs2.join(" ")}`,
|
|
596
648
|
source: "transient"
|
|
597
649
|
};
|
|
598
650
|
}
|
|
599
651
|
if (packageManager === "pnpm") {
|
|
600
|
-
const commandArgs2 = ["dlx", "--package",
|
|
652
|
+
const commandArgs2 = ["dlx", "--package", packageSpec, binName, ...args];
|
|
601
653
|
return {
|
|
602
654
|
command: "pnpm",
|
|
603
655
|
args: commandArgs2,
|
|
@@ -606,7 +658,7 @@ const resolveDownloadCommand = (packageName, binName, packageManager, args) => {
|
|
|
606
658
|
};
|
|
607
659
|
}
|
|
608
660
|
if (packageManager === "bun") {
|
|
609
|
-
const commandArgs2 = ["x", "--package",
|
|
661
|
+
const commandArgs2 = ["x", "--package", packageSpec, binName, ...args];
|
|
610
662
|
return {
|
|
611
663
|
command: "bun",
|
|
612
664
|
args: commandArgs2,
|
|
@@ -614,7 +666,7 @@ const resolveDownloadCommand = (packageName, binName, packageManager, args) => {
|
|
|
614
666
|
source: "transient"
|
|
615
667
|
};
|
|
616
668
|
}
|
|
617
|
-
const commandArgs = ["exec", "--yes", "--package",
|
|
669
|
+
const commandArgs = ["exec", "--yes", "--package", packageSpec, "--", binName, ...args];
|
|
618
670
|
return {
|
|
619
671
|
command: "npm",
|
|
620
672
|
args: commandArgs,
|
|
@@ -622,7 +674,7 @@ const resolveDownloadCommand = (packageName, binName, packageManager, args) => {
|
|
|
622
674
|
source: "transient"
|
|
623
675
|
};
|
|
624
676
|
};
|
|
625
|
-
const resolvePackageHookCommand = (cwd, packageName, binName, packageManager, args) => {
|
|
677
|
+
const resolvePackageHookCommand = (cwd, packageName, binName, packageManager, args, packageVersion = null, versionResolver = resolvePackageManagerVersion$1) => {
|
|
626
678
|
const localBinPath = resolveLocalBinPath(cwd, binName);
|
|
627
679
|
if (localBinPath) {
|
|
628
680
|
return {
|
|
@@ -637,7 +689,7 @@ const resolvePackageHookCommand = (cwd, packageName, binName, packageManager, ar
|
|
|
637
689
|
`${packageName} is installed, but ${binName} was not found in node_modules/.bin. Reinstall dependencies or check the package bin metadata.`
|
|
638
690
|
);
|
|
639
691
|
}
|
|
640
|
-
return resolveDownloadCommand(packageName, binName, packageManager, args);
|
|
692
|
+
return resolveDownloadCommand(packageName, binName, packageManager, args, packageVersion, versionResolver);
|
|
641
693
|
};
|
|
642
694
|
const getExecErrorMessage = (error) => {
|
|
643
695
|
if (error instanceof Error && error.message) {
|
|
@@ -646,7 +698,14 @@ const getExecErrorMessage = (error) => {
|
|
|
646
698
|
return String(error);
|
|
647
699
|
};
|
|
648
700
|
const runPackageHookCommand = (cwd, packageName, binName, packageManager, args, failureMode, options, changes) => {
|
|
649
|
-
const command = resolvePackageHookCommand(
|
|
701
|
+
const command = resolvePackageHookCommand(
|
|
702
|
+
cwd,
|
|
703
|
+
packageName,
|
|
704
|
+
binName,
|
|
705
|
+
packageManager,
|
|
706
|
+
args,
|
|
707
|
+
options.version
|
|
708
|
+
);
|
|
650
709
|
changes.hooks.push(command.display);
|
|
651
710
|
if (options.dryRun) {
|
|
652
711
|
return;
|
|
@@ -2225,124 +2284,2166 @@ const printInitReport = (cwd, sourceRoot, version, packageManager, changes, opti
|
|
|
2225
2284
|
console.log("Dry run enabled, no files were modified.");
|
|
2226
2285
|
}
|
|
2227
2286
|
};
|
|
2228
|
-
const
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2287
|
+
const isUpKey = (key, keybindings = []) => (
|
|
2288
|
+
// The up key
|
|
2289
|
+
key.name === "up" || // Vim keybinding: hjkl keys map to left/down/up/right
|
|
2290
|
+
keybindings.includes("vim") && key.name === "k" || // Emacs keybinding: Ctrl+P means "previous" in Emacs navigation conventions
|
|
2291
|
+
keybindings.includes("emacs") && key.ctrl && key.name === "p"
|
|
2292
|
+
);
|
|
2293
|
+
const isDownKey = (key, keybindings = []) => (
|
|
2294
|
+
// The down key
|
|
2295
|
+
key.name === "down" || // Vim keybinding: hjkl keys map to left/down/up/right
|
|
2296
|
+
keybindings.includes("vim") && key.name === "j" || // Emacs keybinding: Ctrl+N means "next" in Emacs navigation conventions
|
|
2297
|
+
keybindings.includes("emacs") && key.ctrl && key.name === "n"
|
|
2298
|
+
);
|
|
2299
|
+
const isSpaceKey = (key) => key.name === "space";
|
|
2300
|
+
const isBackspaceKey = (key) => key.name === "backspace";
|
|
2301
|
+
const isTabKey = (key) => key.name === "tab";
|
|
2302
|
+
const isNumberKey = (key) => "1234567890".includes(key.name);
|
|
2303
|
+
const isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
2304
|
+
class AbortPromptError extends Error {
|
|
2305
|
+
name = "AbortPromptError";
|
|
2306
|
+
message = "Prompt was aborted";
|
|
2307
|
+
constructor(options) {
|
|
2308
|
+
super();
|
|
2309
|
+
this.cause = options?.cause;
|
|
2232
2310
|
}
|
|
2233
|
-
|
|
2234
|
-
|
|
2311
|
+
}
|
|
2312
|
+
class CancelPromptError extends Error {
|
|
2313
|
+
name = "CancelPromptError";
|
|
2314
|
+
message = "Prompt was canceled";
|
|
2315
|
+
}
|
|
2316
|
+
class ExitPromptError extends Error {
|
|
2317
|
+
name = "ExitPromptError";
|
|
2318
|
+
}
|
|
2319
|
+
class HookError extends Error {
|
|
2320
|
+
name = "HookError";
|
|
2321
|
+
}
|
|
2322
|
+
class ValidationError extends Error {
|
|
2323
|
+
name = "ValidationError";
|
|
2324
|
+
}
|
|
2325
|
+
const hookStorage = new AsyncLocalStorage();
|
|
2326
|
+
function createStore(rl) {
|
|
2327
|
+
const store = {
|
|
2328
|
+
rl,
|
|
2329
|
+
hooks: [],
|
|
2330
|
+
hooksCleanup: [],
|
|
2331
|
+
hooksEffect: [],
|
|
2332
|
+
index: 0,
|
|
2333
|
+
handleChange() {
|
|
2334
|
+
}
|
|
2335
|
+
};
|
|
2336
|
+
return store;
|
|
2337
|
+
}
|
|
2338
|
+
function withHooks(rl, cb) {
|
|
2339
|
+
const store = createStore(rl);
|
|
2340
|
+
return hookStorage.run(store, () => {
|
|
2341
|
+
function cycle(render) {
|
|
2342
|
+
store.handleChange = () => {
|
|
2343
|
+
store.index = 0;
|
|
2344
|
+
render();
|
|
2345
|
+
};
|
|
2346
|
+
store.handleChange();
|
|
2347
|
+
}
|
|
2348
|
+
return cb(cycle);
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
function getStore() {
|
|
2352
|
+
const store = hookStorage.getStore();
|
|
2353
|
+
if (!store) {
|
|
2354
|
+
throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
|
|
2235
2355
|
}
|
|
2236
|
-
return
|
|
2356
|
+
return store;
|
|
2357
|
+
}
|
|
2358
|
+
function readline() {
|
|
2359
|
+
return getStore().rl;
|
|
2360
|
+
}
|
|
2361
|
+
function withUpdates(fn) {
|
|
2362
|
+
const wrapped = (...args) => {
|
|
2363
|
+
const store = getStore();
|
|
2364
|
+
let shouldUpdate = false;
|
|
2365
|
+
const oldHandleChange = store.handleChange;
|
|
2366
|
+
store.handleChange = () => {
|
|
2367
|
+
shouldUpdate = true;
|
|
2368
|
+
};
|
|
2369
|
+
const returnValue = fn(...args);
|
|
2370
|
+
if (shouldUpdate) {
|
|
2371
|
+
oldHandleChange();
|
|
2372
|
+
}
|
|
2373
|
+
store.handleChange = oldHandleChange;
|
|
2374
|
+
return returnValue;
|
|
2375
|
+
};
|
|
2376
|
+
return AsyncResource.bind(wrapped);
|
|
2377
|
+
}
|
|
2378
|
+
function withPointer(cb) {
|
|
2379
|
+
const store = getStore();
|
|
2380
|
+
const { index } = store;
|
|
2381
|
+
const pointer = {
|
|
2382
|
+
get() {
|
|
2383
|
+
return store.hooks[index];
|
|
2384
|
+
},
|
|
2385
|
+
set(value) {
|
|
2386
|
+
store.hooks[index] = value;
|
|
2387
|
+
},
|
|
2388
|
+
initialized: index in store.hooks
|
|
2389
|
+
};
|
|
2390
|
+
const returnValue = cb(pointer);
|
|
2391
|
+
store.index++;
|
|
2392
|
+
return returnValue;
|
|
2393
|
+
}
|
|
2394
|
+
function handleChange() {
|
|
2395
|
+
getStore().handleChange();
|
|
2396
|
+
}
|
|
2397
|
+
const effectScheduler = {
|
|
2398
|
+
queue(cb) {
|
|
2399
|
+
const store = getStore();
|
|
2400
|
+
const { index } = store;
|
|
2401
|
+
store.hooksEffect.push(() => {
|
|
2402
|
+
store.hooksCleanup[index]?.();
|
|
2403
|
+
const cleanFn = cb(readline());
|
|
2404
|
+
if (cleanFn != null && typeof cleanFn !== "function") {
|
|
2405
|
+
throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
|
|
2406
|
+
}
|
|
2407
|
+
store.hooksCleanup[index] = cleanFn;
|
|
2408
|
+
});
|
|
2409
|
+
},
|
|
2410
|
+
run() {
|
|
2411
|
+
const store = getStore();
|
|
2412
|
+
withUpdates(() => {
|
|
2413
|
+
store.hooksEffect.forEach((effect) => {
|
|
2414
|
+
effect();
|
|
2415
|
+
});
|
|
2416
|
+
store.hooksEffect.length = 0;
|
|
2417
|
+
})();
|
|
2418
|
+
},
|
|
2419
|
+
clearAll() {
|
|
2420
|
+
const store = getStore();
|
|
2421
|
+
store.hooksCleanup.forEach((cleanFn) => {
|
|
2422
|
+
cleanFn?.();
|
|
2423
|
+
});
|
|
2424
|
+
store.hooksEffect.length = 0;
|
|
2425
|
+
store.hooksCleanup.length = 0;
|
|
2426
|
+
}
|
|
2427
|
+
};
|
|
2428
|
+
function isFactory(value) {
|
|
2429
|
+
return typeof value === "function";
|
|
2430
|
+
}
|
|
2431
|
+
function useState(defaultValue) {
|
|
2432
|
+
return withPointer((pointer) => {
|
|
2433
|
+
const setState = AsyncResource.bind(function setState2(newValue) {
|
|
2434
|
+
if (pointer.get() !== newValue) {
|
|
2435
|
+
pointer.set(newValue);
|
|
2436
|
+
handleChange();
|
|
2437
|
+
}
|
|
2438
|
+
});
|
|
2439
|
+
if (pointer.initialized) {
|
|
2440
|
+
return [pointer.get(), setState];
|
|
2441
|
+
}
|
|
2442
|
+
const value = isFactory(defaultValue) ? defaultValue() : defaultValue;
|
|
2443
|
+
pointer.set(value);
|
|
2444
|
+
return [value, setState];
|
|
2445
|
+
});
|
|
2446
|
+
}
|
|
2447
|
+
function useEffect(cb, depArray) {
|
|
2448
|
+
withPointer((pointer) => {
|
|
2449
|
+
const oldDeps = pointer.get();
|
|
2450
|
+
const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
|
|
2451
|
+
if (hasChanged) {
|
|
2452
|
+
effectScheduler.queue(cb);
|
|
2453
|
+
}
|
|
2454
|
+
pointer.set(depArray);
|
|
2455
|
+
});
|
|
2456
|
+
}
|
|
2457
|
+
function isUnicodeSupported() {
|
|
2458
|
+
if (!process$2.platform.startsWith("win")) {
|
|
2459
|
+
return process$2.env["TERM"] !== "linux";
|
|
2460
|
+
}
|
|
2461
|
+
return Boolean(process$2.env["CI"]) || // CI environments generally support unicode
|
|
2462
|
+
Boolean(process$2.env["WT_SESSION"]) || // Windows Terminal
|
|
2463
|
+
Boolean(process$2.env["TERMINUS_SUBLIME"]) || // Terminus (<0.2.27)
|
|
2464
|
+
process$2.env["ConEmuTask"] === "{cmd::Cmder}" || // ConEmu and cmder
|
|
2465
|
+
process$2.env["TERM_PROGRAM"] === "Terminus-Sublime" || process$2.env["TERM_PROGRAM"] === "vscode" || process$2.env["TERM"] === "xterm-256color" || process$2.env["TERM"] === "alacritty" || process$2.env["TERMINAL_EMULATOR"] === "JetBrains-JediTerm";
|
|
2466
|
+
}
|
|
2467
|
+
const common = {
|
|
2468
|
+
circleQuestionMark: "(?)",
|
|
2469
|
+
questionMarkPrefix: "(?)",
|
|
2470
|
+
square: "█",
|
|
2471
|
+
squareDarkShade: "▓",
|
|
2472
|
+
squareMediumShade: "▒",
|
|
2473
|
+
squareLightShade: "░",
|
|
2474
|
+
squareTop: "▀",
|
|
2475
|
+
squareBottom: "▄",
|
|
2476
|
+
squareLeft: "▌",
|
|
2477
|
+
squareRight: "▐",
|
|
2478
|
+
squareCenter: "■",
|
|
2479
|
+
bullet: "●",
|
|
2480
|
+
dot: "․",
|
|
2481
|
+
ellipsis: "…",
|
|
2482
|
+
pointerSmall: "›",
|
|
2483
|
+
triangleUp: "▲",
|
|
2484
|
+
triangleUpSmall: "▴",
|
|
2485
|
+
triangleDown: "▼",
|
|
2486
|
+
triangleDownSmall: "▾",
|
|
2487
|
+
triangleLeftSmall: "◂",
|
|
2488
|
+
triangleRightSmall: "▸",
|
|
2489
|
+
home: "⌂",
|
|
2490
|
+
heart: "♥",
|
|
2491
|
+
musicNote: "♪",
|
|
2492
|
+
musicNoteBeamed: "♫",
|
|
2493
|
+
arrowUp: "↑",
|
|
2494
|
+
arrowDown: "↓",
|
|
2495
|
+
arrowLeft: "←",
|
|
2496
|
+
arrowRight: "→",
|
|
2497
|
+
arrowLeftRight: "↔",
|
|
2498
|
+
arrowUpDown: "↕",
|
|
2499
|
+
almostEqual: "≈",
|
|
2500
|
+
notEqual: "≠",
|
|
2501
|
+
lessOrEqual: "≤",
|
|
2502
|
+
greaterOrEqual: "≥",
|
|
2503
|
+
identical: "≡",
|
|
2504
|
+
infinity: "∞",
|
|
2505
|
+
subscriptZero: "₀",
|
|
2506
|
+
subscriptOne: "₁",
|
|
2507
|
+
subscriptTwo: "₂",
|
|
2508
|
+
subscriptThree: "₃",
|
|
2509
|
+
subscriptFour: "₄",
|
|
2510
|
+
subscriptFive: "₅",
|
|
2511
|
+
subscriptSix: "₆",
|
|
2512
|
+
subscriptSeven: "₇",
|
|
2513
|
+
subscriptEight: "₈",
|
|
2514
|
+
subscriptNine: "₉",
|
|
2515
|
+
oneHalf: "½",
|
|
2516
|
+
oneThird: "⅓",
|
|
2517
|
+
oneQuarter: "¼",
|
|
2518
|
+
oneFifth: "⅕",
|
|
2519
|
+
oneSixth: "⅙",
|
|
2520
|
+
oneEighth: "⅛",
|
|
2521
|
+
twoThirds: "⅔",
|
|
2522
|
+
twoFifths: "⅖",
|
|
2523
|
+
threeQuarters: "¾",
|
|
2524
|
+
threeFifths: "⅗",
|
|
2525
|
+
threeEighths: "⅜",
|
|
2526
|
+
fourFifths: "⅘",
|
|
2527
|
+
fiveSixths: "⅚",
|
|
2528
|
+
fiveEighths: "⅝",
|
|
2529
|
+
sevenEighths: "⅞",
|
|
2530
|
+
line: "─",
|
|
2531
|
+
lineBold: "━",
|
|
2532
|
+
lineDouble: "═",
|
|
2533
|
+
lineDashed0: "┄",
|
|
2534
|
+
lineDashed1: "┅",
|
|
2535
|
+
lineDashed2: "┈",
|
|
2536
|
+
lineDashed3: "┉",
|
|
2537
|
+
lineDashed4: "╌",
|
|
2538
|
+
lineDashed5: "╍",
|
|
2539
|
+
lineDashed6: "╴",
|
|
2540
|
+
lineDashed7: "╶",
|
|
2541
|
+
lineDashed8: "╸",
|
|
2542
|
+
lineDashed9: "╺",
|
|
2543
|
+
lineDashed10: "╼",
|
|
2544
|
+
lineDashed11: "╾",
|
|
2545
|
+
lineDashed12: "−",
|
|
2546
|
+
lineDashed13: "–",
|
|
2547
|
+
lineDashed14: "‐",
|
|
2548
|
+
lineDashed15: "⁃",
|
|
2549
|
+
lineVertical: "│",
|
|
2550
|
+
lineVerticalBold: "┃",
|
|
2551
|
+
lineVerticalDouble: "║",
|
|
2552
|
+
lineVerticalDashed0: "┆",
|
|
2553
|
+
lineVerticalDashed1: "┇",
|
|
2554
|
+
lineVerticalDashed2: "┊",
|
|
2555
|
+
lineVerticalDashed3: "┋",
|
|
2556
|
+
lineVerticalDashed4: "╎",
|
|
2557
|
+
lineVerticalDashed5: "╏",
|
|
2558
|
+
lineVerticalDashed6: "╵",
|
|
2559
|
+
lineVerticalDashed7: "╷",
|
|
2560
|
+
lineVerticalDashed8: "╹",
|
|
2561
|
+
lineVerticalDashed9: "╻",
|
|
2562
|
+
lineVerticalDashed10: "╽",
|
|
2563
|
+
lineVerticalDashed11: "╿",
|
|
2564
|
+
lineDownLeft: "┐",
|
|
2565
|
+
lineDownLeftArc: "╮",
|
|
2566
|
+
lineDownBoldLeftBold: "┓",
|
|
2567
|
+
lineDownBoldLeft: "┒",
|
|
2568
|
+
lineDownLeftBold: "┑",
|
|
2569
|
+
lineDownDoubleLeftDouble: "╗",
|
|
2570
|
+
lineDownDoubleLeft: "╖",
|
|
2571
|
+
lineDownLeftDouble: "╕",
|
|
2572
|
+
lineDownRight: "┌",
|
|
2573
|
+
lineDownRightArc: "╭",
|
|
2574
|
+
lineDownBoldRightBold: "┏",
|
|
2575
|
+
lineDownBoldRight: "┎",
|
|
2576
|
+
lineDownRightBold: "┍",
|
|
2577
|
+
lineDownDoubleRightDouble: "╔",
|
|
2578
|
+
lineDownDoubleRight: "╓",
|
|
2579
|
+
lineDownRightDouble: "╒",
|
|
2580
|
+
lineUpLeft: "┘",
|
|
2581
|
+
lineUpLeftArc: "╯",
|
|
2582
|
+
lineUpBoldLeftBold: "┛",
|
|
2583
|
+
lineUpBoldLeft: "┚",
|
|
2584
|
+
lineUpLeftBold: "┙",
|
|
2585
|
+
lineUpDoubleLeftDouble: "╝",
|
|
2586
|
+
lineUpDoubleLeft: "╜",
|
|
2587
|
+
lineUpLeftDouble: "╛",
|
|
2588
|
+
lineUpRight: "└",
|
|
2589
|
+
lineUpRightArc: "╰",
|
|
2590
|
+
lineUpBoldRightBold: "┗",
|
|
2591
|
+
lineUpBoldRight: "┖",
|
|
2592
|
+
lineUpRightBold: "┕",
|
|
2593
|
+
lineUpDoubleRightDouble: "╚",
|
|
2594
|
+
lineUpDoubleRight: "╙",
|
|
2595
|
+
lineUpRightDouble: "╘",
|
|
2596
|
+
lineUpDownLeft: "┤",
|
|
2597
|
+
lineUpBoldDownBoldLeftBold: "┫",
|
|
2598
|
+
lineUpBoldDownBoldLeft: "┨",
|
|
2599
|
+
lineUpDownLeftBold: "┥",
|
|
2600
|
+
lineUpBoldDownLeftBold: "┩",
|
|
2601
|
+
lineUpDownBoldLeftBold: "┪",
|
|
2602
|
+
lineUpDownBoldLeft: "┧",
|
|
2603
|
+
lineUpBoldDownLeft: "┦",
|
|
2604
|
+
lineUpDoubleDownDoubleLeftDouble: "╣",
|
|
2605
|
+
lineUpDoubleDownDoubleLeft: "╢",
|
|
2606
|
+
lineUpDownLeftDouble: "╡",
|
|
2607
|
+
lineUpDownRight: "├",
|
|
2608
|
+
lineUpBoldDownBoldRightBold: "┣",
|
|
2609
|
+
lineUpBoldDownBoldRight: "┠",
|
|
2610
|
+
lineUpDownRightBold: "┝",
|
|
2611
|
+
lineUpBoldDownRightBold: "┡",
|
|
2612
|
+
lineUpDownBoldRightBold: "┢",
|
|
2613
|
+
lineUpDownBoldRight: "┟",
|
|
2614
|
+
lineUpBoldDownRight: "┞",
|
|
2615
|
+
lineUpDoubleDownDoubleRightDouble: "╠",
|
|
2616
|
+
lineUpDoubleDownDoubleRight: "╟",
|
|
2617
|
+
lineUpDownRightDouble: "╞",
|
|
2618
|
+
lineDownLeftRight: "┬",
|
|
2619
|
+
lineDownBoldLeftBoldRightBold: "┳",
|
|
2620
|
+
lineDownLeftBoldRightBold: "┯",
|
|
2621
|
+
lineDownBoldLeftRight: "┰",
|
|
2622
|
+
lineDownBoldLeftBoldRight: "┱",
|
|
2623
|
+
lineDownBoldLeftRightBold: "┲",
|
|
2624
|
+
lineDownLeftRightBold: "┮",
|
|
2625
|
+
lineDownLeftBoldRight: "┭",
|
|
2626
|
+
lineDownDoubleLeftDoubleRightDouble: "╦",
|
|
2627
|
+
lineDownDoubleLeftRight: "╥",
|
|
2628
|
+
lineDownLeftDoubleRightDouble: "╤",
|
|
2629
|
+
lineUpLeftRight: "┴",
|
|
2630
|
+
lineUpBoldLeftBoldRightBold: "┻",
|
|
2631
|
+
lineUpLeftBoldRightBold: "┷",
|
|
2632
|
+
lineUpBoldLeftRight: "┸",
|
|
2633
|
+
lineUpBoldLeftBoldRight: "┹",
|
|
2634
|
+
lineUpBoldLeftRightBold: "┺",
|
|
2635
|
+
lineUpLeftRightBold: "┶",
|
|
2636
|
+
lineUpLeftBoldRight: "┵",
|
|
2637
|
+
lineUpDoubleLeftDoubleRightDouble: "╩",
|
|
2638
|
+
lineUpDoubleLeftRight: "╨",
|
|
2639
|
+
lineUpLeftDoubleRightDouble: "╧",
|
|
2640
|
+
lineUpDownLeftRight: "┼",
|
|
2641
|
+
lineUpBoldDownBoldLeftBoldRightBold: "╋",
|
|
2642
|
+
lineUpDownBoldLeftBoldRightBold: "╈",
|
|
2643
|
+
lineUpBoldDownLeftBoldRightBold: "╇",
|
|
2644
|
+
lineUpBoldDownBoldLeftRightBold: "╊",
|
|
2645
|
+
lineUpBoldDownBoldLeftBoldRight: "╉",
|
|
2646
|
+
lineUpBoldDownLeftRight: "╀",
|
|
2647
|
+
lineUpDownBoldLeftRight: "╁",
|
|
2648
|
+
lineUpDownLeftBoldRight: "┽",
|
|
2649
|
+
lineUpDownLeftRightBold: "┾",
|
|
2650
|
+
lineUpBoldDownBoldLeftRight: "╂",
|
|
2651
|
+
lineUpDownLeftBoldRightBold: "┿",
|
|
2652
|
+
lineUpBoldDownLeftBoldRight: "╃",
|
|
2653
|
+
lineUpBoldDownLeftRightBold: "╄",
|
|
2654
|
+
lineUpDownBoldLeftBoldRight: "╅",
|
|
2655
|
+
lineUpDownBoldLeftRightBold: "╆",
|
|
2656
|
+
lineUpDoubleDownDoubleLeftDoubleRightDouble: "╬",
|
|
2657
|
+
lineUpDoubleDownDoubleLeftRight: "╫",
|
|
2658
|
+
lineUpDownLeftDoubleRightDouble: "╪",
|
|
2659
|
+
lineCross: "╳",
|
|
2660
|
+
lineBackslash: "╲",
|
|
2661
|
+
lineSlash: "╱"
|
|
2237
2662
|
};
|
|
2238
|
-
const
|
|
2239
|
-
|
|
2240
|
-
|
|
2663
|
+
const specialMainSymbols = {
|
|
2664
|
+
tick: "✔",
|
|
2665
|
+
info: "ℹ",
|
|
2666
|
+
warning: "⚠",
|
|
2667
|
+
cross: "✘",
|
|
2668
|
+
squareSmall: "◻",
|
|
2669
|
+
squareSmallFilled: "◼",
|
|
2670
|
+
circle: "◯",
|
|
2671
|
+
circleFilled: "◉",
|
|
2672
|
+
circleDotted: "◌",
|
|
2673
|
+
circleDouble: "◎",
|
|
2674
|
+
circleCircle: "ⓞ",
|
|
2675
|
+
circleCross: "ⓧ",
|
|
2676
|
+
circlePipe: "Ⓘ",
|
|
2677
|
+
radioOn: "◉",
|
|
2678
|
+
radioOff: "◯",
|
|
2679
|
+
checkboxOn: "☒",
|
|
2680
|
+
checkboxOff: "☐",
|
|
2681
|
+
checkboxCircleOn: "ⓧ",
|
|
2682
|
+
checkboxCircleOff: "Ⓘ",
|
|
2683
|
+
pointer: "❯",
|
|
2684
|
+
triangleUpOutline: "△",
|
|
2685
|
+
triangleLeft: "◀",
|
|
2686
|
+
triangleRight: "▶",
|
|
2687
|
+
lozenge: "◆",
|
|
2688
|
+
lozengeOutline: "◇",
|
|
2689
|
+
hamburger: "☰",
|
|
2690
|
+
smiley: "㋡",
|
|
2691
|
+
mustache: "෴",
|
|
2692
|
+
star: "★",
|
|
2693
|
+
play: "▶",
|
|
2694
|
+
nodejs: "⬢",
|
|
2695
|
+
oneSeventh: "⅐",
|
|
2696
|
+
oneNinth: "⅑",
|
|
2697
|
+
oneTenth: "⅒"
|
|
2241
2698
|
};
|
|
2242
|
-
const
|
|
2243
|
-
|
|
2244
|
-
|
|
2699
|
+
const specialFallbackSymbols = {
|
|
2700
|
+
tick: "√",
|
|
2701
|
+
info: "i",
|
|
2702
|
+
warning: "‼",
|
|
2703
|
+
cross: "×",
|
|
2704
|
+
squareSmall: "□",
|
|
2705
|
+
squareSmallFilled: "■",
|
|
2706
|
+
circle: "( )",
|
|
2707
|
+
circleFilled: "(*)",
|
|
2708
|
+
circleDotted: "( )",
|
|
2709
|
+
circleDouble: "( )",
|
|
2710
|
+
circleCircle: "(○)",
|
|
2711
|
+
circleCross: "(×)",
|
|
2712
|
+
circlePipe: "(│)",
|
|
2713
|
+
radioOn: "(*)",
|
|
2714
|
+
radioOff: "( )",
|
|
2715
|
+
checkboxOn: "[×]",
|
|
2716
|
+
checkboxOff: "[ ]",
|
|
2717
|
+
checkboxCircleOn: "(×)",
|
|
2718
|
+
checkboxCircleOff: "( )",
|
|
2719
|
+
pointer: ">",
|
|
2720
|
+
triangleUpOutline: "∆",
|
|
2721
|
+
triangleLeft: "◄",
|
|
2722
|
+
triangleRight: "►",
|
|
2723
|
+
lozenge: "♦",
|
|
2724
|
+
lozengeOutline: "◊",
|
|
2725
|
+
hamburger: "≡",
|
|
2726
|
+
smiley: "☺",
|
|
2727
|
+
mustache: "┌─┐",
|
|
2728
|
+
star: "✶",
|
|
2729
|
+
play: "►",
|
|
2730
|
+
nodejs: "♦",
|
|
2731
|
+
oneSeventh: "1/7",
|
|
2732
|
+
oneNinth: "1/9",
|
|
2733
|
+
oneTenth: "1/10"
|
|
2245
2734
|
};
|
|
2246
|
-
const
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2735
|
+
const mainSymbols = {
|
|
2736
|
+
...common,
|
|
2737
|
+
...specialMainSymbols
|
|
2738
|
+
};
|
|
2739
|
+
const fallbackSymbols = {
|
|
2740
|
+
...common,
|
|
2741
|
+
...specialFallbackSymbols
|
|
2742
|
+
};
|
|
2743
|
+
const shouldUseMain = isUnicodeSupported();
|
|
2744
|
+
const figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
2745
|
+
const defaultTheme = {
|
|
2746
|
+
prefix: {
|
|
2747
|
+
idle: styleText("blue", "?"),
|
|
2748
|
+
done: styleText("green", figures.tick)
|
|
2749
|
+
},
|
|
2750
|
+
spinner: {
|
|
2751
|
+
interval: 80,
|
|
2752
|
+
frames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"].map((frame) => styleText("yellow", frame))
|
|
2753
|
+
},
|
|
2754
|
+
style: {
|
|
2755
|
+
answer: (text) => styleText("cyan", text),
|
|
2756
|
+
message: (text) => styleText("bold", text),
|
|
2757
|
+
error: (text) => styleText("red", `> ${text}`),
|
|
2758
|
+
defaultAnswer: (text) => styleText("dim", `(${text})`),
|
|
2759
|
+
help: (text) => styleText("dim", text),
|
|
2760
|
+
highlight: (text) => styleText("cyan", text),
|
|
2761
|
+
key: (text) => styleText("cyan", styleText("bold", `<${text}>`))
|
|
2762
|
+
}
|
|
2763
|
+
};
|
|
2764
|
+
function isPlainObject(value) {
|
|
2765
|
+
if (typeof value !== "object" || value === null)
|
|
2766
|
+
return false;
|
|
2767
|
+
let proto = value;
|
|
2768
|
+
while (Object.getPrototypeOf(proto) !== null) {
|
|
2769
|
+
proto = Object.getPrototypeOf(proto);
|
|
2770
|
+
}
|
|
2771
|
+
return Object.getPrototypeOf(value) === proto;
|
|
2772
|
+
}
|
|
2773
|
+
function deepMerge(...objects) {
|
|
2774
|
+
const output = {};
|
|
2775
|
+
for (const obj of objects) {
|
|
2776
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
2777
|
+
const prevValue = output[key];
|
|
2778
|
+
output[key] = isPlainObject(prevValue) && isPlainObject(value) ? deepMerge(prevValue, value) : value;
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
return output;
|
|
2782
|
+
}
|
|
2783
|
+
function makeTheme(...themes) {
|
|
2784
|
+
const themesToMerge = [
|
|
2785
|
+
defaultTheme,
|
|
2786
|
+
...themes.filter((theme) => theme != null)
|
|
2787
|
+
];
|
|
2788
|
+
return deepMerge(...themesToMerge);
|
|
2789
|
+
}
|
|
2790
|
+
function usePrefix({ status = "idle", theme }) {
|
|
2791
|
+
const [showLoader, setShowLoader] = useState(false);
|
|
2792
|
+
const [tick, setTick] = useState(0);
|
|
2793
|
+
const { prefix, spinner } = makeTheme(theme);
|
|
2794
|
+
useEffect(() => {
|
|
2795
|
+
if (status === "loading") {
|
|
2796
|
+
let tickInterval;
|
|
2797
|
+
let inc = -1;
|
|
2798
|
+
const delayTimeout = setTimeout(() => {
|
|
2799
|
+
setShowLoader(true);
|
|
2800
|
+
tickInterval = setInterval(() => {
|
|
2801
|
+
inc = inc + 1;
|
|
2802
|
+
setTick(inc % spinner.frames.length);
|
|
2803
|
+
}, spinner.interval);
|
|
2804
|
+
}, 300);
|
|
2805
|
+
return () => {
|
|
2806
|
+
clearTimeout(delayTimeout);
|
|
2807
|
+
clearInterval(tickInterval);
|
|
2808
|
+
};
|
|
2809
|
+
} else {
|
|
2810
|
+
setShowLoader(false);
|
|
2811
|
+
}
|
|
2812
|
+
}, [status]);
|
|
2813
|
+
if (showLoader) {
|
|
2814
|
+
return spinner.frames[tick];
|
|
2815
|
+
}
|
|
2816
|
+
const iconName = status === "loading" ? "idle" : status;
|
|
2817
|
+
return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
|
|
2818
|
+
}
|
|
2819
|
+
function useMemo(fn, dependencies) {
|
|
2820
|
+
return withPointer((pointer) => {
|
|
2821
|
+
const prev = pointer.get();
|
|
2822
|
+
if (!prev || prev.dependencies.length !== dependencies.length || prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
|
|
2823
|
+
const value = fn();
|
|
2824
|
+
pointer.set({ value, dependencies });
|
|
2825
|
+
return value;
|
|
2826
|
+
}
|
|
2827
|
+
return prev.value;
|
|
2828
|
+
});
|
|
2829
|
+
}
|
|
2830
|
+
function useRef(val) {
|
|
2831
|
+
return useState({ current: val })[0];
|
|
2832
|
+
}
|
|
2833
|
+
function useKeypress(userHandler) {
|
|
2834
|
+
const signal = useRef(userHandler);
|
|
2835
|
+
signal.current = userHandler;
|
|
2836
|
+
useEffect((rl) => {
|
|
2837
|
+
let ignore = false;
|
|
2838
|
+
const handler = withUpdates((_input, event) => {
|
|
2839
|
+
if (ignore)
|
|
2840
|
+
return;
|
|
2841
|
+
void signal.current(event, rl);
|
|
2842
|
+
});
|
|
2843
|
+
rl.input.on("keypress", handler);
|
|
2844
|
+
return () => {
|
|
2845
|
+
ignore = true;
|
|
2846
|
+
rl.input.removeListener("keypress", handler);
|
|
2847
|
+
};
|
|
2848
|
+
}, []);
|
|
2849
|
+
}
|
|
2850
|
+
function getDefaultExportFromCjs(x) {
|
|
2851
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
2852
|
+
}
|
|
2853
|
+
var cliWidth_1;
|
|
2854
|
+
var hasRequiredCliWidth;
|
|
2855
|
+
function requireCliWidth() {
|
|
2856
|
+
if (hasRequiredCliWidth) return cliWidth_1;
|
|
2857
|
+
hasRequiredCliWidth = 1;
|
|
2858
|
+
cliWidth_1 = cliWidth2;
|
|
2859
|
+
function normalizeOpts(options) {
|
|
2860
|
+
const defaultOpts = {
|
|
2861
|
+
defaultWidth: 0,
|
|
2862
|
+
output: process.stdout,
|
|
2863
|
+
tty: require$$0
|
|
2864
|
+
};
|
|
2865
|
+
if (!options) {
|
|
2866
|
+
return defaultOpts;
|
|
2867
|
+
}
|
|
2868
|
+
Object.keys(defaultOpts).forEach(function(key) {
|
|
2869
|
+
if (!options[key]) {
|
|
2870
|
+
options[key] = defaultOpts[key];
|
|
2871
|
+
}
|
|
2872
|
+
});
|
|
2873
|
+
return options;
|
|
2874
|
+
}
|
|
2875
|
+
function cliWidth2(options) {
|
|
2876
|
+
const opts = normalizeOpts(options);
|
|
2877
|
+
if (opts.output.getWindowSize) {
|
|
2878
|
+
return opts.output.getWindowSize()[0] || opts.defaultWidth;
|
|
2879
|
+
}
|
|
2880
|
+
if (opts.tty.getWindowSize) {
|
|
2881
|
+
return opts.tty.getWindowSize()[1] || opts.defaultWidth;
|
|
2882
|
+
}
|
|
2883
|
+
if (opts.output.columns) {
|
|
2884
|
+
return opts.output.columns;
|
|
2885
|
+
}
|
|
2886
|
+
if (process.env.CLI_WIDTH) {
|
|
2887
|
+
const width = parseInt(process.env.CLI_WIDTH, 10);
|
|
2888
|
+
if (!isNaN(width) && width !== 0) {
|
|
2889
|
+
return width;
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
return opts.defaultWidth;
|
|
2893
|
+
}
|
|
2894
|
+
return cliWidth_1;
|
|
2895
|
+
}
|
|
2896
|
+
var cliWidthExports = requireCliWidth();
|
|
2897
|
+
const cliWidth = /* @__PURE__ */ getDefaultExportFromCjs(cliWidthExports);
|
|
2898
|
+
const getCodePointsLength = /* @__PURE__ */ (() => {
|
|
2899
|
+
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
2900
|
+
return (input2) => {
|
|
2901
|
+
let surrogatePairsNr = 0;
|
|
2902
|
+
SURROGATE_PAIR_RE.lastIndex = 0;
|
|
2903
|
+
while (SURROGATE_PAIR_RE.test(input2)) {
|
|
2904
|
+
surrogatePairsNr += 1;
|
|
2905
|
+
}
|
|
2906
|
+
return input2.length - surrogatePairsNr;
|
|
2907
|
+
};
|
|
2908
|
+
})();
|
|
2909
|
+
const isFullWidth = (x) => {
|
|
2910
|
+
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
|
|
2911
|
+
};
|
|
2912
|
+
const isWideNotCJKTNotEmoji = (x) => {
|
|
2913
|
+
return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
2914
|
+
};
|
|
2915
|
+
const ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
2916
|
+
const CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
2917
|
+
const CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
|
|
2918
|
+
const TAB_RE = /\t{1,1000}/y;
|
|
2919
|
+
const EMOJI_RE = new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*", "yu");
|
|
2920
|
+
const LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
2921
|
+
const MODIFIER_RE = new RegExp("\\p{M}+", "gu");
|
|
2922
|
+
const NO_TRUNCATION$1 = { limit: Infinity, ellipsis: "" };
|
|
2923
|
+
const getStringTruncatedWidth = (input2, truncationOptions = {}, widthOptions = {}) => {
|
|
2924
|
+
const LIMIT = truncationOptions.limit ?? Infinity;
|
|
2925
|
+
const ELLIPSIS = truncationOptions.ellipsis ?? "";
|
|
2926
|
+
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION$1, widthOptions).width : 0);
|
|
2927
|
+
const ANSI_WIDTH = 0;
|
|
2928
|
+
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
|
|
2929
|
+
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
|
|
2930
|
+
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
|
|
2931
|
+
const FULL_WIDTH_WIDTH = 2;
|
|
2932
|
+
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
|
|
2933
|
+
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
|
|
2934
|
+
const PARSE_BLOCKS = [
|
|
2935
|
+
[LATIN_RE, REGULAR_WIDTH],
|
|
2936
|
+
[ANSI_RE, ANSI_WIDTH],
|
|
2937
|
+
[CONTROL_RE, CONTROL_WIDTH],
|
|
2938
|
+
[TAB_RE, TAB_WIDTH],
|
|
2939
|
+
[EMOJI_RE, EMOJI_WIDTH],
|
|
2940
|
+
[CJKT_WIDE_RE, WIDE_WIDTH]
|
|
2941
|
+
];
|
|
2942
|
+
let indexPrev = 0;
|
|
2943
|
+
let index = 0;
|
|
2944
|
+
let length = input2.length;
|
|
2945
|
+
let lengthExtra = 0;
|
|
2946
|
+
let truncationEnabled = false;
|
|
2947
|
+
let truncationIndex = length;
|
|
2948
|
+
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
|
|
2949
|
+
let unmatchedStart = 0;
|
|
2950
|
+
let unmatchedEnd = 0;
|
|
2951
|
+
let width = 0;
|
|
2952
|
+
let widthExtra = 0;
|
|
2953
|
+
outer: while (true) {
|
|
2954
|
+
if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
|
|
2955
|
+
const unmatched = input2.slice(unmatchedStart, unmatchedEnd) || input2.slice(indexPrev, index);
|
|
2956
|
+
lengthExtra = 0;
|
|
2957
|
+
for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
|
|
2958
|
+
const codePoint = char.codePointAt(0) || 0;
|
|
2959
|
+
if (isFullWidth(codePoint)) {
|
|
2960
|
+
widthExtra = FULL_WIDTH_WIDTH;
|
|
2961
|
+
} else if (isWideNotCJKTNotEmoji(codePoint)) {
|
|
2962
|
+
widthExtra = WIDE_WIDTH;
|
|
2963
|
+
} else {
|
|
2964
|
+
widthExtra = REGULAR_WIDTH;
|
|
2965
|
+
}
|
|
2966
|
+
if (width + widthExtra > truncationLimit) {
|
|
2967
|
+
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
2968
|
+
}
|
|
2969
|
+
if (width + widthExtra > LIMIT) {
|
|
2970
|
+
truncationEnabled = true;
|
|
2971
|
+
break outer;
|
|
2972
|
+
}
|
|
2973
|
+
lengthExtra += char.length;
|
|
2974
|
+
width += widthExtra;
|
|
2975
|
+
}
|
|
2976
|
+
unmatchedStart = unmatchedEnd = 0;
|
|
2977
|
+
}
|
|
2978
|
+
if (index >= length) {
|
|
2979
|
+
break outer;
|
|
2980
|
+
}
|
|
2981
|
+
for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {
|
|
2982
|
+
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
|
|
2983
|
+
BLOCK_RE.lastIndex = index;
|
|
2984
|
+
if (BLOCK_RE.test(input2)) {
|
|
2985
|
+
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input2.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
|
|
2986
|
+
widthExtra = lengthExtra * BLOCK_WIDTH;
|
|
2987
|
+
if (width + widthExtra > truncationLimit) {
|
|
2988
|
+
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
2989
|
+
}
|
|
2990
|
+
if (width + widthExtra > LIMIT) {
|
|
2991
|
+
truncationEnabled = true;
|
|
2992
|
+
break outer;
|
|
2993
|
+
}
|
|
2994
|
+
width += widthExtra;
|
|
2995
|
+
unmatchedStart = indexPrev;
|
|
2996
|
+
unmatchedEnd = index;
|
|
2997
|
+
index = indexPrev = BLOCK_RE.lastIndex;
|
|
2998
|
+
continue outer;
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
index += 1;
|
|
3002
|
+
}
|
|
3003
|
+
return {
|
|
3004
|
+
width: truncationEnabled ? truncationLimit : width,
|
|
3005
|
+
index: truncationEnabled ? truncationIndex : length,
|
|
3006
|
+
truncated: truncationEnabled,
|
|
3007
|
+
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
3008
|
+
};
|
|
3009
|
+
};
|
|
3010
|
+
const NO_TRUNCATION = {
|
|
3011
|
+
limit: Infinity,
|
|
3012
|
+
ellipsis: "",
|
|
3013
|
+
ellipsisWidth: 0
|
|
3014
|
+
};
|
|
3015
|
+
const fastStringWidth = (input2, options = {}) => {
|
|
3016
|
+
return getStringTruncatedWidth(input2, NO_TRUNCATION, options).width;
|
|
3017
|
+
};
|
|
3018
|
+
const ESC$1 = "\x1B";
|
|
3019
|
+
const CSI = "";
|
|
3020
|
+
const END_CODE = 39;
|
|
3021
|
+
const ANSI_ESCAPE_BELL = "\x07";
|
|
3022
|
+
const ANSI_CSI = "[";
|
|
3023
|
+
const ANSI_OSC = "]";
|
|
3024
|
+
const ANSI_SGR_TERMINATOR = "m";
|
|
3025
|
+
const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
3026
|
+
const GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
|
|
3027
|
+
const getClosingCode = (openingCode) => {
|
|
3028
|
+
if (openingCode >= 30 && openingCode <= 37)
|
|
3029
|
+
return 39;
|
|
3030
|
+
if (openingCode >= 90 && openingCode <= 97)
|
|
3031
|
+
return 39;
|
|
3032
|
+
if (openingCode >= 40 && openingCode <= 47)
|
|
3033
|
+
return 49;
|
|
3034
|
+
if (openingCode >= 100 && openingCode <= 107)
|
|
3035
|
+
return 49;
|
|
3036
|
+
if (openingCode === 1 || openingCode === 2)
|
|
3037
|
+
return 22;
|
|
3038
|
+
if (openingCode === 3)
|
|
3039
|
+
return 23;
|
|
3040
|
+
if (openingCode === 4)
|
|
3041
|
+
return 24;
|
|
3042
|
+
if (openingCode === 7)
|
|
3043
|
+
return 27;
|
|
3044
|
+
if (openingCode === 8)
|
|
3045
|
+
return 28;
|
|
3046
|
+
if (openingCode === 9)
|
|
3047
|
+
return 29;
|
|
3048
|
+
if (openingCode === 0)
|
|
3049
|
+
return 0;
|
|
3050
|
+
return void 0;
|
|
3051
|
+
};
|
|
3052
|
+
const wrapAnsiCode = (code) => `${ESC$1}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
3053
|
+
const wrapAnsiHyperlink = (url) => `${ESC$1}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
3054
|
+
const wrapWord = (rows, word, columns) => {
|
|
3055
|
+
const characters = word[Symbol.iterator]();
|
|
3056
|
+
let isInsideEscape = false;
|
|
3057
|
+
let isInsideLinkEscape = false;
|
|
3058
|
+
let lastRow = rows.at(-1);
|
|
3059
|
+
let visible = lastRow === void 0 ? 0 : fastStringWidth(lastRow);
|
|
3060
|
+
let currentCharacter = characters.next();
|
|
3061
|
+
let nextCharacter = characters.next();
|
|
3062
|
+
let rawCharacterIndex = 0;
|
|
3063
|
+
while (!currentCharacter.done) {
|
|
3064
|
+
const character = currentCharacter.value;
|
|
3065
|
+
const characterLength = fastStringWidth(character);
|
|
3066
|
+
if (visible + characterLength <= columns) {
|
|
3067
|
+
rows[rows.length - 1] += character;
|
|
3068
|
+
} else {
|
|
3069
|
+
rows.push(character);
|
|
3070
|
+
visible = 0;
|
|
3071
|
+
}
|
|
3072
|
+
if (character === ESC$1 || character === CSI) {
|
|
3073
|
+
isInsideEscape = true;
|
|
3074
|
+
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
3075
|
+
}
|
|
3076
|
+
if (isInsideEscape) {
|
|
3077
|
+
if (isInsideLinkEscape) {
|
|
3078
|
+
if (character === ANSI_ESCAPE_BELL) {
|
|
3079
|
+
isInsideEscape = false;
|
|
3080
|
+
isInsideLinkEscape = false;
|
|
3081
|
+
}
|
|
3082
|
+
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
3083
|
+
isInsideEscape = false;
|
|
3084
|
+
}
|
|
3085
|
+
} else {
|
|
3086
|
+
visible += characterLength;
|
|
3087
|
+
if (visible === columns && !nextCharacter.done) {
|
|
3088
|
+
rows.push("");
|
|
3089
|
+
visible = 0;
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
currentCharacter = nextCharacter;
|
|
3093
|
+
nextCharacter = characters.next();
|
|
3094
|
+
rawCharacterIndex += character.length;
|
|
3095
|
+
}
|
|
3096
|
+
lastRow = rows.at(-1);
|
|
3097
|
+
if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
|
|
3098
|
+
rows[rows.length - 2] += rows.pop();
|
|
3099
|
+
}
|
|
3100
|
+
};
|
|
3101
|
+
const stringVisibleTrimSpacesRight = (string) => {
|
|
3102
|
+
const words = string.split(" ");
|
|
3103
|
+
let last = words.length;
|
|
3104
|
+
while (last) {
|
|
3105
|
+
if (fastStringWidth(words[last - 1])) {
|
|
3106
|
+
break;
|
|
3107
|
+
}
|
|
3108
|
+
last--;
|
|
3109
|
+
}
|
|
3110
|
+
if (last === words.length) {
|
|
3111
|
+
return string;
|
|
3112
|
+
}
|
|
3113
|
+
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
3114
|
+
};
|
|
3115
|
+
const exec = (string, columns, options = {}) => {
|
|
3116
|
+
if (options.trim !== false && string.trim() === "") {
|
|
3117
|
+
return "";
|
|
3118
|
+
}
|
|
3119
|
+
let returnValue = "";
|
|
3120
|
+
let escapeCode;
|
|
3121
|
+
let escapeUrl;
|
|
3122
|
+
const words = string.split(" ");
|
|
3123
|
+
let rows = [""];
|
|
3124
|
+
let rowLength = 0;
|
|
3125
|
+
for (let index = 0; index < words.length; index++) {
|
|
3126
|
+
const word = words[index];
|
|
3127
|
+
if (options.trim !== false) {
|
|
3128
|
+
const row = rows.at(-1) ?? "";
|
|
3129
|
+
const trimmed = row.trimStart();
|
|
3130
|
+
if (row.length !== trimmed.length) {
|
|
3131
|
+
rows[rows.length - 1] = trimmed;
|
|
3132
|
+
rowLength = fastStringWidth(trimmed);
|
|
3133
|
+
}
|
|
3134
|
+
}
|
|
3135
|
+
if (index !== 0) {
|
|
3136
|
+
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
3137
|
+
rows.push("");
|
|
3138
|
+
rowLength = 0;
|
|
3139
|
+
}
|
|
3140
|
+
if (rowLength || options.trim === false) {
|
|
3141
|
+
rows[rows.length - 1] += " ";
|
|
3142
|
+
rowLength++;
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
const wordLength = fastStringWidth(word);
|
|
3146
|
+
if (options.hard && wordLength > columns) {
|
|
3147
|
+
const remainingColumns = columns - rowLength;
|
|
3148
|
+
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
|
|
3149
|
+
const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
|
|
3150
|
+
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
3151
|
+
rows.push("");
|
|
3152
|
+
}
|
|
3153
|
+
wrapWord(rows, word, columns);
|
|
3154
|
+
rowLength = fastStringWidth(rows.at(-1) ?? "");
|
|
3155
|
+
continue;
|
|
3156
|
+
}
|
|
3157
|
+
if (rowLength + wordLength > columns && rowLength && wordLength) {
|
|
3158
|
+
if (options.wordWrap === false && rowLength < columns) {
|
|
3159
|
+
wrapWord(rows, word, columns);
|
|
3160
|
+
rowLength = fastStringWidth(rows.at(-1) ?? "");
|
|
3161
|
+
continue;
|
|
3162
|
+
}
|
|
3163
|
+
rows.push("");
|
|
3164
|
+
rowLength = 0;
|
|
3165
|
+
}
|
|
3166
|
+
if (rowLength + wordLength > columns && options.wordWrap === false) {
|
|
3167
|
+
wrapWord(rows, word, columns);
|
|
3168
|
+
rowLength = fastStringWidth(rows.at(-1) ?? "");
|
|
3169
|
+
continue;
|
|
3170
|
+
}
|
|
3171
|
+
rows[rows.length - 1] += word;
|
|
3172
|
+
rowLength += wordLength;
|
|
3173
|
+
}
|
|
3174
|
+
if (options.trim !== false) {
|
|
3175
|
+
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
3176
|
+
}
|
|
3177
|
+
const preString = rows.join("\n");
|
|
3178
|
+
let inSurrogate = false;
|
|
3179
|
+
for (let i = 0; i < preString.length; i++) {
|
|
3180
|
+
const character = preString[i];
|
|
3181
|
+
returnValue += character;
|
|
3182
|
+
if (!inSurrogate) {
|
|
3183
|
+
inSurrogate = character >= "\uD800" && character <= "\uDBFF";
|
|
3184
|
+
if (inSurrogate) {
|
|
3185
|
+
continue;
|
|
3186
|
+
}
|
|
3187
|
+
} else {
|
|
3188
|
+
inSurrogate = false;
|
|
3189
|
+
}
|
|
3190
|
+
if (character === ESC$1 || character === CSI) {
|
|
3191
|
+
GROUP_REGEX.lastIndex = i + 1;
|
|
3192
|
+
const groupsResult = GROUP_REGEX.exec(preString);
|
|
3193
|
+
const groups = groupsResult?.groups;
|
|
3194
|
+
if (groups?.code !== void 0) {
|
|
3195
|
+
const code = Number.parseFloat(groups.code);
|
|
3196
|
+
escapeCode = code === END_CODE ? void 0 : code;
|
|
3197
|
+
} else if (groups?.uri !== void 0) {
|
|
3198
|
+
escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
if (preString[i + 1] === "\n") {
|
|
3202
|
+
if (escapeUrl) {
|
|
3203
|
+
returnValue += wrapAnsiHyperlink("");
|
|
3204
|
+
}
|
|
3205
|
+
const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
|
|
3206
|
+
if (escapeCode && closingCode) {
|
|
3207
|
+
returnValue += wrapAnsiCode(closingCode);
|
|
3208
|
+
}
|
|
3209
|
+
} else if (character === "\n") {
|
|
3210
|
+
if (escapeCode && getClosingCode(escapeCode)) {
|
|
3211
|
+
returnValue += wrapAnsiCode(escapeCode);
|
|
3212
|
+
}
|
|
3213
|
+
if (escapeUrl) {
|
|
3214
|
+
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
return returnValue;
|
|
3219
|
+
};
|
|
3220
|
+
const CRLF_OR_LF = /\r?\n/;
|
|
3221
|
+
function wrapAnsi(string, columns, options) {
|
|
3222
|
+
return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
|
|
3223
|
+
}
|
|
3224
|
+
function breakLines(content, width) {
|
|
3225
|
+
return content.split("\n").flatMap((line) => wrapAnsi(line, width, { trim: false, hard: true }).split("\n").map((str) => str.trimEnd())).join("\n");
|
|
3226
|
+
}
|
|
3227
|
+
function readlineWidth() {
|
|
3228
|
+
return cliWidth({ defaultWidth: 80, output: readline().output });
|
|
3229
|
+
}
|
|
3230
|
+
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
3231
|
+
const state = useRef({
|
|
3232
|
+
lastPointer: active,
|
|
3233
|
+
lastActive: void 0
|
|
3234
|
+
});
|
|
3235
|
+
const { lastPointer, lastActive } = state.current;
|
|
3236
|
+
const middle = Math.floor(pageSize / 2);
|
|
3237
|
+
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
3238
|
+
const defaultPointerPosition = renderedItems.slice(0, active).reduce((acc, item) => acc + item.length, 0);
|
|
3239
|
+
let pointer = defaultPointerPosition;
|
|
3240
|
+
if (renderedLength > pageSize) {
|
|
3241
|
+
if (loop) {
|
|
3242
|
+
pointer = lastPointer;
|
|
3243
|
+
if (
|
|
3244
|
+
// First render, skip this logic.
|
|
3245
|
+
lastActive != null && // Only move the pointer down when the user moves down.
|
|
3246
|
+
lastActive < active && // Check user didn't move up across page boundary.
|
|
3247
|
+
active - lastActive < pageSize
|
|
3248
|
+
) {
|
|
3249
|
+
pointer = Math.min(
|
|
3250
|
+
// Furthest allowed position for the pointer is the middle of the list
|
|
3251
|
+
middle,
|
|
3252
|
+
Math.abs(active - lastActive) === 1 ? Math.min(
|
|
3253
|
+
// Move the pointer at most the height of the last active item.
|
|
3254
|
+
lastPointer + (renderedItems[lastActive]?.length ?? 0),
|
|
3255
|
+
// If the user moved by one item, move the pointer to the natural position of the active item as
|
|
3256
|
+
// long as it doesn't move the cursor up.
|
|
3257
|
+
Math.max(defaultPointerPosition, lastPointer)
|
|
3258
|
+
) : (
|
|
3259
|
+
// Otherwise, move the pointer down by the difference between the active and last active item.
|
|
3260
|
+
lastPointer + active - lastActive
|
|
3261
|
+
)
|
|
3262
|
+
);
|
|
3263
|
+
}
|
|
3264
|
+
} else {
|
|
3265
|
+
const spaceUnderActive = renderedItems.slice(active).reduce((acc, item) => acc + item.length, 0);
|
|
3266
|
+
pointer = spaceUnderActive < pageSize - middle ? (
|
|
3267
|
+
// If the active item is near the end of the list, progressively move the cursor towards the end.
|
|
3268
|
+
pageSize - spaceUnderActive
|
|
3269
|
+
) : (
|
|
3270
|
+
// Otherwise, progressively move the pointer to the middle of the list.
|
|
3271
|
+
Math.min(defaultPointerPosition, middle)
|
|
3272
|
+
);
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
state.current.lastPointer = pointer;
|
|
3276
|
+
state.current.lastActive = active;
|
|
3277
|
+
return pointer;
|
|
3278
|
+
}
|
|
3279
|
+
function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
3280
|
+
const width = readlineWidth();
|
|
3281
|
+
const bound = (num) => (num % items.length + items.length) % items.length;
|
|
3282
|
+
const renderedItems = items.map((item, index) => {
|
|
3283
|
+
if (item == null)
|
|
3284
|
+
return [];
|
|
3285
|
+
return breakLines(renderItem({ item, index, isActive: index === active }), width).split("\n");
|
|
3286
|
+
});
|
|
3287
|
+
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
3288
|
+
const renderItemAtIndex = (index) => renderedItems[index] ?? [];
|
|
3289
|
+
const pointer = usePointerPosition({ active, renderedItems, pageSize, loop });
|
|
3290
|
+
const activeItem = renderItemAtIndex(active).slice(0, pageSize);
|
|
3291
|
+
const activeItemPosition = pointer + activeItem.length <= pageSize ? pointer : pageSize - activeItem.length;
|
|
3292
|
+
const pageBuffer = Array.from({ length: pageSize });
|
|
3293
|
+
pageBuffer.splice(activeItemPosition, activeItem.length, ...activeItem);
|
|
3294
|
+
const itemVisited = /* @__PURE__ */ new Set([active]);
|
|
3295
|
+
let bufferPointer = activeItemPosition + activeItem.length;
|
|
3296
|
+
let itemPointer = bound(active + 1);
|
|
3297
|
+
while (bufferPointer < pageSize && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer > active)) {
|
|
3298
|
+
const lines = renderItemAtIndex(itemPointer);
|
|
3299
|
+
const linesToAdd = lines.slice(0, pageSize - bufferPointer);
|
|
3300
|
+
pageBuffer.splice(bufferPointer, linesToAdd.length, ...linesToAdd);
|
|
3301
|
+
itemVisited.add(itemPointer);
|
|
3302
|
+
bufferPointer += linesToAdd.length;
|
|
3303
|
+
itemPointer = bound(itemPointer + 1);
|
|
3304
|
+
}
|
|
3305
|
+
bufferPointer = activeItemPosition - 1;
|
|
3306
|
+
itemPointer = bound(active - 1);
|
|
3307
|
+
while (bufferPointer >= 0 && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer < active)) {
|
|
3308
|
+
const lines = renderItemAtIndex(itemPointer);
|
|
3309
|
+
const linesToAdd = lines.slice(Math.max(0, lines.length - bufferPointer - 1));
|
|
3310
|
+
pageBuffer.splice(bufferPointer - linesToAdd.length + 1, linesToAdd.length, ...linesToAdd);
|
|
3311
|
+
itemVisited.add(itemPointer);
|
|
3312
|
+
bufferPointer -= linesToAdd.length;
|
|
3313
|
+
itemPointer = bound(itemPointer - 1);
|
|
3314
|
+
}
|
|
3315
|
+
return pageBuffer.filter((line) => typeof line === "string").join("\n");
|
|
3316
|
+
}
|
|
3317
|
+
var lib;
|
|
3318
|
+
var hasRequiredLib;
|
|
3319
|
+
function requireLib() {
|
|
3320
|
+
if (hasRequiredLib) return lib;
|
|
3321
|
+
hasRequiredLib = 1;
|
|
3322
|
+
const Stream = require$$0$1;
|
|
3323
|
+
class MuteStream2 extends Stream {
|
|
3324
|
+
#isTTY = null;
|
|
3325
|
+
constructor(opts = {}) {
|
|
3326
|
+
super(opts);
|
|
3327
|
+
this.writable = this.readable = true;
|
|
3328
|
+
this.muted = false;
|
|
3329
|
+
this.on("pipe", this._onpipe);
|
|
3330
|
+
this.replace = opts.replace;
|
|
3331
|
+
this._prompt = opts.prompt || null;
|
|
3332
|
+
this._hadControl = false;
|
|
3333
|
+
}
|
|
3334
|
+
#destSrc(key, def) {
|
|
3335
|
+
if (this._dest) {
|
|
3336
|
+
return this._dest[key];
|
|
3337
|
+
}
|
|
3338
|
+
if (this._src) {
|
|
3339
|
+
return this._src[key];
|
|
3340
|
+
}
|
|
3341
|
+
return def;
|
|
3342
|
+
}
|
|
3343
|
+
#proxy(method, ...args) {
|
|
3344
|
+
if (typeof this._dest?.[method] === "function") {
|
|
3345
|
+
this._dest[method](...args);
|
|
3346
|
+
}
|
|
3347
|
+
if (typeof this._src?.[method] === "function") {
|
|
3348
|
+
this._src[method](...args);
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
get isTTY() {
|
|
3352
|
+
if (this.#isTTY !== null) {
|
|
3353
|
+
return this.#isTTY;
|
|
3354
|
+
}
|
|
3355
|
+
return this.#destSrc("isTTY", false);
|
|
3356
|
+
}
|
|
3357
|
+
// basically just get replace the getter/setter with a regular value
|
|
3358
|
+
set isTTY(val) {
|
|
3359
|
+
this.#isTTY = val;
|
|
3360
|
+
}
|
|
3361
|
+
get rows() {
|
|
3362
|
+
return this.#destSrc("rows");
|
|
3363
|
+
}
|
|
3364
|
+
get columns() {
|
|
3365
|
+
return this.#destSrc("columns");
|
|
3366
|
+
}
|
|
3367
|
+
mute() {
|
|
3368
|
+
this.muted = true;
|
|
3369
|
+
}
|
|
3370
|
+
unmute() {
|
|
3371
|
+
this.muted = false;
|
|
3372
|
+
}
|
|
3373
|
+
_onpipe(src) {
|
|
3374
|
+
this._src = src;
|
|
3375
|
+
}
|
|
3376
|
+
pipe(dest, options) {
|
|
3377
|
+
this._dest = dest;
|
|
3378
|
+
return super.pipe(dest, options);
|
|
3379
|
+
}
|
|
3380
|
+
pause() {
|
|
3381
|
+
if (this._src) {
|
|
3382
|
+
return this._src.pause();
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
resume() {
|
|
3386
|
+
if (this._src) {
|
|
3387
|
+
return this._src.resume();
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
write(c) {
|
|
3391
|
+
if (this.muted) {
|
|
3392
|
+
if (!this.replace) {
|
|
3393
|
+
return true;
|
|
3394
|
+
}
|
|
3395
|
+
if (c.match(/^\u001b/)) {
|
|
3396
|
+
if (c.indexOf(this._prompt) === 0) {
|
|
3397
|
+
c = c.slice(this._prompt.length);
|
|
3398
|
+
c = c.replace(/./g, this.replace);
|
|
3399
|
+
c = this._prompt + c;
|
|
3400
|
+
}
|
|
3401
|
+
this._hadControl = true;
|
|
3402
|
+
return this.emit("data", c);
|
|
3403
|
+
} else {
|
|
3404
|
+
if (this._prompt && this._hadControl && c.indexOf(this._prompt) === 0) {
|
|
3405
|
+
this._hadControl = false;
|
|
3406
|
+
this.emit("data", this._prompt);
|
|
3407
|
+
c = c.slice(this._prompt.length);
|
|
3408
|
+
}
|
|
3409
|
+
c = c.toString().replace(/./g, this.replace);
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
this.emit("data", c);
|
|
3413
|
+
}
|
|
3414
|
+
end(c) {
|
|
3415
|
+
if (this.muted) {
|
|
3416
|
+
if (c && this.replace) {
|
|
3417
|
+
c = c.toString().replace(/./g, this.replace);
|
|
3418
|
+
} else {
|
|
3419
|
+
c = null;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
if (c) {
|
|
3423
|
+
this.emit("data", c);
|
|
3424
|
+
}
|
|
3425
|
+
this.emit("end");
|
|
2252
3426
|
}
|
|
2253
|
-
|
|
2254
|
-
return
|
|
3427
|
+
destroy(...args) {
|
|
3428
|
+
return this.#proxy("destroy", ...args);
|
|
2255
3429
|
}
|
|
2256
|
-
|
|
3430
|
+
destroySoon(...args) {
|
|
3431
|
+
return this.#proxy("destroySoon", ...args);
|
|
3432
|
+
}
|
|
3433
|
+
close(...args) {
|
|
3434
|
+
return this.#proxy("close", ...args);
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
lib = MuteStream2;
|
|
3438
|
+
return lib;
|
|
3439
|
+
}
|
|
3440
|
+
var libExports = requireLib();
|
|
3441
|
+
const MuteStream = /* @__PURE__ */ getDefaultExportFromCjs(libExports);
|
|
3442
|
+
const signals = [];
|
|
3443
|
+
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
3444
|
+
if (process.platform !== "win32") {
|
|
3445
|
+
signals.push(
|
|
3446
|
+
"SIGALRM",
|
|
3447
|
+
"SIGABRT",
|
|
3448
|
+
"SIGVTALRM",
|
|
3449
|
+
"SIGXCPU",
|
|
3450
|
+
"SIGXFSZ",
|
|
3451
|
+
"SIGUSR2",
|
|
3452
|
+
"SIGTRAP",
|
|
3453
|
+
"SIGSYS",
|
|
3454
|
+
"SIGQUIT",
|
|
3455
|
+
"SIGIOT"
|
|
3456
|
+
// should detect profiler and enable/disable accordingly.
|
|
3457
|
+
// see #21
|
|
3458
|
+
// 'SIGPROF'
|
|
3459
|
+
);
|
|
3460
|
+
}
|
|
3461
|
+
if (process.platform === "linux") {
|
|
3462
|
+
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
3463
|
+
}
|
|
3464
|
+
const processOk = (process2) => !!process2 && typeof process2 === "object" && typeof process2.removeListener === "function" && typeof process2.emit === "function" && typeof process2.reallyExit === "function" && typeof process2.listeners === "function" && typeof process2.kill === "function" && typeof process2.pid === "number" && typeof process2.on === "function";
|
|
3465
|
+
const kExitEmitter = /* @__PURE__ */ Symbol.for("signal-exit emitter");
|
|
3466
|
+
const global = globalThis;
|
|
3467
|
+
const ObjectDefineProperty = Object.defineProperty.bind(Object);
|
|
3468
|
+
class Emitter {
|
|
3469
|
+
emitted = {
|
|
3470
|
+
afterExit: false,
|
|
3471
|
+
exit: false
|
|
3472
|
+
};
|
|
3473
|
+
listeners = {
|
|
3474
|
+
afterExit: [],
|
|
3475
|
+
exit: []
|
|
3476
|
+
};
|
|
3477
|
+
count = 0;
|
|
3478
|
+
id = Math.random();
|
|
3479
|
+
constructor() {
|
|
3480
|
+
if (global[kExitEmitter]) {
|
|
3481
|
+
return global[kExitEmitter];
|
|
3482
|
+
}
|
|
3483
|
+
ObjectDefineProperty(global, kExitEmitter, {
|
|
3484
|
+
value: this,
|
|
3485
|
+
writable: false,
|
|
3486
|
+
enumerable: false,
|
|
3487
|
+
configurable: false
|
|
3488
|
+
});
|
|
3489
|
+
}
|
|
3490
|
+
on(ev, fn) {
|
|
3491
|
+
this.listeners[ev].push(fn);
|
|
3492
|
+
}
|
|
3493
|
+
removeListener(ev, fn) {
|
|
3494
|
+
const list = this.listeners[ev];
|
|
3495
|
+
const i = list.indexOf(fn);
|
|
3496
|
+
if (i === -1) {
|
|
3497
|
+
return;
|
|
3498
|
+
}
|
|
3499
|
+
if (i === 0 && list.length === 1) {
|
|
3500
|
+
list.length = 0;
|
|
3501
|
+
} else {
|
|
3502
|
+
list.splice(i, 1);
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
emit(ev, code, signal) {
|
|
3506
|
+
if (this.emitted[ev]) {
|
|
2257
3507
|
return false;
|
|
2258
3508
|
}
|
|
2259
|
-
|
|
3509
|
+
this.emitted[ev] = true;
|
|
3510
|
+
let ret = false;
|
|
3511
|
+
for (const fn of this.listeners[ev]) {
|
|
3512
|
+
ret = fn(code, signal) === true || ret;
|
|
3513
|
+
}
|
|
3514
|
+
if (ev === "exit") {
|
|
3515
|
+
ret = this.emit("afterExit", code, signal) || ret;
|
|
3516
|
+
}
|
|
3517
|
+
return ret;
|
|
2260
3518
|
}
|
|
3519
|
+
}
|
|
3520
|
+
class SignalExitBase {
|
|
3521
|
+
}
|
|
3522
|
+
const signalExitWrap = (handler) => {
|
|
3523
|
+
return {
|
|
3524
|
+
onExit(cb, opts) {
|
|
3525
|
+
return handler.onExit(cb, opts);
|
|
3526
|
+
},
|
|
3527
|
+
load() {
|
|
3528
|
+
return handler.load();
|
|
3529
|
+
},
|
|
3530
|
+
unload() {
|
|
3531
|
+
return handler.unload();
|
|
3532
|
+
}
|
|
3533
|
+
};
|
|
2261
3534
|
};
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
return
|
|
3535
|
+
class SignalExitFallback extends SignalExitBase {
|
|
3536
|
+
onExit() {
|
|
3537
|
+
return () => {
|
|
3538
|
+
};
|
|
2265
3539
|
}
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
3540
|
+
load() {
|
|
3541
|
+
}
|
|
3542
|
+
unload() {
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
class SignalExit extends SignalExitBase {
|
|
3546
|
+
// "SIGHUP" throws an `ENOSYS` error on Windows,
|
|
3547
|
+
// so use a supported signal instead
|
|
3548
|
+
/* c8 ignore start */
|
|
3549
|
+
#hupSig = process$1.platform === "win32" ? "SIGINT" : "SIGHUP";
|
|
3550
|
+
/* c8 ignore stop */
|
|
3551
|
+
#emitter = new Emitter();
|
|
3552
|
+
#process;
|
|
3553
|
+
#originalProcessEmit;
|
|
3554
|
+
#originalProcessReallyExit;
|
|
3555
|
+
#sigListeners = {};
|
|
3556
|
+
#loaded = false;
|
|
3557
|
+
constructor(process2) {
|
|
3558
|
+
super();
|
|
3559
|
+
this.#process = process2;
|
|
3560
|
+
this.#sigListeners = {};
|
|
3561
|
+
for (const sig of signals) {
|
|
3562
|
+
this.#sigListeners[sig] = () => {
|
|
3563
|
+
const listeners = this.#process.listeners(sig);
|
|
3564
|
+
let { count } = this.#emitter;
|
|
3565
|
+
const p = process2;
|
|
3566
|
+
if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
|
|
3567
|
+
count += p.__signal_exit_emitter__.count;
|
|
3568
|
+
}
|
|
3569
|
+
if (listeners.length === count) {
|
|
3570
|
+
this.unload();
|
|
3571
|
+
const ret = this.#emitter.emit("exit", null, sig);
|
|
3572
|
+
const s = sig === "SIGHUP" ? this.#hupSig : sig;
|
|
3573
|
+
if (!ret)
|
|
3574
|
+
process2.kill(process2.pid, s);
|
|
3575
|
+
}
|
|
3576
|
+
};
|
|
3577
|
+
}
|
|
3578
|
+
this.#originalProcessReallyExit = process2.reallyExit;
|
|
3579
|
+
this.#originalProcessEmit = process2.emit;
|
|
3580
|
+
}
|
|
3581
|
+
onExit(cb, opts) {
|
|
3582
|
+
if (!processOk(this.#process)) {
|
|
3583
|
+
return () => {
|
|
3584
|
+
};
|
|
3585
|
+
}
|
|
3586
|
+
if (this.#loaded === false) {
|
|
3587
|
+
this.load();
|
|
3588
|
+
}
|
|
3589
|
+
const ev = opts?.alwaysLast ? "afterExit" : "exit";
|
|
3590
|
+
this.#emitter.on(ev, cb);
|
|
3591
|
+
return () => {
|
|
3592
|
+
this.#emitter.removeListener(ev, cb);
|
|
3593
|
+
if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) {
|
|
3594
|
+
this.unload();
|
|
3595
|
+
}
|
|
3596
|
+
};
|
|
3597
|
+
}
|
|
3598
|
+
load() {
|
|
3599
|
+
if (this.#loaded) {
|
|
3600
|
+
return;
|
|
3601
|
+
}
|
|
3602
|
+
this.#loaded = true;
|
|
3603
|
+
this.#emitter.count += 1;
|
|
3604
|
+
for (const sig of signals) {
|
|
3605
|
+
try {
|
|
3606
|
+
const fn = this.#sigListeners[sig];
|
|
3607
|
+
if (fn)
|
|
3608
|
+
this.#process.on(sig, fn);
|
|
3609
|
+
} catch (_) {
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
this.#process.emit = (ev, ...a) => {
|
|
3613
|
+
return this.#processEmit(ev, ...a);
|
|
3614
|
+
};
|
|
3615
|
+
this.#process.reallyExit = (code) => {
|
|
3616
|
+
return this.#processReallyExit(code);
|
|
3617
|
+
};
|
|
3618
|
+
}
|
|
3619
|
+
unload() {
|
|
3620
|
+
if (!this.#loaded) {
|
|
3621
|
+
return;
|
|
3622
|
+
}
|
|
3623
|
+
this.#loaded = false;
|
|
3624
|
+
signals.forEach((sig) => {
|
|
3625
|
+
const listener = this.#sigListeners[sig];
|
|
3626
|
+
if (!listener) {
|
|
3627
|
+
throw new Error("Listener not defined for signal: " + sig);
|
|
3628
|
+
}
|
|
3629
|
+
try {
|
|
3630
|
+
this.#process.removeListener(sig, listener);
|
|
3631
|
+
} catch (_) {
|
|
3632
|
+
}
|
|
3633
|
+
});
|
|
3634
|
+
this.#process.emit = this.#originalProcessEmit;
|
|
3635
|
+
this.#process.reallyExit = this.#originalProcessReallyExit;
|
|
3636
|
+
this.#emitter.count -= 1;
|
|
3637
|
+
}
|
|
3638
|
+
#processReallyExit(code) {
|
|
3639
|
+
if (!processOk(this.#process)) {
|
|
3640
|
+
return 0;
|
|
3641
|
+
}
|
|
3642
|
+
this.#process.exitCode = code || 0;
|
|
3643
|
+
this.#emitter.emit("exit", this.#process.exitCode, null);
|
|
3644
|
+
return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
|
|
3645
|
+
}
|
|
3646
|
+
#processEmit(ev, ...args) {
|
|
3647
|
+
const og = this.#originalProcessEmit;
|
|
3648
|
+
if (ev === "exit" && processOk(this.#process)) {
|
|
3649
|
+
if (typeof args[0] === "number") {
|
|
3650
|
+
this.#process.exitCode = args[0];
|
|
3651
|
+
}
|
|
3652
|
+
const ret = og.call(this.#process, ev, ...args);
|
|
3653
|
+
this.#emitter.emit("exit", this.#process.exitCode, null);
|
|
3654
|
+
return ret;
|
|
3655
|
+
} else {
|
|
3656
|
+
return og.call(this.#process, ev, ...args);
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
const process$1 = globalThis.process;
|
|
3661
|
+
const {
|
|
3662
|
+
/**
|
|
3663
|
+
* Called when the process is exiting, whether via signal, explicit
|
|
3664
|
+
* exit, or running out of stuff to do.
|
|
3665
|
+
*
|
|
3666
|
+
* If the global process object is not suitable for instrumentation,
|
|
3667
|
+
* then this will be a no-op.
|
|
3668
|
+
*
|
|
3669
|
+
* Returns a function that may be used to unload signal-exit.
|
|
3670
|
+
*/
|
|
3671
|
+
onExit
|
|
3672
|
+
} = signalExitWrap(processOk(process$1) ? new SignalExit(process$1) : new SignalExitFallback());
|
|
3673
|
+
const ESC = "\x1B[";
|
|
3674
|
+
const cursorLeft = ESC + "G";
|
|
3675
|
+
const cursorHide = ESC + "?25l";
|
|
3676
|
+
const cursorShow = ESC + "?25h";
|
|
3677
|
+
const cursorUp = (rows = 1) => rows > 0 ? `${ESC}${rows}A` : "";
|
|
3678
|
+
const cursorDown = (rows = 1) => rows > 0 ? `${ESC}${rows}B` : "";
|
|
3679
|
+
const cursorTo = (x, y) => {
|
|
3680
|
+
return `${ESC}${x + 1}G`;
|
|
3681
|
+
};
|
|
3682
|
+
const eraseLine = ESC + "2K";
|
|
3683
|
+
const eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
|
|
3684
|
+
const height = (content) => content.split("\n").length;
|
|
3685
|
+
const lastLine = (content) => content.split("\n").pop() ?? "";
|
|
3686
|
+
class ScreenManager {
|
|
3687
|
+
// These variables are keeping information to allow correct prompt re-rendering
|
|
3688
|
+
height = 0;
|
|
3689
|
+
extraLinesUnderPrompt = 0;
|
|
3690
|
+
cursorPos;
|
|
3691
|
+
rl;
|
|
3692
|
+
constructor(rl) {
|
|
3693
|
+
this.rl = rl;
|
|
3694
|
+
this.cursorPos = rl.getCursorPos();
|
|
3695
|
+
}
|
|
3696
|
+
write(content) {
|
|
3697
|
+
this.rl.output.unmute();
|
|
3698
|
+
this.rl.output.write(content);
|
|
3699
|
+
this.rl.output.mute();
|
|
3700
|
+
}
|
|
3701
|
+
render(content, bottomContent = "") {
|
|
3702
|
+
const promptLine = lastLine(content);
|
|
3703
|
+
const rawPromptLine = stripVTControlCharacters(promptLine);
|
|
3704
|
+
let prompt = rawPromptLine;
|
|
3705
|
+
if (this.rl.line.length > 0) {
|
|
3706
|
+
prompt = prompt.slice(0, -this.rl.line.length);
|
|
3707
|
+
}
|
|
3708
|
+
this.rl.setPrompt(prompt);
|
|
3709
|
+
this.cursorPos = this.rl.getCursorPos();
|
|
3710
|
+
const width = readlineWidth();
|
|
3711
|
+
content = breakLines(content, width);
|
|
3712
|
+
bottomContent = breakLines(bottomContent, width);
|
|
3713
|
+
if (rawPromptLine.length % width === 0) {
|
|
3714
|
+
content += "\n";
|
|
3715
|
+
}
|
|
3716
|
+
let output = content + (bottomContent ? "\n" + bottomContent : "");
|
|
3717
|
+
const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
|
|
3718
|
+
const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
|
|
3719
|
+
if (bottomContentHeight > 0)
|
|
3720
|
+
output += cursorUp(bottomContentHeight);
|
|
3721
|
+
output += cursorTo(this.cursorPos.cols);
|
|
3722
|
+
this.write(cursorDown(this.extraLinesUnderPrompt) + eraseLines(this.height) + output);
|
|
3723
|
+
this.extraLinesUnderPrompt = bottomContentHeight;
|
|
3724
|
+
this.height = height(output);
|
|
3725
|
+
}
|
|
3726
|
+
checkCursorPos() {
|
|
3727
|
+
const cursorPos = this.rl.getCursorPos();
|
|
3728
|
+
if (cursorPos.cols !== this.cursorPos.cols) {
|
|
3729
|
+
this.write(cursorTo(cursorPos.cols));
|
|
3730
|
+
this.cursorPos = cursorPos;
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
done({ clearContent }) {
|
|
3734
|
+
this.rl.setPrompt("");
|
|
3735
|
+
let output = cursorDown(this.extraLinesUnderPrompt);
|
|
3736
|
+
output += clearContent ? eraseLines(this.height) : "\n";
|
|
3737
|
+
output += cursorLeft;
|
|
3738
|
+
output += cursorShow;
|
|
3739
|
+
this.write(output);
|
|
3740
|
+
this.rl.close();
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
class PromisePolyfill extends Promise {
|
|
3744
|
+
// Available starting from Node 22
|
|
3745
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
|
3746
|
+
static withResolver() {
|
|
3747
|
+
let resolve;
|
|
3748
|
+
let reject;
|
|
3749
|
+
const promise = new Promise((res, rej) => {
|
|
3750
|
+
resolve = res;
|
|
3751
|
+
reject = rej;
|
|
3752
|
+
});
|
|
3753
|
+
return { promise, resolve, reject };
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
const nativeSetImmediate = globalThis.setImmediate;
|
|
3757
|
+
function getCallSites() {
|
|
3758
|
+
const savedPrepareStackTrace = Error.prepareStackTrace;
|
|
3759
|
+
let result = [];
|
|
3760
|
+
try {
|
|
3761
|
+
Error.prepareStackTrace = (_, callSites) => {
|
|
3762
|
+
const callSitesWithoutCurrent = callSites.slice(1);
|
|
3763
|
+
result = callSitesWithoutCurrent;
|
|
3764
|
+
return callSitesWithoutCurrent;
|
|
3765
|
+
};
|
|
3766
|
+
new Error().stack;
|
|
3767
|
+
} catch {
|
|
3768
|
+
return result;
|
|
3769
|
+
}
|
|
3770
|
+
Error.prepareStackTrace = savedPrepareStackTrace;
|
|
3771
|
+
return result;
|
|
3772
|
+
}
|
|
3773
|
+
function createPrompt(view) {
|
|
3774
|
+
const callSites = getCallSites();
|
|
3775
|
+
const prompt = (config, context = {}) => {
|
|
3776
|
+
const { input: input2 = process.stdin, signal } = context;
|
|
3777
|
+
const cleanups = /* @__PURE__ */ new Set();
|
|
3778
|
+
const output = new MuteStream();
|
|
3779
|
+
output.pipe(context.output ?? process.stdout);
|
|
3780
|
+
const rl = readline$1.createInterface({
|
|
3781
|
+
terminal: true,
|
|
3782
|
+
input: input2,
|
|
3783
|
+
output
|
|
3784
|
+
});
|
|
3785
|
+
output.mute();
|
|
3786
|
+
const screen = new ScreenManager(rl);
|
|
3787
|
+
const { promise, resolve, reject } = PromisePolyfill.withResolver();
|
|
3788
|
+
const cancel = () => reject(new CancelPromptError());
|
|
3789
|
+
if (signal) {
|
|
3790
|
+
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
3791
|
+
if (signal.aborted) {
|
|
3792
|
+
abort();
|
|
3793
|
+
return Object.assign(promise, { cancel });
|
|
3794
|
+
}
|
|
3795
|
+
signal.addEventListener("abort", abort);
|
|
3796
|
+
cleanups.add(() => signal.removeEventListener("abort", abort));
|
|
3797
|
+
}
|
|
3798
|
+
cleanups.add(onExit((code, signal2) => {
|
|
3799
|
+
reject(new ExitPromptError(`User force closed the prompt with ${code} ${signal2}`));
|
|
3800
|
+
}));
|
|
3801
|
+
const sigint = () => reject(new ExitPromptError(`User force closed the prompt with SIGINT`));
|
|
3802
|
+
rl.on("SIGINT", sigint);
|
|
3803
|
+
cleanups.add(() => rl.removeListener("SIGINT", sigint));
|
|
3804
|
+
return withHooks(rl, (cycle) => {
|
|
3805
|
+
const hooksCleanup = AsyncResource.bind(() => effectScheduler.clearAll());
|
|
3806
|
+
rl.on("close", hooksCleanup);
|
|
3807
|
+
cleanups.add(() => rl.removeListener("close", hooksCleanup));
|
|
3808
|
+
const startCycle = () => {
|
|
3809
|
+
const checkCursorPos = () => screen.checkCursorPos();
|
|
3810
|
+
rl.input.on("keypress", checkCursorPos);
|
|
3811
|
+
cleanups.add(() => rl.input.removeListener("keypress", checkCursorPos));
|
|
3812
|
+
let pendingDone = null;
|
|
3813
|
+
cycle(() => {
|
|
3814
|
+
let effectsSettled = false;
|
|
3815
|
+
try {
|
|
3816
|
+
const nextView = view(config, (value) => {
|
|
3817
|
+
if (effectsSettled) {
|
|
3818
|
+
resolve(value);
|
|
3819
|
+
} else {
|
|
3820
|
+
pendingDone = { value };
|
|
3821
|
+
}
|
|
3822
|
+
});
|
|
3823
|
+
if (nextView === void 0) {
|
|
3824
|
+
let callerFilename = callSites[1]?.getFileName();
|
|
3825
|
+
if (callerFilename && !callerFilename.startsWith("file://")) {
|
|
3826
|
+
callerFilename = path.resolve(callerFilename);
|
|
3827
|
+
}
|
|
3828
|
+
throw new Error(`Prompt functions must return a string.
|
|
3829
|
+
at ${callerFilename}`);
|
|
3830
|
+
}
|
|
3831
|
+
const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
|
|
3832
|
+
screen.render(content, bottomContent);
|
|
3833
|
+
effectScheduler.run();
|
|
3834
|
+
} catch (error) {
|
|
3835
|
+
reject(error);
|
|
3836
|
+
}
|
|
3837
|
+
effectsSettled = true;
|
|
3838
|
+
if (pendingDone !== null) {
|
|
3839
|
+
const { value } = pendingDone;
|
|
3840
|
+
pendingDone = null;
|
|
3841
|
+
resolve(value);
|
|
3842
|
+
}
|
|
3843
|
+
});
|
|
3844
|
+
};
|
|
3845
|
+
if ("readableFlowing" in input2) {
|
|
3846
|
+
nativeSetImmediate(startCycle);
|
|
3847
|
+
} else {
|
|
3848
|
+
startCycle();
|
|
3849
|
+
}
|
|
3850
|
+
return Object.assign(promise.then((answer) => {
|
|
3851
|
+
effectScheduler.clearAll();
|
|
3852
|
+
return answer;
|
|
3853
|
+
}, (error) => {
|
|
3854
|
+
effectScheduler.clearAll();
|
|
3855
|
+
throw error;
|
|
3856
|
+
}).finally(() => {
|
|
3857
|
+
cleanups.forEach((cleanup) => cleanup());
|
|
3858
|
+
screen.done({ clearContent: Boolean(context.clearPromptOnDone) });
|
|
3859
|
+
output.end();
|
|
3860
|
+
}).then(() => promise), { cancel });
|
|
3861
|
+
});
|
|
3862
|
+
};
|
|
3863
|
+
return prompt;
|
|
3864
|
+
}
|
|
3865
|
+
class Separator {
|
|
3866
|
+
separator = styleText("dim", Array.from({ length: 15 }).join(figures.line));
|
|
3867
|
+
type = "separator";
|
|
3868
|
+
constructor(separator) {
|
|
3869
|
+
if (separator) {
|
|
3870
|
+
this.separator = separator;
|
|
2275
3871
|
}
|
|
2276
|
-
console.error(`Unknown package manager: ${answer}`);
|
|
2277
3872
|
}
|
|
3873
|
+
static isSeparator(choice) {
|
|
3874
|
+
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3877
|
+
const checkboxTheme = {
|
|
3878
|
+
icon: {
|
|
3879
|
+
checked: styleText("green", figures.circleFilled),
|
|
3880
|
+
unchecked: figures.circle,
|
|
3881
|
+
cursor: figures.pointer,
|
|
3882
|
+
disabledChecked: styleText("green", figures.circleDouble),
|
|
3883
|
+
disabledUnchecked: "-"
|
|
3884
|
+
},
|
|
3885
|
+
style: {
|
|
3886
|
+
disabled: (text) => styleText("dim", text),
|
|
3887
|
+
renderSelectedChoices: (selectedChoices) => selectedChoices.map((choice) => choice.short).join(", "),
|
|
3888
|
+
description: (text) => styleText("cyan", text),
|
|
3889
|
+
keysHelpTip: (keys) => keys.map(([key, action]) => `${styleText("bold", key)} ${styleText("dim", action)}`).join(styleText("dim", " • "))
|
|
3890
|
+
},
|
|
3891
|
+
i18n: { disabledError: "This option is disabled and cannot be toggled." },
|
|
3892
|
+
keybindings: []
|
|
2278
3893
|
};
|
|
2279
|
-
|
|
3894
|
+
function isSelectable$1(item) {
|
|
3895
|
+
return !Separator.isSeparator(item) && !item.disabled;
|
|
3896
|
+
}
|
|
3897
|
+
function isNavigable$1(item) {
|
|
3898
|
+
return !Separator.isSeparator(item);
|
|
3899
|
+
}
|
|
3900
|
+
function isChecked(item) {
|
|
3901
|
+
return !Separator.isSeparator(item) && item.checked;
|
|
3902
|
+
}
|
|
3903
|
+
function toggle(item) {
|
|
3904
|
+
return isSelectable$1(item) ? { ...item, checked: !item.checked } : item;
|
|
3905
|
+
}
|
|
3906
|
+
function check(checked) {
|
|
3907
|
+
return function(item) {
|
|
3908
|
+
return isSelectable$1(item) ? { ...item, checked } : item;
|
|
3909
|
+
};
|
|
3910
|
+
}
|
|
3911
|
+
function normalizeChoices$1(choices) {
|
|
3912
|
+
return choices.map((choice) => {
|
|
3913
|
+
if (Separator.isSeparator(choice))
|
|
3914
|
+
return choice;
|
|
3915
|
+
if (typeof choice !== "object" || choice === null || !("value" in choice)) {
|
|
3916
|
+
const name2 = String(choice);
|
|
3917
|
+
return {
|
|
3918
|
+
value: choice,
|
|
3919
|
+
name: name2,
|
|
3920
|
+
short: name2,
|
|
3921
|
+
checkedName: name2,
|
|
3922
|
+
disabled: false,
|
|
3923
|
+
checked: false
|
|
3924
|
+
};
|
|
3925
|
+
}
|
|
3926
|
+
const name = choice.name ?? String(choice.value);
|
|
3927
|
+
const normalizedChoice = {
|
|
3928
|
+
value: choice.value,
|
|
3929
|
+
name,
|
|
3930
|
+
short: choice.short ?? name,
|
|
3931
|
+
checkedName: choice.checkedName ?? name,
|
|
3932
|
+
disabled: choice.disabled ?? false,
|
|
3933
|
+
checked: choice.checked ?? false
|
|
3934
|
+
};
|
|
3935
|
+
if (choice.description) {
|
|
3936
|
+
normalizedChoice.description = choice.description;
|
|
3937
|
+
}
|
|
3938
|
+
return normalizedChoice;
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
const checkbox = createPrompt((config, done) => {
|
|
3942
|
+
const { pageSize = 7, loop = true, required, validate = () => true } = config;
|
|
3943
|
+
const shortcuts = { all: "a", invert: "i", ...config.shortcuts };
|
|
3944
|
+
const theme = makeTheme(checkboxTheme, config.theme);
|
|
3945
|
+
const { keybindings } = theme;
|
|
3946
|
+
const [status, setStatus] = useState("idle");
|
|
3947
|
+
const prefix = usePrefix({ status, theme });
|
|
3948
|
+
const [items, setItems] = useState(normalizeChoices$1(config.choices));
|
|
3949
|
+
const bounds = useMemo(() => {
|
|
3950
|
+
const first = items.findIndex(isNavigable$1);
|
|
3951
|
+
const last = items.findLastIndex(isNavigable$1);
|
|
3952
|
+
if (first === -1) {
|
|
3953
|
+
throw new ValidationError("[checkbox prompt] No selectable choices. All choices are disabled.");
|
|
3954
|
+
}
|
|
3955
|
+
return { first, last };
|
|
3956
|
+
}, [items]);
|
|
3957
|
+
const [active, setActive] = useState(bounds.first);
|
|
3958
|
+
const [errorMsg, setError] = useState();
|
|
3959
|
+
useKeypress(async (key) => {
|
|
3960
|
+
if (isEnterKey(key)) {
|
|
3961
|
+
const selection = items.filter(isChecked);
|
|
3962
|
+
const isValid = await validate([...selection]);
|
|
3963
|
+
if (required && !selection.length) {
|
|
3964
|
+
setError("At least one choice must be selected");
|
|
3965
|
+
} else if (isValid === true) {
|
|
3966
|
+
setStatus("done");
|
|
3967
|
+
done(selection.map((choice) => choice.value));
|
|
3968
|
+
} else {
|
|
3969
|
+
setError(isValid || "You must select a valid value");
|
|
3970
|
+
}
|
|
3971
|
+
} else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
|
|
3972
|
+
if (errorMsg) {
|
|
3973
|
+
setError(void 0);
|
|
3974
|
+
}
|
|
3975
|
+
if (loop || isUpKey(key, keybindings) && active !== bounds.first || isDownKey(key, keybindings) && active !== bounds.last) {
|
|
3976
|
+
const offset = isUpKey(key, keybindings) ? -1 : 1;
|
|
3977
|
+
let next = active;
|
|
3978
|
+
do {
|
|
3979
|
+
next = (next + offset + items.length) % items.length;
|
|
3980
|
+
} while (!isNavigable$1(items[next]));
|
|
3981
|
+
setActive(next);
|
|
3982
|
+
}
|
|
3983
|
+
} else if (isSpaceKey(key)) {
|
|
3984
|
+
const activeItem = items[active];
|
|
3985
|
+
if (activeItem && !Separator.isSeparator(activeItem)) {
|
|
3986
|
+
if (activeItem.disabled) {
|
|
3987
|
+
setError(theme.i18n.disabledError);
|
|
3988
|
+
} else {
|
|
3989
|
+
setError(void 0);
|
|
3990
|
+
setItems(items.map((choice, i) => i === active ? toggle(choice) : choice));
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
} else if (key.name === shortcuts.all) {
|
|
3994
|
+
const selectAll = items.some((choice) => isSelectable$1(choice) && !choice.checked);
|
|
3995
|
+
setItems(items.map(check(selectAll)));
|
|
3996
|
+
} else if (key.name === shortcuts.invert) {
|
|
3997
|
+
setItems(items.map(toggle));
|
|
3998
|
+
} else if (isNumberKey(key)) {
|
|
3999
|
+
const selectedIndex = Number(key.name) - 1;
|
|
4000
|
+
let selectableIndex = -1;
|
|
4001
|
+
const position = items.findIndex((item) => {
|
|
4002
|
+
if (Separator.isSeparator(item))
|
|
4003
|
+
return false;
|
|
4004
|
+
selectableIndex++;
|
|
4005
|
+
return selectableIndex === selectedIndex;
|
|
4006
|
+
});
|
|
4007
|
+
const selectedItem = items[position];
|
|
4008
|
+
if (selectedItem && isSelectable$1(selectedItem)) {
|
|
4009
|
+
setActive(position);
|
|
4010
|
+
setItems(items.map((choice, i) => i === position ? toggle(choice) : choice));
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
});
|
|
4014
|
+
const message = theme.style.message(config.message, status);
|
|
4015
|
+
let description;
|
|
4016
|
+
const page = usePagination({
|
|
4017
|
+
items,
|
|
4018
|
+
active,
|
|
4019
|
+
renderItem({ item, isActive }) {
|
|
4020
|
+
if (Separator.isSeparator(item)) {
|
|
4021
|
+
return ` ${item.separator}`;
|
|
4022
|
+
}
|
|
4023
|
+
const cursor = isActive ? theme.icon.cursor : " ";
|
|
4024
|
+
if (item.disabled) {
|
|
4025
|
+
const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
|
|
4026
|
+
const checkbox3 = item.checked ? theme.icon.disabledChecked : theme.icon.disabledUnchecked;
|
|
4027
|
+
return theme.style.disabled(`${cursor}${checkbox3} ${item.name} ${disabledLabel}`);
|
|
4028
|
+
}
|
|
4029
|
+
if (isActive) {
|
|
4030
|
+
description = item.description;
|
|
4031
|
+
}
|
|
4032
|
+
const checkbox2 = item.checked ? theme.icon.checked : theme.icon.unchecked;
|
|
4033
|
+
const name = item.checked ? item.checkedName : item.name;
|
|
4034
|
+
const color = isActive ? theme.style.highlight : (x) => x;
|
|
4035
|
+
return color(`${cursor}${checkbox2} ${name}`);
|
|
4036
|
+
},
|
|
4037
|
+
pageSize,
|
|
4038
|
+
loop
|
|
4039
|
+
});
|
|
4040
|
+
if (status === "done") {
|
|
4041
|
+
const selection = items.filter(isChecked);
|
|
4042
|
+
const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, items));
|
|
4043
|
+
return [prefix, message, answer].filter(Boolean).join(" ");
|
|
4044
|
+
}
|
|
4045
|
+
const keys = [
|
|
4046
|
+
["↑↓", "navigate"],
|
|
4047
|
+
["space", "select"]
|
|
4048
|
+
];
|
|
4049
|
+
if (shortcuts.all)
|
|
4050
|
+
keys.push([shortcuts.all, "all"]);
|
|
4051
|
+
if (shortcuts.invert)
|
|
4052
|
+
keys.push([shortcuts.invert, "invert"]);
|
|
4053
|
+
keys.push(["⏎", "submit"]);
|
|
4054
|
+
const helpLine = theme.style.keysHelpTip(keys);
|
|
4055
|
+
const lines = [
|
|
4056
|
+
[prefix, message].filter(Boolean).join(" "),
|
|
4057
|
+
page,
|
|
4058
|
+
" ",
|
|
4059
|
+
description ? theme.style.description(description) : "",
|
|
4060
|
+
errorMsg ? theme.style.error(errorMsg) : "",
|
|
4061
|
+
helpLine
|
|
4062
|
+
].filter(Boolean).join("\n").trimEnd();
|
|
4063
|
+
return `${lines}${cursorHide}`;
|
|
4064
|
+
});
|
|
4065
|
+
const inputTheme = {
|
|
4066
|
+
validationFailureMode: "keep"
|
|
4067
|
+
};
|
|
4068
|
+
const input = createPrompt((config, done) => {
|
|
4069
|
+
const { prefill = "tab" } = config;
|
|
4070
|
+
const theme = makeTheme(inputTheme, config.theme);
|
|
4071
|
+
const [status, setStatus] = useState("idle");
|
|
4072
|
+
const [defaultValue, setDefaultValue] = useState(String(config.default ?? ""));
|
|
4073
|
+
const [errorMsg, setError] = useState();
|
|
4074
|
+
const [value, setValue] = useState("");
|
|
4075
|
+
const prefix = usePrefix({ status, theme });
|
|
4076
|
+
async function validate(value2) {
|
|
4077
|
+
const { required, pattern, patternError = "Invalid input" } = config;
|
|
4078
|
+
if (required && !value2) {
|
|
4079
|
+
return "You must provide a value";
|
|
4080
|
+
}
|
|
4081
|
+
if (pattern && !pattern.test(value2)) {
|
|
4082
|
+
return patternError;
|
|
4083
|
+
}
|
|
4084
|
+
if (typeof config.validate === "function") {
|
|
4085
|
+
return await config.validate(value2) || "You must provide a valid value";
|
|
4086
|
+
}
|
|
4087
|
+
return true;
|
|
4088
|
+
}
|
|
4089
|
+
useKeypress(async (key, rl) => {
|
|
4090
|
+
if (status !== "idle") {
|
|
4091
|
+
return;
|
|
4092
|
+
}
|
|
4093
|
+
if (isEnterKey(key)) {
|
|
4094
|
+
const answer = value || defaultValue;
|
|
4095
|
+
setStatus("loading");
|
|
4096
|
+
const isValid = await validate(answer);
|
|
4097
|
+
if (isValid === true) {
|
|
4098
|
+
setValue(answer);
|
|
4099
|
+
setStatus("done");
|
|
4100
|
+
done(answer);
|
|
4101
|
+
} else {
|
|
4102
|
+
if (theme.validationFailureMode === "clear") {
|
|
4103
|
+
setValue("");
|
|
4104
|
+
} else {
|
|
4105
|
+
rl.write(value);
|
|
4106
|
+
}
|
|
4107
|
+
setError(isValid);
|
|
4108
|
+
setStatus("idle");
|
|
4109
|
+
}
|
|
4110
|
+
} else if (isBackspaceKey(key) && !value) {
|
|
4111
|
+
setDefaultValue("");
|
|
4112
|
+
} else if (isTabKey(key) && !value) {
|
|
4113
|
+
setDefaultValue("");
|
|
4114
|
+
rl.clearLine(0);
|
|
4115
|
+
rl.write(defaultValue);
|
|
4116
|
+
setValue(defaultValue);
|
|
4117
|
+
} else {
|
|
4118
|
+
setValue(rl.line);
|
|
4119
|
+
setError(void 0);
|
|
4120
|
+
}
|
|
4121
|
+
});
|
|
4122
|
+
useEffect((rl) => {
|
|
4123
|
+
if (prefill === "editable" && defaultValue) {
|
|
4124
|
+
rl.write(defaultValue);
|
|
4125
|
+
setValue(defaultValue);
|
|
4126
|
+
}
|
|
4127
|
+
}, []);
|
|
4128
|
+
const message = theme.style.message(config.message, status);
|
|
4129
|
+
let formattedValue = value;
|
|
4130
|
+
if (typeof config.transformer === "function") {
|
|
4131
|
+
formattedValue = config.transformer(value, { isFinal: status === "done" });
|
|
4132
|
+
} else if (status === "done") {
|
|
4133
|
+
formattedValue = theme.style.answer(value);
|
|
4134
|
+
}
|
|
4135
|
+
let defaultStr;
|
|
4136
|
+
if (defaultValue && status !== "done" && !value) {
|
|
4137
|
+
defaultStr = theme.style.defaultAnswer(defaultValue);
|
|
4138
|
+
}
|
|
4139
|
+
let error = "";
|
|
4140
|
+
if (errorMsg) {
|
|
4141
|
+
error = theme.style.error(errorMsg);
|
|
4142
|
+
}
|
|
4143
|
+
return [
|
|
4144
|
+
[prefix, message, defaultStr, formattedValue].filter((v) => v !== void 0).join(" "),
|
|
4145
|
+
error
|
|
4146
|
+
];
|
|
4147
|
+
});
|
|
4148
|
+
const selectTheme = {
|
|
4149
|
+
icon: { cursor: figures.pointer },
|
|
4150
|
+
style: {
|
|
4151
|
+
disabled: (text) => styleText("dim", text),
|
|
4152
|
+
description: (text) => styleText("cyan", text),
|
|
4153
|
+
keysHelpTip: (keys) => keys.map(([key, action]) => `${styleText("bold", key)} ${styleText("dim", action)}`).join(styleText("dim", " • "))
|
|
4154
|
+
},
|
|
4155
|
+
i18n: { disabledError: "This option is disabled and cannot be selected." },
|
|
4156
|
+
indexMode: "hidden",
|
|
4157
|
+
keybindings: []
|
|
4158
|
+
};
|
|
4159
|
+
function isSelectable(item) {
|
|
4160
|
+
return !Separator.isSeparator(item) && !item.disabled;
|
|
4161
|
+
}
|
|
4162
|
+
function isNavigable(item) {
|
|
4163
|
+
return !Separator.isSeparator(item);
|
|
4164
|
+
}
|
|
4165
|
+
function normalizeChoices(choices) {
|
|
4166
|
+
return choices.map((choice) => {
|
|
4167
|
+
if (Separator.isSeparator(choice))
|
|
4168
|
+
return choice;
|
|
4169
|
+
if (typeof choice !== "object" || choice === null || !("value" in choice)) {
|
|
4170
|
+
const name2 = String(choice);
|
|
4171
|
+
return {
|
|
4172
|
+
value: choice,
|
|
4173
|
+
name: name2,
|
|
4174
|
+
short: name2,
|
|
4175
|
+
disabled: false
|
|
4176
|
+
};
|
|
4177
|
+
}
|
|
4178
|
+
const name = choice.name ?? String(choice.value);
|
|
4179
|
+
const normalizedChoice = {
|
|
4180
|
+
value: choice.value,
|
|
4181
|
+
name,
|
|
4182
|
+
short: choice.short ?? name,
|
|
4183
|
+
disabled: choice.disabled ?? false
|
|
4184
|
+
};
|
|
4185
|
+
if (choice.description) {
|
|
4186
|
+
normalizedChoice.description = choice.description;
|
|
4187
|
+
}
|
|
4188
|
+
return normalizedChoice;
|
|
4189
|
+
});
|
|
4190
|
+
}
|
|
4191
|
+
const select = createPrompt((config, done) => {
|
|
4192
|
+
const { loop = true, pageSize = 7 } = config;
|
|
4193
|
+
const theme = makeTheme(selectTheme, config.theme);
|
|
4194
|
+
const { keybindings } = theme;
|
|
4195
|
+
const [status, setStatus] = useState("idle");
|
|
4196
|
+
const prefix = usePrefix({ status, theme });
|
|
4197
|
+
const searchTimeoutRef = useRef();
|
|
4198
|
+
const searchEnabled = !keybindings.includes("vim");
|
|
4199
|
+
const items = useMemo(() => normalizeChoices(config.choices), [config.choices]);
|
|
4200
|
+
const bounds = useMemo(() => {
|
|
4201
|
+
const first = items.findIndex(isNavigable);
|
|
4202
|
+
const last = items.findLastIndex(isNavigable);
|
|
4203
|
+
if (first === -1) {
|
|
4204
|
+
throw new ValidationError("[select prompt] No selectable choices. All choices are disabled.");
|
|
4205
|
+
}
|
|
4206
|
+
return { first, last };
|
|
4207
|
+
}, [items]);
|
|
4208
|
+
const defaultItemIndex = useMemo(() => {
|
|
4209
|
+
if (!("default" in config))
|
|
4210
|
+
return -1;
|
|
4211
|
+
return items.findIndex((item) => isSelectable(item) && item.value === config.default);
|
|
4212
|
+
}, [config.default, items]);
|
|
4213
|
+
const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
|
|
4214
|
+
const selectedChoice = items[active];
|
|
4215
|
+
if (selectedChoice == null || Separator.isSeparator(selectedChoice)) {
|
|
4216
|
+
throw new Error("Active index does not point to a choice");
|
|
4217
|
+
}
|
|
4218
|
+
const [errorMsg, setError] = useState();
|
|
4219
|
+
useKeypress((key, rl) => {
|
|
4220
|
+
clearTimeout(searchTimeoutRef.current);
|
|
4221
|
+
if (errorMsg) {
|
|
4222
|
+
setError(void 0);
|
|
4223
|
+
}
|
|
4224
|
+
if (isEnterKey(key)) {
|
|
4225
|
+
if (selectedChoice.disabled) {
|
|
4226
|
+
setError(theme.i18n.disabledError);
|
|
4227
|
+
} else {
|
|
4228
|
+
setStatus("done");
|
|
4229
|
+
done(selectedChoice.value);
|
|
4230
|
+
}
|
|
4231
|
+
} else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
|
|
4232
|
+
rl.clearLine(0);
|
|
4233
|
+
if (loop || isUpKey(key, keybindings) && active !== bounds.first || isDownKey(key, keybindings) && active !== bounds.last) {
|
|
4234
|
+
const offset = isUpKey(key, keybindings) ? -1 : 1;
|
|
4235
|
+
let next = active;
|
|
4236
|
+
do {
|
|
4237
|
+
next = (next + offset + items.length) % items.length;
|
|
4238
|
+
} while (!isNavigable(items[next]));
|
|
4239
|
+
setActive(next);
|
|
4240
|
+
}
|
|
4241
|
+
} else if (isNumberKey(key) && !Number.isNaN(Number(rl.line))) {
|
|
4242
|
+
const selectedIndex = Number(rl.line) - 1;
|
|
4243
|
+
let selectableIndex = -1;
|
|
4244
|
+
const position = items.findIndex((item2) => {
|
|
4245
|
+
if (Separator.isSeparator(item2))
|
|
4246
|
+
return false;
|
|
4247
|
+
selectableIndex++;
|
|
4248
|
+
return selectableIndex === selectedIndex;
|
|
4249
|
+
});
|
|
4250
|
+
const item = items[position];
|
|
4251
|
+
if (item != null && isSelectable(item)) {
|
|
4252
|
+
setActive(position);
|
|
4253
|
+
}
|
|
4254
|
+
searchTimeoutRef.current = setTimeout(() => {
|
|
4255
|
+
rl.clearLine(0);
|
|
4256
|
+
}, 700);
|
|
4257
|
+
} else if (isBackspaceKey(key)) {
|
|
4258
|
+
rl.clearLine(0);
|
|
4259
|
+
} else if (searchEnabled) {
|
|
4260
|
+
const searchTerm = rl.line.toLowerCase();
|
|
4261
|
+
const matchIndex = items.findIndex((item) => {
|
|
4262
|
+
if (Separator.isSeparator(item) || !isSelectable(item))
|
|
4263
|
+
return false;
|
|
4264
|
+
return item.name.toLowerCase().startsWith(searchTerm);
|
|
4265
|
+
});
|
|
4266
|
+
if (matchIndex !== -1) {
|
|
4267
|
+
setActive(matchIndex);
|
|
4268
|
+
}
|
|
4269
|
+
searchTimeoutRef.current = setTimeout(() => {
|
|
4270
|
+
rl.clearLine(0);
|
|
4271
|
+
}, 700);
|
|
4272
|
+
}
|
|
4273
|
+
});
|
|
4274
|
+
useEffect(() => () => {
|
|
4275
|
+
clearTimeout(searchTimeoutRef.current);
|
|
4276
|
+
}, []);
|
|
4277
|
+
const message = theme.style.message(config.message, status);
|
|
4278
|
+
const helpLine = theme.style.keysHelpTip([
|
|
4279
|
+
["↑↓", "navigate"],
|
|
4280
|
+
["⏎", "select"]
|
|
4281
|
+
]);
|
|
4282
|
+
let separatorCount = 0;
|
|
4283
|
+
const page = usePagination({
|
|
4284
|
+
items,
|
|
4285
|
+
active,
|
|
4286
|
+
renderItem({ item, isActive, index }) {
|
|
4287
|
+
if (Separator.isSeparator(item)) {
|
|
4288
|
+
separatorCount++;
|
|
4289
|
+
return ` ${item.separator}`;
|
|
4290
|
+
}
|
|
4291
|
+
const cursor = isActive ? theme.icon.cursor : " ";
|
|
4292
|
+
const indexLabel = theme.indexMode === "number" ? `${index + 1 - separatorCount}. ` : "";
|
|
4293
|
+
if (item.disabled) {
|
|
4294
|
+
const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
|
|
4295
|
+
const disabledCursor = isActive ? theme.icon.cursor : "-";
|
|
4296
|
+
return theme.style.disabled(`${disabledCursor} ${indexLabel}${item.name} ${disabledLabel}`);
|
|
4297
|
+
}
|
|
4298
|
+
const color = isActive ? theme.style.highlight : (x) => x;
|
|
4299
|
+
return color(`${cursor} ${indexLabel}${item.name}`);
|
|
4300
|
+
},
|
|
4301
|
+
pageSize,
|
|
4302
|
+
loop
|
|
4303
|
+
});
|
|
4304
|
+
if (status === "done") {
|
|
4305
|
+
return [prefix, message, theme.style.answer(selectedChoice.short)].filter(Boolean).join(" ");
|
|
4306
|
+
}
|
|
4307
|
+
const { description } = selectedChoice;
|
|
4308
|
+
const lines = [
|
|
4309
|
+
[prefix, message].filter(Boolean).join(" "),
|
|
4310
|
+
page,
|
|
4311
|
+
" ",
|
|
4312
|
+
description ? theme.style.description(description) : "",
|
|
4313
|
+
errorMsg ? theme.style.error(errorMsg) : "",
|
|
4314
|
+
helpLine
|
|
4315
|
+
].filter(Boolean).join("\n").trimEnd();
|
|
4316
|
+
return `${lines}${cursorHide}`;
|
|
4317
|
+
});
|
|
4318
|
+
const INIT_ACTION_LABELS = {
|
|
4319
|
+
configs: "Создать базовые конфиги",
|
|
4320
|
+
template: "Создать стартовый шаблон",
|
|
4321
|
+
agents: "Обновить AGENTS.md",
|
|
4322
|
+
mcp: "Добавить MCP-настройки",
|
|
4323
|
+
install: "Запустить установку зависимостей"
|
|
4324
|
+
};
|
|
4325
|
+
const INIT_ACTION_DESCRIPTIONS = {
|
|
4326
|
+
configs: "tsconfig.json, vite.config.ts, eslint.config.js и env.d.ts",
|
|
4327
|
+
template: "Vue-точка входа, страница настроек, виджет заказа, i18n и publish script",
|
|
4328
|
+
agents: "Общие и пакетные инструкции для AI-агентов",
|
|
4329
|
+
mcp: ".mcp.json и MCP-инструкции пакетов",
|
|
4330
|
+
install: "Запуск выбранного package manager после изменения package.json"
|
|
4331
|
+
};
|
|
4332
|
+
const resolveDefaultSourceRoot = (cwd, options) => {
|
|
4333
|
+
if (options.srcDir) {
|
|
4334
|
+
return options.srcDir;
|
|
4335
|
+
}
|
|
4336
|
+
if (options.target) {
|
|
4337
|
+
return options.target;
|
|
4338
|
+
}
|
|
4339
|
+
return fs.existsSync(path.join(cwd, "src")) ? "./web" : "./src";
|
|
4340
|
+
};
|
|
4341
|
+
const resolvePromptedPackages = async (options) => {
|
|
2280
4342
|
if (options.packages) {
|
|
2281
4343
|
return options.packages;
|
|
2282
4344
|
}
|
|
2283
4345
|
const defaultPackageIds = [...DEFAULT_INIT_PACKAGE_IDS, ...options.with ?? []];
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
4346
|
+
if (defaultPackageIds.includes("testing")) {
|
|
4347
|
+
throw new Error("@retailcrm/embed-ui-v1-testing is not published for public init yet");
|
|
4348
|
+
}
|
|
4349
|
+
const selectedPackageIds = await checkbox({
|
|
4350
|
+
message: "Пакеты для init",
|
|
4351
|
+
choices: INSTALLABLE_PACKAGES.filter((selectedPackage) => selectedPackage.id !== "testing").map((selectedPackage) => ({
|
|
4352
|
+
name: `${selectedPackage.id}: ${selectedPackage.name}`,
|
|
4353
|
+
value: selectedPackage.id,
|
|
4354
|
+
checked: defaultPackageIds.includes(selectedPackage.id),
|
|
4355
|
+
description: selectedPackage.description
|
|
4356
|
+
})),
|
|
4357
|
+
required: true
|
|
4358
|
+
});
|
|
4359
|
+
resolveInstallPackages(selectedPackageIds);
|
|
4360
|
+
return selectedPackageIds;
|
|
4361
|
+
};
|
|
4362
|
+
const resolveAvailableActions = (options) => {
|
|
4363
|
+
const actions = [];
|
|
4364
|
+
if (!options.agentsOnly && !options.noConfigs) {
|
|
4365
|
+
actions.push("configs");
|
|
2288
4366
|
}
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
}
|
|
2301
|
-
return tokens;
|
|
2302
|
-
} catch (error) {
|
|
2303
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
2304
|
-
}
|
|
4367
|
+
if (!options.agentsOnly && !options.noTemplate) {
|
|
4368
|
+
actions.push("template");
|
|
4369
|
+
}
|
|
4370
|
+
if (!options.noAgents) {
|
|
4371
|
+
actions.push("agents");
|
|
4372
|
+
}
|
|
4373
|
+
if (!options.noMcp) {
|
|
4374
|
+
actions.push("mcp");
|
|
4375
|
+
}
|
|
4376
|
+
if (!options.agentsOnly && !options.noInstall) {
|
|
4377
|
+
actions.push("install");
|
|
2305
4378
|
}
|
|
4379
|
+
return actions;
|
|
4380
|
+
};
|
|
4381
|
+
const applyPromptedActions = (options, selectedActions) => {
|
|
4382
|
+
const selectedActionSet = new Set(selectedActions);
|
|
4383
|
+
options.noConfigs = options.noConfigs || !selectedActionSet.has("configs");
|
|
4384
|
+
options.noTemplate = options.noTemplate || !selectedActionSet.has("template");
|
|
4385
|
+
options.noAgents = options.noAgents || !selectedActionSet.has("agents");
|
|
4386
|
+
options.noMcp = options.noMcp || !selectedActionSet.has("mcp");
|
|
4387
|
+
options.noInstall = options.noInstall || !selectedActionSet.has("install");
|
|
4388
|
+
};
|
|
4389
|
+
const resolvePromptedActions = async (options) => {
|
|
4390
|
+
const availableActions = resolveAvailableActions(options);
|
|
4391
|
+
if (availableActions.length === 0) {
|
|
4392
|
+
return [];
|
|
4393
|
+
}
|
|
4394
|
+
return checkbox({
|
|
4395
|
+
message: "Действия init",
|
|
4396
|
+
choices: availableActions.map((action) => ({
|
|
4397
|
+
name: INIT_ACTION_LABELS[action],
|
|
4398
|
+
value: action,
|
|
4399
|
+
checked: true,
|
|
4400
|
+
description: INIT_ACTION_DESCRIPTIONS[action]
|
|
4401
|
+
}))
|
|
4402
|
+
});
|
|
4403
|
+
};
|
|
4404
|
+
const resolvePromptedPackageManager = async (detectedPackageManager, explicitPackageManager) => {
|
|
4405
|
+
if (explicitPackageManager) {
|
|
4406
|
+
return explicitPackageManager;
|
|
4407
|
+
}
|
|
4408
|
+
const defaultPackageManager = detectedPackageManager ?? "npm";
|
|
4409
|
+
return select({
|
|
4410
|
+
message: "Package manager",
|
|
4411
|
+
default: defaultPackageManager,
|
|
4412
|
+
choices: PACKAGE_MANAGERS.map((packageManager) => ({
|
|
4413
|
+
name: packageManager,
|
|
4414
|
+
value: packageManager
|
|
4415
|
+
}))
|
|
4416
|
+
});
|
|
2306
4417
|
};
|
|
2307
4418
|
const resolveInteractiveInitOptions = async (cwd, options, detectedPackageManager) => {
|
|
2308
4419
|
if (!options.interactive) {
|
|
2309
4420
|
return options;
|
|
2310
4421
|
}
|
|
2311
|
-
if (!process$
|
|
4422
|
+
if (!process$2.stdin.isTTY || !process$2.stdout.isTTY) {
|
|
2312
4423
|
throw new Error("Interactive init mode requires a TTY. Use explicit flags or omit --interactive.");
|
|
2313
4424
|
}
|
|
2314
|
-
const
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
nextOptions.target = sourceRoot;
|
|
2327
|
-
}
|
|
2328
|
-
nextOptions.packages = await askPackages(readline, nextOptions);
|
|
2329
|
-
nextOptions.noConfigs = nextOptions.noConfigs || !await askBoolean(readline, "Создать базовые конфиги", true);
|
|
2330
|
-
nextOptions.noTemplate = nextOptions.noTemplate || !await askBoolean(readline, "Создать стартовый шаблон", true);
|
|
2331
|
-
}
|
|
2332
|
-
nextOptions.packageManager = await askPackageManager(
|
|
2333
|
-
readline,
|
|
2334
|
-
detectedPackageManager,
|
|
2335
|
-
nextOptions.packageManager
|
|
2336
|
-
);
|
|
2337
|
-
nextOptions.noAgents = nextOptions.noAgents || !await askBoolean(readline, "Обновить AGENTS.md", true);
|
|
2338
|
-
nextOptions.noMcp = nextOptions.noMcp || !await askBoolean(readline, "Добавить MCP-настройки", true);
|
|
2339
|
-
if (!nextOptions.agentsOnly) {
|
|
2340
|
-
nextOptions.noInstall = nextOptions.noInstall || !await askBoolean(readline, "Запустить установку зависимостей", true);
|
|
4425
|
+
const nextOptions = { ...options };
|
|
4426
|
+
if (!nextOptions.agentsOnly) {
|
|
4427
|
+
const defaultSourceRoot = resolveDefaultSourceRoot(cwd, nextOptions);
|
|
4428
|
+
const sourceRoot = await input({
|
|
4429
|
+
message: "Frontend source root",
|
|
4430
|
+
default: defaultSourceRoot,
|
|
4431
|
+
validate: (value) => value.trim().length > 0 || "Укажите каталог фронтенда."
|
|
4432
|
+
});
|
|
4433
|
+
if (nextOptions.srcDir) {
|
|
4434
|
+
nextOptions.srcDir = sourceRoot;
|
|
4435
|
+
} else {
|
|
4436
|
+
nextOptions.target = sourceRoot;
|
|
2341
4437
|
}
|
|
2342
|
-
|
|
2343
|
-
} finally {
|
|
2344
|
-
readline.close();
|
|
4438
|
+
nextOptions.packages = await resolvePromptedPackages(nextOptions);
|
|
2345
4439
|
}
|
|
4440
|
+
const selectedActions = await resolvePromptedActions(nextOptions);
|
|
4441
|
+
applyPromptedActions(nextOptions, selectedActions);
|
|
4442
|
+
nextOptions.packageManager = await resolvePromptedPackageManager(
|
|
4443
|
+
detectedPackageManager,
|
|
4444
|
+
nextOptions.packageManager
|
|
4445
|
+
);
|
|
4446
|
+
return nextOptions;
|
|
2346
4447
|
};
|
|
2347
4448
|
const DEFAULT_INIT_DIRS = ["endpoint", "pages", "widgets", "shared", "i18n"];
|
|
2348
4449
|
const detectPackageManagerByLockfile = (cwd) => {
|
|
@@ -2366,20 +4467,20 @@ const resolvePackageManagerVersion = (packageManager) => {
|
|
|
2366
4467
|
}
|
|
2367
4468
|
};
|
|
2368
4469
|
const promptForPackageManager = async () => {
|
|
2369
|
-
const
|
|
2370
|
-
input: process$
|
|
2371
|
-
output: process$
|
|
4470
|
+
const readline2 = createInterface({
|
|
4471
|
+
input: process$2.stdin,
|
|
4472
|
+
output: process$2.stdout
|
|
2372
4473
|
});
|
|
2373
4474
|
try {
|
|
2374
4475
|
while (true) {
|
|
2375
|
-
const answer = await
|
|
4476
|
+
const answer = await readline2.question("Choose package manager (yarn/npm/pnpm/bun): ");
|
|
2376
4477
|
if (PACKAGE_MANAGERS.includes(answer)) {
|
|
2377
4478
|
return answer;
|
|
2378
4479
|
}
|
|
2379
4480
|
console.error(`Unknown package manager: ${answer}`);
|
|
2380
4481
|
}
|
|
2381
4482
|
} finally {
|
|
2382
|
-
|
|
4483
|
+
readline2.close();
|
|
2383
4484
|
}
|
|
2384
4485
|
};
|
|
2385
4486
|
const resolvePackageManager = async (cwd, explicitPackageManager) => {
|
|
@@ -2393,7 +4494,7 @@ const resolvePackageManager = async (cwd, explicitPackageManager) => {
|
|
|
2393
4494
|
if (packageManager) {
|
|
2394
4495
|
return packageManager;
|
|
2395
4496
|
}
|
|
2396
|
-
if (process$
|
|
4497
|
+
if (process$2.stdin.isTTY && process$2.stdout.isTTY) {
|
|
2397
4498
|
return promptForPackageManager();
|
|
2398
4499
|
}
|
|
2399
4500
|
return "npm";
|
|
@@ -2627,23 +4728,24 @@ const runInit = async (options) => {
|
|
|
2627
4728
|
throw new Error(`Target path is not a directory: ${sourceRoot}`);
|
|
2628
4729
|
}
|
|
2629
4730
|
const selectedPackages = resolveInitPackages(interactiveOptions.packages, interactiveOptions.with);
|
|
2630
|
-
const version = interactiveOptions.agentsOnly ? interactiveOptions.version ?? "not used" : interactiveOptions.version ??
|
|
4731
|
+
const version = interactiveOptions.agentsOnly ? interactiveOptions.version ?? "not used" : interactiveOptions.version ?? resolveDefaultInitVersion();
|
|
4732
|
+
const resolvedOptions = version === "not used" ? interactiveOptions : { ...interactiveOptions, version };
|
|
2631
4733
|
const packageManager = interactiveOptions.agentsOnly ? interactiveOptions.packageManager ?? detectPackageManagerByLockfile(cwd) ?? "npm" : await resolvePackageManager(cwd, interactiveOptions.packageManager);
|
|
2632
4734
|
const changes = createInitChanges();
|
|
2633
|
-
applyInitPreflight(cwd, sourceRoot, packageManager, selectedPackages, version,
|
|
4735
|
+
applyInitPreflight(cwd, sourceRoot, packageManager, selectedPackages, version, resolvedOptions, changes);
|
|
2634
4736
|
let packageJsonPath = null;
|
|
2635
|
-
if (!
|
|
2636
|
-
packageJsonPath = applyInitPackageJson(cwd, selectedPackages, version, packageManager,
|
|
2637
|
-
applyInitDirectories(sourceRoot,
|
|
2638
|
-
applyInitConfigs(cwd, sourceRoot,
|
|
2639
|
-
applyInitTemplate(cwd, sourceRoot, packageManager,
|
|
2640
|
-
applyInitPackageConfigHooks(cwd, selectedPackages, packageManager,
|
|
2641
|
-
}
|
|
2642
|
-
applyInitAgents(cwd, selectedPackages, packageManager,
|
|
2643
|
-
runInstall(cwd, packageManager,
|
|
2644
|
-
printInitReport(cwd, sourceRoot, version, packageManager, changes,
|
|
2645
|
-
};
|
|
2646
|
-
const main = async (argv = process$
|
|
4737
|
+
if (!resolvedOptions.agentsOnly) {
|
|
4738
|
+
packageJsonPath = applyInitPackageJson(cwd, selectedPackages, version, packageManager, resolvedOptions, changes);
|
|
4739
|
+
applyInitDirectories(sourceRoot, resolvedOptions, changes);
|
|
4740
|
+
applyInitConfigs(cwd, sourceRoot, resolvedOptions, changes);
|
|
4741
|
+
applyInitTemplate(cwd, sourceRoot, packageManager, resolvedOptions, changes);
|
|
4742
|
+
applyInitPackageConfigHooks(cwd, selectedPackages, packageManager, resolvedOptions, changes);
|
|
4743
|
+
}
|
|
4744
|
+
applyInitAgents(cwd, selectedPackages, packageManager, resolvedOptions, changes);
|
|
4745
|
+
runInstall(cwd, packageManager, resolvedOptions, changes, Boolean(packageJsonPath && changes.packageJson.length > 0));
|
|
4746
|
+
printInitReport(cwd, sourceRoot, version, packageManager, changes, resolvedOptions);
|
|
4747
|
+
};
|
|
4748
|
+
const main = async (argv = process$2.argv.slice(2)) => {
|
|
2647
4749
|
const options = parseArgs(argv);
|
|
2648
4750
|
if (options.command === "init") {
|
|
2649
4751
|
await runInit(options);
|
|
@@ -2655,12 +4757,19 @@ const main = async (argv = process$1.argv.slice(2)) => {
|
|
|
2655
4757
|
}
|
|
2656
4758
|
runUpdate(options);
|
|
2657
4759
|
};
|
|
4760
|
+
const isSameExecutablePath = (entryPath, moduleUrl) => {
|
|
4761
|
+
try {
|
|
4762
|
+
return fs.realpathSync(entryPath) === fs.realpathSync(fileURLToPath(moduleUrl));
|
|
4763
|
+
} catch {
|
|
4764
|
+
return false;
|
|
4765
|
+
}
|
|
4766
|
+
};
|
|
2658
4767
|
const isExecutedDirectly = () => {
|
|
2659
|
-
const entryPath = process$
|
|
4768
|
+
const entryPath = process$2.argv[1];
|
|
2660
4769
|
if (!entryPath) {
|
|
2661
4770
|
return false;
|
|
2662
4771
|
}
|
|
2663
|
-
return
|
|
4772
|
+
return isSameExecutablePath(path.resolve(entryPath), import.meta.url);
|
|
2664
4773
|
};
|
|
2665
4774
|
if (isExecutedDirectly()) {
|
|
2666
4775
|
try {
|
|
@@ -2668,10 +4777,11 @@ if (isExecutedDirectly()) {
|
|
|
2668
4777
|
} catch (error) {
|
|
2669
4778
|
const message = error instanceof Error ? error.message : String(error);
|
|
2670
4779
|
console.error(message);
|
|
2671
|
-
process$
|
|
4780
|
+
process$2.exit(1);
|
|
2672
4781
|
}
|
|
2673
4782
|
}
|
|
2674
4783
|
export {
|
|
4784
|
+
isSameExecutablePath,
|
|
2675
4785
|
main,
|
|
2676
4786
|
parseArgs,
|
|
2677
4787
|
parseInitArgs,
|