citty 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -11
- package/README.md +1 -1
- package/dist/index.cjs +30 -192
- package/dist/index.d.ts +8 -6
- package/dist/index.mjs +28 -180
- package/package.json +15 -13
package/LICENSE
CHANGED
|
@@ -34,14 +34,3 @@ The above copyright notice and this permission notice shall be included in all c
|
|
|
34
34
|
|
|
35
35
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
36
36
|
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
Colorette dependency is bundled (https://github.com/jorgebucaran/colorette)
|
|
40
|
-
|
|
41
|
-
Copyright © Jorge Bucaran <https://jorgebucaran.com>
|
|
42
|
-
|
|
43
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
44
|
-
|
|
45
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
46
|
-
|
|
47
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const consola = require('consola');
|
|
4
|
+
const utils = require('consola/utils');
|
|
4
5
|
|
|
5
|
-
function
|
|
6
|
-
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
7
|
-
const n = Object.create(null);
|
|
8
|
-
if (e) {
|
|
9
|
-
for (const k in e) {
|
|
10
|
-
n[k] = e[k];
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
n.default = e;
|
|
14
|
-
return n;
|
|
15
|
-
}
|
|
6
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
16
7
|
|
|
17
|
-
const
|
|
8
|
+
const consola__default = /*#__PURE__*/_interopDefaultCompat(consola);
|
|
18
9
|
|
|
19
10
|
function toArray(val) {
|
|
20
11
|
if (Array.isArray(val)) {
|
|
21
12
|
return val;
|
|
22
13
|
}
|
|
23
|
-
return val
|
|
14
|
+
return val === void 0 ? [] : [val];
|
|
24
15
|
}
|
|
25
16
|
function formatLineColumns(lines, linePrefix = "") {
|
|
26
17
|
const maxLengh = [];
|
|
@@ -261,13 +252,13 @@ function parseArgs(rawArgs, argsDef) {
|
|
|
261
252
|
const nextPositionalArgument = positionalArguments.shift();
|
|
262
253
|
if (nextPositionalArgument !== void 0) {
|
|
263
254
|
parsedArgsProxy[arg.name] = nextPositionalArgument;
|
|
264
|
-
} else if (arg.default
|
|
265
|
-
parsedArgsProxy[arg.name] = arg.default;
|
|
266
|
-
} else {
|
|
255
|
+
} else if (arg.default === void 0 && arg.required !== false) {
|
|
267
256
|
throw new CLIError(
|
|
268
257
|
`Missing required positional argument: ${arg.name.toUpperCase()}`,
|
|
269
258
|
"EARG"
|
|
270
259
|
);
|
|
260
|
+
} else {
|
|
261
|
+
parsedArgsProxy[arg.name] = arg.default;
|
|
271
262
|
}
|
|
272
263
|
} else if (arg.required && parsedArgsProxy[arg.name] === void 0) {
|
|
273
264
|
throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
|
|
@@ -296,6 +287,7 @@ async function runCommand(cmd, opts) {
|
|
|
296
287
|
const context = {
|
|
297
288
|
rawArgs: opts.rawArgs,
|
|
298
289
|
args: parsedArgs,
|
|
290
|
+
data: opts.data,
|
|
299
291
|
cmd
|
|
300
292
|
};
|
|
301
293
|
if (typeof cmd.setup === "function") {
|
|
@@ -308,15 +300,12 @@ async function runCommand(cmd, opts) {
|
|
|
308
300
|
);
|
|
309
301
|
const subCommandName = opts.rawArgs[subCommandArgIndex];
|
|
310
302
|
if (!subCommandName && !cmd.run) {
|
|
311
|
-
throw new CLIError(
|
|
312
|
-
`Missing sub command. Use --help to see available sub commands.`,
|
|
313
|
-
"ESUBCOMMAND"
|
|
314
|
-
);
|
|
303
|
+
throw new CLIError(`No command specified.`, "E_NO_COMMAND");
|
|
315
304
|
}
|
|
316
305
|
if (!subCommands[subCommandName]) {
|
|
317
306
|
throw new CLIError(
|
|
318
|
-
`Unknown
|
|
319
|
-
"
|
|
307
|
+
`Unknown command \`${subCommandName}\``,
|
|
308
|
+
"E_UNKNOWN_COMMAND"
|
|
320
309
|
);
|
|
321
310
|
}
|
|
322
311
|
const subCommand = await resolveValue(subCommands[subCommandName]);
|
|
@@ -349,9 +338,9 @@ async function resolveSubCommand(cmd, rawArgs, parent) {
|
|
|
349
338
|
|
|
350
339
|
async function showUsage(cmd, parent) {
|
|
351
340
|
try {
|
|
352
|
-
|
|
341
|
+
consola__default.log(await renderUsage(cmd, parent) + "\n");
|
|
353
342
|
} catch (error) {
|
|
354
|
-
|
|
343
|
+
consola__default.error(error);
|
|
355
344
|
}
|
|
356
345
|
}
|
|
357
346
|
async function renderUsage(cmd, parent) {
|
|
@@ -368,7 +357,7 @@ async function renderUsage(cmd, parent) {
|
|
|
368
357
|
const name = arg.name.toUpperCase();
|
|
369
358
|
const isRequired = arg.required !== false && arg.default === void 0;
|
|
370
359
|
const usageHint = arg.default ? `="${arg.default}"` : "";
|
|
371
|
-
posLines.push([name + usageHint, arg.description || ""]);
|
|
360
|
+
posLines.push(["`" + name + usageHint + "`", arg.description || ""]);
|
|
372
361
|
usageLine.push(isRequired ? `<${name}>` : `[${name}]`);
|
|
373
362
|
} else {
|
|
374
363
|
const isRequired = arg.required === true && arg.default === void 0;
|
|
@@ -379,7 +368,7 @@ async function renderUsage(cmd, parent) {
|
|
|
379
368
|
", "
|
|
380
369
|
)) + (arg.type === "string" && (arg.valueHint || arg.default) ? `=${arg.valueHint ? `<${arg.valueHint}>` : `"${arg.default || ""}"`}` : "");
|
|
381
370
|
argLines.push([
|
|
382
|
-
argStr + (isRequired ? " (required)" : ""),
|
|
371
|
+
"`" + argStr + (isRequired ? " (required)" : "") + "`",
|
|
383
372
|
arg.description || ""
|
|
384
373
|
]);
|
|
385
374
|
if (isRequired) {
|
|
@@ -389,8 +378,11 @@ async function renderUsage(cmd, parent) {
|
|
|
389
378
|
}
|
|
390
379
|
if (cmd.subCommands) {
|
|
391
380
|
const commandNames = [];
|
|
392
|
-
|
|
393
|
-
|
|
381
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
382
|
+
for (const [name, sub] of Object.entries(subCommands)) {
|
|
383
|
+
const subCmd = await resolveValue(sub);
|
|
384
|
+
const meta = await resolveValue(subCmd?.meta);
|
|
385
|
+
commandsLines.push([`\`${name}\``, meta?.description || ""]);
|
|
394
386
|
commandNames.push(name);
|
|
395
387
|
}
|
|
396
388
|
usageLine.push(commandNames.join("|"));
|
|
@@ -398,29 +390,28 @@ async function renderUsage(cmd, parent) {
|
|
|
398
390
|
const usageLines = [];
|
|
399
391
|
const version = cmdMeta.version || parentMeta.version;
|
|
400
392
|
usageLines.push(
|
|
401
|
-
|
|
402
|
-
|
|
393
|
+
utils.colors.gray(
|
|
394
|
+
`${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`
|
|
395
|
+
),
|
|
403
396
|
""
|
|
404
397
|
);
|
|
405
398
|
const hasOptions = argLines.length > 0 || posLines.length > 0;
|
|
406
399
|
usageLines.push(
|
|
407
|
-
|
|
408
|
-
" "
|
|
409
|
-
)}`,
|
|
400
|
+
`${utils.colors.underline(utils.colors.bold("USAGE"))} \`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}\``,
|
|
410
401
|
""
|
|
411
402
|
);
|
|
412
403
|
if (posLines.length > 0) {
|
|
413
|
-
usageLines.push("ARGUMENTS
|
|
404
|
+
usageLines.push(utils.colors.underline(utils.colors.bold("ARGUMENTS")), "");
|
|
414
405
|
usageLines.push(formatLineColumns(posLines, " "));
|
|
415
406
|
usageLines.push("");
|
|
416
407
|
}
|
|
417
408
|
if (argLines.length > 0) {
|
|
418
|
-
usageLines.push("OPTIONS
|
|
409
|
+
usageLines.push(utils.colors.underline(utils.colors.bold("OPTIONS")), "");
|
|
419
410
|
usageLines.push(formatLineColumns(argLines, " "));
|
|
420
411
|
usageLines.push("");
|
|
421
412
|
}
|
|
422
413
|
if (commandsLines.length > 0) {
|
|
423
|
-
usageLines.push("COMMANDS
|
|
414
|
+
usageLines.push(utils.colors.underline(utils.colors.bold("COMMANDS")), "");
|
|
424
415
|
usageLines.push(formatLineColumns(commandsLines, " "));
|
|
425
416
|
usageLines.push(
|
|
426
417
|
"",
|
|
@@ -430,155 +421,6 @@ async function renderUsage(cmd, parent) {
|
|
|
430
421
|
return usageLines.filter((l) => typeof l === "string").join("\n");
|
|
431
422
|
}
|
|
432
423
|
|
|
433
|
-
const {
|
|
434
|
-
env = {},
|
|
435
|
-
argv = [],
|
|
436
|
-
platform = "",
|
|
437
|
-
} = typeof process === "undefined" ? {} : process;
|
|
438
|
-
|
|
439
|
-
const isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
|
|
440
|
-
const isForced = "FORCE_COLOR" in env || argv.includes("--color");
|
|
441
|
-
const isWindows = platform === "win32";
|
|
442
|
-
const isDumbTerminal = env.TERM === "dumb";
|
|
443
|
-
|
|
444
|
-
const isCompatibleTerminal =
|
|
445
|
-
tty__namespace && tty__namespace.isatty && tty__namespace.isatty(1) && env.TERM && !isDumbTerminal;
|
|
446
|
-
|
|
447
|
-
const isCI =
|
|
448
|
-
"CI" in env &&
|
|
449
|
-
("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);
|
|
450
|
-
|
|
451
|
-
const isColorSupported =
|
|
452
|
-
!isDisabled &&
|
|
453
|
-
(isForced || (isWindows && !isDumbTerminal) || isCompatibleTerminal || isCI);
|
|
454
|
-
|
|
455
|
-
const replaceClose = (
|
|
456
|
-
index,
|
|
457
|
-
string,
|
|
458
|
-
close,
|
|
459
|
-
replace,
|
|
460
|
-
head = string.substring(0, index) + replace,
|
|
461
|
-
tail = string.substring(index + close.length),
|
|
462
|
-
next = tail.indexOf(close)
|
|
463
|
-
) => head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
|
|
464
|
-
|
|
465
|
-
const clearBleed = (index, string, open, close, replace) =>
|
|
466
|
-
index < 0
|
|
467
|
-
? open + string + close
|
|
468
|
-
: open + replaceClose(index, string, close, replace) + close;
|
|
469
|
-
|
|
470
|
-
const filterEmpty =
|
|
471
|
-
(open, close, replace = open, at = open.length + 1) =>
|
|
472
|
-
(string) =>
|
|
473
|
-
string || !(string === "" || string === undefined)
|
|
474
|
-
? clearBleed(
|
|
475
|
-
("" + string).indexOf(close, at),
|
|
476
|
-
string,
|
|
477
|
-
open,
|
|
478
|
-
close,
|
|
479
|
-
replace
|
|
480
|
-
)
|
|
481
|
-
: "";
|
|
482
|
-
|
|
483
|
-
const init = (open, close, replace) =>
|
|
484
|
-
filterEmpty(`\x1b[${open}m`, `\x1b[${close}m`, replace);
|
|
485
|
-
|
|
486
|
-
const colors = {
|
|
487
|
-
reset: init(0, 0),
|
|
488
|
-
bold: init(1, 22, "\x1b[22m\x1b[1m"),
|
|
489
|
-
dim: init(2, 22, "\x1b[22m\x1b[2m"),
|
|
490
|
-
italic: init(3, 23),
|
|
491
|
-
underline: init(4, 24),
|
|
492
|
-
inverse: init(7, 27),
|
|
493
|
-
hidden: init(8, 28),
|
|
494
|
-
strikethrough: init(9, 29),
|
|
495
|
-
black: init(30, 39),
|
|
496
|
-
red: init(31, 39),
|
|
497
|
-
green: init(32, 39),
|
|
498
|
-
yellow: init(33, 39),
|
|
499
|
-
blue: init(34, 39),
|
|
500
|
-
magenta: init(35, 39),
|
|
501
|
-
cyan: init(36, 39),
|
|
502
|
-
white: init(37, 39),
|
|
503
|
-
gray: init(90, 39),
|
|
504
|
-
bgBlack: init(40, 49),
|
|
505
|
-
bgRed: init(41, 49),
|
|
506
|
-
bgGreen: init(42, 49),
|
|
507
|
-
bgYellow: init(43, 49),
|
|
508
|
-
bgBlue: init(44, 49),
|
|
509
|
-
bgMagenta: init(45, 49),
|
|
510
|
-
bgCyan: init(46, 49),
|
|
511
|
-
bgWhite: init(47, 49),
|
|
512
|
-
blackBright: init(90, 39),
|
|
513
|
-
redBright: init(91, 39),
|
|
514
|
-
greenBright: init(92, 39),
|
|
515
|
-
yellowBright: init(93, 39),
|
|
516
|
-
blueBright: init(94, 39),
|
|
517
|
-
magentaBright: init(95, 39),
|
|
518
|
-
cyanBright: init(96, 39),
|
|
519
|
-
whiteBright: init(97, 39),
|
|
520
|
-
bgBlackBright: init(100, 49),
|
|
521
|
-
bgRedBright: init(101, 49),
|
|
522
|
-
bgGreenBright: init(102, 49),
|
|
523
|
-
bgYellowBright: init(103, 49),
|
|
524
|
-
bgBlueBright: init(104, 49),
|
|
525
|
-
bgMagentaBright: init(105, 49),
|
|
526
|
-
bgCyanBright: init(106, 49),
|
|
527
|
-
bgWhiteBright: init(107, 49),
|
|
528
|
-
};
|
|
529
|
-
|
|
530
|
-
const createColors = ({ useColor = isColorSupported } = {}) =>
|
|
531
|
-
useColor
|
|
532
|
-
? colors
|
|
533
|
-
: Object.keys(colors).reduce(
|
|
534
|
-
(colors, key) => ({ ...colors, [key]: String }),
|
|
535
|
-
{}
|
|
536
|
-
);
|
|
537
|
-
|
|
538
|
-
const {
|
|
539
|
-
reset,
|
|
540
|
-
bold,
|
|
541
|
-
dim,
|
|
542
|
-
italic,
|
|
543
|
-
underline,
|
|
544
|
-
inverse,
|
|
545
|
-
hidden,
|
|
546
|
-
strikethrough,
|
|
547
|
-
black,
|
|
548
|
-
red,
|
|
549
|
-
green,
|
|
550
|
-
yellow,
|
|
551
|
-
blue,
|
|
552
|
-
magenta,
|
|
553
|
-
cyan,
|
|
554
|
-
white,
|
|
555
|
-
gray,
|
|
556
|
-
bgBlack,
|
|
557
|
-
bgRed,
|
|
558
|
-
bgGreen,
|
|
559
|
-
bgYellow,
|
|
560
|
-
bgBlue,
|
|
561
|
-
bgMagenta,
|
|
562
|
-
bgCyan,
|
|
563
|
-
bgWhite,
|
|
564
|
-
blackBright,
|
|
565
|
-
redBright,
|
|
566
|
-
greenBright,
|
|
567
|
-
yellowBright,
|
|
568
|
-
blueBright,
|
|
569
|
-
magentaBright,
|
|
570
|
-
cyanBright,
|
|
571
|
-
whiteBright,
|
|
572
|
-
bgBlackBright,
|
|
573
|
-
bgRedBright,
|
|
574
|
-
bgGreenBright,
|
|
575
|
-
bgYellowBright,
|
|
576
|
-
bgBlueBright,
|
|
577
|
-
bgMagentaBright,
|
|
578
|
-
bgCyanBright,
|
|
579
|
-
bgWhiteBright,
|
|
580
|
-
} = createColors();
|
|
581
|
-
|
|
582
424
|
async function runMain(cmd, opts = {}) {
|
|
583
425
|
const rawArgs = opts.rawArgs || process.argv.slice(2);
|
|
584
426
|
try {
|
|
@@ -591,16 +433,12 @@ async function runMain(cmd, opts = {}) {
|
|
|
591
433
|
} catch (error) {
|
|
592
434
|
const isCLIError = error instanceof CLIError;
|
|
593
435
|
if (!isCLIError) {
|
|
594
|
-
|
|
436
|
+
consola__default.error(error, "\n");
|
|
595
437
|
}
|
|
596
|
-
console.error(
|
|
597
|
-
`
|
|
598
|
-
${bgRed(` ${error.code || error.name} `)} ${error.message}
|
|
599
|
-
`
|
|
600
|
-
);
|
|
601
438
|
if (isCLIError) {
|
|
602
439
|
await showUsage(...await resolveSubCommand(cmd, rawArgs));
|
|
603
440
|
}
|
|
441
|
+
consola__default.error(error.message);
|
|
604
442
|
process.exit(1);
|
|
605
443
|
}
|
|
606
444
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -48,8 +48,9 @@ type CommandDef<T extends ArgsDef = ArgsDef> = {
|
|
|
48
48
|
type CommandContext<T extends ArgsDef = ArgsDef> = {
|
|
49
49
|
rawArgs: string[];
|
|
50
50
|
args: ParsedArgs<T>;
|
|
51
|
-
cmd: CommandDef
|
|
51
|
+
cmd: CommandDef<T>;
|
|
52
52
|
subCommand?: CommandDef<T>;
|
|
53
|
+
data?: any;
|
|
53
54
|
};
|
|
54
55
|
type Awaitable<T> = () => T | Promise<T>;
|
|
55
56
|
type Resolvable<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
|
|
@@ -57,18 +58,19 @@ type Resolvable<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
|
|
|
57
58
|
declare function defineCommand<T extends ArgsDef = ArgsDef>(def: CommandDef<T>): CommandDef<T>;
|
|
58
59
|
interface RunCommandOptions {
|
|
59
60
|
rawArgs: string[];
|
|
61
|
+
data?: any;
|
|
60
62
|
showUsage?: boolean;
|
|
61
63
|
}
|
|
62
|
-
declare function runCommand(cmd: CommandDef
|
|
64
|
+
declare function runCommand<T extends ArgsDef = ArgsDef>(cmd: CommandDef<T>, opts: RunCommandOptions): Promise<void>;
|
|
63
65
|
|
|
64
66
|
interface RunMainOptions {
|
|
65
67
|
rawArgs?: string[];
|
|
66
68
|
}
|
|
67
|
-
declare function runMain(cmd: CommandDef
|
|
69
|
+
declare function runMain<T extends ArgsDef = ArgsDef>(cmd: CommandDef<T>, opts?: RunMainOptions): Promise<void>;
|
|
68
70
|
|
|
69
|
-
declare function parseArgs(rawArgs: string[], argsDef: ArgsDef): ParsedArgs
|
|
71
|
+
declare function parseArgs<T extends ArgsDef = ArgsDef>(rawArgs: string[], argsDef: ArgsDef): ParsedArgs<T>;
|
|
70
72
|
|
|
71
|
-
declare function showUsage(cmd: CommandDef
|
|
72
|
-
declare function renderUsage(cmd: CommandDef
|
|
73
|
+
declare function showUsage<T extends ArgsDef = ArgsDef>(cmd: CommandDef<T>, parent?: CommandDef<T>): Promise<void>;
|
|
74
|
+
declare function renderUsage<T extends ArgsDef = ArgsDef>(cmd: CommandDef<T>, parent?: CommandDef<T>): Promise<string>;
|
|
73
75
|
|
|
74
76
|
export { Arg, ArgDef, ArgType, ArgsDef, Awaitable, BooleanArgDef, CommandContext, CommandDef, CommandMeta, ParsedArgs, PositionalArgDef, Resolvable, RunCommandOptions, RunMainOptions, StringArgDef, SubCommandsDef, _ArgDef, defineCommand, parseArgs, renderUsage, runCommand, runMain, showUsage };
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import consola from 'consola';
|
|
2
|
+
import { colors } from 'consola/utils';
|
|
2
3
|
|
|
3
4
|
function toArray(val) {
|
|
4
5
|
if (Array.isArray(val)) {
|
|
5
6
|
return val;
|
|
6
7
|
}
|
|
7
|
-
return val
|
|
8
|
+
return val === void 0 ? [] : [val];
|
|
8
9
|
}
|
|
9
10
|
function formatLineColumns(lines, linePrefix = "") {
|
|
10
11
|
const maxLengh = [];
|
|
@@ -245,13 +246,13 @@ function parseArgs(rawArgs, argsDef) {
|
|
|
245
246
|
const nextPositionalArgument = positionalArguments.shift();
|
|
246
247
|
if (nextPositionalArgument !== void 0) {
|
|
247
248
|
parsedArgsProxy[arg.name] = nextPositionalArgument;
|
|
248
|
-
} else if (arg.default
|
|
249
|
-
parsedArgsProxy[arg.name] = arg.default;
|
|
250
|
-
} else {
|
|
249
|
+
} else if (arg.default === void 0 && arg.required !== false) {
|
|
251
250
|
throw new CLIError(
|
|
252
251
|
`Missing required positional argument: ${arg.name.toUpperCase()}`,
|
|
253
252
|
"EARG"
|
|
254
253
|
);
|
|
254
|
+
} else {
|
|
255
|
+
parsedArgsProxy[arg.name] = arg.default;
|
|
255
256
|
}
|
|
256
257
|
} else if (arg.required && parsedArgsProxy[arg.name] === void 0) {
|
|
257
258
|
throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
|
|
@@ -280,6 +281,7 @@ async function runCommand(cmd, opts) {
|
|
|
280
281
|
const context = {
|
|
281
282
|
rawArgs: opts.rawArgs,
|
|
282
283
|
args: parsedArgs,
|
|
284
|
+
data: opts.data,
|
|
283
285
|
cmd
|
|
284
286
|
};
|
|
285
287
|
if (typeof cmd.setup === "function") {
|
|
@@ -292,15 +294,12 @@ async function runCommand(cmd, opts) {
|
|
|
292
294
|
);
|
|
293
295
|
const subCommandName = opts.rawArgs[subCommandArgIndex];
|
|
294
296
|
if (!subCommandName && !cmd.run) {
|
|
295
|
-
throw new CLIError(
|
|
296
|
-
`Missing sub command. Use --help to see available sub commands.`,
|
|
297
|
-
"ESUBCOMMAND"
|
|
298
|
-
);
|
|
297
|
+
throw new CLIError(`No command specified.`, "E_NO_COMMAND");
|
|
299
298
|
}
|
|
300
299
|
if (!subCommands[subCommandName]) {
|
|
301
300
|
throw new CLIError(
|
|
302
|
-
`Unknown
|
|
303
|
-
"
|
|
301
|
+
`Unknown command \`${subCommandName}\``,
|
|
302
|
+
"E_UNKNOWN_COMMAND"
|
|
304
303
|
);
|
|
305
304
|
}
|
|
306
305
|
const subCommand = await resolveValue(subCommands[subCommandName]);
|
|
@@ -333,9 +332,9 @@ async function resolveSubCommand(cmd, rawArgs, parent) {
|
|
|
333
332
|
|
|
334
333
|
async function showUsage(cmd, parent) {
|
|
335
334
|
try {
|
|
336
|
-
|
|
335
|
+
consola.log(await renderUsage(cmd, parent) + "\n");
|
|
337
336
|
} catch (error) {
|
|
338
|
-
|
|
337
|
+
consola.error(error);
|
|
339
338
|
}
|
|
340
339
|
}
|
|
341
340
|
async function renderUsage(cmd, parent) {
|
|
@@ -352,7 +351,7 @@ async function renderUsage(cmd, parent) {
|
|
|
352
351
|
const name = arg.name.toUpperCase();
|
|
353
352
|
const isRequired = arg.required !== false && arg.default === void 0;
|
|
354
353
|
const usageHint = arg.default ? `="${arg.default}"` : "";
|
|
355
|
-
posLines.push([name + usageHint, arg.description || ""]);
|
|
354
|
+
posLines.push(["`" + name + usageHint + "`", arg.description || ""]);
|
|
356
355
|
usageLine.push(isRequired ? `<${name}>` : `[${name}]`);
|
|
357
356
|
} else {
|
|
358
357
|
const isRequired = arg.required === true && arg.default === void 0;
|
|
@@ -363,7 +362,7 @@ async function renderUsage(cmd, parent) {
|
|
|
363
362
|
", "
|
|
364
363
|
)) + (arg.type === "string" && (arg.valueHint || arg.default) ? `=${arg.valueHint ? `<${arg.valueHint}>` : `"${arg.default || ""}"`}` : "");
|
|
365
364
|
argLines.push([
|
|
366
|
-
argStr + (isRequired ? " (required)" : ""),
|
|
365
|
+
"`" + argStr + (isRequired ? " (required)" : "") + "`",
|
|
367
366
|
arg.description || ""
|
|
368
367
|
]);
|
|
369
368
|
if (isRequired) {
|
|
@@ -373,8 +372,11 @@ async function renderUsage(cmd, parent) {
|
|
|
373
372
|
}
|
|
374
373
|
if (cmd.subCommands) {
|
|
375
374
|
const commandNames = [];
|
|
376
|
-
|
|
377
|
-
|
|
375
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
376
|
+
for (const [name, sub] of Object.entries(subCommands)) {
|
|
377
|
+
const subCmd = await resolveValue(sub);
|
|
378
|
+
const meta = await resolveValue(subCmd?.meta);
|
|
379
|
+
commandsLines.push([`\`${name}\``, meta?.description || ""]);
|
|
378
380
|
commandNames.push(name);
|
|
379
381
|
}
|
|
380
382
|
usageLine.push(commandNames.join("|"));
|
|
@@ -382,29 +384,28 @@ async function renderUsage(cmd, parent) {
|
|
|
382
384
|
const usageLines = [];
|
|
383
385
|
const version = cmdMeta.version || parentMeta.version;
|
|
384
386
|
usageLines.push(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
+
colors.gray(
|
|
388
|
+
`${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`
|
|
389
|
+
),
|
|
387
390
|
""
|
|
388
391
|
);
|
|
389
392
|
const hasOptions = argLines.length > 0 || posLines.length > 0;
|
|
390
393
|
usageLines.push(
|
|
391
|
-
|
|
392
|
-
" "
|
|
393
|
-
)}`,
|
|
394
|
+
`${colors.underline(colors.bold("USAGE"))} \`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}\``,
|
|
394
395
|
""
|
|
395
396
|
);
|
|
396
397
|
if (posLines.length > 0) {
|
|
397
|
-
usageLines.push("ARGUMENTS
|
|
398
|
+
usageLines.push(colors.underline(colors.bold("ARGUMENTS")), "");
|
|
398
399
|
usageLines.push(formatLineColumns(posLines, " "));
|
|
399
400
|
usageLines.push("");
|
|
400
401
|
}
|
|
401
402
|
if (argLines.length > 0) {
|
|
402
|
-
usageLines.push("OPTIONS
|
|
403
|
+
usageLines.push(colors.underline(colors.bold("OPTIONS")), "");
|
|
403
404
|
usageLines.push(formatLineColumns(argLines, " "));
|
|
404
405
|
usageLines.push("");
|
|
405
406
|
}
|
|
406
407
|
if (commandsLines.length > 0) {
|
|
407
|
-
usageLines.push("COMMANDS
|
|
408
|
+
usageLines.push(colors.underline(colors.bold("COMMANDS")), "");
|
|
408
409
|
usageLines.push(formatLineColumns(commandsLines, " "));
|
|
409
410
|
usageLines.push(
|
|
410
411
|
"",
|
|
@@ -414,155 +415,6 @@ async function renderUsage(cmd, parent) {
|
|
|
414
415
|
return usageLines.filter((l) => typeof l === "string").join("\n");
|
|
415
416
|
}
|
|
416
417
|
|
|
417
|
-
const {
|
|
418
|
-
env = {},
|
|
419
|
-
argv = [],
|
|
420
|
-
platform = "",
|
|
421
|
-
} = typeof process === "undefined" ? {} : process;
|
|
422
|
-
|
|
423
|
-
const isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
|
|
424
|
-
const isForced = "FORCE_COLOR" in env || argv.includes("--color");
|
|
425
|
-
const isWindows = platform === "win32";
|
|
426
|
-
const isDumbTerminal = env.TERM === "dumb";
|
|
427
|
-
|
|
428
|
-
const isCompatibleTerminal =
|
|
429
|
-
tty && tty.isatty && tty.isatty(1) && env.TERM && !isDumbTerminal;
|
|
430
|
-
|
|
431
|
-
const isCI =
|
|
432
|
-
"CI" in env &&
|
|
433
|
-
("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);
|
|
434
|
-
|
|
435
|
-
const isColorSupported =
|
|
436
|
-
!isDisabled &&
|
|
437
|
-
(isForced || (isWindows && !isDumbTerminal) || isCompatibleTerminal || isCI);
|
|
438
|
-
|
|
439
|
-
const replaceClose = (
|
|
440
|
-
index,
|
|
441
|
-
string,
|
|
442
|
-
close,
|
|
443
|
-
replace,
|
|
444
|
-
head = string.substring(0, index) + replace,
|
|
445
|
-
tail = string.substring(index + close.length),
|
|
446
|
-
next = tail.indexOf(close)
|
|
447
|
-
) => head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
|
|
448
|
-
|
|
449
|
-
const clearBleed = (index, string, open, close, replace) =>
|
|
450
|
-
index < 0
|
|
451
|
-
? open + string + close
|
|
452
|
-
: open + replaceClose(index, string, close, replace) + close;
|
|
453
|
-
|
|
454
|
-
const filterEmpty =
|
|
455
|
-
(open, close, replace = open, at = open.length + 1) =>
|
|
456
|
-
(string) =>
|
|
457
|
-
string || !(string === "" || string === undefined)
|
|
458
|
-
? clearBleed(
|
|
459
|
-
("" + string).indexOf(close, at),
|
|
460
|
-
string,
|
|
461
|
-
open,
|
|
462
|
-
close,
|
|
463
|
-
replace
|
|
464
|
-
)
|
|
465
|
-
: "";
|
|
466
|
-
|
|
467
|
-
const init = (open, close, replace) =>
|
|
468
|
-
filterEmpty(`\x1b[${open}m`, `\x1b[${close}m`, replace);
|
|
469
|
-
|
|
470
|
-
const colors = {
|
|
471
|
-
reset: init(0, 0),
|
|
472
|
-
bold: init(1, 22, "\x1b[22m\x1b[1m"),
|
|
473
|
-
dim: init(2, 22, "\x1b[22m\x1b[2m"),
|
|
474
|
-
italic: init(3, 23),
|
|
475
|
-
underline: init(4, 24),
|
|
476
|
-
inverse: init(7, 27),
|
|
477
|
-
hidden: init(8, 28),
|
|
478
|
-
strikethrough: init(9, 29),
|
|
479
|
-
black: init(30, 39),
|
|
480
|
-
red: init(31, 39),
|
|
481
|
-
green: init(32, 39),
|
|
482
|
-
yellow: init(33, 39),
|
|
483
|
-
blue: init(34, 39),
|
|
484
|
-
magenta: init(35, 39),
|
|
485
|
-
cyan: init(36, 39),
|
|
486
|
-
white: init(37, 39),
|
|
487
|
-
gray: init(90, 39),
|
|
488
|
-
bgBlack: init(40, 49),
|
|
489
|
-
bgRed: init(41, 49),
|
|
490
|
-
bgGreen: init(42, 49),
|
|
491
|
-
bgYellow: init(43, 49),
|
|
492
|
-
bgBlue: init(44, 49),
|
|
493
|
-
bgMagenta: init(45, 49),
|
|
494
|
-
bgCyan: init(46, 49),
|
|
495
|
-
bgWhite: init(47, 49),
|
|
496
|
-
blackBright: init(90, 39),
|
|
497
|
-
redBright: init(91, 39),
|
|
498
|
-
greenBright: init(92, 39),
|
|
499
|
-
yellowBright: init(93, 39),
|
|
500
|
-
blueBright: init(94, 39),
|
|
501
|
-
magentaBright: init(95, 39),
|
|
502
|
-
cyanBright: init(96, 39),
|
|
503
|
-
whiteBright: init(97, 39),
|
|
504
|
-
bgBlackBright: init(100, 49),
|
|
505
|
-
bgRedBright: init(101, 49),
|
|
506
|
-
bgGreenBright: init(102, 49),
|
|
507
|
-
bgYellowBright: init(103, 49),
|
|
508
|
-
bgBlueBright: init(104, 49),
|
|
509
|
-
bgMagentaBright: init(105, 49),
|
|
510
|
-
bgCyanBright: init(106, 49),
|
|
511
|
-
bgWhiteBright: init(107, 49),
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
const createColors = ({ useColor = isColorSupported } = {}) =>
|
|
515
|
-
useColor
|
|
516
|
-
? colors
|
|
517
|
-
: Object.keys(colors).reduce(
|
|
518
|
-
(colors, key) => ({ ...colors, [key]: String }),
|
|
519
|
-
{}
|
|
520
|
-
);
|
|
521
|
-
|
|
522
|
-
const {
|
|
523
|
-
reset,
|
|
524
|
-
bold,
|
|
525
|
-
dim,
|
|
526
|
-
italic,
|
|
527
|
-
underline,
|
|
528
|
-
inverse,
|
|
529
|
-
hidden,
|
|
530
|
-
strikethrough,
|
|
531
|
-
black,
|
|
532
|
-
red,
|
|
533
|
-
green,
|
|
534
|
-
yellow,
|
|
535
|
-
blue,
|
|
536
|
-
magenta,
|
|
537
|
-
cyan,
|
|
538
|
-
white,
|
|
539
|
-
gray,
|
|
540
|
-
bgBlack,
|
|
541
|
-
bgRed,
|
|
542
|
-
bgGreen,
|
|
543
|
-
bgYellow,
|
|
544
|
-
bgBlue,
|
|
545
|
-
bgMagenta,
|
|
546
|
-
bgCyan,
|
|
547
|
-
bgWhite,
|
|
548
|
-
blackBright,
|
|
549
|
-
redBright,
|
|
550
|
-
greenBright,
|
|
551
|
-
yellowBright,
|
|
552
|
-
blueBright,
|
|
553
|
-
magentaBright,
|
|
554
|
-
cyanBright,
|
|
555
|
-
whiteBright,
|
|
556
|
-
bgBlackBright,
|
|
557
|
-
bgRedBright,
|
|
558
|
-
bgGreenBright,
|
|
559
|
-
bgYellowBright,
|
|
560
|
-
bgBlueBright,
|
|
561
|
-
bgMagentaBright,
|
|
562
|
-
bgCyanBright,
|
|
563
|
-
bgWhiteBright,
|
|
564
|
-
} = createColors();
|
|
565
|
-
|
|
566
418
|
async function runMain(cmd, opts = {}) {
|
|
567
419
|
const rawArgs = opts.rawArgs || process.argv.slice(2);
|
|
568
420
|
try {
|
|
@@ -575,16 +427,12 @@ async function runMain(cmd, opts = {}) {
|
|
|
575
427
|
} catch (error) {
|
|
576
428
|
const isCLIError = error instanceof CLIError;
|
|
577
429
|
if (!isCLIError) {
|
|
578
|
-
|
|
430
|
+
consola.error(error, "\n");
|
|
579
431
|
}
|
|
580
|
-
console.error(
|
|
581
|
-
`
|
|
582
|
-
${bgRed(` ${error.code || error.name} `)} ${error.message}
|
|
583
|
-
`
|
|
584
|
-
);
|
|
585
432
|
if (isCLIError) {
|
|
586
433
|
await showUsage(...await resolveSubCommand(cmd, rawArgs));
|
|
587
434
|
}
|
|
435
|
+
consola.error(error.message);
|
|
588
436
|
process.exit(1);
|
|
589
437
|
}
|
|
590
438
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "citty",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Elegant CLI Builder",
|
|
5
5
|
"repository": "unjs/citty",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,19 +29,21 @@
|
|
|
29
29
|
"release": "pnpm test && changelogen --release --push && npm publish",
|
|
30
30
|
"test": "pnpm lint && vitest run --coverage"
|
|
31
31
|
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"consola": "^3.2.3"
|
|
34
|
+
},
|
|
32
35
|
"devDependencies": {
|
|
33
|
-
"@types/node": "^
|
|
34
|
-
"@vitest/coverage-
|
|
35
|
-
"changelogen": "^0.5.
|
|
36
|
-
"
|
|
37
|
-
"eslint": "^
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"prettier": "^2.8.7",
|
|
36
|
+
"@types/node": "^20.4.0",
|
|
37
|
+
"@vitest/coverage-v8": "^0.32.4",
|
|
38
|
+
"changelogen": "^0.5.4",
|
|
39
|
+
"eslint": "^8.44.0",
|
|
40
|
+
"eslint-config-unjs": "^0.2.1",
|
|
41
|
+
"jiti": "^1.19.1",
|
|
42
|
+
"prettier": "^3.0.0",
|
|
41
43
|
"scule": "^1.0.0",
|
|
42
|
-
"typescript": "^5.
|
|
43
|
-
"unbuild": "^1.2.
|
|
44
|
-
"vitest": "^0.
|
|
44
|
+
"typescript": "^5.1.6",
|
|
45
|
+
"unbuild": "^1.2.1",
|
|
46
|
+
"vitest": "^0.32.4"
|
|
45
47
|
},
|
|
46
|
-
"packageManager": "pnpm@8.
|
|
48
|
+
"packageManager": "pnpm@8.6.6"
|
|
47
49
|
}
|