@bemoje/cli 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.mjs +450 -285
- 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 +1 -1
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) {
|
|
@@ -68,10 +70,32 @@ function filterObject(obj, predicate) {
|
|
|
68
70
|
}
|
|
69
71
|
__name(filterObject, "filterObject");
|
|
70
72
|
|
|
73
|
+
// ../object/src/objSortKeys.ts
|
|
74
|
+
function objSortKeys(o, compare) {
|
|
75
|
+
const entries = Object.entries(o);
|
|
76
|
+
if (compare) {
|
|
77
|
+
entries.sort(compare);
|
|
78
|
+
} else {
|
|
79
|
+
entries.sort((a, b) => {
|
|
80
|
+
return a[0].localeCompare(b[0]);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return Object.fromEntries(entries);
|
|
84
|
+
}
|
|
85
|
+
__name(objSortKeys, "objSortKeys");
|
|
86
|
+
|
|
87
|
+
// ../object/src/valuesOf.ts
|
|
88
|
+
function valuesOf(obj) {
|
|
89
|
+
return Object.values(obj);
|
|
90
|
+
}
|
|
91
|
+
__name(valuesOf, "valuesOf");
|
|
92
|
+
|
|
71
93
|
// ../map/src/mapGetOrDefault.ts
|
|
72
94
|
function mapGetOrDefault(map, key, factory) {
|
|
73
95
|
let value = map.get(key);
|
|
74
|
-
if (value !== void 0 || map.has(key))
|
|
96
|
+
if (value !== void 0 || map.has(key)) {
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
75
99
|
value = factory(key, map);
|
|
76
100
|
map.set(key, value);
|
|
77
101
|
return value;
|
|
@@ -98,7 +122,9 @@ var TimeoutWeakMap = class {
|
|
|
98
122
|
*/
|
|
99
123
|
get(key) {
|
|
100
124
|
const vt = this.wmap.get(key);
|
|
101
|
-
if (!vt)
|
|
125
|
+
if (!vt) {
|
|
126
|
+
return void 0;
|
|
127
|
+
}
|
|
102
128
|
const [value, timeout] = vt;
|
|
103
129
|
timeout.refresh();
|
|
104
130
|
return value;
|
|
@@ -128,7 +154,9 @@ var TimeoutWeakMap = class {
|
|
|
128
154
|
*/
|
|
129
155
|
delete(key) {
|
|
130
156
|
const vt = this.wmap.get(key);
|
|
131
|
-
if (!vt)
|
|
157
|
+
if (!vt) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
132
160
|
const timeout = vt[1];
|
|
133
161
|
clearTimeout(timeout);
|
|
134
162
|
return this.wmap.delete(key);
|
|
@@ -189,150 +217,8 @@ var TimeoutWeakMap = class {
|
|
|
189
217
|
}
|
|
190
218
|
};
|
|
191
219
|
|
|
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
220
|
// ../decorators/src/lazyProp.ts
|
|
334
221
|
import { isFunction } from "es-toolkit/predicate";
|
|
335
|
-
import { ms as ms2 } from "enhanced-ms";
|
|
336
222
|
|
|
337
223
|
// ../decorators/src/memoizeSync.ts
|
|
338
224
|
import memoizee from "memoizee";
|
|
@@ -340,7 +226,9 @@ import { ms } from "enhanced-ms";
|
|
|
340
226
|
function memoizeSync(arg = {}) {
|
|
341
227
|
const opts = typeof arg === "object" ? arg : { maxAge: typeof arg === "number" ? arg : ms(arg) };
|
|
342
228
|
return /* @__PURE__ */ __name(function decorator(target, key, descriptor) {
|
|
343
|
-
if (!descriptor)
|
|
229
|
+
if (!descriptor) {
|
|
230
|
+
throw new TypeError("descriptor is undefined");
|
|
231
|
+
}
|
|
344
232
|
const orig = descriptor.value;
|
|
345
233
|
assertDescriptorValueIsFunction(key, descriptor);
|
|
346
234
|
const options = { length: false, ...opts };
|
|
@@ -350,7 +238,9 @@ function memoizeSync(arg = {}) {
|
|
|
350
238
|
} else {
|
|
351
239
|
const wmap = /* @__PURE__ */ new WeakMap();
|
|
352
240
|
descriptor.value = function(...args) {
|
|
353
|
-
const memoized = mapGetOrDefault(wmap, this, () =>
|
|
241
|
+
const memoized = mapGetOrDefault(wmap, this, () => {
|
|
242
|
+
return memoizee(orig, options);
|
|
243
|
+
});
|
|
354
244
|
return memoized.apply(this, args);
|
|
355
245
|
};
|
|
356
246
|
}
|
|
@@ -360,6 +250,7 @@ function memoizeSync(arg = {}) {
|
|
|
360
250
|
__name(memoizeSync, "memoizeSync");
|
|
361
251
|
|
|
362
252
|
// ../decorators/src/lazyProp.ts
|
|
253
|
+
import { ms as ms2 } from "enhanced-ms";
|
|
363
254
|
function lazyProp(targetOrTimeout, key, descriptor) {
|
|
364
255
|
if (typeof targetOrTimeout === "number" || typeof targetOrTimeout === "string") {
|
|
365
256
|
const maxAge = typeof targetOrTimeout === "number" ? targetOrTimeout : ms2(targetOrTimeout);
|
|
@@ -375,7 +266,9 @@ function createLazyPropDecorator(map) {
|
|
|
375
266
|
const { get, value } = descriptor;
|
|
376
267
|
if (isFunction(get)) {
|
|
377
268
|
descriptor.get = function() {
|
|
378
|
-
return mapGetOrDefault(map, this, () =>
|
|
269
|
+
return mapGetOrDefault(map, this, () => {
|
|
270
|
+
return get.call(this);
|
|
271
|
+
});
|
|
379
272
|
};
|
|
380
273
|
return descriptor;
|
|
381
274
|
}
|
|
@@ -388,7 +281,6 @@ function createLazyPropDecorator(map) {
|
|
|
388
281
|
__name(createLazyPropDecorator, "createLazyPropDecorator");
|
|
389
282
|
|
|
390
283
|
// src/lib/Help.ts
|
|
391
|
-
import C from "ansi-colors";
|
|
392
284
|
var Help = class {
|
|
393
285
|
static {
|
|
394
286
|
__name(this, "Help");
|
|
@@ -406,7 +298,9 @@ var Help = class {
|
|
|
406
298
|
Object.defineProperty(this, "cmd", { enumerable: false });
|
|
407
299
|
}
|
|
408
300
|
visibleCommands() {
|
|
409
|
-
const res = Object.values(this.cmd.commands).filter((c) =>
|
|
301
|
+
const res = Object.values(this.cmd.commands).filter((c) => {
|
|
302
|
+
return !c.hidden;
|
|
303
|
+
});
|
|
410
304
|
if (this.sortSubcommands) {
|
|
411
305
|
res.sort((a, b) => {
|
|
412
306
|
return a.name.localeCompare(b.name);
|
|
@@ -424,12 +318,18 @@ var Help = class {
|
|
|
424
318
|
return getSortKey(a).localeCompare(getSortKey(b));
|
|
425
319
|
}
|
|
426
320
|
visibleOptions() {
|
|
427
|
-
const res = this.cmd.options.filter((option) =>
|
|
428
|
-
|
|
321
|
+
const res = this.cmd.options.filter((option) => {
|
|
322
|
+
return !option.hidden;
|
|
323
|
+
});
|
|
324
|
+
if (this.sortOptions) {
|
|
325
|
+
res.sort(this.compareOptions);
|
|
326
|
+
}
|
|
429
327
|
return res;
|
|
430
328
|
}
|
|
431
329
|
visibleArguments() {
|
|
432
|
-
if (this.cmd.arguments.find((argument) =>
|
|
330
|
+
if (this.cmd.arguments.find((argument) => {
|
|
331
|
+
return !!argument.description;
|
|
332
|
+
})) {
|
|
433
333
|
return [...this.cmd.arguments];
|
|
434
334
|
}
|
|
435
335
|
return [];
|
|
@@ -438,9 +338,11 @@ var Help = class {
|
|
|
438
338
|
* Get the command term to show in the list of subcommands.
|
|
439
339
|
*/
|
|
440
340
|
subcommandTerm(sub) {
|
|
441
|
-
const args = sub.arguments.map((arg) =>
|
|
442
|
-
|
|
443
|
-
(
|
|
341
|
+
const args = sub.arguments.map((arg) => {
|
|
342
|
+
return arg.usage;
|
|
343
|
+
}).join(" ");
|
|
344
|
+
return (sub.aliases[0] ? `${sub.aliases[0].padEnd(this.longestSubcommandAliasLength(), " ")} | ` : "") + sub.name + (sub.options.length ? ` ${this.usageDisplayOptionsAs}` : "") + // simplistic check for non-help option
|
|
345
|
+
(args ? ` ${args}` : "");
|
|
444
346
|
}
|
|
445
347
|
/**
|
|
446
348
|
* Get the option term to show in the list of options.
|
|
@@ -455,7 +357,12 @@ var Help = class {
|
|
|
455
357
|
return argument.name;
|
|
456
358
|
}
|
|
457
359
|
longestSubcommandAliasLength() {
|
|
458
|
-
return Math.max(
|
|
360
|
+
return Math.max(
|
|
361
|
+
0,
|
|
362
|
+
...this.visibleCommands().map((c) => {
|
|
363
|
+
return c.aliases[0]?.length || 0;
|
|
364
|
+
})
|
|
365
|
+
);
|
|
459
366
|
}
|
|
460
367
|
longestSubcommandTermLength() {
|
|
461
368
|
return this.visibleCommands().reduce((max, command) => {
|
|
@@ -478,15 +385,15 @@ var Help = class {
|
|
|
478
385
|
commandUsage() {
|
|
479
386
|
let path = "";
|
|
480
387
|
for (let ancestor = this.cmd.parent; ancestor; ancestor = ancestor.parent) {
|
|
481
|
-
path = ancestor.name
|
|
388
|
+
path = `${ancestor.name} ${path}`;
|
|
482
389
|
}
|
|
483
|
-
return
|
|
390
|
+
return `${path + this.cmd.name} ${[
|
|
484
391
|
...Object.keys(this.cmd.commands).length ? [this.usageDisplaySubcommandAs] : [],
|
|
485
392
|
...this.cmd.options.length ? [this.usageDisplayOptionsAs] : [],
|
|
486
393
|
...this.cmd.arguments.map((arg) => {
|
|
487
394
|
return arg.required ? arg.variadic ? `<${arg.name}...>` : `<${arg.name}>` : arg.variadic ? `[${arg.name}...]` : `[${arg.name}]`;
|
|
488
395
|
})
|
|
489
|
-
].join(" ")
|
|
396
|
+
].join(" ")}`.trim();
|
|
490
397
|
}
|
|
491
398
|
/**
|
|
492
399
|
* Get the description for the command.
|
|
@@ -515,7 +422,9 @@ var Help = class {
|
|
|
515
422
|
if (option.choices) {
|
|
516
423
|
extraInfo.push(
|
|
517
424
|
// use stringify to match the display of the default value
|
|
518
|
-
`choices: ${option.choices.map((choice) =>
|
|
425
|
+
`choices: ${option.choices.map((choice) => {
|
|
426
|
+
return String(choice);
|
|
427
|
+
}).join(", ")}`
|
|
519
428
|
);
|
|
520
429
|
}
|
|
521
430
|
if (option.defaultValue && !(Array.isArray(option.defaultValue) && option.defaultValue.length === 0)) {
|
|
@@ -541,7 +450,9 @@ var Help = class {
|
|
|
541
450
|
if (argument.choices) {
|
|
542
451
|
extraInfo.push(
|
|
543
452
|
// use stringify to match the display of the default value
|
|
544
|
-
`choices: ${argument.choices.map((choice) =>
|
|
453
|
+
`choices: ${argument.choices.map((choice) => {
|
|
454
|
+
return String(choice);
|
|
455
|
+
}).join(", ")}`
|
|
545
456
|
);
|
|
546
457
|
}
|
|
547
458
|
if (argument.defaultValue !== void 0) {
|
|
@@ -560,7 +471,9 @@ var Help = class {
|
|
|
560
471
|
* Format a list of items, given a heading and an array of formatted items.
|
|
561
472
|
*/
|
|
562
473
|
formatItemList(heading, items) {
|
|
563
|
-
if (items.length === 0)
|
|
474
|
+
if (items.length === 0) {
|
|
475
|
+
return [];
|
|
476
|
+
}
|
|
564
477
|
return [this.styleTitle(heading), ...items, ""];
|
|
565
478
|
}
|
|
566
479
|
/**
|
|
@@ -570,7 +483,9 @@ var Help = class {
|
|
|
570
483
|
const result = /* @__PURE__ */ new Map();
|
|
571
484
|
unsortedItems.forEach((item) => {
|
|
572
485
|
const group = getGroup(item);
|
|
573
|
-
if (!result.has(group))
|
|
486
|
+
if (!result.has(group)) {
|
|
487
|
+
result.set(group, []);
|
|
488
|
+
}
|
|
574
489
|
});
|
|
575
490
|
visibleItems.forEach((item) => {
|
|
576
491
|
const group = getGroup(item);
|
|
@@ -599,11 +514,21 @@ var Help = class {
|
|
|
599
514
|
*/
|
|
600
515
|
styleUsage(str) {
|
|
601
516
|
return str.split(" ").map((word, index, arr) => {
|
|
602
|
-
if (word === this.usageDisplaySubcommandAs)
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
if (word
|
|
606
|
-
|
|
517
|
+
if (word === this.usageDisplaySubcommandAs) {
|
|
518
|
+
return C.green(word);
|
|
519
|
+
}
|
|
520
|
+
if (word === this.usageDisplayOptionsAs) {
|
|
521
|
+
return C.blue(word);
|
|
522
|
+
}
|
|
523
|
+
if (word[0] === "<") {
|
|
524
|
+
return C.red(word);
|
|
525
|
+
}
|
|
526
|
+
if (word[0] === "[") {
|
|
527
|
+
return C.cyan(word);
|
|
528
|
+
}
|
|
529
|
+
if (arr[index + 1]?.startsWith("[")) {
|
|
530
|
+
return C.magenta(word);
|
|
531
|
+
}
|
|
607
532
|
return this.styleCommandText(word);
|
|
608
533
|
}).join(" ");
|
|
609
534
|
}
|
|
@@ -648,8 +573,12 @@ var Help = class {
|
|
|
648
573
|
*/
|
|
649
574
|
styleSubcommandTerm(str) {
|
|
650
575
|
const res = str.split(" ").map((word) => {
|
|
651
|
-
if (word === this.usageDisplayOptionsAs)
|
|
652
|
-
|
|
576
|
+
if (word === this.usageDisplayOptionsAs) {
|
|
577
|
+
return C.dim(word);
|
|
578
|
+
}
|
|
579
|
+
if (word[0] === "[" || word[0] === "<") {
|
|
580
|
+
return C.dim(word);
|
|
581
|
+
}
|
|
653
582
|
return this.styleSubcommandText(word);
|
|
654
583
|
}).join(" ");
|
|
655
584
|
const split = res.split("|");
|
|
@@ -712,7 +641,9 @@ var Help = class {
|
|
|
712
641
|
formatItem(term, termWidth, description) {
|
|
713
642
|
const itemIndent = 2;
|
|
714
643
|
const itemIndentStr = " ".repeat(itemIndent);
|
|
715
|
-
if (!description)
|
|
644
|
+
if (!description) {
|
|
645
|
+
return itemIndentStr + term;
|
|
646
|
+
}
|
|
716
647
|
const paddedTerm = term.padEnd(termWidth + term.length - this.displayWidth(term));
|
|
717
648
|
const spacerWidth = 2;
|
|
718
649
|
const helpWidth = this.helpWidth;
|
|
@@ -722,7 +653,8 @@ var Help = class {
|
|
|
722
653
|
formattedDescription = description;
|
|
723
654
|
} else {
|
|
724
655
|
const wrappedDescription = this.boxWrap(description, remainingWidth);
|
|
725
|
-
formattedDescription = wrappedDescription.replace(/\n/g,
|
|
656
|
+
formattedDescription = wrappedDescription.replace(/\n/g, `
|
|
657
|
+
${" ".repeat(termWidth + spacerWidth)}`);
|
|
726
658
|
}
|
|
727
659
|
return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
|
|
728
660
|
${itemIndentStr}`);
|
|
@@ -732,7 +664,9 @@ ${itemIndentStr}`);
|
|
|
732
664
|
* Wrapping is skipped if the width is less than `minWidthToWrap`.
|
|
733
665
|
*/
|
|
734
666
|
boxWrap(str, width) {
|
|
735
|
-
if (width < this.minWidthToWrap)
|
|
667
|
+
if (width < this.minWidthToWrap) {
|
|
668
|
+
return str;
|
|
669
|
+
}
|
|
736
670
|
const rawLines = str.split(/\r\n|\n/);
|
|
737
671
|
const chunkPattern = /[\s]*[^\s]+/g;
|
|
738
672
|
const wrappedLines = [];
|
|
@@ -777,11 +711,9 @@ ${itemIndentStr}`);
|
|
|
777
711
|
);
|
|
778
712
|
});
|
|
779
713
|
output = output.concat(this.formatItemList("Arguments:", argumentList));
|
|
780
|
-
const optionGroups = this.groupItems(
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
(option) => option.group ?? "Options:"
|
|
784
|
-
);
|
|
714
|
+
const optionGroups = this.groupItems(this.cmd.options, this.visibleOptions(), (option) => {
|
|
715
|
+
return option.group ?? "Options:";
|
|
716
|
+
});
|
|
785
717
|
optionGroups.forEach((options, group) => {
|
|
786
718
|
const optionList = options.map((option) => {
|
|
787
719
|
return this.formatItem(
|
|
@@ -795,7 +727,9 @@ ${itemIndentStr}`);
|
|
|
795
727
|
const commandGroups = this.groupItems(
|
|
796
728
|
Object.values(this.cmd.commands),
|
|
797
729
|
this.visibleCommands(),
|
|
798
|
-
(sub) =>
|
|
730
|
+
(sub) => {
|
|
731
|
+
return sub.group || "Commands:";
|
|
732
|
+
}
|
|
799
733
|
);
|
|
800
734
|
commandGroups.forEach((commands, group) => {
|
|
801
735
|
const commandList = commands.map((sub) => {
|
|
@@ -835,16 +769,87 @@ __decorateClass([
|
|
|
835
769
|
lazyProp
|
|
836
770
|
], Help.prototype, "padWidth", 1);
|
|
837
771
|
|
|
772
|
+
// ../array/src/arrLast.ts
|
|
773
|
+
function arrLast(array) {
|
|
774
|
+
if (!array.length) {
|
|
775
|
+
throw new Error("Cannot get last element of empty array.");
|
|
776
|
+
}
|
|
777
|
+
return array[array.length - 1];
|
|
778
|
+
}
|
|
779
|
+
__name(arrLast, "arrLast");
|
|
780
|
+
|
|
781
|
+
// ../array/src/arrRemoveDuplicates.ts
|
|
782
|
+
function arrRemoveDuplicates(array) {
|
|
783
|
+
return Array.from(new Set(array));
|
|
784
|
+
}
|
|
785
|
+
__name(arrRemoveDuplicates, "arrRemoveDuplicates");
|
|
786
|
+
|
|
787
|
+
// src/lib/internal/collectVariadicOptionValues.ts
|
|
788
|
+
function collectVariadicOptionValues(parsed, options) {
|
|
789
|
+
for (let i = 0; i < parsed.tokens.length; i++) {
|
|
790
|
+
const token = parsed.tokens[i];
|
|
791
|
+
if (token.kind !== "option") {
|
|
792
|
+
continue;
|
|
793
|
+
}
|
|
794
|
+
const def = options.find((o) => {
|
|
795
|
+
return o.name === token.name;
|
|
796
|
+
});
|
|
797
|
+
if (!def?.variadic || def.type !== "string") {
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
const values = [token.value];
|
|
801
|
+
let j = i + 1;
|
|
802
|
+
while (j < parsed.tokens.length && parsed.tokens[j].kind === "positional") {
|
|
803
|
+
const positionalToken = parsed.tokens[j];
|
|
804
|
+
values.push(positionalToken.value);
|
|
805
|
+
const posIndex = parsed.positionals.indexOf(positionalToken.value);
|
|
806
|
+
if (posIndex !== -1) {
|
|
807
|
+
parsed.positionals.splice(posIndex, 1);
|
|
808
|
+
}
|
|
809
|
+
j++;
|
|
810
|
+
}
|
|
811
|
+
Reflect.set(
|
|
812
|
+
parsed.values,
|
|
813
|
+
token.name,
|
|
814
|
+
values.filter((v) => {
|
|
815
|
+
return v !== void 0;
|
|
816
|
+
})
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
__name(collectVariadicOptionValues, "collectVariadicOptionValues");
|
|
821
|
+
|
|
822
|
+
// src/lib/Command.ts
|
|
823
|
+
import colors3 from "ansi-colors";
|
|
824
|
+
|
|
838
825
|
// src/lib/helpers/findCommand.ts
|
|
839
826
|
var findCommand_exports = {};
|
|
840
827
|
__export(findCommand_exports, {
|
|
841
828
|
findCommand: () => findCommand
|
|
842
829
|
});
|
|
843
830
|
function findCommand(cmd, nameOrAlias) {
|
|
844
|
-
return cmd.commands[nameOrAlias] ?? valuesOf(cmd.commands).find((c) =>
|
|
831
|
+
return cmd.commands[nameOrAlias] ?? valuesOf(cmd.commands).find((c) => {
|
|
832
|
+
return c.aliases.includes(nameOrAlias);
|
|
833
|
+
});
|
|
845
834
|
}
|
|
846
835
|
__name(findCommand, "findCommand");
|
|
847
836
|
|
|
837
|
+
// src/lib/helpers/findOption.ts
|
|
838
|
+
var findOption_exports = {};
|
|
839
|
+
__export(findOption_exports, {
|
|
840
|
+
findOption: () => findOption
|
|
841
|
+
});
|
|
842
|
+
function findOption(cmd, nameOrShortOrLong) {
|
|
843
|
+
return nameOrShortOrLong.startsWith("--") ? cmd.options.find((o) => {
|
|
844
|
+
return o.long === nameOrShortOrLong.slice(2);
|
|
845
|
+
}) : nameOrShortOrLong.startsWith("-") ? cmd.options.find((o) => {
|
|
846
|
+
return o.short === nameOrShortOrLong.slice(1);
|
|
847
|
+
}) : cmd.options.find((o) => {
|
|
848
|
+
return o.name === nameOrShortOrLong;
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
__name(findOption, "findOption");
|
|
852
|
+
|
|
848
853
|
// src/lib/helpers/getCommandAncestors.ts
|
|
849
854
|
var getCommandAncestors_exports = {};
|
|
850
855
|
__export(getCommandAncestors_exports, {
|
|
@@ -872,9 +877,98 @@ function getCommandAncestors(cmd) {
|
|
|
872
877
|
}
|
|
873
878
|
__name(getCommandAncestors, "getCommandAncestors");
|
|
874
879
|
|
|
880
|
+
// src/lib/Command.ts
|
|
881
|
+
import { inspect } from "node:util";
|
|
882
|
+
import { kebabCase } from "es-toolkit/string";
|
|
883
|
+
|
|
884
|
+
// src/lib/internal/mergeOptionDefaults.ts
|
|
885
|
+
function mergeOptionDefaults(values, options) {
|
|
886
|
+
for (const option of options) {
|
|
887
|
+
if (option.defaultValue !== void 0 && option.name in values) {
|
|
888
|
+
values[option.name] ??= option.defaultValue;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
__name(mergeOptionDefaults, "mergeOptionDefaults");
|
|
893
|
+
|
|
894
|
+
// src/lib/internal/normalizeArgv.ts
|
|
895
|
+
function normalizeArgv(argv, options) {
|
|
896
|
+
for (const o of options) {
|
|
897
|
+
if (o.long === o.name) {
|
|
898
|
+
continue;
|
|
899
|
+
}
|
|
900
|
+
argv = argv.map((a) => {
|
|
901
|
+
if (a === `--${o.long}`) {
|
|
902
|
+
return `--${o.name}`;
|
|
903
|
+
}
|
|
904
|
+
if (a === `--no-${o.long}`) {
|
|
905
|
+
return `--no-${o.name}`;
|
|
906
|
+
}
|
|
907
|
+
return a;
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
return argv;
|
|
911
|
+
}
|
|
912
|
+
__name(normalizeArgv, "normalizeArgv");
|
|
913
|
+
|
|
914
|
+
// src/lib/Command.ts
|
|
915
|
+
import { parseArgs } from "node:util";
|
|
916
|
+
|
|
917
|
+
// src/lib/helpers/parseOptionFlags.ts
|
|
918
|
+
var parseOptionFlags_exports = {};
|
|
919
|
+
__export(parseOptionFlags_exports, {
|
|
920
|
+
parseOptionFlags: () => parseOptionFlags
|
|
921
|
+
});
|
|
922
|
+
function parseOptionFlags(flags) {
|
|
923
|
+
const match = flags.match(/^-(.+?), --([a-zA-Z][\w-]*)(?:\s*(<(.+?)>|\[(.+?)\]))?$/);
|
|
924
|
+
if (!match) {
|
|
925
|
+
throw new Error(`Invalid option format: ${flags}`);
|
|
926
|
+
}
|
|
927
|
+
const short = match[1];
|
|
928
|
+
if (short.length !== 1) {
|
|
929
|
+
throw new Error(`Expected short name to be a single character. Got: -${short}`);
|
|
930
|
+
}
|
|
931
|
+
const long = match[2];
|
|
932
|
+
const argName = (match[4] || match[5])?.replace(/\.\.\.$/, "") || void 0;
|
|
933
|
+
const name = long.split("-").reduce((str, word) => {
|
|
934
|
+
return str + word[0].toUpperCase() + word.slice(1);
|
|
935
|
+
});
|
|
936
|
+
return { short, long, name, argName };
|
|
937
|
+
}
|
|
938
|
+
__name(parseOptionFlags, "parseOptionFlags");
|
|
939
|
+
|
|
940
|
+
// src/lib/internal/resolveArguments.ts
|
|
941
|
+
function resolveArguments(positionals, args) {
|
|
942
|
+
const result = args.map((arg, index) => {
|
|
943
|
+
if (arg.variadic) {
|
|
944
|
+
const remaining = positionals.slice(index);
|
|
945
|
+
return remaining.length > 0 ? remaining : arg.defaultValue;
|
|
946
|
+
}
|
|
947
|
+
return positionals[index] ?? arg.defaultValue;
|
|
948
|
+
});
|
|
949
|
+
while (result.length && arrLast(result) === void 0) {
|
|
950
|
+
result.pop();
|
|
951
|
+
}
|
|
952
|
+
return result;
|
|
953
|
+
}
|
|
954
|
+
__name(resolveArguments, "resolveArguments");
|
|
955
|
+
|
|
956
|
+
// ../fn/src/setName.ts
|
|
957
|
+
function setName(name, target) {
|
|
958
|
+
return defineValue(target, "name", typeof name === "string" ? name : name.name, { enumerable: false });
|
|
959
|
+
}
|
|
960
|
+
__name(setName, "setName");
|
|
961
|
+
|
|
962
|
+
// ../string/src/lib/strFirstCharToUpperCase.ts
|
|
963
|
+
function strFirstCharToUpperCase(string) {
|
|
964
|
+
return string.charAt(0).toUpperCase() + string.substring(1);
|
|
965
|
+
}
|
|
966
|
+
__name(strFirstCharToUpperCase, "strFirstCharToUpperCase");
|
|
967
|
+
|
|
875
968
|
// ../node/src/createLogger.ts
|
|
876
969
|
import colors from "ansi-colors";
|
|
877
|
-
import { isPrimitive
|
|
970
|
+
import { isPrimitive } from "es-toolkit/predicate";
|
|
971
|
+
import { isString } from "es-toolkit/predicate";
|
|
878
972
|
function createLogger(name) {
|
|
879
973
|
const NAME = name ? colors.dim.cyan(name) : name;
|
|
880
974
|
const START = [NAME, colors.dim.gray("[START]")].filter(Boolean);
|
|
@@ -887,13 +981,29 @@ function createLogger(name) {
|
|
|
887
981
|
const cyanArgs = createColoredArgs(colors.cyan);
|
|
888
982
|
const yellowArgs = createColoredArgs(colors.yellow);
|
|
889
983
|
return {
|
|
890
|
-
start: /* @__PURE__ */ __name((...args) =>
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
984
|
+
start: /* @__PURE__ */ __name((...args) => {
|
|
985
|
+
return console.info(...START, ...args);
|
|
986
|
+
}, "start"),
|
|
987
|
+
done: /* @__PURE__ */ __name((...args) => {
|
|
988
|
+
return console.info(...DONE, ...args);
|
|
989
|
+
}, "done"),
|
|
990
|
+
info: /* @__PURE__ */ __name((...args) => {
|
|
991
|
+
return console.info(...INFO, ...grayArgs(args));
|
|
992
|
+
}, "info"),
|
|
993
|
+
log: /* @__PURE__ */ __name((...args) => {
|
|
994
|
+
return console.log(...NAME ? [NAME, ...args] : args);
|
|
995
|
+
}, "log"),
|
|
996
|
+
warn: /* @__PURE__ */ __name((...args) => {
|
|
997
|
+
return console.warn(...WARN, ...yellowArgs(args));
|
|
998
|
+
}, "warn"),
|
|
999
|
+
debug: /* @__PURE__ */ __name((...args) => {
|
|
1000
|
+
return console.debug(...DEBUG, ...cyanArgs(args));
|
|
1001
|
+
}, "debug"),
|
|
1002
|
+
error: /* @__PURE__ */ __name((...args) => {
|
|
1003
|
+
return args.forEach((arg) => {
|
|
1004
|
+
return console.error(...ERROR, arg);
|
|
1005
|
+
});
|
|
1006
|
+
}, "error")
|
|
897
1007
|
};
|
|
898
1008
|
}
|
|
899
1009
|
__name(createLogger, "createLogger");
|
|
@@ -917,9 +1027,9 @@ function createColoredArgs(colorFn) {
|
|
|
917
1027
|
__name(createColoredArgs, "createColoredArgs");
|
|
918
1028
|
|
|
919
1029
|
// ../node/src/timer.ts
|
|
920
|
-
import { isPromise } from "node:util/types";
|
|
921
1030
|
import colors2 from "ansi-colors";
|
|
922
1031
|
import humanizeDuration from "humanize-duration";
|
|
1032
|
+
import { isPromise } from "node:util/types";
|
|
923
1033
|
function timer(arg, task) {
|
|
924
1034
|
const t0 = process.hrtime.bigint();
|
|
925
1035
|
const [name, description] = Array.isArray(arg) ? arg : [arg, ""];
|
|
@@ -935,7 +1045,9 @@ function timer(arg, task) {
|
|
|
935
1045
|
return done(result);
|
|
936
1046
|
});
|
|
937
1047
|
function done(retval2) {
|
|
938
|
-
if (process.exitCode)
|
|
1048
|
+
if (process.exitCode) {
|
|
1049
|
+
return retval2;
|
|
1050
|
+
}
|
|
939
1051
|
const ns = process.hrtime.bigint() - t0;
|
|
940
1052
|
const ms3 = Math.floor(Number(ns) / 1e6);
|
|
941
1053
|
log.done(colors2.dim(humanizeDuration(ms3)));
|
|
@@ -945,68 +1057,83 @@ function timer(arg, task) {
|
|
|
945
1057
|
}
|
|
946
1058
|
__name(timer, "timer");
|
|
947
1059
|
|
|
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
|
-
|
|
1060
|
+
// src/lib/internal/validateParsed.ts
|
|
1061
|
+
function validateParsed(args, optionValues, argDefs, optionDefs) {
|
|
1062
|
+
return argDefs.map((def, index) => {
|
|
1063
|
+
const value = args[index];
|
|
1064
|
+
if (def.required) {
|
|
1065
|
+
if (def.variadic ? Array.isArray(value) && value.length === 0 : value === void 0) {
|
|
1066
|
+
return `Missing argument [${index}] ${def.usage}`;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
if (def.choices && value !== void 0) {
|
|
1070
|
+
if (![value].flat().every((v) => {
|
|
1071
|
+
return def.choices.includes(v);
|
|
1072
|
+
})) {
|
|
1073
|
+
return `Invalid argument [${index}] ${def.usage}: Got \`${value}\`. Accepted values: [${def.choices.map((c) => {
|
|
1074
|
+
return `\`${c}\``;
|
|
1075
|
+
}).join(",")}]`;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}).concat(
|
|
1079
|
+
entriesOf(optionValues).map(([key, value]) => {
|
|
1080
|
+
const def = optionDefs.find((o) => {
|
|
1081
|
+
return o.name === key;
|
|
1082
|
+
});
|
|
1083
|
+
if (!def) {
|
|
1084
|
+
return `Unknown option --${key}`;
|
|
1085
|
+
}
|
|
1086
|
+
if (def.choices && value !== void 0) {
|
|
1087
|
+
if (!(def.variadic ? value : [value]).every((v) => {
|
|
1088
|
+
return def.choices.includes(v);
|
|
1089
|
+
})) {
|
|
1090
|
+
return `Invalid option value ${def.flags}: Got \`${value}\`. Accepted values: [${def.choices.map((c) => {
|
|
1091
|
+
return `\`${c}\``;
|
|
1092
|
+
}).join(",")}]`;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
})
|
|
1096
|
+
).filter((s) => {
|
|
1097
|
+
return s !== void 0;
|
|
1098
|
+
}).reduce(
|
|
1099
|
+
(acc, curr) => {
|
|
1100
|
+
return (acc ?? []).concat(curr);
|
|
1101
|
+
},
|
|
1102
|
+
void 0
|
|
1103
|
+
);
|
|
976
1104
|
}
|
|
977
|
-
__name(
|
|
1105
|
+
__name(validateParsed, "validateParsed");
|
|
978
1106
|
|
|
979
1107
|
// src/lib/Command.ts
|
|
980
|
-
import { kebabCase } from "es-toolkit/string";
|
|
981
1108
|
var _Command = class _Command {
|
|
982
1109
|
static {
|
|
983
1110
|
__name(this, "Command");
|
|
984
1111
|
}
|
|
985
|
-
/**
|
|
1112
|
+
/** parent command in the hierarchy, undefined for root command */
|
|
986
1113
|
parent;
|
|
987
|
-
/**
|
|
1114
|
+
/** the command name used to invoke it */
|
|
988
1115
|
name;
|
|
989
|
-
/**
|
|
1116
|
+
/** semantic version string displayed by --version flag */
|
|
990
1117
|
version;
|
|
991
|
-
/**
|
|
1118
|
+
/** alternative names for invoking this command */
|
|
992
1119
|
aliases;
|
|
993
|
-
/**
|
|
1120
|
+
/** brief one-line description shown in command lists */
|
|
994
1121
|
summary;
|
|
995
|
-
/**
|
|
1122
|
+
/** full description displayed in help text */
|
|
996
1123
|
description;
|
|
997
|
-
/**
|
|
1124
|
+
/** whether to exclude from help listings */
|
|
998
1125
|
hidden;
|
|
999
|
-
/**
|
|
1126
|
+
/** category for organizing related commands in help output */
|
|
1000
1127
|
group;
|
|
1001
|
-
/**
|
|
1128
|
+
/** positional arguments this command accepts */
|
|
1002
1129
|
arguments;
|
|
1003
|
-
/**
|
|
1130
|
+
/** cLI options (flags) this command recognizes */
|
|
1004
1131
|
options;
|
|
1005
|
-
/**
|
|
1132
|
+
/** subcommands registered with this command */
|
|
1006
1133
|
commands;
|
|
1007
|
-
/**
|
|
1134
|
+
/** main action handler executed when command is invoked */
|
|
1008
1135
|
action;
|
|
1009
|
-
/**
|
|
1136
|
+
/** option-driven actions (e.g., --help, --version) executed when their conditions match */
|
|
1010
1137
|
hooks;
|
|
1011
1138
|
constructor(name, parent) {
|
|
1012
1139
|
this.name = name;
|
|
@@ -1031,31 +1158,35 @@ var _Command = class _Command {
|
|
|
1031
1158
|
get help() {
|
|
1032
1159
|
return new Help(this);
|
|
1033
1160
|
}
|
|
1034
|
-
/**
|
|
1161
|
+
/** configure how the help is rendered */
|
|
1035
1162
|
helpConfiguration(cb) {
|
|
1036
1163
|
const help = this.help;
|
|
1037
1164
|
cb?.(help);
|
|
1038
1165
|
return this;
|
|
1039
1166
|
}
|
|
1040
|
-
/**
|
|
1167
|
+
/** renders formatted help text using provided help definition */
|
|
1041
1168
|
renderHelp(config = {}) {
|
|
1042
1169
|
const result = this.help.render();
|
|
1043
1170
|
return config.noColor ? colors3.stripColor(result) : result;
|
|
1044
1171
|
}
|
|
1045
|
-
/**
|
|
1172
|
+
/** sets the command name */
|
|
1046
1173
|
setName(name) {
|
|
1047
1174
|
this.name = name;
|
|
1048
1175
|
}
|
|
1049
|
-
/**
|
|
1176
|
+
/** sets command aliases, flattening nested arrays */
|
|
1050
1177
|
setAliases(...aliases) {
|
|
1051
1178
|
this.aliases = [];
|
|
1052
1179
|
this.addAliases(...aliases);
|
|
1053
1180
|
return this;
|
|
1054
1181
|
}
|
|
1055
|
-
/**
|
|
1182
|
+
/** adds aliases to existing ones */
|
|
1056
1183
|
addAliases(...aliases) {
|
|
1057
|
-
const taken = this.parent ? valuesOf(this.parent.commands).flatMap((c) =>
|
|
1058
|
-
|
|
1184
|
+
const taken = this.parent ? valuesOf(this.parent.commands).flatMap((c) => {
|
|
1185
|
+
return [c.name, ...c.aliases];
|
|
1186
|
+
}) : [];
|
|
1187
|
+
arrRemoveDuplicates(aliases.flat()).filter((a) => {
|
|
1188
|
+
return !this.aliases.includes(a) && a !== this.name;
|
|
1189
|
+
}).forEach((a) => {
|
|
1059
1190
|
if (taken.includes(a)) {
|
|
1060
1191
|
throw new Error(
|
|
1061
1192
|
`Alias "${a}" is already used by a sibling command: ${findCommand(this.parent, a)?.name}`
|
|
@@ -1063,39 +1194,47 @@ var _Command = class _Command {
|
|
|
1063
1194
|
}
|
|
1064
1195
|
this.aliases.push(a);
|
|
1065
1196
|
});
|
|
1066
|
-
this.aliases.sort((a, b) =>
|
|
1197
|
+
this.aliases.sort((a, b) => {
|
|
1198
|
+
return a.length - b.length;
|
|
1199
|
+
});
|
|
1067
1200
|
return this;
|
|
1068
1201
|
}
|
|
1069
|
-
/**
|
|
1202
|
+
/** sets the command version */
|
|
1070
1203
|
setVersion(version) {
|
|
1071
1204
|
this.version = version;
|
|
1072
|
-
if (findOption(this, "version"))
|
|
1205
|
+
if (findOption(this, "version")) {
|
|
1206
|
+
return this;
|
|
1207
|
+
}
|
|
1073
1208
|
return this.addOption("-V, --version", { description: "Display semver version" }).addOptionHook("version", ({ cmd }) => {
|
|
1074
|
-
console.log(
|
|
1209
|
+
console.log(
|
|
1210
|
+
getCommandAndAncestors(cmd).find((c) => {
|
|
1211
|
+
return c.version;
|
|
1212
|
+
})?.version
|
|
1213
|
+
);
|
|
1075
1214
|
process.exitCode = 0;
|
|
1076
1215
|
});
|
|
1077
1216
|
}
|
|
1078
|
-
/**
|
|
1217
|
+
/** sets the command summary */
|
|
1079
1218
|
setSummary(summary) {
|
|
1080
1219
|
this.summary = summary;
|
|
1081
1220
|
return this;
|
|
1082
1221
|
}
|
|
1083
|
-
/**
|
|
1222
|
+
/** sets command description, joining variadic lines */
|
|
1084
1223
|
setDescription(...lines) {
|
|
1085
1224
|
this.description = lines.join("\n");
|
|
1086
1225
|
return this;
|
|
1087
1226
|
}
|
|
1088
|
-
/**
|
|
1227
|
+
/** sets whether command is hidden from help */
|
|
1089
1228
|
setHidden(hidden = true) {
|
|
1090
1229
|
this.hidden = hidden;
|
|
1091
1230
|
return this;
|
|
1092
1231
|
}
|
|
1093
|
-
/**
|
|
1232
|
+
/** sets the command group for help organization */
|
|
1094
1233
|
setGroup(group) {
|
|
1095
1234
|
this.group = group;
|
|
1096
1235
|
return this;
|
|
1097
1236
|
}
|
|
1098
|
-
/**
|
|
1237
|
+
/** add a subcommand and return the subcommand. All options are inherited by the subcommand. */
|
|
1099
1238
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1100
1239
|
command(name, cb) {
|
|
1101
1240
|
if (this.arguments.length) {
|
|
@@ -1106,21 +1245,33 @@ var _Command = class _Command {
|
|
|
1106
1245
|
const sub = this.createSubcommand(name);
|
|
1107
1246
|
const inherit = this.options;
|
|
1108
1247
|
sub.options.push(...inherit);
|
|
1109
|
-
const inheritHooks = this.hooks.filter((t) =>
|
|
1248
|
+
const inheritHooks = this.hooks.filter((t) => {
|
|
1249
|
+
return inherit.some((i) => {
|
|
1250
|
+
return i.name === t.name;
|
|
1251
|
+
});
|
|
1252
|
+
});
|
|
1110
1253
|
sub.hooks.push(...inheritHooks);
|
|
1111
|
-
const taken = valuesOf(this.commands).flatMap((c) =>
|
|
1254
|
+
const taken = valuesOf(this.commands).flatMap((c) => {
|
|
1255
|
+
return [c.name, ...c.aliases];
|
|
1256
|
+
});
|
|
1112
1257
|
if (taken.includes(name)) {
|
|
1113
1258
|
throw new Error(
|
|
1114
|
-
`Command name "${getCommandAndAncestors(sub).map((c) =>
|
|
1259
|
+
`Command name "${getCommandAndAncestors(sub).map((c) => {
|
|
1260
|
+
return c.name;
|
|
1261
|
+
})}" is already used by this command or its aliases: ${taken.join(", ")}`
|
|
1115
1262
|
);
|
|
1116
1263
|
}
|
|
1117
1264
|
const kebab = kebabCase(name);
|
|
1118
1265
|
const words = kebab.split("-");
|
|
1119
|
-
const initials = words.map((s) =>
|
|
1266
|
+
const initials = words.map((s) => {
|
|
1267
|
+
return s[0];
|
|
1268
|
+
}).join("");
|
|
1120
1269
|
if (!taken.includes(initials)) {
|
|
1121
1270
|
sub.addAliases(initials);
|
|
1122
1271
|
} else {
|
|
1123
|
-
const initials2 = words.map((s) =>
|
|
1272
|
+
const initials2 = words.map((s) => {
|
|
1273
|
+
return s[0] + s[1];
|
|
1274
|
+
}).join("");
|
|
1124
1275
|
if (!taken.includes(initials2)) {
|
|
1125
1276
|
sub.addAliases(initials2);
|
|
1126
1277
|
}
|
|
@@ -1128,13 +1279,13 @@ var _Command = class _Command {
|
|
|
1128
1279
|
this.commands[name] = sub;
|
|
1129
1280
|
return cb ? cb(sub, this) : sub;
|
|
1130
1281
|
}
|
|
1131
|
-
/**
|
|
1282
|
+
/** add a subcommand and return the subcommand. All options are inherited by the subcommand. */
|
|
1132
1283
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1133
1284
|
addCommand(name, cb) {
|
|
1134
1285
|
this.command(name, cb);
|
|
1135
1286
|
return this;
|
|
1136
1287
|
}
|
|
1137
|
-
//
|
|
1288
|
+
// implementation
|
|
1138
1289
|
addArgument(usage, options = {}) {
|
|
1139
1290
|
if (!/^<(.*?)>$|^\[(.*?)\]$/.test(usage)) {
|
|
1140
1291
|
throw new Error(`Invalid argument format: ${usage}`);
|
|
@@ -1168,7 +1319,7 @@ var _Command = class _Command {
|
|
|
1168
1319
|
return this;
|
|
1169
1320
|
}
|
|
1170
1321
|
/**
|
|
1171
|
-
*
|
|
1322
|
+
* adds command-line option with type inference. Parses format: `-s, --long [<value>|[value]|<value...>|[value...]]`
|
|
1172
1323
|
*/
|
|
1173
1324
|
addOption(flags, opts = {}) {
|
|
1174
1325
|
const ins = {};
|
|
@@ -1206,7 +1357,9 @@ var _Command = class _Command {
|
|
|
1206
1357
|
}
|
|
1207
1358
|
}
|
|
1208
1359
|
for (const [key, value] of Object.entries(opts)) {
|
|
1209
|
-
if (value !== void 0)
|
|
1360
|
+
if (value !== void 0) {
|
|
1361
|
+
Reflect.set(ins, key, value);
|
|
1362
|
+
}
|
|
1210
1363
|
}
|
|
1211
1364
|
if (ins.env && ins.defaultValue === void 0 && typeof process.env[ins.env] === "string") {
|
|
1212
1365
|
ins.required = false;
|
|
@@ -1214,7 +1367,9 @@ var _Command = class _Command {
|
|
|
1214
1367
|
if (ins.type === "boolean") {
|
|
1215
1368
|
ins.defaultValue = /^(t(rue)?|y(es)?|1)$/i.test(process.env[ins.env]);
|
|
1216
1369
|
} else if (ins.variadic) {
|
|
1217
|
-
ins.defaultValue = process.env[ins.env].replace(/\]|\[/, "").split(",").map((v) =>
|
|
1370
|
+
ins.defaultValue = process.env[ins.env].replace(/\]|\[/, "").split(",").map((v) => {
|
|
1371
|
+
return v.trim();
|
|
1372
|
+
});
|
|
1218
1373
|
} else {
|
|
1219
1374
|
ins.defaultValue = process.env[ins.env];
|
|
1220
1375
|
}
|
|
@@ -1223,7 +1378,7 @@ var _Command = class _Command {
|
|
|
1223
1378
|
return this;
|
|
1224
1379
|
}
|
|
1225
1380
|
/**
|
|
1226
|
-
*
|
|
1381
|
+
* register an action to be invoked when an option is set to true or string value.
|
|
1227
1382
|
*
|
|
1228
1383
|
* Hooks execute in addition to or instead of the main action handler,
|
|
1229
1384
|
* allowing for option-driven behavior. For example, `--help` and `--version`
|
|
@@ -1236,25 +1391,26 @@ var _Command = class _Command {
|
|
|
1236
1391
|
}
|
|
1237
1392
|
this.hooks.push({
|
|
1238
1393
|
name: optionName,
|
|
1239
|
-
predicate: setName(
|
|
1394
|
+
predicate: setName(`has${strFirstCharToUpperCase(optionName)}`, ({ opts }) => {
|
|
1240
1395
|
return opts[optionName] !== void 0 && opts[optionName] !== false && !(Array.isArray(opts[optionName]) && opts[optionName].length === 0);
|
|
1241
1396
|
}),
|
|
1242
1397
|
action: setName(optionName, action)
|
|
1243
1398
|
});
|
|
1244
1399
|
return this;
|
|
1245
1400
|
}
|
|
1246
|
-
/**
|
|
1401
|
+
/** parses command-line arguments with subcommand support and type-safe validation. */
|
|
1247
1402
|
parseArgv(argv = process.argv.slice(2)) {
|
|
1248
1403
|
const sub = findCommand(this, argv[0]);
|
|
1249
|
-
if (sub)
|
|
1404
|
+
if (sub) {
|
|
1405
|
+
return sub.parseArgv(argv.slice(1));
|
|
1406
|
+
}
|
|
1250
1407
|
argv = normalizeArgv(argv, this.options);
|
|
1251
1408
|
const parsed = parseArgs({
|
|
1252
1409
|
args: argv,
|
|
1253
1410
|
options: Object.fromEntries(
|
|
1254
|
-
this.options.map((o) =>
|
|
1255
|
-
o.name,
|
|
1256
|
-
|
|
1257
|
-
])
|
|
1411
|
+
this.options.map((o) => {
|
|
1412
|
+
return [o.name, { type: o.type, short: o.short, default: o.defaultValue, multiple: !!o.variadic }];
|
|
1413
|
+
})
|
|
1258
1414
|
),
|
|
1259
1415
|
allowPositionals: true,
|
|
1260
1416
|
tokens: true,
|
|
@@ -1267,9 +1423,13 @@ var _Command = class _Command {
|
|
|
1267
1423
|
return a[1] === false ? 1 : b[1] === false ? -1 : a[1] === true ? 1 : b[1] === true ? -1 : 0;
|
|
1268
1424
|
});
|
|
1269
1425
|
const args = resolveArguments(parsed.positionals, this.arguments);
|
|
1270
|
-
const opts = filterObject(parsed.values, (value) =>
|
|
1426
|
+
const opts = filterObject(parsed.values, (value) => {
|
|
1427
|
+
return value !== void 0;
|
|
1428
|
+
});
|
|
1271
1429
|
const errors = validateParsed(args, parsed.values, this.arguments, this.options);
|
|
1272
|
-
const path = getCommandAncestors(this).map((c) =>
|
|
1430
|
+
const path = getCommandAncestors(this).map((c) => {
|
|
1431
|
+
return c.name;
|
|
1432
|
+
});
|
|
1273
1433
|
const data = {
|
|
1274
1434
|
path,
|
|
1275
1435
|
name: this.name,
|
|
@@ -1279,18 +1439,23 @@ var _Command = class _Command {
|
|
|
1279
1439
|
errors,
|
|
1280
1440
|
cmd: this
|
|
1281
1441
|
};
|
|
1282
|
-
const hooks = this.hooks.filter((t) =>
|
|
1442
|
+
const hooks = this.hooks.filter((t) => {
|
|
1443
|
+
return t.predicate(data);
|
|
1444
|
+
});
|
|
1283
1445
|
const execute = /* @__PURE__ */ __name(async () => {
|
|
1284
1446
|
for (const hook of hooks) {
|
|
1285
1447
|
await hook.action(data);
|
|
1286
|
-
if (process.exitCode) {
|
|
1448
|
+
if (process.exitCode !== void 0) {
|
|
1287
1449
|
return;
|
|
1288
1450
|
}
|
|
1289
1451
|
}
|
|
1290
1452
|
await timer([[...path, this.name].join(" "), this.description], async (logger) => {
|
|
1291
1453
|
if (errors) {
|
|
1292
|
-
errors.forEach((msg) =>
|
|
1454
|
+
errors.forEach((msg) => {
|
|
1455
|
+
return logger.error(colors3.red(msg));
|
|
1456
|
+
});
|
|
1293
1457
|
process.exitCode = 1;
|
|
1458
|
+
return;
|
|
1294
1459
|
}
|
|
1295
1460
|
if (this.action) {
|
|
1296
1461
|
return await this.action(...args, opts, {
|
|
@@ -1307,14 +1472,14 @@ var _Command = class _Command {
|
|
|
1307
1472
|
return { ...data, hooks, execute };
|
|
1308
1473
|
}
|
|
1309
1474
|
/**
|
|
1310
|
-
*
|
|
1475
|
+
* sets the main action handler for this command, which is executed after any matching option hooks when the command is invoked.
|
|
1311
1476
|
* The handler receives parsed arguments and options with correct typings.
|
|
1312
1477
|
*/
|
|
1313
1478
|
setAction(fn) {
|
|
1314
1479
|
this.action = setName(this.name, fn);
|
|
1315
1480
|
return this;
|
|
1316
1481
|
}
|
|
1317
|
-
/**
|
|
1482
|
+
/** returns a new Command instance. Override this method in subclasses. */
|
|
1318
1483
|
createSubcommand(name) {
|
|
1319
1484
|
return new _Command(name, this);
|
|
1320
1485
|
}
|