@bemoje/cli 2.0.1 → 2.0.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/index.mjs +453 -296
- package/index.mjs.map +4 -4
- package/lib/Command.d.ts +69 -45
- package/lib/Help.d.ts +4 -1
- package/lib/helpers/findOption.d.ts +2 -1
- package/lib/internal/validateParsed.d.ts +2 -1
- package/lib/types.d.ts +4 -1
- package/package.json +2 -9
package/index.mjs
CHANGED
|
@@ -20,18 +20,20 @@ __export(Command_exports, {
|
|
|
20
20
|
Command: () => Command
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
23
|
+
// src/lib/Help.ts
|
|
24
|
+
var Help_exports = {};
|
|
25
|
+
__export(Help_exports, {
|
|
26
|
+
Help: () => Help
|
|
27
|
+
});
|
|
28
|
+
import C from "ansi-colors";
|
|
29
29
|
|
|
30
|
-
// ../
|
|
31
|
-
function
|
|
32
|
-
|
|
30
|
+
// ../decorators/src/assertDescriptorValueIsFunction.ts
|
|
31
|
+
function assertDescriptorValueIsFunction(key, descriptor) {
|
|
32
|
+
if (!(typeof descriptor.value === "function" && descriptor.value !== Function.prototype)) {
|
|
33
|
+
throw new TypeError(`"value" not a function for ${key} with descriptor: ${JSON.stringify(descriptor)}.`);
|
|
34
|
+
}
|
|
33
35
|
}
|
|
34
|
-
__name(
|
|
36
|
+
__name(assertDescriptorValueIsFunction, "assertDescriptorValueIsFunction");
|
|
35
37
|
|
|
36
38
|
// ../object/src/entriesOf.ts
|
|
37
39
|
function entriesOf(obj) {
|
|
@@ -45,17 +47,6 @@ function keysOf(obj) {
|
|
|
45
47
|
}
|
|
46
48
|
__name(keysOf, "keysOf");
|
|
47
49
|
|
|
48
|
-
// ../object/src/defineValue.ts
|
|
49
|
-
function defineValue(obj, key, value, des = {}) {
|
|
50
|
-
return Object.defineProperty(obj, key, {
|
|
51
|
-
configurable: true,
|
|
52
|
-
value,
|
|
53
|
-
enumerable: true,
|
|
54
|
-
...des
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
__name(defineValue, "defineValue");
|
|
58
|
-
|
|
59
50
|
// ../object/src/filterObject.ts
|
|
60
51
|
function filterObject(obj, predicate) {
|
|
61
52
|
const accum = {};
|
|
@@ -68,10 +59,32 @@ function filterObject(obj, predicate) {
|
|
|
68
59
|
}
|
|
69
60
|
__name(filterObject, "filterObject");
|
|
70
61
|
|
|
62
|
+
// ../object/src/objSortKeys.ts
|
|
63
|
+
function objSortKeys(o, compare) {
|
|
64
|
+
const entries = Object.entries(o);
|
|
65
|
+
if (compare) {
|
|
66
|
+
entries.sort(compare);
|
|
67
|
+
} else {
|
|
68
|
+
entries.sort((a, b) => {
|
|
69
|
+
return a[0].localeCompare(b[0]);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return Object.fromEntries(entries);
|
|
73
|
+
}
|
|
74
|
+
__name(objSortKeys, "objSortKeys");
|
|
75
|
+
|
|
76
|
+
// ../object/src/valuesOf.ts
|
|
77
|
+
function valuesOf(obj) {
|
|
78
|
+
return Object.values(obj);
|
|
79
|
+
}
|
|
80
|
+
__name(valuesOf, "valuesOf");
|
|
81
|
+
|
|
71
82
|
// ../map/src/mapGetOrDefault.ts
|
|
72
83
|
function mapGetOrDefault(map, key, factory) {
|
|
73
84
|
let value = map.get(key);
|
|
74
|
-
if (value !== void 0 || map.has(key))
|
|
85
|
+
if (value !== void 0 || map.has(key)) {
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
75
88
|
value = factory(key, map);
|
|
76
89
|
map.set(key, value);
|
|
77
90
|
return value;
|
|
@@ -98,7 +111,9 @@ var TimeoutWeakMap = class {
|
|
|
98
111
|
*/
|
|
99
112
|
get(key) {
|
|
100
113
|
const vt = this.wmap.get(key);
|
|
101
|
-
if (!vt)
|
|
114
|
+
if (!vt) {
|
|
115
|
+
return void 0;
|
|
116
|
+
}
|
|
102
117
|
const [value, timeout] = vt;
|
|
103
118
|
timeout.refresh();
|
|
104
119
|
return value;
|
|
@@ -128,7 +143,9 @@ var TimeoutWeakMap = class {
|
|
|
128
143
|
*/
|
|
129
144
|
delete(key) {
|
|
130
145
|
const vt = this.wmap.get(key);
|
|
131
|
-
if (!vt)
|
|
146
|
+
if (!vt) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
132
149
|
const timeout = vt[1];
|
|
133
150
|
clearTimeout(timeout);
|
|
134
151
|
return this.wmap.delete(key);
|
|
@@ -189,150 +206,8 @@ var TimeoutWeakMap = class {
|
|
|
189
206
|
}
|
|
190
207
|
};
|
|
191
208
|
|
|
192
|
-
// ../object/src/objSortKeys.ts
|
|
193
|
-
function objSortKeys(o, compare) {
|
|
194
|
-
const entries = Object.entries(o);
|
|
195
|
-
if (compare) entries.sort(compare);
|
|
196
|
-
else entries.sort((a, b) => a[0].localeCompare(b[0]));
|
|
197
|
-
return Object.fromEntries(entries);
|
|
198
|
-
}
|
|
199
|
-
__name(objSortKeys, "objSortKeys");
|
|
200
|
-
|
|
201
|
-
// ../object/src/valuesOf.ts
|
|
202
|
-
function valuesOf(obj) {
|
|
203
|
-
return Object.values(obj);
|
|
204
|
-
}
|
|
205
|
-
__name(valuesOf, "valuesOf");
|
|
206
|
-
|
|
207
|
-
// ../fn/src/setName.ts
|
|
208
|
-
function setName(name, target) {
|
|
209
|
-
return defineValue(target, "name", typeof name === "string" ? name : name.name, { enumerable: false });
|
|
210
|
-
}
|
|
211
|
-
__name(setName, "setName");
|
|
212
|
-
|
|
213
|
-
// src/lib/internal/collectVariadicOptionValues.ts
|
|
214
|
-
function collectVariadicOptionValues(parsed, options) {
|
|
215
|
-
for (let i = 0; i < parsed.tokens.length; i++) {
|
|
216
|
-
const token = parsed.tokens[i];
|
|
217
|
-
if (token.kind !== "option") continue;
|
|
218
|
-
const def = options.find((o) => o.name === token.name);
|
|
219
|
-
if (!def?.variadic || def.type !== "string") continue;
|
|
220
|
-
const values = [token.value];
|
|
221
|
-
let j = i + 1;
|
|
222
|
-
while (j < parsed.tokens.length && parsed.tokens[j].kind === "positional") {
|
|
223
|
-
const positionalToken = parsed.tokens[j];
|
|
224
|
-
values.push(positionalToken.value);
|
|
225
|
-
const posIndex = parsed.positionals.indexOf(positionalToken.value);
|
|
226
|
-
if (posIndex !== -1) parsed.positionals.splice(posIndex, 1);
|
|
227
|
-
j++;
|
|
228
|
-
}
|
|
229
|
-
Reflect.set(
|
|
230
|
-
parsed.values,
|
|
231
|
-
token.name,
|
|
232
|
-
values.filter((v) => v !== void 0)
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
__name(collectVariadicOptionValues, "collectVariadicOptionValues");
|
|
237
|
-
|
|
238
|
-
// src/lib/internal/mergeOptionDefaults.ts
|
|
239
|
-
function mergeOptionDefaults(values, options) {
|
|
240
|
-
for (const option of options) {
|
|
241
|
-
if (option.defaultValue !== void 0 && option.name in values) {
|
|
242
|
-
values[option.name] ??= option.defaultValue;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
__name(mergeOptionDefaults, "mergeOptionDefaults");
|
|
247
|
-
|
|
248
|
-
// src/lib/internal/normalizeArgv.ts
|
|
249
|
-
function normalizeArgv(argv, options) {
|
|
250
|
-
for (const o of options) {
|
|
251
|
-
if (o.long === o.name) continue;
|
|
252
|
-
argv = argv.map((a) => {
|
|
253
|
-
if (a === `--${o.long}`) return `--${o.name}`;
|
|
254
|
-
if (a === `--no-${o.long}`) return `--no-${o.name}`;
|
|
255
|
-
return a;
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
return argv;
|
|
259
|
-
}
|
|
260
|
-
__name(normalizeArgv, "normalizeArgv");
|
|
261
|
-
|
|
262
|
-
// src/lib/internal/resolveArguments.ts
|
|
263
|
-
function resolveArguments(positionals, args) {
|
|
264
|
-
const result = args.map((arg, index) => {
|
|
265
|
-
if (arg.variadic) {
|
|
266
|
-
const remaining = positionals.slice(index);
|
|
267
|
-
return remaining.length > 0 ? remaining : arg.defaultValue;
|
|
268
|
-
}
|
|
269
|
-
return positionals[index] ?? arg.defaultValue;
|
|
270
|
-
});
|
|
271
|
-
while (result.length && arrLast(result) === void 0) result.pop();
|
|
272
|
-
return result;
|
|
273
|
-
}
|
|
274
|
-
__name(resolveArguments, "resolveArguments");
|
|
275
|
-
|
|
276
|
-
// src/lib/internal/validateParsed.ts
|
|
277
|
-
function validateParsed(args, optionValues, argDefs, optionDefs) {
|
|
278
|
-
return argDefs.map((def, index) => {
|
|
279
|
-
const value = args[index];
|
|
280
|
-
if (def.required) {
|
|
281
|
-
if (def.variadic ? Array.isArray(value) && value.length === 0 : value === void 0) {
|
|
282
|
-
return `Missing argument [${index}] ${def.usage}`;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
if (def.choices && value !== void 0) {
|
|
286
|
-
if (![value].flat().every((v) => def.choices.includes(v))) {
|
|
287
|
-
return `Invalid argument [${index}] ${def.usage}: Got \`${value}\`. Accepted values: [${def.choices.map((c) => `\`${c}\``).join(",")}]`;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}).concat(
|
|
291
|
-
entriesOf(optionValues).map(([key, value]) => {
|
|
292
|
-
const def = optionDefs.find((o) => o.name === key);
|
|
293
|
-
if (!def) return `Unknown option --${key}`;
|
|
294
|
-
if (def.choices && value !== void 0) {
|
|
295
|
-
if (!(def.variadic ? value : [value]).every((v) => def.choices.includes(v))) {
|
|
296
|
-
return `Invalid option value ${def.flags}: Got \`${value}\`. Accepted values: [${def.choices.map((c) => `\`${c}\``).join(",")}]`;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
})
|
|
300
|
-
).filter((s) => s !== void 0).reduce(
|
|
301
|
-
(acc, curr) => {
|
|
302
|
-
return (acc ?? []).concat(curr);
|
|
303
|
-
},
|
|
304
|
-
void 0
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
__name(validateParsed, "validateParsed");
|
|
308
|
-
|
|
309
|
-
// ../string/src/lib/strFirstCharToUpperCase.ts
|
|
310
|
-
function strFirstCharToUpperCase(string) {
|
|
311
|
-
return string.charAt(0).toUpperCase() + string.substring(1);
|
|
312
|
-
}
|
|
313
|
-
__name(strFirstCharToUpperCase, "strFirstCharToUpperCase");
|
|
314
|
-
|
|
315
|
-
// src/lib/Command.ts
|
|
316
|
-
import colors3 from "ansi-colors";
|
|
317
|
-
import { inspect, parseArgs } from "node:util";
|
|
318
|
-
|
|
319
|
-
// src/lib/Help.ts
|
|
320
|
-
var Help_exports = {};
|
|
321
|
-
__export(Help_exports, {
|
|
322
|
-
Help: () => Help
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
// ../decorators/src/assertDescriptorValueIsFunction.ts
|
|
326
|
-
function assertDescriptorValueIsFunction(key, descriptor) {
|
|
327
|
-
if (!(typeof descriptor.value === "function" && descriptor.value !== Function.prototype)) {
|
|
328
|
-
throw new TypeError(`"value" not a function for ${key} with descriptor: ${JSON.stringify(descriptor)}.`);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
__name(assertDescriptorValueIsFunction, "assertDescriptorValueIsFunction");
|
|
332
|
-
|
|
333
209
|
// ../decorators/src/lazyProp.ts
|
|
334
210
|
import { isFunction } from "es-toolkit/predicate";
|
|
335
|
-
import { ms as ms2 } from "enhanced-ms";
|
|
336
211
|
|
|
337
212
|
// ../decorators/src/memoizeSync.ts
|
|
338
213
|
import memoizee from "memoizee";
|
|
@@ -340,7 +215,9 @@ import { ms } from "enhanced-ms";
|
|
|
340
215
|
function memoizeSync(arg = {}) {
|
|
341
216
|
const opts = typeof arg === "object" ? arg : { maxAge: typeof arg === "number" ? arg : ms(arg) };
|
|
342
217
|
return /* @__PURE__ */ __name(function decorator(target, key, descriptor) {
|
|
343
|
-
if (!descriptor)
|
|
218
|
+
if (!descriptor) {
|
|
219
|
+
throw new TypeError("descriptor is undefined");
|
|
220
|
+
}
|
|
344
221
|
const orig = descriptor.value;
|
|
345
222
|
assertDescriptorValueIsFunction(key, descriptor);
|
|
346
223
|
const options = { length: false, ...opts };
|
|
@@ -350,7 +227,9 @@ function memoizeSync(arg = {}) {
|
|
|
350
227
|
} else {
|
|
351
228
|
const wmap = /* @__PURE__ */ new WeakMap();
|
|
352
229
|
descriptor.value = function(...args) {
|
|
353
|
-
const memoized = mapGetOrDefault(wmap, this, () =>
|
|
230
|
+
const memoized = mapGetOrDefault(wmap, this, () => {
|
|
231
|
+
return memoizee(orig, options);
|
|
232
|
+
});
|
|
354
233
|
return memoized.apply(this, args);
|
|
355
234
|
};
|
|
356
235
|
}
|
|
@@ -360,6 +239,7 @@ function memoizeSync(arg = {}) {
|
|
|
360
239
|
__name(memoizeSync, "memoizeSync");
|
|
361
240
|
|
|
362
241
|
// ../decorators/src/lazyProp.ts
|
|
242
|
+
import { ms as ms2 } from "enhanced-ms";
|
|
363
243
|
function lazyProp(targetOrTimeout, key, descriptor) {
|
|
364
244
|
if (typeof targetOrTimeout === "number" || typeof targetOrTimeout === "string") {
|
|
365
245
|
const maxAge = typeof targetOrTimeout === "number" ? targetOrTimeout : ms2(targetOrTimeout);
|
|
@@ -375,7 +255,9 @@ function createLazyPropDecorator(map) {
|
|
|
375
255
|
const { get, value } = descriptor;
|
|
376
256
|
if (isFunction(get)) {
|
|
377
257
|
descriptor.get = function() {
|
|
378
|
-
return mapGetOrDefault(map, this, () =>
|
|
258
|
+
return mapGetOrDefault(map, this, () => {
|
|
259
|
+
return get.call(this);
|
|
260
|
+
});
|
|
379
261
|
};
|
|
380
262
|
return descriptor;
|
|
381
263
|
}
|
|
@@ -388,7 +270,6 @@ function createLazyPropDecorator(map) {
|
|
|
388
270
|
__name(createLazyPropDecorator, "createLazyPropDecorator");
|
|
389
271
|
|
|
390
272
|
// src/lib/Help.ts
|
|
391
|
-
import C from "ansi-colors";
|
|
392
273
|
var Help = class {
|
|
393
274
|
static {
|
|
394
275
|
__name(this, "Help");
|
|
@@ -406,7 +287,9 @@ var Help = class {
|
|
|
406
287
|
Object.defineProperty(this, "cmd", { enumerable: false });
|
|
407
288
|
}
|
|
408
289
|
visibleCommands() {
|
|
409
|
-
const res = Object.values(this.cmd.commands).filter((c) =>
|
|
290
|
+
const res = Object.values(this.cmd.commands).filter((c) => {
|
|
291
|
+
return !c.hidden;
|
|
292
|
+
});
|
|
410
293
|
if (this.sortSubcommands) {
|
|
411
294
|
res.sort((a, b) => {
|
|
412
295
|
return a.name.localeCompare(b.name);
|
|
@@ -424,12 +307,18 @@ var Help = class {
|
|
|
424
307
|
return getSortKey(a).localeCompare(getSortKey(b));
|
|
425
308
|
}
|
|
426
309
|
visibleOptions() {
|
|
427
|
-
const res = this.cmd.options.filter((option) =>
|
|
428
|
-
|
|
310
|
+
const res = this.cmd.options.filter((option) => {
|
|
311
|
+
return !option.hidden;
|
|
312
|
+
});
|
|
313
|
+
if (this.sortOptions) {
|
|
314
|
+
res.sort(this.compareOptions);
|
|
315
|
+
}
|
|
429
316
|
return res;
|
|
430
317
|
}
|
|
431
318
|
visibleArguments() {
|
|
432
|
-
if (this.cmd.arguments.find((argument) =>
|
|
319
|
+
if (this.cmd.arguments.find((argument) => {
|
|
320
|
+
return !!argument.description;
|
|
321
|
+
})) {
|
|
433
322
|
return [...this.cmd.arguments];
|
|
434
323
|
}
|
|
435
324
|
return [];
|
|
@@ -438,9 +327,11 @@ var Help = class {
|
|
|
438
327
|
* Get the command term to show in the list of subcommands.
|
|
439
328
|
*/
|
|
440
329
|
subcommandTerm(sub) {
|
|
441
|
-
const args = sub.arguments.map((arg) =>
|
|
442
|
-
|
|
443
|
-
(
|
|
330
|
+
const args = sub.arguments.map((arg) => {
|
|
331
|
+
return arg.usage;
|
|
332
|
+
}).join(" ");
|
|
333
|
+
return (sub.aliases[0] ? `${sub.aliases[0].padEnd(this.longestSubcommandAliasLength(), " ")} | ` : "") + sub.name + (sub.options.length ? ` ${this.usageDisplayOptionsAs}` : "") + // simplistic check for non-help option
|
|
334
|
+
(args ? ` ${args}` : "");
|
|
444
335
|
}
|
|
445
336
|
/**
|
|
446
337
|
* Get the option term to show in the list of options.
|
|
@@ -455,7 +346,12 @@ var Help = class {
|
|
|
455
346
|
return argument.name;
|
|
456
347
|
}
|
|
457
348
|
longestSubcommandAliasLength() {
|
|
458
|
-
return Math.max(
|
|
349
|
+
return Math.max(
|
|
350
|
+
0,
|
|
351
|
+
...this.visibleCommands().map((c) => {
|
|
352
|
+
return c.aliases[0]?.length || 0;
|
|
353
|
+
})
|
|
354
|
+
);
|
|
459
355
|
}
|
|
460
356
|
longestSubcommandTermLength() {
|
|
461
357
|
return this.visibleCommands().reduce((max, command) => {
|
|
@@ -478,15 +374,15 @@ var Help = class {
|
|
|
478
374
|
commandUsage() {
|
|
479
375
|
let path = "";
|
|
480
376
|
for (let ancestor = this.cmd.parent; ancestor; ancestor = ancestor.parent) {
|
|
481
|
-
path = ancestor.name
|
|
377
|
+
path = `${ancestor.name} ${path}`;
|
|
482
378
|
}
|
|
483
|
-
return
|
|
379
|
+
return `${path + this.cmd.name} ${[
|
|
484
380
|
...Object.keys(this.cmd.commands).length ? [this.usageDisplaySubcommandAs] : [],
|
|
485
381
|
...this.cmd.options.length ? [this.usageDisplayOptionsAs] : [],
|
|
486
382
|
...this.cmd.arguments.map((arg) => {
|
|
487
383
|
return arg.required ? arg.variadic ? `<${arg.name}...>` : `<${arg.name}>` : arg.variadic ? `[${arg.name}...]` : `[${arg.name}]`;
|
|
488
384
|
})
|
|
489
|
-
].join(" ")
|
|
385
|
+
].join(" ")}`.trim();
|
|
490
386
|
}
|
|
491
387
|
/**
|
|
492
388
|
* Get the description for the command.
|
|
@@ -515,7 +411,9 @@ var Help = class {
|
|
|
515
411
|
if (option.choices) {
|
|
516
412
|
extraInfo.push(
|
|
517
413
|
// use stringify to match the display of the default value
|
|
518
|
-
`choices: ${option.choices.map((choice) =>
|
|
414
|
+
`choices: ${option.choices.map((choice) => {
|
|
415
|
+
return String(choice);
|
|
416
|
+
}).join(", ")}`
|
|
519
417
|
);
|
|
520
418
|
}
|
|
521
419
|
if (option.defaultValue && !(Array.isArray(option.defaultValue) && option.defaultValue.length === 0)) {
|
|
@@ -541,7 +439,9 @@ var Help = class {
|
|
|
541
439
|
if (argument.choices) {
|
|
542
440
|
extraInfo.push(
|
|
543
441
|
// use stringify to match the display of the default value
|
|
544
|
-
`choices: ${argument.choices.map((choice) =>
|
|
442
|
+
`choices: ${argument.choices.map((choice) => {
|
|
443
|
+
return String(choice);
|
|
444
|
+
}).join(", ")}`
|
|
545
445
|
);
|
|
546
446
|
}
|
|
547
447
|
if (argument.defaultValue !== void 0) {
|
|
@@ -560,7 +460,9 @@ var Help = class {
|
|
|
560
460
|
* Format a list of items, given a heading and an array of formatted items.
|
|
561
461
|
*/
|
|
562
462
|
formatItemList(heading, items) {
|
|
563
|
-
if (items.length === 0)
|
|
463
|
+
if (items.length === 0) {
|
|
464
|
+
return [];
|
|
465
|
+
}
|
|
564
466
|
return [this.styleTitle(heading), ...items, ""];
|
|
565
467
|
}
|
|
566
468
|
/**
|
|
@@ -570,7 +472,9 @@ var Help = class {
|
|
|
570
472
|
const result = /* @__PURE__ */ new Map();
|
|
571
473
|
unsortedItems.forEach((item) => {
|
|
572
474
|
const group = getGroup(item);
|
|
573
|
-
if (!result.has(group))
|
|
475
|
+
if (!result.has(group)) {
|
|
476
|
+
result.set(group, []);
|
|
477
|
+
}
|
|
574
478
|
});
|
|
575
479
|
visibleItems.forEach((item) => {
|
|
576
480
|
const group = getGroup(item);
|
|
@@ -599,11 +503,21 @@ var Help = class {
|
|
|
599
503
|
*/
|
|
600
504
|
styleUsage(str) {
|
|
601
505
|
return str.split(" ").map((word, index, arr) => {
|
|
602
|
-
if (word === this.usageDisplaySubcommandAs)
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
if (word
|
|
606
|
-
|
|
506
|
+
if (word === this.usageDisplaySubcommandAs) {
|
|
507
|
+
return C.green(word);
|
|
508
|
+
}
|
|
509
|
+
if (word === this.usageDisplayOptionsAs) {
|
|
510
|
+
return C.blue(word);
|
|
511
|
+
}
|
|
512
|
+
if (word[0] === "<") {
|
|
513
|
+
return C.red(word);
|
|
514
|
+
}
|
|
515
|
+
if (word[0] === "[") {
|
|
516
|
+
return C.cyan(word);
|
|
517
|
+
}
|
|
518
|
+
if (arr[index + 1]?.startsWith("[")) {
|
|
519
|
+
return C.magenta(word);
|
|
520
|
+
}
|
|
607
521
|
return this.styleCommandText(word);
|
|
608
522
|
}).join(" ");
|
|
609
523
|
}
|
|
@@ -648,8 +562,12 @@ var Help = class {
|
|
|
648
562
|
*/
|
|
649
563
|
styleSubcommandTerm(str) {
|
|
650
564
|
const res = str.split(" ").map((word) => {
|
|
651
|
-
if (word === this.usageDisplayOptionsAs)
|
|
652
|
-
|
|
565
|
+
if (word === this.usageDisplayOptionsAs) {
|
|
566
|
+
return C.dim(word);
|
|
567
|
+
}
|
|
568
|
+
if (word[0] === "[" || word[0] === "<") {
|
|
569
|
+
return C.dim(word);
|
|
570
|
+
}
|
|
653
571
|
return this.styleSubcommandText(word);
|
|
654
572
|
}).join(" ");
|
|
655
573
|
const split = res.split("|");
|
|
@@ -712,7 +630,9 @@ var Help = class {
|
|
|
712
630
|
formatItem(term, termWidth, description) {
|
|
713
631
|
const itemIndent = 2;
|
|
714
632
|
const itemIndentStr = " ".repeat(itemIndent);
|
|
715
|
-
if (!description)
|
|
633
|
+
if (!description) {
|
|
634
|
+
return itemIndentStr + term;
|
|
635
|
+
}
|
|
716
636
|
const paddedTerm = term.padEnd(termWidth + term.length - this.displayWidth(term));
|
|
717
637
|
const spacerWidth = 2;
|
|
718
638
|
const helpWidth = this.helpWidth;
|
|
@@ -722,7 +642,8 @@ var Help = class {
|
|
|
722
642
|
formattedDescription = description;
|
|
723
643
|
} else {
|
|
724
644
|
const wrappedDescription = this.boxWrap(description, remainingWidth);
|
|
725
|
-
formattedDescription = wrappedDescription.replace(/\n/g,
|
|
645
|
+
formattedDescription = wrappedDescription.replace(/\n/g, `
|
|
646
|
+
${" ".repeat(termWidth + spacerWidth)}`);
|
|
726
647
|
}
|
|
727
648
|
return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
|
|
728
649
|
${itemIndentStr}`);
|
|
@@ -732,7 +653,9 @@ ${itemIndentStr}`);
|
|
|
732
653
|
* Wrapping is skipped if the width is less than `minWidthToWrap`.
|
|
733
654
|
*/
|
|
734
655
|
boxWrap(str, width) {
|
|
735
|
-
if (width < this.minWidthToWrap)
|
|
656
|
+
if (width < this.minWidthToWrap) {
|
|
657
|
+
return str;
|
|
658
|
+
}
|
|
736
659
|
const rawLines = str.split(/\r\n|\n/);
|
|
737
660
|
const chunkPattern = /[\s]*[^\s]+/g;
|
|
738
661
|
const wrappedLines = [];
|
|
@@ -777,11 +700,9 @@ ${itemIndentStr}`);
|
|
|
777
700
|
);
|
|
778
701
|
});
|
|
779
702
|
output = output.concat(this.formatItemList("Arguments:", argumentList));
|
|
780
|
-
const optionGroups = this.groupItems(
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
(option) => option.group ?? "Options:"
|
|
784
|
-
);
|
|
703
|
+
const optionGroups = this.groupItems(this.cmd.options, this.visibleOptions(), (option) => {
|
|
704
|
+
return option.group ?? "Options:";
|
|
705
|
+
});
|
|
785
706
|
optionGroups.forEach((options, group) => {
|
|
786
707
|
const optionList = options.map((option) => {
|
|
787
708
|
return this.formatItem(
|
|
@@ -795,7 +716,9 @@ ${itemIndentStr}`);
|
|
|
795
716
|
const commandGroups = this.groupItems(
|
|
796
717
|
Object.values(this.cmd.commands),
|
|
797
718
|
this.visibleCommands(),
|
|
798
|
-
(sub) =>
|
|
719
|
+
(sub) => {
|
|
720
|
+
return sub.group || "Commands:";
|
|
721
|
+
}
|
|
799
722
|
);
|
|
800
723
|
commandGroups.forEach((commands, group) => {
|
|
801
724
|
const commandList = commands.map((sub) => {
|
|
@@ -835,16 +758,87 @@ __decorateClass([
|
|
|
835
758
|
lazyProp
|
|
836
759
|
], Help.prototype, "padWidth", 1);
|
|
837
760
|
|
|
761
|
+
// ../array/src/arrLast.ts
|
|
762
|
+
function arrLast(array) {
|
|
763
|
+
if (!array.length) {
|
|
764
|
+
throw new Error("Cannot get last element of empty array.");
|
|
765
|
+
}
|
|
766
|
+
return array[array.length - 1];
|
|
767
|
+
}
|
|
768
|
+
__name(arrLast, "arrLast");
|
|
769
|
+
|
|
770
|
+
// ../array/src/arrRemoveDuplicates.ts
|
|
771
|
+
function arrRemoveDuplicates(array) {
|
|
772
|
+
return Array.from(new Set(array));
|
|
773
|
+
}
|
|
774
|
+
__name(arrRemoveDuplicates, "arrRemoveDuplicates");
|
|
775
|
+
|
|
776
|
+
// src/lib/internal/collectVariadicOptionValues.ts
|
|
777
|
+
function collectVariadicOptionValues(parsed, options) {
|
|
778
|
+
for (let i = 0; i < parsed.tokens.length; i++) {
|
|
779
|
+
const token = parsed.tokens[i];
|
|
780
|
+
if (token.kind !== "option") {
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
const def = options.find((o) => {
|
|
784
|
+
return o.name === token.name;
|
|
785
|
+
});
|
|
786
|
+
if (!def?.variadic || def.type !== "string") {
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
const values = [token.value];
|
|
790
|
+
let j = i + 1;
|
|
791
|
+
while (j < parsed.tokens.length && parsed.tokens[j].kind === "positional") {
|
|
792
|
+
const positionalToken = parsed.tokens[j];
|
|
793
|
+
values.push(positionalToken.value);
|
|
794
|
+
const posIndex = parsed.positionals.indexOf(positionalToken.value);
|
|
795
|
+
if (posIndex !== -1) {
|
|
796
|
+
parsed.positionals.splice(posIndex, 1);
|
|
797
|
+
}
|
|
798
|
+
j++;
|
|
799
|
+
}
|
|
800
|
+
Reflect.set(
|
|
801
|
+
parsed.values,
|
|
802
|
+
token.name,
|
|
803
|
+
values.filter((v) => {
|
|
804
|
+
return v !== void 0;
|
|
805
|
+
})
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
__name(collectVariadicOptionValues, "collectVariadicOptionValues");
|
|
810
|
+
|
|
811
|
+
// src/lib/Command.ts
|
|
812
|
+
import colors3 from "ansi-colors";
|
|
813
|
+
|
|
838
814
|
// src/lib/helpers/findCommand.ts
|
|
839
815
|
var findCommand_exports = {};
|
|
840
816
|
__export(findCommand_exports, {
|
|
841
817
|
findCommand: () => findCommand
|
|
842
818
|
});
|
|
843
819
|
function findCommand(cmd, nameOrAlias) {
|
|
844
|
-
return cmd.commands[nameOrAlias] ?? valuesOf(cmd.commands).find((c) =>
|
|
820
|
+
return cmd.commands[nameOrAlias] ?? valuesOf(cmd.commands).find((c) => {
|
|
821
|
+
return c.aliases.includes(nameOrAlias);
|
|
822
|
+
});
|
|
845
823
|
}
|
|
846
824
|
__name(findCommand, "findCommand");
|
|
847
825
|
|
|
826
|
+
// src/lib/helpers/findOption.ts
|
|
827
|
+
var findOption_exports = {};
|
|
828
|
+
__export(findOption_exports, {
|
|
829
|
+
findOption: () => findOption
|
|
830
|
+
});
|
|
831
|
+
function findOption(cmd, nameOrShortOrLong) {
|
|
832
|
+
return nameOrShortOrLong.startsWith("--") ? cmd.options.find((o) => {
|
|
833
|
+
return o.long === nameOrShortOrLong.slice(2);
|
|
834
|
+
}) : nameOrShortOrLong.startsWith("-") ? cmd.options.find((o) => {
|
|
835
|
+
return o.short === nameOrShortOrLong.slice(1);
|
|
836
|
+
}) : cmd.options.find((o) => {
|
|
837
|
+
return o.name === nameOrShortOrLong;
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
__name(findOption, "findOption");
|
|
841
|
+
|
|
848
842
|
// src/lib/helpers/getCommandAncestors.ts
|
|
849
843
|
var getCommandAncestors_exports = {};
|
|
850
844
|
__export(getCommandAncestors_exports, {
|
|
@@ -872,9 +866,102 @@ function getCommandAncestors(cmd) {
|
|
|
872
866
|
}
|
|
873
867
|
__name(getCommandAncestors, "getCommandAncestors");
|
|
874
868
|
|
|
869
|
+
// src/lib/Command.ts
|
|
870
|
+
import { inspect } from "node:util";
|
|
871
|
+
import { kebabCase } from "es-toolkit/string";
|
|
872
|
+
|
|
873
|
+
// src/lib/internal/mergeOptionDefaults.ts
|
|
874
|
+
function mergeOptionDefaults(values, options) {
|
|
875
|
+
for (const option of options) {
|
|
876
|
+
if (option.defaultValue !== void 0 && option.name in values) {
|
|
877
|
+
values[option.name] ??= option.defaultValue;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
__name(mergeOptionDefaults, "mergeOptionDefaults");
|
|
882
|
+
|
|
883
|
+
// src/lib/internal/normalizeArgv.ts
|
|
884
|
+
function normalizeArgv(argv, options) {
|
|
885
|
+
for (const o of options) {
|
|
886
|
+
if (o.long === o.name) {
|
|
887
|
+
continue;
|
|
888
|
+
}
|
|
889
|
+
argv = argv.map((a) => {
|
|
890
|
+
if (a === `--${o.long}`) {
|
|
891
|
+
return `--${o.name}`;
|
|
892
|
+
}
|
|
893
|
+
if (a === `--no-${o.long}`) {
|
|
894
|
+
return `--no-${o.name}`;
|
|
895
|
+
}
|
|
896
|
+
return a;
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
return argv;
|
|
900
|
+
}
|
|
901
|
+
__name(normalizeArgv, "normalizeArgv");
|
|
902
|
+
|
|
903
|
+
// src/lib/Command.ts
|
|
904
|
+
import { parseArgs } from "node:util";
|
|
905
|
+
|
|
906
|
+
// src/lib/helpers/parseOptionFlags.ts
|
|
907
|
+
var parseOptionFlags_exports = {};
|
|
908
|
+
__export(parseOptionFlags_exports, {
|
|
909
|
+
parseOptionFlags: () => parseOptionFlags
|
|
910
|
+
});
|
|
911
|
+
function parseOptionFlags(flags) {
|
|
912
|
+
const match = flags.match(/^-(.+?), --([a-zA-Z][\w-]*)(?:\s*(<(.+?)>|\[(.+?)\]))?$/);
|
|
913
|
+
if (!match) {
|
|
914
|
+
throw new Error(`Invalid option format: ${flags}`);
|
|
915
|
+
}
|
|
916
|
+
const short = match[1];
|
|
917
|
+
if (short.length !== 1) {
|
|
918
|
+
throw new Error(`Expected short name to be a single character. Got: -${short}`);
|
|
919
|
+
}
|
|
920
|
+
const long = match[2];
|
|
921
|
+
const argName = (match[4] || match[5])?.replace(/\.\.\.$/, "") || void 0;
|
|
922
|
+
const name = long.split("-").reduce((str, word) => {
|
|
923
|
+
return str + word[0].toUpperCase() + word.slice(1);
|
|
924
|
+
});
|
|
925
|
+
return { short, long, name, argName };
|
|
926
|
+
}
|
|
927
|
+
__name(parseOptionFlags, "parseOptionFlags");
|
|
928
|
+
|
|
929
|
+
// src/lib/internal/resolveArguments.ts
|
|
930
|
+
function resolveArguments(positionals, args) {
|
|
931
|
+
const result = args.map((arg, index) => {
|
|
932
|
+
if (arg.variadic) {
|
|
933
|
+
const remaining = positionals.slice(index);
|
|
934
|
+
return remaining.length > 0 ? remaining : arg.defaultValue;
|
|
935
|
+
}
|
|
936
|
+
return positionals[index] ?? arg.defaultValue;
|
|
937
|
+
});
|
|
938
|
+
while (result.length && arrLast(result) === void 0) {
|
|
939
|
+
result.pop();
|
|
940
|
+
}
|
|
941
|
+
return result;
|
|
942
|
+
}
|
|
943
|
+
__name(resolveArguments, "resolveArguments");
|
|
944
|
+
|
|
945
|
+
// ../fn/src/setName.ts
|
|
946
|
+
function setName(name, target) {
|
|
947
|
+
return Object.defineProperty(target, "name", {
|
|
948
|
+
value: typeof name === "string" ? name : name.name,
|
|
949
|
+
configurable: true,
|
|
950
|
+
enumerable: false
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
__name(setName, "setName");
|
|
954
|
+
|
|
955
|
+
// ../string/src/lib/strFirstCharToUpperCase.ts
|
|
956
|
+
function strFirstCharToUpperCase(string) {
|
|
957
|
+
return string.charAt(0).toUpperCase() + string.substring(1);
|
|
958
|
+
}
|
|
959
|
+
__name(strFirstCharToUpperCase, "strFirstCharToUpperCase");
|
|
960
|
+
|
|
875
961
|
// ../node/src/createLogger.ts
|
|
876
962
|
import colors from "ansi-colors";
|
|
877
|
-
import { isPrimitive
|
|
963
|
+
import { isPrimitive } from "es-toolkit/predicate";
|
|
964
|
+
import { isString } from "es-toolkit/predicate";
|
|
878
965
|
function createLogger(name) {
|
|
879
966
|
const NAME = name ? colors.dim.cyan(name) : name;
|
|
880
967
|
const START = [NAME, colors.dim.gray("[START]")].filter(Boolean);
|
|
@@ -887,13 +974,29 @@ function createLogger(name) {
|
|
|
887
974
|
const cyanArgs = createColoredArgs(colors.cyan);
|
|
888
975
|
const yellowArgs = createColoredArgs(colors.yellow);
|
|
889
976
|
return {
|
|
890
|
-
start: /* @__PURE__ */ __name((...args) =>
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
977
|
+
start: /* @__PURE__ */ __name((...args) => {
|
|
978
|
+
return console.info(...START, ...args);
|
|
979
|
+
}, "start"),
|
|
980
|
+
done: /* @__PURE__ */ __name((...args) => {
|
|
981
|
+
return console.info(...DONE, ...args);
|
|
982
|
+
}, "done"),
|
|
983
|
+
info: /* @__PURE__ */ __name((...args) => {
|
|
984
|
+
return console.info(...INFO, ...grayArgs(args));
|
|
985
|
+
}, "info"),
|
|
986
|
+
log: /* @__PURE__ */ __name((...args) => {
|
|
987
|
+
return console.log(...NAME ? [NAME, ...args] : args);
|
|
988
|
+
}, "log"),
|
|
989
|
+
warn: /* @__PURE__ */ __name((...args) => {
|
|
990
|
+
return console.warn(...WARN, ...yellowArgs(args));
|
|
991
|
+
}, "warn"),
|
|
992
|
+
debug: /* @__PURE__ */ __name((...args) => {
|
|
993
|
+
return console.debug(...DEBUG, ...cyanArgs(args));
|
|
994
|
+
}, "debug"),
|
|
995
|
+
error: /* @__PURE__ */ __name((...args) => {
|
|
996
|
+
return args.forEach((arg) => {
|
|
997
|
+
return console.error(...ERROR, arg);
|
|
998
|
+
});
|
|
999
|
+
}, "error")
|
|
897
1000
|
};
|
|
898
1001
|
}
|
|
899
1002
|
__name(createLogger, "createLogger");
|
|
@@ -917,9 +1020,9 @@ function createColoredArgs(colorFn) {
|
|
|
917
1020
|
__name(createColoredArgs, "createColoredArgs");
|
|
918
1021
|
|
|
919
1022
|
// ../node/src/timer.ts
|
|
920
|
-
import { isPromise } from "node:util/types";
|
|
921
1023
|
import colors2 from "ansi-colors";
|
|
922
1024
|
import humanizeDuration from "humanize-duration";
|
|
1025
|
+
import { isPromise } from "node:util/types";
|
|
923
1026
|
function timer(arg, task) {
|
|
924
1027
|
const t0 = process.hrtime.bigint();
|
|
925
1028
|
const [name, description] = Array.isArray(arg) ? arg : [arg, ""];
|
|
@@ -935,7 +1038,9 @@ function timer(arg, task) {
|
|
|
935
1038
|
return done(result);
|
|
936
1039
|
});
|
|
937
1040
|
function done(retval2) {
|
|
938
|
-
if (process.exitCode)
|
|
1041
|
+
if (process.exitCode) {
|
|
1042
|
+
return retval2;
|
|
1043
|
+
}
|
|
939
1044
|
const ns = process.hrtime.bigint() - t0;
|
|
940
1045
|
const ms3 = Math.floor(Number(ns) / 1e6);
|
|
941
1046
|
log.done(colors2.dim(humanizeDuration(ms3)));
|
|
@@ -945,68 +1050,83 @@ function timer(arg, task) {
|
|
|
945
1050
|
}
|
|
946
1051
|
__name(timer, "timer");
|
|
947
1052
|
|
|
948
|
-
// src/lib/
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1053
|
+
// src/lib/internal/validateParsed.ts
|
|
1054
|
+
function validateParsed(args, optionValues, argDefs, optionDefs) {
|
|
1055
|
+
return argDefs.map((def, index) => {
|
|
1056
|
+
const value = args[index];
|
|
1057
|
+
if (def.required) {
|
|
1058
|
+
if (def.variadic ? Array.isArray(value) && value.length === 0 : value === void 0) {
|
|
1059
|
+
return `Missing argument [${index}] ${def.usage}`;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
if (def.choices && value !== void 0) {
|
|
1063
|
+
if (![value].flat().every((v) => {
|
|
1064
|
+
return def.choices.includes(v);
|
|
1065
|
+
})) {
|
|
1066
|
+
return `Invalid argument [${index}] ${def.usage}: Got \`${value}\`. Accepted values: [${def.choices.map((c) => {
|
|
1067
|
+
return `\`${c}\``;
|
|
1068
|
+
}).join(",")}]`;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}).concat(
|
|
1072
|
+
entriesOf(optionValues).map(([key, value]) => {
|
|
1073
|
+
const def = optionDefs.find((o) => {
|
|
1074
|
+
return o.name === key;
|
|
1075
|
+
});
|
|
1076
|
+
if (!def) {
|
|
1077
|
+
return `Unknown option --${key}`;
|
|
1078
|
+
}
|
|
1079
|
+
if (def.choices && value !== void 0) {
|
|
1080
|
+
if (!(def.variadic ? value : [value]).every((v) => {
|
|
1081
|
+
return def.choices.includes(v);
|
|
1082
|
+
})) {
|
|
1083
|
+
return `Invalid option value ${def.flags}: Got \`${value}\`. Accepted values: [${def.choices.map((c) => {
|
|
1084
|
+
return `\`${c}\``;
|
|
1085
|
+
}).join(",")}]`;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
})
|
|
1089
|
+
).filter((s) => {
|
|
1090
|
+
return s !== void 0;
|
|
1091
|
+
}).reduce(
|
|
1092
|
+
(acc, curr) => {
|
|
1093
|
+
return (acc ?? []).concat(curr);
|
|
1094
|
+
},
|
|
1095
|
+
void 0
|
|
1096
|
+
);
|
|
976
1097
|
}
|
|
977
|
-
__name(
|
|
1098
|
+
__name(validateParsed, "validateParsed");
|
|
978
1099
|
|
|
979
1100
|
// src/lib/Command.ts
|
|
980
|
-
import { kebabCase } from "es-toolkit/string";
|
|
981
1101
|
var _Command = class _Command {
|
|
982
1102
|
static {
|
|
983
1103
|
__name(this, "Command");
|
|
984
1104
|
}
|
|
985
|
-
/**
|
|
1105
|
+
/** parent command in the hierarchy, undefined for root command */
|
|
986
1106
|
parent;
|
|
987
|
-
/**
|
|
1107
|
+
/** the command name used to invoke it */
|
|
988
1108
|
name;
|
|
989
|
-
/**
|
|
1109
|
+
/** semantic version string displayed by --version flag */
|
|
990
1110
|
version;
|
|
991
|
-
/**
|
|
1111
|
+
/** alternative names for invoking this command */
|
|
992
1112
|
aliases;
|
|
993
|
-
/**
|
|
1113
|
+
/** brief one-line description shown in command lists */
|
|
994
1114
|
summary;
|
|
995
|
-
/**
|
|
1115
|
+
/** full description displayed in help text */
|
|
996
1116
|
description;
|
|
997
|
-
/**
|
|
1117
|
+
/** whether to exclude from help listings */
|
|
998
1118
|
hidden;
|
|
999
|
-
/**
|
|
1119
|
+
/** category for organizing related commands in help output */
|
|
1000
1120
|
group;
|
|
1001
|
-
/**
|
|
1121
|
+
/** positional arguments this command accepts */
|
|
1002
1122
|
arguments;
|
|
1003
|
-
/**
|
|
1123
|
+
/** cLI options (flags) this command recognizes */
|
|
1004
1124
|
options;
|
|
1005
|
-
/**
|
|
1125
|
+
/** subcommands registered with this command */
|
|
1006
1126
|
commands;
|
|
1007
|
-
/**
|
|
1127
|
+
/** main action handler executed when command is invoked */
|
|
1008
1128
|
action;
|
|
1009
|
-
/**
|
|
1129
|
+
/** option-driven actions (e.g., --help, --version) executed when their conditions match */
|
|
1010
1130
|
hooks;
|
|
1011
1131
|
constructor(name, parent) {
|
|
1012
1132
|
this.name = name;
|
|
@@ -1031,31 +1151,35 @@ var _Command = class _Command {
|
|
|
1031
1151
|
get help() {
|
|
1032
1152
|
return new Help(this);
|
|
1033
1153
|
}
|
|
1034
|
-
/**
|
|
1154
|
+
/** configure how the help is rendered */
|
|
1035
1155
|
helpConfiguration(cb) {
|
|
1036
1156
|
const help = this.help;
|
|
1037
1157
|
cb?.(help);
|
|
1038
1158
|
return this;
|
|
1039
1159
|
}
|
|
1040
|
-
/**
|
|
1160
|
+
/** renders formatted help text using provided help definition */
|
|
1041
1161
|
renderHelp(config = {}) {
|
|
1042
1162
|
const result = this.help.render();
|
|
1043
1163
|
return config.noColor ? colors3.stripColor(result) : result;
|
|
1044
1164
|
}
|
|
1045
|
-
/**
|
|
1165
|
+
/** sets the command name */
|
|
1046
1166
|
setName(name) {
|
|
1047
1167
|
this.name = name;
|
|
1048
1168
|
}
|
|
1049
|
-
/**
|
|
1169
|
+
/** sets command aliases, flattening nested arrays */
|
|
1050
1170
|
setAliases(...aliases) {
|
|
1051
1171
|
this.aliases = [];
|
|
1052
1172
|
this.addAliases(...aliases);
|
|
1053
1173
|
return this;
|
|
1054
1174
|
}
|
|
1055
|
-
/**
|
|
1175
|
+
/** adds aliases to existing ones */
|
|
1056
1176
|
addAliases(...aliases) {
|
|
1057
|
-
const taken = this.parent ? valuesOf(this.parent.commands).flatMap((c) =>
|
|
1058
|
-
|
|
1177
|
+
const taken = this.parent ? valuesOf(this.parent.commands).flatMap((c) => {
|
|
1178
|
+
return [c.name, ...c.aliases];
|
|
1179
|
+
}) : [];
|
|
1180
|
+
arrRemoveDuplicates(aliases.flat()).filter((a) => {
|
|
1181
|
+
return !this.aliases.includes(a) && a !== this.name;
|
|
1182
|
+
}).forEach((a) => {
|
|
1059
1183
|
if (taken.includes(a)) {
|
|
1060
1184
|
throw new Error(
|
|
1061
1185
|
`Alias "${a}" is already used by a sibling command: ${findCommand(this.parent, a)?.name}`
|
|
@@ -1063,39 +1187,47 @@ var _Command = class _Command {
|
|
|
1063
1187
|
}
|
|
1064
1188
|
this.aliases.push(a);
|
|
1065
1189
|
});
|
|
1066
|
-
this.aliases.sort((a, b) =>
|
|
1190
|
+
this.aliases.sort((a, b) => {
|
|
1191
|
+
return a.length - b.length;
|
|
1192
|
+
});
|
|
1067
1193
|
return this;
|
|
1068
1194
|
}
|
|
1069
|
-
/**
|
|
1195
|
+
/** sets the command version */
|
|
1070
1196
|
setVersion(version) {
|
|
1071
1197
|
this.version = version;
|
|
1072
|
-
if (findOption(this, "version"))
|
|
1198
|
+
if (findOption(this, "version")) {
|
|
1199
|
+
return this;
|
|
1200
|
+
}
|
|
1073
1201
|
return this.addOption("-V, --version", { description: "Display semver version" }).addOptionHook("version", ({ cmd }) => {
|
|
1074
|
-
console.log(
|
|
1202
|
+
console.log(
|
|
1203
|
+
getCommandAndAncestors(cmd).find((c) => {
|
|
1204
|
+
return c.version;
|
|
1205
|
+
})?.version
|
|
1206
|
+
);
|
|
1075
1207
|
process.exitCode = 0;
|
|
1076
1208
|
});
|
|
1077
1209
|
}
|
|
1078
|
-
/**
|
|
1210
|
+
/** sets the command summary */
|
|
1079
1211
|
setSummary(summary) {
|
|
1080
1212
|
this.summary = summary;
|
|
1081
1213
|
return this;
|
|
1082
1214
|
}
|
|
1083
|
-
/**
|
|
1215
|
+
/** sets command description, joining variadic lines */
|
|
1084
1216
|
setDescription(...lines) {
|
|
1085
1217
|
this.description = lines.join("\n");
|
|
1086
1218
|
return this;
|
|
1087
1219
|
}
|
|
1088
|
-
/**
|
|
1220
|
+
/** sets whether command is hidden from help */
|
|
1089
1221
|
setHidden(hidden = true) {
|
|
1090
1222
|
this.hidden = hidden;
|
|
1091
1223
|
return this;
|
|
1092
1224
|
}
|
|
1093
|
-
/**
|
|
1225
|
+
/** sets the command group for help organization */
|
|
1094
1226
|
setGroup(group) {
|
|
1095
1227
|
this.group = group;
|
|
1096
1228
|
return this;
|
|
1097
1229
|
}
|
|
1098
|
-
/**
|
|
1230
|
+
/** add a subcommand and return the subcommand. All options are inherited by the subcommand. */
|
|
1099
1231
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1100
1232
|
command(name, cb) {
|
|
1101
1233
|
if (this.arguments.length) {
|
|
@@ -1106,21 +1238,33 @@ var _Command = class _Command {
|
|
|
1106
1238
|
const sub = this.createSubcommand(name);
|
|
1107
1239
|
const inherit = this.options;
|
|
1108
1240
|
sub.options.push(...inherit);
|
|
1109
|
-
const inheritHooks = this.hooks.filter((t) =>
|
|
1241
|
+
const inheritHooks = this.hooks.filter((t) => {
|
|
1242
|
+
return inherit.some((i) => {
|
|
1243
|
+
return i.name === t.name;
|
|
1244
|
+
});
|
|
1245
|
+
});
|
|
1110
1246
|
sub.hooks.push(...inheritHooks);
|
|
1111
|
-
const taken = valuesOf(this.commands).flatMap((c) =>
|
|
1247
|
+
const taken = valuesOf(this.commands).flatMap((c) => {
|
|
1248
|
+
return [c.name, ...c.aliases];
|
|
1249
|
+
});
|
|
1112
1250
|
if (taken.includes(name)) {
|
|
1113
1251
|
throw new Error(
|
|
1114
|
-
`Command name "${getCommandAndAncestors(sub).map((c) =>
|
|
1252
|
+
`Command name "${getCommandAndAncestors(sub).map((c) => {
|
|
1253
|
+
return c.name;
|
|
1254
|
+
})}" is already used by this command or its aliases: ${taken.join(", ")}`
|
|
1115
1255
|
);
|
|
1116
1256
|
}
|
|
1117
1257
|
const kebab = kebabCase(name);
|
|
1118
1258
|
const words = kebab.split("-");
|
|
1119
|
-
const initials = words.map((s) =>
|
|
1259
|
+
const initials = words.map((s) => {
|
|
1260
|
+
return s[0];
|
|
1261
|
+
}).join("");
|
|
1120
1262
|
if (!taken.includes(initials)) {
|
|
1121
1263
|
sub.addAliases(initials);
|
|
1122
1264
|
} else {
|
|
1123
|
-
const initials2 = words.map((s) =>
|
|
1265
|
+
const initials2 = words.map((s) => {
|
|
1266
|
+
return s[0] + s[1];
|
|
1267
|
+
}).join("");
|
|
1124
1268
|
if (!taken.includes(initials2)) {
|
|
1125
1269
|
sub.addAliases(initials2);
|
|
1126
1270
|
}
|
|
@@ -1128,13 +1272,13 @@ var _Command = class _Command {
|
|
|
1128
1272
|
this.commands[name] = sub;
|
|
1129
1273
|
return cb ? cb(sub, this) : sub;
|
|
1130
1274
|
}
|
|
1131
|
-
/**
|
|
1275
|
+
/** add a subcommand and return the subcommand. All options are inherited by the subcommand. */
|
|
1132
1276
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1133
1277
|
addCommand(name, cb) {
|
|
1134
1278
|
this.command(name, cb);
|
|
1135
1279
|
return this;
|
|
1136
1280
|
}
|
|
1137
|
-
//
|
|
1281
|
+
// implementation
|
|
1138
1282
|
addArgument(usage, options = {}) {
|
|
1139
1283
|
if (!/^<(.*?)>$|^\[(.*?)\]$/.test(usage)) {
|
|
1140
1284
|
throw new Error(`Invalid argument format: ${usage}`);
|
|
@@ -1168,7 +1312,7 @@ var _Command = class _Command {
|
|
|
1168
1312
|
return this;
|
|
1169
1313
|
}
|
|
1170
1314
|
/**
|
|
1171
|
-
*
|
|
1315
|
+
* adds command-line option with type inference. Parses format: `-s, --long [<value>|[value]|<value...>|[value...]]`
|
|
1172
1316
|
*/
|
|
1173
1317
|
addOption(flags, opts = {}) {
|
|
1174
1318
|
const ins = {};
|
|
@@ -1206,7 +1350,9 @@ var _Command = class _Command {
|
|
|
1206
1350
|
}
|
|
1207
1351
|
}
|
|
1208
1352
|
for (const [key, value] of Object.entries(opts)) {
|
|
1209
|
-
if (value !== void 0)
|
|
1353
|
+
if (value !== void 0) {
|
|
1354
|
+
Reflect.set(ins, key, value);
|
|
1355
|
+
}
|
|
1210
1356
|
}
|
|
1211
1357
|
if (ins.env && ins.defaultValue === void 0 && typeof process.env[ins.env] === "string") {
|
|
1212
1358
|
ins.required = false;
|
|
@@ -1214,7 +1360,9 @@ var _Command = class _Command {
|
|
|
1214
1360
|
if (ins.type === "boolean") {
|
|
1215
1361
|
ins.defaultValue = /^(t(rue)?|y(es)?|1)$/i.test(process.env[ins.env]);
|
|
1216
1362
|
} else if (ins.variadic) {
|
|
1217
|
-
ins.defaultValue = process.env[ins.env].replace(/\]|\[/, "").split(",").map((v) =>
|
|
1363
|
+
ins.defaultValue = process.env[ins.env].replace(/\]|\[/, "").split(",").map((v) => {
|
|
1364
|
+
return v.trim();
|
|
1365
|
+
});
|
|
1218
1366
|
} else {
|
|
1219
1367
|
ins.defaultValue = process.env[ins.env];
|
|
1220
1368
|
}
|
|
@@ -1223,7 +1371,7 @@ var _Command = class _Command {
|
|
|
1223
1371
|
return this;
|
|
1224
1372
|
}
|
|
1225
1373
|
/**
|
|
1226
|
-
*
|
|
1374
|
+
* register an action to be invoked when an option is set to true or string value.
|
|
1227
1375
|
*
|
|
1228
1376
|
* Hooks execute in addition to or instead of the main action handler,
|
|
1229
1377
|
* allowing for option-driven behavior. For example, `--help` and `--version`
|
|
@@ -1236,25 +1384,26 @@ var _Command = class _Command {
|
|
|
1236
1384
|
}
|
|
1237
1385
|
this.hooks.push({
|
|
1238
1386
|
name: optionName,
|
|
1239
|
-
predicate: setName(
|
|
1387
|
+
predicate: setName(`has${strFirstCharToUpperCase(optionName)}`, ({ opts }) => {
|
|
1240
1388
|
return opts[optionName] !== void 0 && opts[optionName] !== false && !(Array.isArray(opts[optionName]) && opts[optionName].length === 0);
|
|
1241
1389
|
}),
|
|
1242
1390
|
action: setName(optionName, action)
|
|
1243
1391
|
});
|
|
1244
1392
|
return this;
|
|
1245
1393
|
}
|
|
1246
|
-
/**
|
|
1394
|
+
/** parses command-line arguments with subcommand support and type-safe validation. */
|
|
1247
1395
|
parseArgv(argv = process.argv.slice(2)) {
|
|
1248
1396
|
const sub = findCommand(this, argv[0]);
|
|
1249
|
-
if (sub)
|
|
1397
|
+
if (sub) {
|
|
1398
|
+
return sub.parseArgv(argv.slice(1));
|
|
1399
|
+
}
|
|
1250
1400
|
argv = normalizeArgv(argv, this.options);
|
|
1251
1401
|
const parsed = parseArgs({
|
|
1252
1402
|
args: argv,
|
|
1253
1403
|
options: Object.fromEntries(
|
|
1254
|
-
this.options.map((o) =>
|
|
1255
|
-
o.name,
|
|
1256
|
-
|
|
1257
|
-
])
|
|
1404
|
+
this.options.map((o) => {
|
|
1405
|
+
return [o.name, { type: o.type, short: o.short, default: o.defaultValue, multiple: !!o.variadic }];
|
|
1406
|
+
})
|
|
1258
1407
|
),
|
|
1259
1408
|
allowPositionals: true,
|
|
1260
1409
|
tokens: true,
|
|
@@ -1267,9 +1416,13 @@ var _Command = class _Command {
|
|
|
1267
1416
|
return a[1] === false ? 1 : b[1] === false ? -1 : a[1] === true ? 1 : b[1] === true ? -1 : 0;
|
|
1268
1417
|
});
|
|
1269
1418
|
const args = resolveArguments(parsed.positionals, this.arguments);
|
|
1270
|
-
const opts = filterObject(parsed.values, (value) =>
|
|
1419
|
+
const opts = filterObject(parsed.values, (value) => {
|
|
1420
|
+
return value !== void 0;
|
|
1421
|
+
});
|
|
1271
1422
|
const errors = validateParsed(args, parsed.values, this.arguments, this.options);
|
|
1272
|
-
const path = getCommandAncestors(this).map((c) =>
|
|
1423
|
+
const path = getCommandAncestors(this).map((c) => {
|
|
1424
|
+
return c.name;
|
|
1425
|
+
});
|
|
1273
1426
|
const data = {
|
|
1274
1427
|
path,
|
|
1275
1428
|
name: this.name,
|
|
@@ -1279,17 +1432,21 @@ var _Command = class _Command {
|
|
|
1279
1432
|
errors,
|
|
1280
1433
|
cmd: this
|
|
1281
1434
|
};
|
|
1282
|
-
const hooks = this.hooks.filter((t) =>
|
|
1435
|
+
const hooks = this.hooks.filter((t) => {
|
|
1436
|
+
return t.predicate(data);
|
|
1437
|
+
});
|
|
1283
1438
|
const execute = /* @__PURE__ */ __name(async () => {
|
|
1284
1439
|
for (const hook of hooks) {
|
|
1285
1440
|
await hook.action(data);
|
|
1286
|
-
if (process.exitCode) {
|
|
1441
|
+
if (process.exitCode !== void 0) {
|
|
1287
1442
|
return;
|
|
1288
1443
|
}
|
|
1289
1444
|
}
|
|
1290
1445
|
await timer([[...path, this.name].join(" "), this.description], async (logger) => {
|
|
1291
1446
|
if (errors) {
|
|
1292
|
-
errors.forEach((msg) =>
|
|
1447
|
+
errors.forEach((msg) => {
|
|
1448
|
+
return logger.error(colors3.red(msg));
|
|
1449
|
+
});
|
|
1293
1450
|
process.exitCode = 1;
|
|
1294
1451
|
return;
|
|
1295
1452
|
}
|
|
@@ -1308,14 +1465,14 @@ var _Command = class _Command {
|
|
|
1308
1465
|
return { ...data, hooks, execute };
|
|
1309
1466
|
}
|
|
1310
1467
|
/**
|
|
1311
|
-
*
|
|
1468
|
+
* sets the main action handler for this command, which is executed after any matching option hooks when the command is invoked.
|
|
1312
1469
|
* The handler receives parsed arguments and options with correct typings.
|
|
1313
1470
|
*/
|
|
1314
1471
|
setAction(fn) {
|
|
1315
1472
|
this.action = setName(this.name, fn);
|
|
1316
1473
|
return this;
|
|
1317
1474
|
}
|
|
1318
|
-
/**
|
|
1475
|
+
/** returns a new Command instance. Override this method in subclasses. */
|
|
1319
1476
|
createSubcommand(name) {
|
|
1320
1477
|
return new _Command(name, this);
|
|
1321
1478
|
}
|