@kaynooo/cli-pkg 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +384 -166
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -26,7 +26,7 @@ var __esm = (fn, res, err) => () => {
|
|
|
26
26
|
return res;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
// ../../node_modules/.bun/@kaynooo+utils@2.31.
|
|
29
|
+
// ../../node_modules/.bun/@kaynooo+utils@2.31.2+d0769e28dc4dad16/node_modules/@kaynooo/utils/dist/chunk-mtetydvc.js
|
|
30
30
|
function x(s) {
|
|
31
31
|
let r = s.startsWith("#") ? s.slice(1).toLowerCase() : s.toLowerCase();
|
|
32
32
|
if (!/^[a-f0-9]+$/.test(r))
|
|
@@ -245,7 +245,7 @@ class e {
|
|
|
245
245
|
var m = (s) => s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4, p = (s) => s <= 0.0031308 ? 12.92 * s : 1.055 * s ** 0.4166666666666667 - 0.055, i = (s, r) => Math.round(s * 10 ** r) / 10 ** r;
|
|
246
246
|
var init_chunk_mtetydvc = () => {};
|
|
247
247
|
|
|
248
|
-
// ../../node_modules/.bun/@kaynooo+utils@2.31.
|
|
248
|
+
// ../../node_modules/.bun/@kaynooo+utils@2.31.2+d0769e28dc4dad16/node_modules/@kaynooo/utils/dist/chunk-y1msbssb.js
|
|
249
249
|
function h(i, n = globalThis.process?.env ?? {}) {
|
|
250
250
|
if (n.FORCE_COLOR !== undefined)
|
|
251
251
|
return b.has(n.FORCE_COLOR);
|
|
@@ -287,7 +287,7 @@ var init_chunk_y1msbssb = __esm(() => {
|
|
|
287
287
|
t = le();
|
|
288
288
|
});
|
|
289
289
|
|
|
290
|
-
// ../../node_modules/.bun/@kaynooo+utils@2.31.
|
|
290
|
+
// ../../node_modules/.bun/@kaynooo+utils@2.31.2+d0769e28dc4dad16/node_modules/@kaynooo/utils/dist/tools/colors.js
|
|
291
291
|
var init_colors = __esm(() => {
|
|
292
292
|
init_chunk_y1msbssb();
|
|
293
293
|
});
|
|
@@ -421,48 +421,8 @@ var init_format = __esm(() => {
|
|
|
421
421
|
ESCAPE = String.fromCharCode(27);
|
|
422
422
|
});
|
|
423
423
|
|
|
424
|
-
// ../kit/src/
|
|
425
|
-
function distance(a, b) {
|
|
426
|
-
let previous = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
427
|
-
for (const [i, left] of [...a].entries()) {
|
|
428
|
-
const current = [i + 1];
|
|
429
|
-
for (const [j, right] of [...b].entries())
|
|
430
|
-
current.push(Math.min((previous[j + 1] ?? 0) + 1, (current[j] ?? 0) + 1, (previous[j] ?? 0) + (left === right ? 0 : 1)));
|
|
431
|
-
previous = current;
|
|
432
|
-
}
|
|
433
|
-
return previous[b.length] ?? 0;
|
|
434
|
-
}
|
|
435
|
-
function closest(name, names) {
|
|
436
|
-
const started = names.find((known) => known.startsWith(name));
|
|
437
|
-
if (started !== undefined)
|
|
438
|
-
return started;
|
|
439
|
-
const [best] = names.map((known) => ({ known, far: distance(name, known) })).sort((a, b) => a.far - b.far);
|
|
440
|
-
return best !== undefined && best.far <= (name.length < 4 ? 1 : 2) ? best.known : undefined;
|
|
441
|
-
}
|
|
442
|
-
var ANSI;
|
|
443
|
-
var init_text = __esm(() => {
|
|
444
|
-
ANSI = new RegExp(`${String.fromCharCode(27)}\\[[\\d;?]*[a-z]`, "gi");
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
// ../kit/src/args.ts
|
|
424
|
+
// ../kit/src/help.ts
|
|
448
425
|
import process3 from "process";
|
|
449
|
-
import { parseArgs } from "util";
|
|
450
|
-
function jsonOption(holds) {
|
|
451
|
-
return { type: "boolean", description: holds === undefined ? "print JSON" : `print JSON: ${holds}` };
|
|
452
|
-
}
|
|
453
|
-
function fail(message, code = 2, hint) {
|
|
454
|
-
throw new Exit(message, code, hint);
|
|
455
|
-
}
|
|
456
|
-
function badUsage(message) {
|
|
457
|
-
throw new UsageError(message);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
class Completing {
|
|
461
|
-
options;
|
|
462
|
-
constructor(options) {
|
|
463
|
-
this.options = options;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
426
|
function usageLine(usage, colors = paint(process3.stdout)) {
|
|
467
427
|
return `${colors.bold("Usage:")} ${usage.replace(USAGE_PREFIX, "").replaceAll(OPTIONAL, (part) => colors.dim(part))}`;
|
|
468
428
|
}
|
|
@@ -498,13 +458,95 @@ function exampleRows(examples, colors = paint(process3.stdout)) {
|
|
|
498
458
|
function optionRows(options, colors = paint(process3.stdout)) {
|
|
499
459
|
const rows = Object.entries(options).map(([name, option]) => {
|
|
500
460
|
const short = option.short === undefined ? " " : `${colors.cyan(`-${option.short}`)}, `;
|
|
501
|
-
const
|
|
502
|
-
|
|
461
|
+
const named = option.choices === undefined ? "<value>" : `<${option.choices.join("|")}>`;
|
|
462
|
+
const placeholder = option.optional === undefined ? named : `[${named}]`;
|
|
463
|
+
const value = option.type === "string" ? ` ${colors.dim(placeholder)}` : "";
|
|
464
|
+
return { flag: `${short}${colors.cyan(`--${name}`)}${value}`, width: `-x, --${name}`.length + (option.type === "string" ? placeholder.length + 1 : 0), description: option.description ?? "" };
|
|
503
465
|
});
|
|
504
466
|
const width = Math.max(0, ...rows.map((row) => row.width));
|
|
505
467
|
return rows.map((row) => row.description === "" ? ` ${row.flag}` : ` ${row.flag}${" ".repeat(width - row.width)} ${colors.dim(row.description)}`);
|
|
506
468
|
}
|
|
507
|
-
|
|
469
|
+
var OPTIONAL, USAGE_PREFIX, FULL_STOP;
|
|
470
|
+
var init_help = __esm(() => {
|
|
471
|
+
init_style();
|
|
472
|
+
OPTIONAL = /\[[^\]]+\]/g;
|
|
473
|
+
USAGE_PREFIX = /^usage:\s*/i;
|
|
474
|
+
FULL_STOP = /\.$/;
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// ../kit/src/text.ts
|
|
478
|
+
function distance(a, b) {
|
|
479
|
+
let previous = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
480
|
+
for (const [i, left] of [...a].entries()) {
|
|
481
|
+
const current = [i + 1];
|
|
482
|
+
for (const [j, right] of [...b].entries())
|
|
483
|
+
current.push(Math.min((previous[j + 1] ?? 0) + 1, (current[j] ?? 0) + 1, (previous[j] ?? 0) + (left === right ? 0 : 1)));
|
|
484
|
+
previous = current;
|
|
485
|
+
}
|
|
486
|
+
return previous[b.length] ?? 0;
|
|
487
|
+
}
|
|
488
|
+
function closest(name, names) {
|
|
489
|
+
const started = names.find((known) => known.startsWith(name));
|
|
490
|
+
if (started !== undefined)
|
|
491
|
+
return started;
|
|
492
|
+
const [best] = names.map((known) => ({ known, far: distance(name, known) })).sort((a, b) => a.far - b.far);
|
|
493
|
+
return best !== undefined && best.far <= (name.length < 4 ? 1 : 2) ? best.known : undefined;
|
|
494
|
+
}
|
|
495
|
+
var ANSI;
|
|
496
|
+
var init_text = __esm(() => {
|
|
497
|
+
ANSI = new RegExp(`${String.fromCharCode(27)}\\[[\\d;?]*[a-z]`, "gi");
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
// ../kit/src/input.ts
|
|
501
|
+
function wholeNumber(value, name, fallback, min = 1) {
|
|
502
|
+
if (value === undefined)
|
|
503
|
+
return fallback;
|
|
504
|
+
const number = Number(value);
|
|
505
|
+
if (!WHOLE.test(value) || !Number.isSafeInteger(number) || number < min)
|
|
506
|
+
badUsage(`${name.startsWith("<") ? name : `--${name}`} takes a whole number from ${min}, not ${value}`);
|
|
507
|
+
return number;
|
|
508
|
+
}
|
|
509
|
+
function duration(value, name, fallback, unit = "s") {
|
|
510
|
+
if (value === undefined)
|
|
511
|
+
return fallback;
|
|
512
|
+
const match = DURATION.exec(value.trim());
|
|
513
|
+
const ms = match === null ? 0 : Number(match[1]) * UNIT_MS[match[2] ?? unit];
|
|
514
|
+
if (ms < 1)
|
|
515
|
+
badUsage(`--${name} takes a duration such as 30s, 5m, 1h or 7d, not ${value}`);
|
|
516
|
+
return ms;
|
|
517
|
+
}
|
|
518
|
+
var WHOLE, DURATION, UNIT_MS;
|
|
519
|
+
var init_input = __esm(() => {
|
|
520
|
+
init_args();
|
|
521
|
+
WHOLE = /^\d+$/;
|
|
522
|
+
DURATION = /^(\d+(?:\.\d+)?)(ms|[smhd])?$/;
|
|
523
|
+
UNIT_MS = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000 };
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
// ../kit/src/args.ts
|
|
527
|
+
import process4 from "process";
|
|
528
|
+
import { parseArgs } from "util";
|
|
529
|
+
function jsonOption(holds) {
|
|
530
|
+
return { type: "boolean", description: holds === undefined ? "print JSON" : `print JSON: ${holds}` };
|
|
531
|
+
}
|
|
532
|
+
function fail(message, code = 2, hint) {
|
|
533
|
+
throw new Exit(message, code, hint);
|
|
534
|
+
}
|
|
535
|
+
function badUsage(message) {
|
|
536
|
+
throw new UsageError(message);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
class Completing {
|
|
540
|
+
options;
|
|
541
|
+
positionals;
|
|
542
|
+
candidates;
|
|
543
|
+
constructor(options, positionals = [], candidates = {}) {
|
|
544
|
+
this.options = options;
|
|
545
|
+
this.positionals = positionals;
|
|
546
|
+
this.candidates = candidates;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
function applyOutput(color, plain, env = process4.env) {
|
|
508
550
|
const when = plain === true ? "never" : color ?? "auto";
|
|
509
551
|
if (when === "auto")
|
|
510
552
|
return;
|
|
@@ -521,14 +563,13 @@ function applyOutput(color, plain, env = process3.env) {
|
|
|
521
563
|
function parse(args, usage, options, settings = {}) {
|
|
522
564
|
const output = Object.fromEntries(Object.entries(OUTPUT_OPTIONS).filter(([name]) => !(name in options)));
|
|
523
565
|
const all = { ...options, ...output, help: { type: "boolean", short: "h", description: "show this help" } };
|
|
566
|
+
const listing = listed(all, settings.allowNegative === true);
|
|
524
567
|
if (completion.active)
|
|
525
|
-
throw new Completing(
|
|
526
|
-
const
|
|
527
|
-
const own = separator === -1 ? args : args.slice(0, separator);
|
|
528
|
-
const rest = separator === -1 ? undefined : args.slice(separator + 1);
|
|
568
|
+
throw new Completing(listing, settings.positionals, settings.candidates);
|
|
569
|
+
const { own, rest } = settings.trailing === true ? splitTrailing(args, all, settings.positionals?.length ?? 0) : splitRest(args, settings.rest === true);
|
|
529
570
|
let parsed;
|
|
530
571
|
try {
|
|
531
|
-
parsed = parseArgs({ args: joinDashValues(own, all), options: all, allowPositionals: true, allowNegative: settings.allowNegative === true, strict: true });
|
|
572
|
+
parsed = parseArgs({ args: joinDashValues(withBare(own, all), all), options: all, allowPositionals: true, allowNegative: settings.allowNegative === true, strict: true });
|
|
532
573
|
} catch (error) {
|
|
533
574
|
const message = parseError(error);
|
|
534
575
|
throw new UsageError(message, nearestOption(message, all, settings.allowNegative === true));
|
|
@@ -536,12 +577,84 @@ function parse(args, usage, options, settings = {}) {
|
|
|
536
577
|
const values = parsed.values;
|
|
537
578
|
applyOutput("color" in output ? values.color : undefined, "plain" in output ? values.plain : undefined);
|
|
538
579
|
if (values.help === true) {
|
|
539
|
-
console.log(wantsHelpJson() ? JSON.stringify(description(usage, settings)) : helpText(usage,
|
|
580
|
+
console.log(wantsHelpJson() ? JSON.stringify(description(usage, settings)) : helpText(usage, listing, undefined, settings));
|
|
540
581
|
throw new HelpShown;
|
|
541
582
|
}
|
|
583
|
+
checkChoices(parsed.values, all);
|
|
584
|
+
checkConflicts(parsed.values, all);
|
|
542
585
|
if (settings.positionals !== undefined)
|
|
543
586
|
checkPositionals(parsed.positionals, settings.positionals);
|
|
544
|
-
return { ...parsed, positionals: parsed.positionals, rest };
|
|
587
|
+
return { ...parsed, values: parsed.values, positionals: parsed.positionals, rest };
|
|
588
|
+
}
|
|
589
|
+
function splitRest(args, passes) {
|
|
590
|
+
const separator = passes ? args.indexOf("--") : -1;
|
|
591
|
+
return { own: separator === -1 ? args : args.slice(0, separator), rest: separator === -1 ? undefined : args.slice(separator + 1) };
|
|
592
|
+
}
|
|
593
|
+
function splitTrailing(args, options, count) {
|
|
594
|
+
const takesValue = (word) => !word.includes("=") && Object.entries(options).some(([name, { short, type }]) => type === "string" && (word === `--${name}` || word === `-${short}`));
|
|
595
|
+
let seen = 0;
|
|
596
|
+
if (count === 0)
|
|
597
|
+
return { own: args, rest: undefined };
|
|
598
|
+
for (let at = 0;at < args.length; at++) {
|
|
599
|
+
const word = args[at];
|
|
600
|
+
if (word === "--")
|
|
601
|
+
break;
|
|
602
|
+
if (word.startsWith("-")) {
|
|
603
|
+
if (takesValue(word))
|
|
604
|
+
at++;
|
|
605
|
+
continue;
|
|
606
|
+
}
|
|
607
|
+
seen++;
|
|
608
|
+
if (seen === count)
|
|
609
|
+
return { own: args.slice(0, at + 1), rest: args.slice(at + 1) };
|
|
610
|
+
}
|
|
611
|
+
return { own: args, rest: undefined };
|
|
612
|
+
}
|
|
613
|
+
function listed(options, allowNegative) {
|
|
614
|
+
if (!allowNegative)
|
|
615
|
+
return options;
|
|
616
|
+
return Object.fromEntries(Object.entries(options).flatMap(([name, option]) => {
|
|
617
|
+
if (option.type !== "boolean" || option.negative === undefined)
|
|
618
|
+
return [[name, option]];
|
|
619
|
+
return [...option.description === undefined ? [] : [[name, option]], [`no-${name}`, { type: "boolean", description: option.negative }]];
|
|
620
|
+
}));
|
|
621
|
+
}
|
|
622
|
+
function withBare(args, options) {
|
|
623
|
+
const bare = new Map(Object.entries(options).flatMap(([name, { short, optional }]) => optional === undefined ? [] : [[`--${name}`, optional], ...short === undefined ? [] : [[`-${short}`, optional]]]));
|
|
624
|
+
if (bare.size === 0)
|
|
625
|
+
return args;
|
|
626
|
+
const separator = args.indexOf("--");
|
|
627
|
+
const own = separator === -1 ? args : args.slice(0, separator);
|
|
628
|
+
return [...own.flatMap((arg, index) => {
|
|
629
|
+
const optional = bare.get(arg);
|
|
630
|
+
const next = own[index + 1];
|
|
631
|
+
const value = next !== undefined && (optional?.accepts === undefined ? !next.startsWith("-") : optional.accepts.test(next));
|
|
632
|
+
return optional === undefined || value ? [arg] : [arg, optional.bare];
|
|
633
|
+
}), ...separator === -1 ? [] : args.slice(separator)];
|
|
634
|
+
}
|
|
635
|
+
function checkConflicts(values, options) {
|
|
636
|
+
const given = (name) => values[name] !== undefined && values[name] !== false;
|
|
637
|
+
for (const [name, { conflicts = [] }] of Object.entries(options)) {
|
|
638
|
+
const other = given(name) ? conflicts.find(given) : undefined;
|
|
639
|
+
if (other !== undefined)
|
|
640
|
+
badUsage(`--${name} cannot be used with --${other}`);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
function checkChoices(values, options) {
|
|
644
|
+
for (const [name, option] of Object.entries(options)) {
|
|
645
|
+
if (option.choices === undefined)
|
|
646
|
+
continue;
|
|
647
|
+
const given = values[name];
|
|
648
|
+
for (const value of Array.isArray(given) ? given : [given]) {
|
|
649
|
+
if (typeof value === "string")
|
|
650
|
+
oneOf(value, name, option.choices);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
function oneOf(value, name, choices) {
|
|
655
|
+
if (!choices.includes(value))
|
|
656
|
+
badUsage(`${name.startsWith("<") ? name : `--${name}`} takes one of ${choices.join(", ")}, not ${value}`);
|
|
657
|
+
return value;
|
|
545
658
|
}
|
|
546
659
|
function checkPositionals(given, names) {
|
|
547
660
|
const variadic = names.at(-1)?.replace("]", "").endsWith("...") === true;
|
|
@@ -589,28 +702,14 @@ function nearestOption(message, options, allowNegative) {
|
|
|
589
702
|
const meant = closest(word, known.map((flag) => flag.replace(DASHES, "")));
|
|
590
703
|
return meant === undefined ? undefined : `did you mean ${known.find((flag) => flag.replace(DASHES, "") === meant)}?`;
|
|
591
704
|
}
|
|
592
|
-
|
|
593
|
-
if (value === undefined)
|
|
594
|
-
return fallback;
|
|
595
|
-
const number = Number(value);
|
|
596
|
-
if (!WHOLE.test(value) || !Number.isSafeInteger(number) || number < min)
|
|
597
|
-
badUsage(`${name.startsWith("<") ? name : `--${name}`} takes a whole number from ${min}, not ${value}`);
|
|
598
|
-
return number;
|
|
599
|
-
}
|
|
600
|
-
function duration(value, name, fallback, unit = "s") {
|
|
601
|
-
if (value === undefined)
|
|
602
|
-
return fallback;
|
|
603
|
-
const match = DURATION.exec(value.trim());
|
|
604
|
-
const ms = match === null ? 0 : Number(match[1]) * UNIT_MS[match[2] ?? unit];
|
|
605
|
-
if (ms < 1)
|
|
606
|
-
badUsage(`--${name} takes a duration such as 30s, 5m, 1h or 7d, not ${value}`);
|
|
607
|
-
return ms;
|
|
608
|
-
}
|
|
609
|
-
var Exit, UsageError, HelpShown, completion, OPTIONAL, USAGE_PREFIX, FULL_STOP, DASHES, OUTPUT_OPTIONS, UNKNOWN_OPTION, WHOLE, DURATION, UNIT_MS;
|
|
705
|
+
var DASHES, Exit, UsageError, HelpShown, completion, OUTPUT_OPTIONS, UNKNOWN_OPTION;
|
|
610
706
|
var init_args = __esm(() => {
|
|
611
707
|
init_format();
|
|
612
|
-
|
|
708
|
+
init_help();
|
|
613
709
|
init_text();
|
|
710
|
+
init_help();
|
|
711
|
+
init_input();
|
|
712
|
+
DASHES = /^-+/;
|
|
614
713
|
Exit = class Exit extends Error {
|
|
615
714
|
code;
|
|
616
715
|
hint;
|
|
@@ -631,18 +730,11 @@ var init_args = __esm(() => {
|
|
|
631
730
|
}
|
|
632
731
|
};
|
|
633
732
|
completion = { active: false };
|
|
634
|
-
OPTIONAL = /\[[^\]]+\]/g;
|
|
635
|
-
USAGE_PREFIX = /^usage:\s*/i;
|
|
636
|
-
FULL_STOP = /\.$/;
|
|
637
|
-
DASHES = /^-+/;
|
|
638
733
|
OUTPUT_OPTIONS = {
|
|
639
734
|
color: { type: "string", description: "auto (on a terminal alone), always or never" },
|
|
640
735
|
plain: { type: "boolean", description: "plain text, no colour or spinner: --color never" }
|
|
641
736
|
};
|
|
642
737
|
UNKNOWN_OPTION = /^unknown option '(-[^']+)'/;
|
|
643
|
-
WHOLE = /^\d+$/;
|
|
644
|
-
DURATION = /^(\d+(?:\.\d+)?)(ms|[smhd])?$/;
|
|
645
|
-
UNIT_MS = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000 };
|
|
646
738
|
});
|
|
647
739
|
|
|
648
740
|
// ../kit/src/chart.ts
|
|
@@ -653,7 +745,7 @@ var init_chart = __esm(() => {
|
|
|
653
745
|
|
|
654
746
|
// ../kit/src/process.ts
|
|
655
747
|
import { constants } from "os";
|
|
656
|
-
import
|
|
748
|
+
import process5 from "process";
|
|
657
749
|
function exitCodeOf(code, signal) {
|
|
658
750
|
if (code !== null)
|
|
659
751
|
return code;
|
|
@@ -673,7 +765,7 @@ function holdSignals(cleanup) {
|
|
|
673
765
|
},
|
|
674
766
|
release: () => {
|
|
675
767
|
for (const signal of SIGNALS)
|
|
676
|
-
|
|
768
|
+
process5.off(signal, onSignal);
|
|
677
769
|
}
|
|
678
770
|
};
|
|
679
771
|
function onSignal(signal) {
|
|
@@ -686,10 +778,10 @@ function holdSignals(cleanup) {
|
|
|
686
778
|
return;
|
|
687
779
|
held.release();
|
|
688
780
|
cleanup(signal);
|
|
689
|
-
|
|
781
|
+
process5.kill(process5.pid, signal);
|
|
690
782
|
}
|
|
691
783
|
for (const signal of SIGNALS)
|
|
692
|
-
|
|
784
|
+
process5.on(signal, onSignal);
|
|
693
785
|
return held;
|
|
694
786
|
}
|
|
695
787
|
async function runCommand(argv, { cwd, env, stdin = "ignore", timeoutMs, signal, maxBytes = Infinity, onChunk, onStart } = {}) {
|
|
@@ -703,7 +795,7 @@ async function runCommand(argv, { cwd, env, stdin = "ignore", timeoutMs, signal,
|
|
|
703
795
|
return;
|
|
704
796
|
try {
|
|
705
797
|
if (grouped)
|
|
706
|
-
|
|
798
|
+
process5.kill(-proc.pid, killing);
|
|
707
799
|
else
|
|
708
800
|
proc.kill(killing);
|
|
709
801
|
} catch {}
|
|
@@ -776,8 +868,8 @@ var init_process = __esm(() => {
|
|
|
776
868
|
});
|
|
777
869
|
|
|
778
870
|
// ../kit/src/progress.ts
|
|
779
|
-
import
|
|
780
|
-
function liveRegion(render, stream =
|
|
871
|
+
import process6 from "process";
|
|
872
|
+
function liveRegion(render, stream = process6.stderr, env = process6.env) {
|
|
781
873
|
if (!takesControlCodes(stream, env))
|
|
782
874
|
return { redraw: () => {
|
|
783
875
|
return;
|
|
@@ -818,11 +910,11 @@ function liveRegion(render, stream = process5.stderr, env = process5.env) {
|
|
|
818
910
|
clear();
|
|
819
911
|
restore();
|
|
820
912
|
release();
|
|
821
|
-
|
|
913
|
+
process6.off("exit", onExit);
|
|
822
914
|
signals.release();
|
|
823
915
|
}
|
|
824
916
|
timer.unref();
|
|
825
|
-
|
|
917
|
+
process6.on("exit", onExit);
|
|
826
918
|
return {
|
|
827
919
|
redraw: draw,
|
|
828
920
|
print: (text) => {
|
|
@@ -861,14 +953,14 @@ function cutToWidth(line, width) {
|
|
|
861
953
|
return `${kept}${RESET_STYLE}${linked ? CLOSE_LINK : ""}`;
|
|
862
954
|
}
|
|
863
955
|
function swallowInput() {
|
|
864
|
-
const input =
|
|
956
|
+
const input = process6.stdin;
|
|
865
957
|
if (!input.isTTY)
|
|
866
958
|
return () => {
|
|
867
959
|
return;
|
|
868
960
|
};
|
|
869
961
|
const onData = (data) => {
|
|
870
962
|
if (data.includes(CTRL_C))
|
|
871
|
-
|
|
963
|
+
process6.kill(process6.pid, "SIGINT");
|
|
872
964
|
};
|
|
873
965
|
input.setRawMode(true);
|
|
874
966
|
input.on("data", onData);
|
|
@@ -884,7 +976,7 @@ function swallowInput() {
|
|
|
884
976
|
};
|
|
885
977
|
}
|
|
886
978
|
function interceptOutput(clear) {
|
|
887
|
-
const targets = [...CONSOLE_METHODS.map((name) => [console, name]), [
|
|
979
|
+
const targets = [...CONSOLE_METHODS.map((name) => [console, name]), [process6.stdout, "write"], [process6.stderr, "write"]];
|
|
888
980
|
const wrapped = targets.map(([target, name]) => {
|
|
889
981
|
const original = Reflect.get(target, name);
|
|
890
982
|
const wrapper = (...args) => {
|
|
@@ -928,10 +1020,63 @@ var init_ci = __esm(() => {
|
|
|
928
1020
|
init_tool();
|
|
929
1021
|
});
|
|
930
1022
|
|
|
1023
|
+
// ../kit/src/logs.ts
|
|
1024
|
+
var DAY_MS, CLI_FOLDER = "kaynooo-cli";
|
|
1025
|
+
var init_logs = __esm(() => {
|
|
1026
|
+
DAY_MS = 24 * 60 * 60 * 1000;
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
// ../kit/src/usage.ts
|
|
1030
|
+
import { appendFileSync, mkdirSync } from "fs";
|
|
1031
|
+
import { homedir } from "os";
|
|
1032
|
+
import { dirname, isAbsolute, join } from "path";
|
|
1033
|
+
import process7 from "process";
|
|
1034
|
+
function noteUsageError(message) {
|
|
1035
|
+
usageError = message;
|
|
1036
|
+
}
|
|
1037
|
+
function stateHome(env = process7.env) {
|
|
1038
|
+
const dir = env.XDG_STATE_HOME;
|
|
1039
|
+
return dir !== undefined && isAbsolute(dir) ? dir : join(homedir(), ".local", "state");
|
|
1040
|
+
}
|
|
1041
|
+
function usagePath(env = process7.env) {
|
|
1042
|
+
return join(stateHome(env), CLI_FOLDER, "usage.jsonl");
|
|
1043
|
+
}
|
|
1044
|
+
function usageRecorded(env = process7.env) {
|
|
1045
|
+
const off = env.KAYNOOO_CLI_NO_USAGE;
|
|
1046
|
+
return env.NODE_ENV !== "test" && (off === undefined || off === "" || off === "0");
|
|
1047
|
+
}
|
|
1048
|
+
function flagNames(argv) {
|
|
1049
|
+
const end = argv.indexOf("--");
|
|
1050
|
+
const names = (end === -1 ? argv : argv.slice(0, end)).filter((word) => word.startsWith("-") && word !== "-").map((word) => word.includes("=") ? word.slice(0, word.indexOf("=")) : word);
|
|
1051
|
+
return [...new Set(names)].filter((name) => name.length <= LONGEST_NAME && FLAG_NAME.test(name));
|
|
1052
|
+
}
|
|
1053
|
+
function usageEntry(bin, command, argv, code, now = new Date) {
|
|
1054
|
+
const unknown = code === 2 && usageError !== undefined ? UNKNOWN_OPTION2.exec(usageError)?.[1] : undefined;
|
|
1055
|
+
usageError = undefined;
|
|
1056
|
+
return { at: now.toISOString(), bin, ...command === undefined ? {} : { command }, flags: flagNames(argv), code, ...unknown === undefined ? {} : { unknown } };
|
|
1057
|
+
}
|
|
1058
|
+
function recordUsage(entry, env = process7.env) {
|
|
1059
|
+
if (!usageRecorded(env))
|
|
1060
|
+
return;
|
|
1061
|
+
try {
|
|
1062
|
+
const path = usagePath(env);
|
|
1063
|
+
mkdirSync(dirname(path), { recursive: true, mode: 448 });
|
|
1064
|
+
appendFileSync(path, `${JSON.stringify(entry)}
|
|
1065
|
+
`, { mode: 384 });
|
|
1066
|
+
} catch {}
|
|
1067
|
+
}
|
|
1068
|
+
var UNKNOWN_OPTION2, FLAG_NAME, LONGEST_NAME = 40, usageError;
|
|
1069
|
+
var init_usage = __esm(() => {
|
|
1070
|
+
init_logs();
|
|
1071
|
+
UNKNOWN_OPTION2 = /unknown option '(--[a-z][a-z0-9-]*)[=']/;
|
|
1072
|
+
FLAG_NAME = /^(?:--[a-z][a-z0-9-]*|-[a-zA-Z])$/;
|
|
1073
|
+
});
|
|
1074
|
+
|
|
931
1075
|
// ../kit/src/cli.ts
|
|
932
|
-
import
|
|
933
|
-
async function commandRows(
|
|
934
|
-
const
|
|
1076
|
+
import process8 from "process";
|
|
1077
|
+
async function commandRows(all, colors) {
|
|
1078
|
+
const commands = shown(all);
|
|
1079
|
+
const width = Math.max(0, ...Object.keys(commands).map((name) => name.length));
|
|
935
1080
|
const groups = new Map([["Commands:", []]]);
|
|
936
1081
|
const summaries = await Promise.all(Object.values(commands).map(async ({ summary }) => resolveSummary(summary)));
|
|
937
1082
|
for (const [index, [name, { group }]] of Object.entries(commands).entries()) {
|
|
@@ -942,6 +1087,9 @@ async function commandRows(commands, colors) {
|
|
|
942
1087
|
}
|
|
943
1088
|
return [...groups].filter(([, rows]) => rows.length > 0).flatMap(([heading, rows], index) => [...index === 0 ? [] : [""], colors.bold(heading), ...rows]);
|
|
944
1089
|
}
|
|
1090
|
+
function shown(commands) {
|
|
1091
|
+
return Object.fromEntries(Object.entries(commands).filter(([, { hidden }]) => hidden !== true));
|
|
1092
|
+
}
|
|
945
1093
|
function takeOutputFlags(argv) {
|
|
946
1094
|
let index = 0;
|
|
947
1095
|
for (;index < argv.length; index++) {
|
|
@@ -973,7 +1121,7 @@ async function expand(scope, words) {
|
|
|
973
1121
|
}
|
|
974
1122
|
return { ...scope, commands, lazy: [] };
|
|
975
1123
|
}
|
|
976
|
-
async function
|
|
1124
|
+
async function help2({ path, header, summary: lazySummary, commands, defaultCommand, examples, replaces }, stream) {
|
|
977
1125
|
const colors = paint(stream);
|
|
978
1126
|
const prefix = path.join(" ");
|
|
979
1127
|
const summary = await resolveSummary(lazySummary);
|
|
@@ -1000,8 +1148,8 @@ async function help({ path, header, summary: lazySummary, commands, defaultComma
|
|
|
1000
1148
|
`);
|
|
1001
1149
|
}
|
|
1002
1150
|
function printError(prefix, message, hint, cause) {
|
|
1003
|
-
const colors = paint(
|
|
1004
|
-
const styled = takesControlCodes(
|
|
1151
|
+
const colors = paint(process8.stderr);
|
|
1152
|
+
const styled = takesControlCodes(process8.stderr);
|
|
1005
1153
|
const head = styled ? `${colors.red.bold("error")} ${colors.dim(`${prefix}:`)}` : `error: ${prefix}:`;
|
|
1006
1154
|
const under = (label, text, tint) => text === undefined ? "" : `
|
|
1007
1155
|
${styled ? tint(label) : `${label}:`} ${text}`;
|
|
@@ -1020,6 +1168,8 @@ function reportThrown(prefix, error, redact = (text) => text, json = false) {
|
|
|
1020
1168
|
const help = error instanceof UsageError ? `run ${prefix} --help for its options` : undefined;
|
|
1021
1169
|
const named = error instanceof Error && !(error instanceof Exit) && error.name !== "Error" ? `${error.name}: ${error.message}` : undefined;
|
|
1022
1170
|
const cause = error instanceof Error && error.cause instanceof Error ? redact(error.cause.message) : undefined;
|
|
1171
|
+
if (error instanceof UsageError)
|
|
1172
|
+
noteUsageError(error.message);
|
|
1023
1173
|
const report = json ? printJsonError : (message, hint, causeText) => printError(prefix, message, hint, causeText);
|
|
1024
1174
|
report(redact(named ?? (error instanceof Error ? error.message : String(error))), error instanceof Exit ? error.hint ?? help : undefined, cause);
|
|
1025
1175
|
return error instanceof Exit ? error.code : 1;
|
|
@@ -1033,12 +1183,20 @@ async function dispatch(level, typed, { version, redact }) {
|
|
|
1033
1183
|
return reportThrown(prefix, error);
|
|
1034
1184
|
}
|
|
1035
1185
|
const [name, ...args] = argv;
|
|
1186
|
+
const fallback = level.defaultCommand === undefined ? undefined : level.commands[level.defaultCommand];
|
|
1187
|
+
if (name === undefined && level.runBare && fallback !== undefined && "run" in fallback) {
|
|
1188
|
+
try {
|
|
1189
|
+
return await fallback.run([]);
|
|
1190
|
+
} catch (error) {
|
|
1191
|
+
return reportThrown(`${prefix} ${level.defaultCommand}`, error, redact, false);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1036
1194
|
if (name === undefined && level.path.length > 1) {
|
|
1037
|
-
console.error(await
|
|
1195
|
+
console.error(await help2(await expand(level, [...level.path.slice(1), ...argv]), process8.stderr));
|
|
1038
1196
|
return 2;
|
|
1039
1197
|
}
|
|
1040
1198
|
if (name === undefined || name === "help" || name === "--help" || name === "-h") {
|
|
1041
|
-
console.log(await
|
|
1199
|
+
console.log(await help2(await expand(level, [...level.path.slice(1), ...argv]), process8.stdout));
|
|
1042
1200
|
return 0;
|
|
1043
1201
|
}
|
|
1044
1202
|
if (level.path.length === 1 && (name === "--version" || name === "-v")) {
|
|
@@ -1047,6 +1205,7 @@ async function dispatch(level, typed, { version, redact }) {
|
|
|
1047
1205
|
}
|
|
1048
1206
|
let command = level.commands[level.aliases?.[name] ?? name];
|
|
1049
1207
|
let rest = args;
|
|
1208
|
+
let ran = name;
|
|
1050
1209
|
if (command === undefined && level.lazy.length > 0) {
|
|
1051
1210
|
level = await expand(level, [...level.path.slice(1), ...argv]);
|
|
1052
1211
|
command = level.commands[level.aliases?.[name] ?? name];
|
|
@@ -1054,38 +1213,75 @@ async function dispatch(level, typed, { version, redact }) {
|
|
|
1054
1213
|
if (command === undefined && level.defaultCommand !== undefined) {
|
|
1055
1214
|
command = level.commands[level.defaultCommand];
|
|
1056
1215
|
rest = argv;
|
|
1216
|
+
ran = level.defaultCommand;
|
|
1057
1217
|
}
|
|
1058
1218
|
if (command === undefined) {
|
|
1059
|
-
const meant = closest(name, Object.keys(level.commands));
|
|
1219
|
+
const meant = closest(name, Object.keys(shown(level.commands)));
|
|
1060
1220
|
printError(prefix, `no command ${name}`, meant === undefined ? `run ${prefix} --help for its commands` : `did you mean ${meant}?`);
|
|
1061
1221
|
return 2;
|
|
1062
1222
|
}
|
|
1063
1223
|
if ("commands" in command) {
|
|
1064
1224
|
const { summary } = command;
|
|
1065
|
-
return dispatch({ path: [...level.path, name], header: (colors, text) => `${colors.bold(`${prefix} ${name}`)} ${text}`, summary, ...scopeOf(command.commands, command.extraCommands, command.aliases), defaultCommand: undefined, examples: command.examples, replaces: undefined }, rest, { version, redact });
|
|
1225
|
+
return dispatch({ path: [...level.path, name], header: (colors, text) => `${colors.bold(`${prefix} ${name}`)} ${text}`, summary, ...scopeOf(command.commands, command.extraCommands, command.aliases), defaultCommand: undefined, runBare: false, examples: command.examples, replaces: undefined }, rest, { version, redact });
|
|
1066
1226
|
}
|
|
1067
1227
|
try {
|
|
1068
1228
|
return await command.run(rest);
|
|
1069
1229
|
} catch (error) {
|
|
1070
|
-
return reportThrown(`${prefix} ${
|
|
1230
|
+
return reportThrown(`${prefix} ${ran}`, error, redact, wantsJson(rest));
|
|
1071
1231
|
}
|
|
1072
1232
|
}
|
|
1073
|
-
async function
|
|
1233
|
+
async function completingOf(run) {
|
|
1074
1234
|
completion.active = true;
|
|
1075
1235
|
try {
|
|
1076
1236
|
await run([]);
|
|
1077
1237
|
} catch (error) {
|
|
1078
1238
|
if (error instanceof Completing)
|
|
1079
|
-
return error
|
|
1239
|
+
return error;
|
|
1080
1240
|
} finally {
|
|
1081
1241
|
completion.active = false;
|
|
1082
1242
|
}
|
|
1083
|
-
return {};
|
|
1243
|
+
return new Completing({});
|
|
1244
|
+
}
|
|
1245
|
+
async function optionsOf(run) {
|
|
1246
|
+
return (await completingOf(run)).options;
|
|
1247
|
+
}
|
|
1248
|
+
function candidateLine(candidate) {
|
|
1249
|
+
return typeof candidate === "string" ? candidate : candidate.join("\t");
|
|
1250
|
+
}
|
|
1251
|
+
function positionalBeingTyped(before, { options, positionals }) {
|
|
1252
|
+
const takesValue = (word) => !word.includes("=") && Object.entries(options).some(([name, { short, type }]) => type === "string" && (word === `--${name}` || word === `-${short}`));
|
|
1253
|
+
let index = 0;
|
|
1254
|
+
let at = 0;
|
|
1255
|
+
while (at < before.length) {
|
|
1256
|
+
const word = before[at];
|
|
1257
|
+
if (word === "--") {
|
|
1258
|
+
index += before.length - at - 1;
|
|
1259
|
+
break;
|
|
1260
|
+
}
|
|
1261
|
+
if (!word.startsWith("-"))
|
|
1262
|
+
index++;
|
|
1263
|
+
else if (takesValue(word))
|
|
1264
|
+
at++;
|
|
1265
|
+
at++;
|
|
1266
|
+
}
|
|
1267
|
+
const last = positionals.at(-1);
|
|
1268
|
+
if (index < positionals.length)
|
|
1269
|
+
return positionals[index];
|
|
1270
|
+
return last?.replace("]", "").endsWith("...") === true ? last : undefined;
|
|
1084
1271
|
}
|
|
1085
1272
|
async function leafCandidates(run, words) {
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1273
|
+
const completing = await completingOf(run);
|
|
1274
|
+
if ((words.at(-1) ?? "").startsWith("-"))
|
|
1275
|
+
return Object.entries(completing.options).map(([name, option]) => option.description === undefined ? `--${name}` : `--${name} ${option.description}`);
|
|
1276
|
+
const flag = words.at(-2);
|
|
1277
|
+
const option = flag?.startsWith("-") === true ? Object.entries(completing.options).find(([name, { short }]) => flag === `--${name}` || flag === `-${short}`)?.[1] : undefined;
|
|
1278
|
+
if (option?.type === "string") {
|
|
1279
|
+
const values = option.choices === undefined ? await option.candidates?.() : option.choices;
|
|
1280
|
+
return values === undefined ? [FILES] : values.map(candidateLine);
|
|
1281
|
+
}
|
|
1282
|
+
const name = positionalBeingTyped(words.slice(0, -1), completing);
|
|
1283
|
+
const values = name === undefined ? undefined : await completing.candidates[name]?.();
|
|
1284
|
+
return values === undefined ? [FILES] : values.map(candidateLine);
|
|
1089
1285
|
}
|
|
1090
1286
|
async function candidates(scope, defaultCommand, words, before = []) {
|
|
1091
1287
|
const [word = "", ...rest] = words;
|
|
@@ -1096,8 +1292,13 @@ async function candidates(scope, defaultCommand, words, before = []) {
|
|
|
1096
1292
|
({ commands, aliases } = await expand(scope, [...before, ...words]));
|
|
1097
1293
|
command = commands[aliases?.[word] ?? word];
|
|
1098
1294
|
}
|
|
1099
|
-
if (listing)
|
|
1100
|
-
|
|
1295
|
+
if (listing) {
|
|
1296
|
+
const own = await Promise.all(Object.entries(shown(commands)).map(async ([name, { summary }]) => `${name} ${await resolveSummary(summary)}`));
|
|
1297
|
+
const fallback = defaultCommand === undefined ? undefined : commands[defaultCommand];
|
|
1298
|
+
const values = fallback !== undefined && "run" in fallback ? await leafCandidates(fallback.run, [word]) : [];
|
|
1299
|
+
const valueOf = (line) => line.slice(0, line.includes("\t") ? line.indexOf("\t") : undefined);
|
|
1300
|
+
return [...own, ...values.filter((line) => line !== FILES && !(valueOf(line) in commands))];
|
|
1301
|
+
}
|
|
1101
1302
|
if (command === undefined) {
|
|
1102
1303
|
const fallback = defaultCommand === undefined ? undefined : commands[defaultCommand];
|
|
1103
1304
|
return fallback !== undefined && "run" in fallback ? leafCandidates(fallback.run, words) : [];
|
|
@@ -1109,16 +1310,38 @@ async function printCandidates(found) {
|
|
|
1109
1310
|
console.log(line);
|
|
1110
1311
|
return 0;
|
|
1111
1312
|
}
|
|
1112
|
-
async function runCli(cli, argv =
|
|
1313
|
+
async function runCli(cli, argv = process8.argv.slice(2)) {
|
|
1113
1314
|
if (argv[0] === COMPLETE)
|
|
1114
1315
|
return printCandidates(candidates(scopeOf(cli.commands, cli.extraCommands, cli.aliases), cli.defaultCommand, argv.slice(1)));
|
|
1115
|
-
|
|
1316
|
+
const code = await dispatch({ path: [cli.name], header: (colors, about) => `${colors.bold(cli.name)} ${colors.dim(cli.version)} ${about}`, summary: cli.about, ...scopeOf(cli.commands, cli.extraCommands, cli.aliases), defaultCommand: cli.defaultCommand, runBare: cli.runBare === true, examples: cli.examples, replaces: cli.replaces }, argv, { version: cli.version, redact: cli.redact });
|
|
1317
|
+
if (cli.usage !== false) {
|
|
1318
|
+
try {
|
|
1319
|
+
recordUsage(usageEntry(cli.name, commandPath(scopeOf(cli.commands, cli.extraCommands, cli.aliases), argv), argv, code));
|
|
1320
|
+
} catch {}
|
|
1321
|
+
}
|
|
1322
|
+
return code;
|
|
1323
|
+
}
|
|
1324
|
+
function commandPath(scope, argv) {
|
|
1325
|
+
const path = [];
|
|
1326
|
+
let level = scope;
|
|
1327
|
+
for (const word of argv.filter((each) => !each.startsWith("-"))) {
|
|
1328
|
+
const name = level.aliases !== undefined && Object.hasOwn(level.aliases, word) ? level.aliases[word] ?? word : word;
|
|
1329
|
+
const command = Object.hasOwn(level.commands, name) ? level.commands[name] : undefined;
|
|
1330
|
+
if (command === undefined)
|
|
1331
|
+
break;
|
|
1332
|
+
path.push(word);
|
|
1333
|
+
if (!("commands" in command))
|
|
1334
|
+
break;
|
|
1335
|
+
level = scopeOf(command.commands, command.extraCommands, command.aliases);
|
|
1336
|
+
}
|
|
1337
|
+
return path.length === 0 ? undefined : path.join(" ");
|
|
1116
1338
|
}
|
|
1117
1339
|
var LEVEL_OPTIONS, TOP_OPTIONS, COMPLETE = "__complete", FILES = "__files__";
|
|
1118
1340
|
var init_cli = __esm(() => {
|
|
1119
1341
|
init_args();
|
|
1120
1342
|
init_style();
|
|
1121
1343
|
init_text();
|
|
1344
|
+
init_usage();
|
|
1122
1345
|
LEVEL_OPTIONS = {
|
|
1123
1346
|
...OUTPUT_OPTIONS,
|
|
1124
1347
|
help: { type: "boolean", short: "h", description: "show this help" }
|
|
@@ -1140,7 +1363,7 @@ var init_git = __esm(() => {
|
|
|
1140
1363
|
// ../kit/src/limit.ts
|
|
1141
1364
|
function limitOptions(fallback) {
|
|
1142
1365
|
return {
|
|
1143
|
-
limit: { type: "string", description: `show at most this many rows, the rest counted (${fallback})` },
|
|
1366
|
+
limit: { type: "string", short: "n", description: `show at most this many rows, the rest counted (${fallback})` },
|
|
1144
1367
|
full: { type: "boolean", description: "show every row" }
|
|
1145
1368
|
};
|
|
1146
1369
|
}
|
|
@@ -1162,12 +1385,6 @@ var init_limit = __esm(() => {
|
|
|
1162
1385
|
init_args();
|
|
1163
1386
|
});
|
|
1164
1387
|
|
|
1165
|
-
// ../kit/src/logs.ts
|
|
1166
|
-
var DAY_MS;
|
|
1167
|
-
var init_logs = __esm(() => {
|
|
1168
|
-
DAY_MS = 24 * 60 * 60 * 1000;
|
|
1169
|
-
});
|
|
1170
|
-
|
|
1171
1388
|
// ../kit/src/secrets.ts
|
|
1172
1389
|
var SECRET_WORDS;
|
|
1173
1390
|
var init_secrets = __esm(() => {
|
|
@@ -1199,6 +1416,7 @@ var init_src = __esm(() => {
|
|
|
1199
1416
|
init_style();
|
|
1200
1417
|
init_text();
|
|
1201
1418
|
init_tool();
|
|
1419
|
+
init_usage();
|
|
1202
1420
|
});
|
|
1203
1421
|
|
|
1204
1422
|
// src/registry.ts
|
|
@@ -1257,9 +1475,9 @@ var init_registry = __esm(() => {
|
|
|
1257
1475
|
});
|
|
1258
1476
|
|
|
1259
1477
|
// src/config.ts
|
|
1260
|
-
import { homedir } from "os";
|
|
1261
|
-
import { dirname, join } from "path";
|
|
1262
|
-
import
|
|
1478
|
+
import { homedir as homedir2 } from "os";
|
|
1479
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
1480
|
+
import process10 from "process";
|
|
1263
1481
|
function expand2(value, env) {
|
|
1264
1482
|
let missing = false;
|
|
1265
1483
|
const expanded = value.replace(ENV_REFERENCE, (_, braced, bare) => {
|
|
@@ -1348,18 +1566,18 @@ async function readIfThere(path) {
|
|
|
1348
1566
|
const file = Bun.file(path);
|
|
1349
1567
|
return await file.exists() ? file.text() : undefined;
|
|
1350
1568
|
}
|
|
1351
|
-
async function loadConfigs(cwd =
|
|
1569
|
+
async function loadConfigs(cwd = process10.cwd(), env = process10.env, home = homedir2()) {
|
|
1352
1570
|
const directories = [];
|
|
1353
|
-
for (let dir = cwd;!directories.includes(dir); dir =
|
|
1571
|
+
for (let dir = cwd;!directories.includes(dir); dir = dirname2(dir))
|
|
1354
1572
|
directories.push(dir);
|
|
1355
1573
|
if (!directories.includes(home))
|
|
1356
1574
|
directories.push(home);
|
|
1357
1575
|
const configs = [];
|
|
1358
1576
|
for (const dir of directories) {
|
|
1359
|
-
const bunfig = await readIfThere(
|
|
1360
|
-
const npmrc = await readIfThere(
|
|
1577
|
+
const bunfig = await readIfThere(join2(dir, "bunfig.toml"));
|
|
1578
|
+
const npmrc = await readIfThere(join2(dir, ".npmrc"));
|
|
1361
1579
|
if (bunfig !== undefined)
|
|
1362
|
-
configs.push(readable(
|
|
1580
|
+
configs.push(readable(join2(dir, "bunfig.toml"), () => parseBunfig(bunfig, env)));
|
|
1363
1581
|
if (npmrc !== undefined)
|
|
1364
1582
|
configs.push(parseNpmrc(npmrc, env));
|
|
1365
1583
|
}
|
|
@@ -1377,11 +1595,11 @@ function parseSettings(text) {
|
|
|
1377
1595
|
settings.blockSeverity = raw.blockSeverity;
|
|
1378
1596
|
return settings;
|
|
1379
1597
|
}
|
|
1380
|
-
async function loadSettings(cwd =
|
|
1598
|
+
async function loadSettings(cwd = process10.cwd(), home = homedir2()) {
|
|
1381
1599
|
const files = [];
|
|
1382
|
-
for (let dir = cwd;!files.includes(
|
|
1383
|
-
files.push(
|
|
1384
|
-
files.push(
|
|
1600
|
+
for (let dir = cwd;!files.includes(join2(dir, SETTINGS_FILE)); dir = dirname2(dir))
|
|
1601
|
+
files.push(join2(dir, SETTINGS_FILE));
|
|
1602
|
+
files.push(join2(home, ".config", "pkg", "config.json"));
|
|
1385
1603
|
const settings = {};
|
|
1386
1604
|
for (const file of files) {
|
|
1387
1605
|
const text = await readIfThere(file);
|
|
@@ -2240,12 +2458,12 @@ function render(report, now = Date.now()) {
|
|
|
2240
2458
|
`);
|
|
2241
2459
|
}
|
|
2242
2460
|
async function check(args) {
|
|
2243
|
-
const parsed = parse(args,
|
|
2461
|
+
const parsed = parse(args, usage2, options);
|
|
2244
2462
|
const { values, positionals } = parsed;
|
|
2245
2463
|
if (positionals.length === 0)
|
|
2246
2464
|
fail(`a package name is needed
|
|
2247
2465
|
|
|
2248
|
-
${
|
|
2466
|
+
${usage2}`);
|
|
2249
2467
|
const context = { configs: await loadConfigs(), settings: await loadSettings(), minAgeDays: wholeNumber(values["min-age"], "min-age", DEFAULT_MIN_AGE_DAYS, 0) };
|
|
2250
2468
|
const reports = await Promise.all(positionals.map(async (text) => checkPackage(text, context)));
|
|
2251
2469
|
if (values.json === true)
|
|
@@ -2256,7 +2474,7 @@ ${usage}`);
|
|
|
2256
2474
|
`));
|
|
2257
2475
|
return reports.some((report) => report.blocked) ? 1 : 0;
|
|
2258
2476
|
}
|
|
2259
|
-
var
|
|
2477
|
+
var usage2 = `pkg [check] <name>[@version]...
|
|
2260
2478
|
|
|
2261
2479
|
Checks npm packages before they are added: whether the name exists, the latest and the newest version at least two weeks old, weekly downloads, licence, repository, install scripts and a near miss of a popular name.
|
|
2262
2480
|
|
|
@@ -2309,8 +2527,8 @@ var exports_audit = {};
|
|
|
2309
2527
|
__export(exports_audit, {
|
|
2310
2528
|
audit: () => audit
|
|
2311
2529
|
});
|
|
2312
|
-
import { join as
|
|
2313
|
-
import
|
|
2530
|
+
import { join as join3, resolve as resolve2 } from "path";
|
|
2531
|
+
import process11 from "process";
|
|
2314
2532
|
function hasFinding(audited) {
|
|
2315
2533
|
return audited.blocked || audited.warnings.length > 0 || audited.advisories.length > 0;
|
|
2316
2534
|
}
|
|
@@ -2365,12 +2583,12 @@ function renderAudit(findings, total) {
|
|
|
2365
2583
|
`);
|
|
2366
2584
|
}
|
|
2367
2585
|
async function audit(args) {
|
|
2368
|
-
const { values, positionals: [asked] } = parse(args,
|
|
2586
|
+
const { values, positionals: [asked] } = parse(args, usage3, options2, { positionals: ["[dir]"] });
|
|
2369
2587
|
const level = values["audit-level"] ?? "low";
|
|
2370
2588
|
if (!isSeverity(level))
|
|
2371
2589
|
fail(`--audit-level takes ${SEVERITIES.join(", ")}, not ${level}`);
|
|
2372
|
-
const dir = resolve2(asked ??
|
|
2373
|
-
const lock = Bun.file(
|
|
2590
|
+
const dir = resolve2(asked ?? process11.cwd());
|
|
2591
|
+
const lock = Bun.file(join3(dir, "bun.lock"));
|
|
2374
2592
|
if (!await lock.exists())
|
|
2375
2593
|
fail(`no bun.lock in ${dir}`);
|
|
2376
2594
|
const packages = parseBunLock(await lock.text());
|
|
@@ -2393,7 +2611,7 @@ async function audit(args) {
|
|
|
2393
2611
|
return 1;
|
|
2394
2612
|
return unavailable.length > 0 ? 2 : 0;
|
|
2395
2613
|
}
|
|
2396
|
-
var
|
|
2614
|
+
var usage3 = `pkg audit [dir]
|
|
2397
2615
|
|
|
2398
2616
|
Reads the bun.lock in the folder (the current one by default) and runs on every registry package it pins the checks \`pkg check\` runs before an add: age, install scripts, a deprecated version, a near miss of a popular name, and the licence allowlist of the pkg config. It also lists the known advisories of each version, with the GHSA, the severity and the fixed version, from the registry's bulk advisory endpoint, the one \`bun audit\` reads.
|
|
2399
2617
|
Findings are grouped per package, each registry package looked up once per run.
|
|
@@ -2492,7 +2710,7 @@ var init_pin = __esm(() => {
|
|
|
2492
2710
|
|
|
2493
2711
|
// src/consumers.ts
|
|
2494
2712
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
2495
|
-
import { dirname as
|
|
2713
|
+
import { dirname as dirname3, join as join4, relative } from "path";
|
|
2496
2714
|
function packageFiles(dir, depth, found) {
|
|
2497
2715
|
let entries;
|
|
2498
2716
|
try {
|
|
@@ -2502,18 +2720,18 @@ function packageFiles(dir, depth, found) {
|
|
|
2502
2720
|
}
|
|
2503
2721
|
for (const entry of entries) {
|
|
2504
2722
|
if (entry.isFile() && entry.name === "package.json")
|
|
2505
|
-
found.push(
|
|
2723
|
+
found.push(join4(dir, entry.name));
|
|
2506
2724
|
else if (entry.isDirectory() && depth < MAX_DEPTH && !entry.name.startsWith(".") && !SKIPPED.has(entry.name))
|
|
2507
|
-
packageFiles(
|
|
2725
|
+
packageFiles(join4(dir, entry.name), depth + 1, found);
|
|
2508
2726
|
}
|
|
2509
2727
|
return found;
|
|
2510
2728
|
}
|
|
2511
2729
|
function managerFor(dir, root) {
|
|
2512
|
-
for (let at = dir;; at =
|
|
2513
|
-
const lockfile = LOCKFILES.find(([file]) => existsSync(
|
|
2730
|
+
for (let at = dir;; at = dirname3(at)) {
|
|
2731
|
+
const lockfile = LOCKFILES.find(([file]) => existsSync(join4(at, file)));
|
|
2514
2732
|
if (lockfile !== undefined)
|
|
2515
2733
|
return lockfile[1];
|
|
2516
|
-
if (at === root || at ===
|
|
2734
|
+
if (at === root || at === dirname3(at))
|
|
2517
2735
|
return "bun";
|
|
2518
2736
|
}
|
|
2519
2737
|
}
|
|
@@ -2529,7 +2747,7 @@ function findConsumers(name, root) {
|
|
|
2529
2747
|
const kind = KINDS.find((each) => typeof manifest[each]?.[name] === "string");
|
|
2530
2748
|
const spec = kind === undefined ? undefined : manifest[kind]?.[name];
|
|
2531
2749
|
if (kind !== undefined && spec !== undefined)
|
|
2532
|
-
consumers.push({ dir: relative(root,
|
|
2750
|
+
consumers.push({ dir: relative(root, dirname3(path)) || ".", path, kind, spec, manager: managerFor(dirname3(path), root) });
|
|
2533
2751
|
}
|
|
2534
2752
|
return consumers;
|
|
2535
2753
|
}
|
|
@@ -2555,8 +2773,8 @@ __export(exports_bump, {
|
|
|
2555
2773
|
bump: () => bump
|
|
2556
2774
|
});
|
|
2557
2775
|
import { existsSync as existsSync2 } from "fs";
|
|
2558
|
-
import { homedir as
|
|
2559
|
-
import { dirname as
|
|
2776
|
+
import { homedir as homedir3 } from "os";
|
|
2777
|
+
import { dirname as dirname4, join as join5, relative as relative2 } from "path";
|
|
2560
2778
|
async function lookup(name, registry, fetcher) {
|
|
2561
2779
|
try {
|
|
2562
2780
|
return { packument: await fetchPackument(name, registry, fetcher) };
|
|
@@ -2616,11 +2834,11 @@ async function vet(name, version, settings) {
|
|
|
2616
2834
|
return false;
|
|
2617
2835
|
}
|
|
2618
2836
|
function lockfileOf(dir, root) {
|
|
2619
|
-
for (let at = dir;; at =
|
|
2620
|
-
const found = ["bun.lock", "bun.lockb"].find((file) => existsSync2(
|
|
2837
|
+
for (let at = dir;; at = dirname4(at)) {
|
|
2838
|
+
const found = ["bun.lock", "bun.lockb"].find((file) => existsSync2(join5(at, file)));
|
|
2621
2839
|
if (found !== undefined)
|
|
2622
|
-
return relative2(dir,
|
|
2623
|
-
if (at === root || at ===
|
|
2840
|
+
return relative2(dir, join5(at, found));
|
|
2841
|
+
if (at === root || at === dirname4(at))
|
|
2624
2842
|
return;
|
|
2625
2843
|
}
|
|
2626
2844
|
}
|
|
@@ -2654,7 +2872,7 @@ async function bumpConsumers(name, version, settings) {
|
|
|
2654
2872
|
note(`${local} non-registry dependenc${local === 1 ? "y" : "ies"} (workspace:, file:, git, URL, alias, catalog:)`, "left as they are");
|
|
2655
2873
|
for (const consumer of consumers) {
|
|
2656
2874
|
const argv = addCommand(consumer, name, version);
|
|
2657
|
-
const where =
|
|
2875
|
+
const where = join5(settings.root, consumer.dir);
|
|
2658
2876
|
if (consumer.kind === "peerDependencies") {
|
|
2659
2877
|
skipped.push(consumer.dir);
|
|
2660
2878
|
note(consumer.dir, `peer range ${consumer.spec}, left as it is`);
|
|
@@ -2697,9 +2915,9 @@ async function bumpConsumers(name, version, settings) {
|
|
|
2697
2915
|
return isClean;
|
|
2698
2916
|
}
|
|
2699
2917
|
async function bump(args) {
|
|
2700
|
-
const { values, positionals: [name, asked] } = parse(args,
|
|
2918
|
+
const { values, positionals: [name, asked] } = parse(args, usage4, options3, { positionals: ["<name>", "[version]"] });
|
|
2701
2919
|
const settings = {
|
|
2702
|
-
root: values.root ??
|
|
2920
|
+
root: values.root ?? join5(homedir3(), "Workspace"),
|
|
2703
2921
|
configs: await loadConfigs(),
|
|
2704
2922
|
timeout: duration(values.timeout, "timeout", 10 * 60000),
|
|
2705
2923
|
isDryRun: values["dry-run"] === true,
|
|
@@ -2713,7 +2931,7 @@ async function bump(args) {
|
|
|
2713
2931
|
return 1;
|
|
2714
2932
|
return await bumpConsumers(name, version, settings) ? 0 : 1;
|
|
2715
2933
|
}
|
|
2716
|
-
var
|
|
2934
|
+
var usage4 = `pkg bump <name> [version]
|
|
2717
2935
|
|
|
2718
2936
|
Waits until the registry serves the version (the latest when none is given, an exact version otherwise), vets it as \`pkg check\` does (advisories, licence allowlist, and a minimum age only when --min-age asks for one), then runs \`bun add --exact --no-cache\` in each folder under --root whose package.json depends on the package, the kind of dependency kept, a line per folder.
|
|
2719
2937
|
A version the vetting blocks is refused before any folder is touched, unless --force is given.
|
|
@@ -2745,11 +2963,11 @@ var exports_consumers = {};
|
|
|
2745
2963
|
__export(exports_consumers, {
|
|
2746
2964
|
consumers: () => consumers
|
|
2747
2965
|
});
|
|
2748
|
-
import { homedir as
|
|
2749
|
-
import { join as
|
|
2966
|
+
import { homedir as homedir4 } from "os";
|
|
2967
|
+
import { join as join6 } from "path";
|
|
2750
2968
|
function consumers(args) {
|
|
2751
|
-
const { values, positionals: [name] } = parse(args,
|
|
2752
|
-
const root = values.root ??
|
|
2969
|
+
const { values, positionals: [name] } = parse(args, usage5, options4, { positionals: ["<name>"] });
|
|
2970
|
+
const root = values.root ?? join6(homedir4(), "Workspace");
|
|
2753
2971
|
const { shown, footer } = capped(findConsumers(name, root), limitOf(values, CONSUMERS_LIMIT));
|
|
2754
2972
|
if (values.json === true)
|
|
2755
2973
|
printJson(shown);
|
|
@@ -2760,7 +2978,7 @@ function consumers(args) {
|
|
|
2760
2978
|
`));
|
|
2761
2979
|
return 0;
|
|
2762
2980
|
}
|
|
2763
|
-
var
|
|
2981
|
+
var usage5 = `pkg consumers <name>
|
|
2764
2982
|
|
|
2765
2983
|
Lists the folders under --root whose package.json depends on the package: the folder, the kind of dependency, the version it asks for and the manager its lockfile pins, 30 at most with the count of the rest after them (--limit <n>, --full for all; --json is never cut unless --limit is given).
|
|
2766
2984
|
|
|
@@ -2778,12 +2996,12 @@ var init_consumers2 = __esm(() => {
|
|
|
2778
2996
|
|
|
2779
2997
|
// src/cli.ts
|
|
2780
2998
|
init_src();
|
|
2781
|
-
import
|
|
2999
|
+
import process12 from "process";
|
|
2782
3000
|
// package.json
|
|
2783
|
-
var version = "0.7.
|
|
3001
|
+
var version = "0.7.1";
|
|
2784
3002
|
|
|
2785
3003
|
// src/cli.ts
|
|
2786
|
-
|
|
3004
|
+
process12.exitCode = await runCli({
|
|
2787
3005
|
name: "pkg",
|
|
2788
3006
|
version,
|
|
2789
3007
|
about: "checks npm packages before they are added, and moves a lib's consumers onto a new release",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaynooo/cli-pkg",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.1",
|
|
5
5
|
"description": "pkg: check an npm package before it is added, for a guessed name, a version under two weeks old and install scripts.",
|
|
6
6
|
"author": "Kaynooo <contact@kaynooo.fr>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -30,6 +30,6 @@
|
|
|
30
30
|
"record": "$npm_execpath scripts/record.ts"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@kaynooo/cli-kit": "0.
|
|
33
|
+
"@kaynooo/cli-kit": "0.20.0"
|
|
34
34
|
}
|
|
35
35
|
}
|