@kaynooo/pkg-tools 0.2.1 → 0.4.0

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.
Files changed (4) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +37 -1
  3. package/dist/cli.js +1757 -726
  4. package/package.json +6 -6
package/dist/cli.js CHANGED
@@ -1,18 +1,30 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
-
4
- // src/cli.ts
5
- import process7 from "process";
6
-
7
- // ../kit/src/args.ts
8
- import process3 from "process";
9
- import { parseArgs } from "util";
10
-
11
- // ../kit/src/format.ts
12
- import process2 from "process";
13
-
14
- // ../kit/src/style.ts
15
- import process from "process";
3
+ var __defProp = Object.defineProperty;
4
+ var __returnValue = (v) => v;
5
+ function __exportSetter(name, newValue) {
6
+ this[name] = __returnValue.bind(null, newValue);
7
+ }
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, {
11
+ get: all[name],
12
+ enumerable: true,
13
+ configurable: true,
14
+ set: __exportSetter.bind(all, name)
15
+ });
16
+ };
17
+ var __esm = (fn, res, err) => () => {
18
+ if (fn)
19
+ try {
20
+ res = fn(fn = 0);
21
+ } catch (e) {
22
+ err = [e];
23
+ }
24
+ if (err)
25
+ throw err[0];
26
+ return res;
27
+ };
16
28
 
17
29
  // ../../node_modules/.bun/@kaynooo+utils@2.31.0+d0769e28dc4dad16/node_modules/@kaynooo/utils/dist/chunk-mtetydvc.js
18
30
  function x(s) {
@@ -94,9 +106,6 @@ function O(s) {
94
106
  function v(s, r, t, n) {
95
107
  return s /= 100, r /= 100, t /= 100, n /= 100, [Math.round(255 * (1 - s) * (1 - n)), Math.round(255 * (1 - r) * (1 - n)), Math.round(255 * (1 - t) * (1 - n))];
96
108
  }
97
- var m = (s) => s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
98
- var p = (s) => s <= 0.0031308 ? 12.92 * s : 1.055 * s ** 0.4166666666666667 - 0.055;
99
- var i = (s, r) => Math.round(s * 10 ** r) / 10 ** r;
100
109
  function T(s) {
101
110
  let r = m(s[0] / 255), t = m(s[1] / 255), n = m(s[2] / 255), a = Math.cbrt(0.4122214708 * r + 0.5363325363 * t + 0.0514459929 * n), b = Math.cbrt(0.2119034982 * r + 0.6806995451 * t + 0.1073969566 * n), o = Math.cbrt(0.0883024619 * r + 0.2817188376 * t + 0.6299787005 * n);
102
111
  return [i(0.2104542553 * a + 0.793617785 * b - 0.0040720468 * o, 4), i(1.9779984951 * a - 2.428592205 * b + 0.4505937099 * o, 4), i(0.0259040371 * a + 0.7827717662 * b - 0.808675766 * o, 4)];
@@ -233,16 +242,10 @@ class e {
233
242
  return t >= n ? s : r;
234
243
  }
235
244
  }
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
+ var init_chunk_mtetydvc = () => {};
236
247
 
237
248
  // ../../node_modules/.bun/@kaynooo+utils@2.31.0+d0769e28dc4dad16/node_modules/@kaynooo/utils/dist/chunk-y1msbssb.js
238
- var r = 39;
239
- var o = 49;
240
- var f2 = "\x1B[";
241
- var C2 = { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29], black: [30, r], red: [31, r], green: [32, r], yellow: [33, r], blue: [34, r], magenta: [35, r], cyan: [36, r], white: [37, r], gray: [90, r], grey: [90, r], blackBright: [90, r], redBright: [91, r], greenBright: [92, r], yellowBright: [93, r], blueBright: [94, r], magentaBright: [95, r], cyanBright: [96, r], whiteBright: [97, r], bgBlack: [40, o], bgRed: [41, o], bgGreen: [42, o], bgYellow: [43, o], bgBlue: [44, o], bgMagenta: [45, o], bgCyan: [46, o], bgWhite: [47, o], bgBlackBright: [100, o], bgRedBright: [101, o], bgGreenBright: [102, o], bgYellowBright: [103, o], bgBlueBright: [104, o], bgMagentaBright: [105, o], bgCyanBright: [106, o], bgWhiteBright: [107, o], rgb: (i, n, a, l = "fg") => [`${l === "fg" ? 38 : 48};2;${i};${n};${a}`, l === "fg" ? r : o], hex: (i, n = "fg") => {
242
- let [a, l, s] = e.from("hex", i).to("rgb");
243
- return [`${n === "fg" ? 38 : 48};2;${a};${l};${s}`, n === "fg" ? r : o];
244
- }, ansi256: (i, n = "fg") => [`${n === "fg" ? 38 : 48};5;${i}`, n === "fg" ? r : o] };
245
- var b = new Set(["", "1", "2", "3", "true"]);
246
249
  function h(i, n = globalThis.process?.env ?? {}) {
247
250
  if (n.FORCE_COLOR !== undefined)
248
251
  return b.has(n.FORCE_COLOR);
@@ -273,26 +276,69 @@ function u(i, n = []) {
273
276
  function le(i = {}) {
274
277
  return u(i);
275
278
  }
276
- var t = le();
279
+ var r = 39, o = 49, f2 = "\x1B[", C2, b, t;
280
+ var init_chunk_y1msbssb = __esm(() => {
281
+ init_chunk_mtetydvc();
282
+ C2 = { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29], black: [30, r], red: [31, r], green: [32, r], yellow: [33, r], blue: [34, r], magenta: [35, r], cyan: [36, r], white: [37, r], gray: [90, r], grey: [90, r], blackBright: [90, r], redBright: [91, r], greenBright: [92, r], yellowBright: [93, r], blueBright: [94, r], magentaBright: [95, r], cyanBright: [96, r], whiteBright: [97, r], bgBlack: [40, o], bgRed: [41, o], bgGreen: [42, o], bgYellow: [43, o], bgBlue: [44, o], bgMagenta: [45, o], bgCyan: [46, o], bgWhite: [47, o], bgBlackBright: [100, o], bgRedBright: [101, o], bgGreenBright: [102, o], bgYellowBright: [103, o], bgBlueBright: [104, o], bgMagentaBright: [105, o], bgCyanBright: [106, o], bgWhiteBright: [107, o], rgb: (i, n, a, l = "fg") => [`${l === "fg" ? 38 : 48};2;${i};${n};${a}`, l === "fg" ? r : o], hex: (i, n = "fg") => {
283
+ let [a, l, s] = e.from("hex", i).to("rgb");
284
+ return [`${n === "fg" ? 38 : 48};2;${a};${l};${s}`, n === "fg" ? r : o];
285
+ }, ansi256: (i, n = "fg") => [`${n === "fg" ? 38 : 48};5;${i}`, n === "fg" ? r : o] };
286
+ b = new Set(["", "1", "2", "3", "true"]);
287
+ t = le();
288
+ });
289
+
290
+ // ../../node_modules/.bun/@kaynooo+utils@2.31.0+d0769e28dc4dad16/node_modules/@kaynooo/utils/dist/tools/colors.js
291
+ var init_colors = __esm(() => {
292
+ init_chunk_y1msbssb();
293
+ });
277
294
 
278
295
  // ../kit/src/style.ts
296
+ import process from "process";
279
297
  function takesControlCodes(stream, env = process.env) {
280
298
  return stream.isTTY === true && env.NO_COLOR === undefined && env.NODE_DISABLE_COLORS === undefined && env.TERM !== "dumb";
281
299
  }
282
300
  function paint(stream, env = process.env) {
283
301
  return le({ stream: { isTTY: takesControlCodes(stream, env) }, env });
284
302
  }
285
- var STATUSES = {
286
- passed: { symbol: "\u2713", words: ["passed", "success", "succeeded", "ok"], paint: (colors) => colors.green },
287
- failed: { symbol: "\u2717", words: ["failed", "failure", "error", "errored"], paint: (colors) => colors.red },
288
- running: { symbol: "\u25CF", words: ["running", "in_progress", "started"], paint: (colors) => colors.cyan },
289
- queued: { symbol: "\u25CB", words: ["queued", "waiting", "pending", "created", "blocked", "scheduled"], paint: (colors) => colors.yellow },
290
- skipped: { symbol: "-", words: ["skipped", "cancelled", "canceled", "manual"], paint: (colors) => colors.dim }
291
- };
292
- var STATUS_OF = new Map(Object.entries(STATUSES).flatMap(([status, { words }]) => words.map((word) => [word, status])));
303
+ function marked(mark, text, stream, detail, env = process.env) {
304
+ const colors = paint(stream, env);
305
+ const { symbol, word, paint: tint } = MARKS[mark];
306
+ const head = takesControlCodes(stream, env) ? tint(colors)(symbol) : word;
307
+ return `${head} ${text}${detail === undefined ? "" : ` ${colors.dim(detail)}`}`;
308
+ }
309
+ function ok(text, detail) {
310
+ console.log(marked("ok", text, process.stdout, detail));
311
+ }
312
+ function note(text, detail) {
313
+ console.log(marked("note", text, process.stdout, detail));
314
+ }
315
+ function warn(text, detail) {
316
+ console.error(marked("warn", text, process.stderr, detail));
317
+ }
318
+ function problem(text, detail) {
319
+ console.error(marked("problem", text, process.stderr, detail));
320
+ }
321
+ var MARKS, STATUSES, STATUS_OF;
322
+ var init_style = __esm(() => {
323
+ init_colors();
324
+ MARKS = {
325
+ ok: { symbol: "\u2713", word: "ok:", paint: (colors) => colors.green },
326
+ warn: { symbol: "!", word: "warning:", paint: (colors) => colors.yellow },
327
+ problem: { symbol: "\u2717", word: "error:", paint: (colors) => colors.red },
328
+ note: { symbol: "\xB7", word: "note:", paint: (colors) => colors.dim }
329
+ };
330
+ STATUSES = {
331
+ passed: { symbol: "\u2713", words: ["passed", "success", "succeeded", "ok"], paint: (colors) => colors.green },
332
+ failed: { symbol: "\u2717", words: ["failed", "failure", "error", "errored"], paint: (colors) => colors.red },
333
+ running: { symbol: "\u25CF", words: ["running", "in_progress", "started"], paint: (colors) => colors.cyan },
334
+ queued: { symbol: "\u25CB", words: ["queued", "waiting", "pending", "created", "blocked", "scheduled"], paint: (colors) => colors.yellow },
335
+ skipped: { symbol: "-", words: ["skipped", "cancelled", "canceled", "manual"], paint: (colors) => colors.dim }
336
+ };
337
+ STATUS_OF = new Map(Object.entries(STATUSES).flatMap(([status, { words }]) => words.map((word) => [word, status])));
338
+ });
293
339
 
294
340
  // ../kit/src/format.ts
295
- var UNITS = [["d", 86400], ["h", 3600], ["m", 60], ["s", 1]];
341
+ import process2 from "process";
296
342
  function formatSeconds(total) {
297
343
  let rest = Math.max(0, Math.round(total));
298
344
  const amounts = UNITS.map(([unit, size]) => {
@@ -306,6 +352,9 @@ function formatSeconds(total) {
306
352
  const next = amounts[first + 1];
307
353
  return next === undefined || next.startsWith("0") ? amounts[first] ?? "0s" : `${amounts[first]} ${next}`;
308
354
  }
355
+ function formatDuration(ms) {
356
+ return ms < 60000 ? `${(Math.max(0, ms) / 1000).toFixed(1)}s` : formatSeconds(ms / 1000);
357
+ }
309
358
  function upTo(text, separator) {
310
359
  const end = text.indexOf(separator);
311
360
  return end === -1 ? text : text.slice(0, end);
@@ -320,8 +369,6 @@ function formatAge(date, now = Date.now()) {
320
369
  function truncate(text, width) {
321
370
  return text.length <= width ? text : `${text.slice(0, Math.max(0, width - 1))}\u2026`;
322
371
  }
323
- var LINE_BREAKS = /\s*\n\s*/g;
324
- var ESCAPE = String.fromCharCode(27);
325
372
  function textWidth(text) {
326
373
  return Bun.stringWidth(text);
327
374
  }
@@ -363,56 +410,65 @@ function narrow(rows, widths, limit) {
363
410
  function printJson(value) {
364
411
  console.log(JSON.stringify(value, undefined, 2));
365
412
  }
413
+ var UNITS, LINE_BREAKS, ESCAPE;
414
+ var init_format = __esm(() => {
415
+ init_style();
416
+ UNITS = [["d", 86400], ["h", 3600], ["m", 60], ["s", 1]];
417
+ LINE_BREAKS = /\s*\n\s*/g;
418
+ ESCAPE = String.fromCharCode(27);
419
+ });
366
420
 
367
421
  // ../kit/src/args.ts
422
+ import process3 from "process";
423
+ import { parseArgs } from "util";
368
424
  function jsonOption(holds) {
369
425
  return { type: "boolean", description: holds === undefined ? "print JSON" : `print JSON: ${holds}` };
370
426
  }
371
-
372
- class Exit extends Error {
373
- code;
374
- hint;
375
- constructor(message, code, hint) {
376
- super(message);
377
- this.code = code;
378
- this.hint = hint;
379
- }
380
- }
381
427
  function fail(message, code = 2, hint) {
382
428
  throw new Exit(message, code, hint);
383
429
  }
384
-
385
- class UsageError extends Exit {
386
- constructor(message) {
387
- super(message, 2);
388
- }
389
- }
390
430
  function badUsage(message) {
391
431
  throw new UsageError(message);
392
432
  }
393
433
 
394
- class HelpShown extends Exit {
395
- constructor() {
396
- super("help shown", 0);
397
- }
398
- }
399
-
400
434
  class Completing {
401
435
  options;
402
436
  constructor(options) {
403
437
  this.options = options;
404
438
  }
405
439
  }
406
- var completion = { active: false };
407
- var OPTIONAL = /\[[^\]]+\]/g;
408
- var USAGE_PREFIX = /^usage:\s*/i;
409
440
  function usageLine(usage, colors = paint(process3.stdout)) {
410
441
  return `${colors.bold("Usage:")} ${usage.replace(USAGE_PREFIX, "").replaceAll(OPTIONAL, (part) => colors.dim(part))}`;
411
442
  }
412
- function helpText(usage, options, colors = paint(process3.stdout)) {
413
- return [usageLine(usage, colors), "", colors.bold("Options:"), ...optionRows(options, colors)].join(`
443
+ function helpText(usage, options, colors = paint(process3.stdout), { examples = [], replaces } = {}) {
444
+ return [usageLine(usage, colors), ...replacesRows(replaces, colors), "", colors.bold("Options:"), ...optionRows(options, colors), ...exampleRows(examples, colors)].join(`
414
445
  `);
415
446
  }
447
+ function replacesRows(replaces, colors = paint(process3.stdout)) {
448
+ return replaces === undefined ? [] : ["", `${colors.bold("Instead of:")} ${replaces}`];
449
+ }
450
+ function wantsHelpJson(env = process3.env) {
451
+ return env.KIT_HELP === "json";
452
+ }
453
+ function description(usage, { examples = [], replaces } = {}) {
454
+ const lines = usage.replace(USAGE_PREFIX, "").split(`
455
+ `);
456
+ const first = lines[0];
457
+ const colon = first.indexOf(": ");
458
+ const prose = lines[lines.indexOf("") + 1] ?? "";
459
+ const fallback = lines.includes("") ? `${prose.charAt(0).toLowerCase()}${prose.slice(1)}`.replace(FULL_STOP, "") : "";
460
+ return {
461
+ synopsis: colon === -1 ? first : first.slice(0, colon),
462
+ summary: colon === -1 ? fallback : first.slice(colon + 2),
463
+ ...replaces === undefined ? {} : { replaces },
464
+ examples: examples.map((example) => typeof example === "string" ? { line: example } : { line: example[0], note: example[1] })
465
+ };
466
+ }
467
+ function exampleRows(examples, colors = paint(process3.stdout)) {
468
+ if (examples.length === 0)
469
+ return [];
470
+ return ["", colors.bold("Examples:"), ...examples.map((example) => typeof example === "string" ? ` ${example}` : ` ${example[0]} ${colors.dim(`# ${example[1]}`)}`)];
471
+ }
416
472
  function optionRows(options, colors = paint(process3.stdout)) {
417
473
  const rows = Object.entries(options).map(([name, option]) => {
418
474
  const short = option.short === undefined ? " " : `${colors.cyan(`-${option.short}`)}, `;
@@ -422,8 +478,23 @@ function optionRows(options, colors = paint(process3.stdout)) {
422
478
  const width = Math.max(0, ...rows.map((row) => row.width));
423
479
  return rows.map((row) => ` ${row.flag}${" ".repeat(width - row.width)} ${colors.dim(row.description)}`);
424
480
  }
481
+ function applyOutput(color, plain, env = process3.env) {
482
+ const when = plain === true ? "never" : color ?? "auto";
483
+ if (when === "auto")
484
+ return;
485
+ if (when !== "always" && when !== "never")
486
+ badUsage(`--color takes auto, always or never, not ${when}`);
487
+ if (when === "always") {
488
+ env.FORCE_COLOR = "1";
489
+ delete env.NO_COLOR;
490
+ } else {
491
+ env.NO_COLOR = "1";
492
+ delete env.FORCE_COLOR;
493
+ }
494
+ }
425
495
  function parse(args, usage, options, settings = {}) {
426
- const all = { ...options, help: { type: "boolean", short: "h", description: "show this help" } };
496
+ const output = Object.fromEntries(Object.entries(OUTPUT_OPTIONS).filter(([name]) => !(name in options)));
497
+ const all = { ...options, ...output, help: { type: "boolean", short: "h", description: "show this help" } };
427
498
  if (completion.active)
428
499
  throw new Completing(all);
429
500
  const separator = settings.rest === true ? args.indexOf("--") : -1;
@@ -431,12 +502,14 @@ function parse(args, usage, options, settings = {}) {
431
502
  const rest = separator === -1 ? undefined : args.slice(separator + 1);
432
503
  let parsed;
433
504
  try {
434
- parsed = parseArgs({ args: own, options: all, allowPositionals: true, allowNegative: settings.allowNegative === true, strict: true });
505
+ parsed = parseArgs({ args: joinDashValues(own, all), options: all, allowPositionals: true, allowNegative: settings.allowNegative === true, strict: true });
435
506
  } catch (error) {
436
507
  badUsage(parseError(error));
437
508
  }
438
- if (parsed.values.help === true) {
439
- console.log(helpText(usage, all));
509
+ const values = parsed.values;
510
+ applyOutput("color" in output ? values.color : undefined, "plain" in output ? values.plain : undefined);
511
+ if (values.help === true) {
512
+ console.log(wantsHelpJson() ? JSON.stringify(description(usage, settings)) : helpText(usage, all, undefined, settings));
440
513
  throw new HelpShown;
441
514
  }
442
515
  if (settings.positionals !== undefined)
@@ -451,6 +524,25 @@ function checkPositionals(given, names) {
451
524
  if (!variadic && given.length > names.length)
452
525
  badUsage(`unexpected argument ${given[names.length]}`);
453
526
  }
527
+ function joinDashValues(args, options) {
528
+ const longOf = new Map(Object.entries(options).flatMap(([name, option]) => option.short === undefined ? [[`--${name}`, name]] : [[`--${name}`, name], [`-${option.short}`, name]]));
529
+ const isOption = (arg) => arg === "--" || longOf.has(arg.includes("=") ? arg.slice(0, arg.indexOf("=")) : arg);
530
+ const joined = [];
531
+ for (let i = 0;i < args.length; i++) {
532
+ const arg = args[i] ?? "";
533
+ if (arg === "--")
534
+ return [...joined, ...args.slice(i)];
535
+ const name = longOf.get(arg);
536
+ const next = args[i + 1];
537
+ if (name !== undefined && options[name]?.type === "string" && next !== undefined && next.startsWith("-") && next !== "-" && !isOption(next)) {
538
+ joined.push(`--${name}=${next}`);
539
+ i++;
540
+ } else {
541
+ joined.push(arg);
542
+ }
543
+ }
544
+ return joined;
545
+ }
454
546
  function parseError(error) {
455
547
  const message = upTo(error instanceof Error ? error.message : String(error), ". ");
456
548
  return `${message.charAt(0).toLowerCase()}${message.slice(1)}`;
@@ -463,11 +555,57 @@ function wholeNumber(value, name, fallback, min = 1) {
463
555
  badUsage(`--${name} takes a whole number from ${min}, not ${value}`);
464
556
  return number;
465
557
  }
466
- // ../kit/src/cli.ts
467
- import process4 from "process";
558
+ function duration(value, name, fallback, unit = "s") {
559
+ if (value === undefined)
560
+ return fallback;
561
+ const match = DURATION.exec(value.trim());
562
+ const ms = match === null ? 0 : Number(match[1]) * UNIT_MS[match[2] ?? unit];
563
+ if (ms < 1)
564
+ badUsage(`--${name} takes a duration such as 30s, 5m or 1h, not ${value}`);
565
+ return ms;
566
+ }
567
+ var Exit, UsageError, HelpShown, completion, OPTIONAL, USAGE_PREFIX, FULL_STOP, OUTPUT_OPTIONS, DURATION, UNIT_MS;
568
+ var init_args = __esm(() => {
569
+ init_format();
570
+ init_style();
571
+ Exit = class Exit extends Error {
572
+ code;
573
+ hint;
574
+ constructor(message, code, hint) {
575
+ super(message);
576
+ this.code = code;
577
+ this.hint = hint;
578
+ }
579
+ };
580
+ UsageError = class UsageError extends Exit {
581
+ constructor(message) {
582
+ super(message, 2);
583
+ }
584
+ };
585
+ HelpShown = class HelpShown extends Exit {
586
+ constructor() {
587
+ super("help shown", 0);
588
+ }
589
+ };
590
+ completion = { active: false };
591
+ OPTIONAL = /\[[^\]]+\]/g;
592
+ USAGE_PREFIX = /^usage:\s*/i;
593
+ FULL_STOP = /\.$/;
594
+ OUTPUT_OPTIONS = {
595
+ color: { type: "string", description: "auto (on a terminal alone), always or never" },
596
+ plain: { type: "boolean", description: "plain text, no colour or spinner: --color never" }
597
+ };
598
+ DURATION = /^(\d+(?:\.\d+)?)(ms|[smh])?$/;
599
+ UNIT_MS = { ms: 1, s: 1000, m: 60000, h: 3600000 };
600
+ });
601
+
602
+ // ../kit/src/chart.ts
603
+ var init_chart = __esm(() => {
604
+ init_format();
605
+ init_style();
606
+ });
468
607
 
469
608
  // ../kit/src/text.ts
470
- var ANSI = new RegExp(`${String.fromCharCode(27)}\\[[\\d;?]*[a-z]`, "gi");
471
609
  function distance(a, b) {
472
610
  let previous = Array.from({ length: b.length + 1 }, (_, index) => index);
473
611
  for (const [i, left] of [...a].entries()) {
@@ -478,8 +616,71 @@ function distance(a, b) {
478
616
  }
479
617
  return previous[b.length] ?? 0;
480
618
  }
619
+ var ANSI;
620
+ var init_text = __esm(() => {
621
+ ANSI = new RegExp(`${String.fromCharCode(27)}\\[[\\d;?]*[a-z]`, "gi");
622
+ });
481
623
 
482
624
  // ../kit/src/cli.ts
625
+ import process4 from "process";
626
+ function commandRows(commands, colors) {
627
+ const width = Math.max(...Object.keys(commands).map((name) => name.length));
628
+ const groups = new Map([["Commands:", []]]);
629
+ for (const [name, { summary, group }] of Object.entries(commands)) {
630
+ const heading = group === undefined ? "Commands:" : `${group}:`;
631
+ const rows = groups.get(heading) ?? [];
632
+ rows.push(` ${colors.cyan(name.padEnd(width))} ${colors.dim(summary)}`);
633
+ groups.set(heading, rows);
634
+ }
635
+ return [...groups].filter(([, rows]) => rows.length > 0).flatMap(([heading, rows], index) => [...index === 0 ? [] : [""], colors.bold(heading), ...rows]);
636
+ }
637
+ function takeOutputFlags(argv) {
638
+ let index = 0;
639
+ for (;index < argv.length; index++) {
640
+ const word = argv[index];
641
+ if (word === "--plain")
642
+ applyOutput(undefined, true);
643
+ else if (word.startsWith("--color="))
644
+ applyOutput(word.slice("--color=".length), undefined);
645
+ else if (word === "--color" && argv[index + 1] !== undefined)
646
+ applyOutput(argv[++index], undefined);
647
+ else
648
+ break;
649
+ }
650
+ return argv.slice(index);
651
+ }
652
+ function closest(name, names) {
653
+ const started = names.find((known) => known.startsWith(name));
654
+ if (started !== undefined)
655
+ return started;
656
+ const [best] = names.map((known) => ({ known, far: distance(name, known) })).sort((a, b) => a.far - b.far);
657
+ return best !== undefined && best.far <= (name.length < 4 ? 1 : 2) ? best.known : undefined;
658
+ }
659
+ async function help({ path, header, summary, commands, defaultCommand, examples, replaces }, stream) {
660
+ const colors = paint(stream);
661
+ const prefix = path.join(" ");
662
+ if (wantsHelpJson())
663
+ return JSON.stringify(description(`${prefix} <command> [options]: ${summary}`, { examples, replaces }));
664
+ const fallback = defaultCommand === undefined ? undefined : commands[defaultCommand];
665
+ const options = fallback !== undefined && "run" in fallback ? await optionsOf(fallback.run) : undefined;
666
+ const own = Object.entries(options ?? {}).filter(([name]) => !(name in TOP_OPTIONS));
667
+ return [
668
+ header(colors),
669
+ "",
670
+ usageLine(`${prefix} ${defaultCommand === undefined ? colors.cyan("<command>") : `[${colors.cyan("<command>")}]`} [options]`, colors),
671
+ ...replacesRows(replaces, colors),
672
+ "",
673
+ ...commandRows(commands, colors),
674
+ ...own.length === 0 ? [] : ["", `${colors.bold(`Options of ${defaultCommand}:`)} ${colors.dim("the command run when none is named")}`, ...optionRows(Object.fromEntries(own), colors)],
675
+ "",
676
+ colors.bold("Options:"),
677
+ ...optionRows(path.length === 1 ? TOP_OPTIONS : LEVEL_OPTIONS, colors),
678
+ ...exampleRows(examples ?? [], colors),
679
+ "",
680
+ `${colors.dim("Run")} ${prefix} ${colors.cyan("<command>")} --help ${colors.dim("for its options.")}`
681
+ ].join(`
682
+ `);
683
+ }
483
684
  function printError(prefix, message, hint, cause) {
484
685
  const colors = paint(process4.stderr);
485
686
  const styled = takesControlCodes(process4.stderr);
@@ -488,17 +689,65 @@ function printError(prefix, message, hint, cause) {
488
689
  ${styled ? tint(label) : `${label}:`} ${text}`;
489
690
  console.error(`${head} ${message}${under("cause", cause, colors.dim)}${under("hint", hint, colors.yellow)}`);
490
691
  }
491
- function reportThrown(prefix, error, redact = (text) => text) {
692
+ function printJsonError(message, hint, cause) {
693
+ console.error(JSON.stringify({ error: message, ...hint === undefined ? {} : { hint }, ...cause === undefined ? {} : { cause } }));
694
+ }
695
+ function wantsJson(argv) {
696
+ const end = argv.indexOf("--");
697
+ return (end === -1 ? argv : argv.slice(0, end)).includes("--json");
698
+ }
699
+ function reportThrown(prefix, error, redact = (text) => text, json = false) {
492
700
  if (error instanceof HelpShown)
493
701
  return 0;
494
702
  const help = error instanceof UsageError ? `run ${prefix} --help for its options` : undefined;
495
703
  const named = error instanceof Error && !(error instanceof Exit) && error.name !== "Error" ? `${error.name}: ${error.message}` : undefined;
496
704
  const cause = error instanceof Error && error.cause instanceof Error ? redact(error.cause.message) : undefined;
497
- printError(prefix, redact(named ?? (error instanceof Error ? error.message : String(error))), error instanceof Exit ? error.hint ?? help : undefined, cause);
705
+ const report = json ? printJsonError : (message, hint, causeText) => printError(prefix, message, hint, causeText);
706
+ report(redact(named ?? (error instanceof Error ? error.message : String(error))), error instanceof Exit ? error.hint ?? help : undefined, cause);
498
707
  return error instanceof Exit ? error.code : 1;
499
708
  }
500
- var COMPLETE = "__complete";
501
- var FILES = "__files__";
709
+ async function dispatch(level, typed, { version, redact }) {
710
+ const prefix = level.path.join(" ");
711
+ let argv;
712
+ try {
713
+ argv = takeOutputFlags(typed);
714
+ } catch (error) {
715
+ return reportThrown(prefix, error);
716
+ }
717
+ const [name, ...args] = argv;
718
+ if (name === undefined && level.path.length > 1) {
719
+ console.error(await help(level, process4.stderr));
720
+ return 2;
721
+ }
722
+ if (name === undefined || name === "help" || name === "--help" || name === "-h") {
723
+ console.log(await help(level, process4.stdout));
724
+ return 0;
725
+ }
726
+ if (level.path.length === 1 && (name === "--version" || name === "-v")) {
727
+ console.log(version);
728
+ return 0;
729
+ }
730
+ let command = level.commands[level.aliases?.[name] ?? name];
731
+ let rest = args;
732
+ if (command === undefined && level.defaultCommand !== undefined) {
733
+ command = level.commands[level.defaultCommand];
734
+ rest = argv;
735
+ }
736
+ if (command === undefined) {
737
+ const meant = closest(name, Object.keys(level.commands));
738
+ printError(prefix, `no command ${name}`, meant === undefined ? `run ${prefix} --help for its commands` : `did you mean ${meant}?`);
739
+ return 2;
740
+ }
741
+ if ("commands" in command) {
742
+ const { summary } = command;
743
+ return dispatch({ path: [...level.path, name], header: (colors) => `${colors.bold(`${prefix} ${name}`)} ${summary}`, summary, commands: command.commands, aliases: command.aliases, defaultCommand: undefined, examples: command.examples, replaces: undefined }, rest, { version, redact });
744
+ }
745
+ try {
746
+ return await command.run(rest);
747
+ } catch (error) {
748
+ return reportThrown(`${prefix} ${name}`, error, redact, wantsJson(rest));
749
+ }
750
+ }
502
751
  async function optionsOf(run) {
503
752
  completion.active = true;
504
753
  try {
@@ -516,657 +765,141 @@ async function leafCandidates(run, words) {
516
765
  return [FILES];
517
766
  return Object.entries(await optionsOf(run)).map(([name, option]) => `--${name} ${option.description}`);
518
767
  }
768
+ async function candidates(commands, aliases, defaultCommand, words) {
769
+ const [word = "", ...rest] = words;
770
+ const command = commands[aliases?.[word] ?? word];
771
+ if (rest.length === 0 && !word.startsWith("-"))
772
+ return Object.entries(commands).map(([name, { summary }]) => `${name} ${summary}`);
773
+ if (command === undefined) {
774
+ const fallback = defaultCommand === undefined ? undefined : commands[defaultCommand];
775
+ return fallback !== undefined && "run" in fallback ? leafCandidates(fallback.run, words) : [];
776
+ }
777
+ return "commands" in command ? candidates(command.commands, command.aliases, undefined, rest) : leafCandidates(command.run, rest);
778
+ }
519
779
  async function printCandidates(found) {
520
780
  for (const line of await found)
521
781
  console.log(line);
522
782
  return 0;
523
783
  }
524
- async function runMain({ name, version, run, redact }, argv = process4.argv.slice(2)) {
784
+ async function runCli(cli, argv = process4.argv.slice(2)) {
525
785
  if (argv[0] === COMPLETE)
526
- return printCandidates(leafCandidates(run, argv.slice(1)));
527
- if (argv.length === 1 && (argv[0] === "--version" || argv[0] === "-v")) {
528
- console.log(version);
529
- return 0;
530
- }
531
- try {
532
- return await run(argv);
533
- } catch (error) {
534
- return reportThrown(name, error, redact);
535
- }
536
- }
537
- // package.json
538
- var version = "0.2.1";
786
+ return printCandidates(candidates(cli.commands, cli.aliases, cli.defaultCommand, argv.slice(1)));
787
+ return dispatch({ path: [cli.name], header: (colors) => `${colors.bold(cli.name)} ${colors.dim(cli.version)} ${cli.about}`, summary: cli.about, commands: cli.commands, aliases: cli.aliases, defaultCommand: cli.defaultCommand, examples: cli.examples, replaces: cli.replaces }, argv, { version: cli.version, redact: cli.redact });
788
+ }
789
+ var LEVEL_OPTIONS, TOP_OPTIONS, COMPLETE = "__complete", FILES = "__files__";
790
+ var init_cli = __esm(() => {
791
+ init_args();
792
+ init_style();
793
+ init_text();
794
+ LEVEL_OPTIONS = {
795
+ ...OUTPUT_OPTIONS,
796
+ help: { type: "boolean", short: "h", description: "show this help" }
797
+ };
798
+ TOP_OPTIONS = { ...LEVEL_OPTIONS, version: { type: "boolean", short: "v", description: "print the version" } };
799
+ });
539
800
 
540
- // src/popular.json
541
- var popular_default = [
542
- "semver",
543
- "minimatch",
544
- "debug",
545
- "ansi-styles",
546
- "brace-expansion",
547
- "strip-ansi",
548
- "ansi-regex",
549
- "ms",
550
- "supports-color",
551
- "chalk",
552
- "commander",
553
- "lru-cache",
554
- "string-width",
555
- "wrap-ansi",
556
- "tslib",
557
- "picomatch",
558
- "emoji-regex",
559
- "glob",
560
- "type-fest",
561
- "color-name",
562
- "eslint-visitor-keys",
563
- "color-convert",
564
- "ajv",
565
- "minipass",
566
- "source-map",
567
- "balanced-match",
568
- "readable-stream",
569
- "which",
570
- "glob-parent",
571
- "escape-string-regexp",
572
- "has-flag",
573
- "find-up",
574
- "locate-path",
575
- "json-schema-traverse",
576
- "p-limit",
577
- "yallist",
578
- "safe-buffer",
579
- "uuid",
580
- "p-locate",
581
- "undici-types",
582
- "ignore",
583
- "iconv-lite",
584
- "signal-exit",
585
- "esbuild",
586
- "is-fullwidth-code-point",
587
- "js-yaml",
588
- "entities",
589
- "globals",
590
- "postcss",
591
- "isexe",
592
- "isarray",
593
- "path-key",
594
- "string_decoder",
595
- "argparse",
596
- "ws",
597
- "mime-db",
598
- "resolve",
599
- "agent-base",
600
- "@esbuild/linux-x64",
601
- "yargs-parser",
602
- "mime-types",
603
- "acorn",
604
- "estraverse",
605
- "cross-spawn",
606
- "react-is",
607
- "picocolors",
608
- "fs-extra",
609
- "hasown",
610
- "nanoid",
611
- "yargs",
612
- "resolve-from",
613
- "shebang-command",
614
- "pretty-format",
615
- "json5",
616
- "https-proxy-agent",
617
- "path-to-regexp",
618
- "path-exists",
619
- "punycode",
620
- "js-tokens",
621
- "cliui",
622
- "shebang-regex",
623
- "@babel/types",
624
- "chokidar",
625
- "strip-json-comments",
626
- "inherits",
627
- "webidl-conversions",
628
- "get-stream",
629
- "eslint-scope",
630
- "cookie",
631
- "@babel/parser",
632
- "qs",
633
- "is-number",
634
- "whatwg-url",
635
- "@types/estree",
636
- "tr46",
637
- "convert-source-map",
638
- "is-glob",
639
- "braces",
640
- "fast-deep-equal",
641
- "form-data",
642
- "lodash",
643
- "@babel/helper-validator-identifier",
644
- "electron-to-chromium",
645
- "fill-range",
646
- "function-bind",
647
- "readdirp",
648
- "escalade",
649
- "graceful-fs",
650
- "negotiator",
651
- "is-stream",
652
- "camelcase",
653
- "@babel/runtime",
654
- "yocto-queue",
655
- "to-regex-range",
656
- "node-fetch",
657
- "micromatch",
658
- "node-releases",
659
- "get-intrinsic",
660
- "universalify",
661
- "path-scurry",
662
- "jsesc",
663
- "browserslist",
664
- "es-errors",
665
- "statuses",
666
- "@radix-ui/react-primitive",
667
- "magic-string",
668
- "rimraf",
669
- "is-extglob",
670
- "@jridgewell/trace-mapping",
671
- "@jridgewell/resolve-uri",
672
- "http-errors",
673
- "onetime",
674
- "has-symbols",
675
- "es-define-property",
676
- "gopd",
677
- "util-deprecate",
678
- "object-assign",
679
- "jiti",
680
- "yaml",
681
- "dotenv",
682
- "@babel/generator",
683
- "@babel/template",
684
- "imurmurhash",
685
- "postcss-selector-parser",
686
- "fast-glob",
687
- "update-browserslist-db",
688
- "@types/node",
689
- "@babel/compat-data",
690
- "eventemitter3",
691
- "callsites",
692
- "http-proxy-agent",
693
- "detect-libc",
694
- "espree",
695
- "execa",
696
- "@babel/core",
697
- "@babel/helpers",
698
- "concat-map",
699
- "source-map-js",
700
- "tinyglobby",
701
- "call-bind-apply-helpers",
702
- "flat-cache",
703
- "fdir",
704
- "pify",
705
- "@jest/types",
706
- "normalize-path",
707
- "is-core-module",
708
- "eslint",
709
- "minimist",
710
- "estree-walker",
711
- "file-entry-cache",
712
- "object-inspect",
713
- "buffer",
714
- "uri-js",
715
- "import-fresh",
716
- "@babel/helper-module-transforms",
717
- "optionator",
718
- "flatted",
719
- "math-intrinsics",
720
- "safer-buffer",
721
- "y18n",
722
- "@babel/helper-module-imports",
723
- "mkdirp",
724
- "dunder-proto",
725
- "path-parse",
726
- "fastq",
727
- "levn",
728
- "@babel/helper-compilation-targets",
729
- "@babel/helper-string-parser",
730
- "keyv",
731
- "get-proto",
732
- "csstype",
733
- "npm-run-path",
734
- "fast-json-stable-stringify",
735
- "reusify",
736
- "@babel/helper-plugin-utils",
737
- "kind-of",
738
- "mime",
739
- "caniuse-lite",
740
- "lines-and-columns",
741
- "fast-levenshtein",
742
- "supports-preserve-symlinks-flag",
743
- "make-dir",
744
- "slash",
745
- "prelude-ls",
746
- "typescript",
747
- "strip-bom",
748
- "parent-module",
749
- "esutils",
750
- "ci-info",
751
- "@smithy/util-utf8",
752
- "type-check",
753
- "mimic-fn",
754
- "@babel/helper-validator-option",
755
- "@types/json-schema",
756
- "@rolldown/pluginutils",
757
- "side-channel-list",
758
- "json-buffer",
759
- "raw-body",
760
- "has-tostringtag",
761
- "wrappy",
762
- "diff",
763
- "jackspeak",
764
- "baseline-browser-mapping",
765
- "deep-is",
766
- "foreground-child",
767
- "@eslint/js",
768
- "anymatch",
769
- "natural-compare",
770
- "esquery",
771
- "@eslint-community/regexpp",
772
- "es-set-tostringtag",
773
- "acorn-jsx",
774
- "parse5",
775
- "finalhandler",
776
- "parse-json",
777
- "depd",
778
- "axios",
779
- "run-parallel",
780
- "source-map-support",
781
- "esrecurse",
782
- "call-bound",
783
- "content-disposition",
784
- "human-signals",
785
- "ts-api-utils",
786
- "ansi-escapes",
787
- "jest-util",
788
- "send",
789
- "@opentelemetry/core",
790
- "type-is",
791
- "encodeurl",
792
- "once",
793
- "cosmiconfig",
794
- "lodash.merge",
795
- "json-stable-stringify-without-jsonify",
796
- "open",
797
- "prettier",
798
- "@eslint/eslintrc",
799
- "is-arrayish",
800
- "@jridgewell/sourcemap-codec",
801
- "gensync",
802
- "word-wrap",
803
- "express",
804
- "arg",
805
- "jsonfile",
806
- "schema-utils",
807
- "@smithy/is-array-buffer",
808
- "@typescript-eslint/types",
809
- "chownr",
810
- "delayed-stream",
811
- "@smithy/util-buffer-from",
812
- "asynckit",
813
- "tapable",
814
- "enhanced-resolve",
815
- "aria-query",
816
- "indent-string",
817
- "bytes",
818
- "binary-extensions",
819
- "ini",
820
- "@radix-ui/react-context",
821
- "doctrine",
822
- "queue-microtask",
823
- "accepts",
824
- "merge2",
825
- "get-caller-file",
826
- "@humanwhocodes/retry",
827
- "@jridgewell/gen-mapping",
828
- "@typescript-eslint/typescript-estree",
829
- "jest-worker",
830
- "proxy-from-env",
831
- "clsx",
832
- "side-channel-map",
833
- "@typescript-eslint/visitor-keys",
834
- "fresh",
835
- "restore-cursor",
836
- "on-finished",
837
- "is-plain-obj",
838
- "ipaddr.js",
839
- "pathe",
840
- "@jest/schemas",
841
- "base64-js",
842
- "@smithy/types",
843
- "require-directory",
844
- "tough-cookie",
845
- "is-binary-path",
846
- "body-parser",
847
- "postcss-value-parser",
848
- "media-typer",
849
- "setprototypeof",
850
- "side-channel-weakmap",
851
- "@typescript-eslint/tsconfig-utils",
852
- "@isaacs/cliui",
853
- "@rollup/rollup-linux-x64-gnu",
854
- "is-wsl",
855
- "retry",
856
- "@aws-sdk/types",
857
- "@types/react-dom",
858
- "combined-stream",
859
- "es-object-atoms",
860
- "@eslint/core",
861
- "whatwg-mimetype",
862
- "domutils",
863
- "@rollup/rollup-linux-x64-musl",
864
- "core-util-is",
865
- "@typescript-eslint/scope-manager",
866
- "esprima",
867
- "loose-envify",
868
- "cookie-signature",
869
- "follow-redirects",
870
- "cli-cursor",
871
- "strip-final-newline",
872
- "@typescript-eslint/project-service",
873
- "eastasianwidth",
874
- "json-parse-even-better-errors",
875
- "sprintf-js",
876
- "path-type",
877
- "content-type",
878
- "es-module-lexer",
879
- "@nodelib/fs.scandir",
880
- "write-file-atomic",
881
- "@eslint/plugin-kit",
882
- "ieee754",
883
- "prop-types",
884
- "require-from-string",
885
- "dom-serializer",
886
- "call-bind",
887
- "@eslint/config-array",
888
- "has-property-descriptors",
889
- "@nodelib/fs.stat",
890
- "merge-descriptors",
891
- "slice-ansi",
892
- "rxjs",
893
- "p-map",
894
- "toidentifier",
895
- "globby",
896
- "domhandler",
897
- "async",
898
- "@babel/helper-globals",
899
- "pirates",
900
- "@opentelemetry/semantic-conventions",
901
- "@typescript-eslint/utils",
902
- "date-fns",
903
- "is-docker",
904
- "tar",
905
- "which-typed-array",
906
- "ajv-formats",
907
- "@opentelemetry/api-logs",
908
- "@opentelemetry/resources",
909
- "side-channel",
910
- "cjs-module-lexer",
911
- "range-parser",
912
- "@humanfs/node",
913
- "define-data-property",
914
- "node-addon-api",
915
- "pako",
916
- "lilconfig",
917
- "fast-uri",
918
- "ip-address",
919
- "fs.realpath",
920
- "@img/sharp-libvips-linuxmusl-x64",
921
- "cssesc",
922
- "@opentelemetry/instrumentation",
923
- "domelementtype",
924
- "hosted-git-info",
925
- "@eslint/object-schema",
926
- "etag",
927
- "@eslint/config-helpers",
928
- "package-json-from-dist",
929
- "@humanfs/core",
930
- "htmlparser2",
931
- "jest-message-util",
932
- "for-each",
933
- "pkg-dir",
934
- "unpipe",
935
- "buffer-from",
936
- "es-abstract",
937
- "is-unicode-supported",
938
- "@types/yargs",
939
- "is-callable",
940
- "fast-xml-parser",
941
- "istanbul-lib-instrument",
942
- "escape-html",
943
- "is-regex",
944
- "dom-accessibility-api",
945
- "css-tree",
946
- "error-ex",
947
- "ee-first",
948
- "@types/unist",
949
- "log-symbols",
950
- "path-is-absolute",
951
- "end-of-stream",
952
- "@vitest/utils",
953
- "object.assign",
954
- "object-keys",
955
- "tinyexec",
956
- "scheduler",
957
- "p-try",
958
- "process-nextick-args",
959
- "vary",
960
- "@babel/traverse",
961
- "@pkgjs/parseargs",
962
- "@types/babel__generator",
963
- "kleur",
964
- "zod",
965
- "merge-stream",
966
- "available-typed-arrays",
967
- "mute-stream",
968
- "is-typed-array",
969
- "safe-regex-test",
970
- "tsconfig-paths",
971
- "minizlib",
972
- "tar-stream",
973
- "@floating-ui/core",
974
- "jose",
975
- "deepmerge",
976
- "get-tsconfig",
977
- "set-function-length",
978
- "@vitest/spy",
979
- "css-select",
980
- "@types/babel__core",
981
- "forwarded",
982
- "react",
983
- "@typescript-eslint/parser",
984
- "ajv-keywords",
985
- "define-properties",
986
- "is-generator-function",
987
- "regexp.prototype.flags",
988
- "acorn-walk",
989
- "pump",
990
- "data-uri-to-buffer",
991
- "object-hash",
992
- "jsdom",
993
- "nopt",
994
- "@babel/plugin-syntax-jsx",
995
- "@floating-ui/dom",
996
- "tiny-invariant",
997
- "strip-indent",
998
- "d3-array",
999
- "chai",
1000
- "@babel/code-frame",
1001
- "@typescript-eslint/eslint-plugin",
1002
- "proxy-addr",
1003
- "parseurl",
1004
- "@floating-ui/utils",
1005
- "ora",
1006
- "html-encoding-sniffer",
1007
- "pnpm",
1008
- "whatwg-encoding",
1009
- "events",
1010
- "@typescript-eslint/type-utils",
1011
- "env-paths",
1012
- "internal-slot",
1013
- "string.prototype.trimend",
1014
- "extend",
1015
- "resolve-pkg-maps",
1016
- "istanbul-lib-coverage",
1017
- "react-dom",
1018
- "is-number-object",
1019
- "@radix-ui/primitive",
1020
- "is-plain-object",
1021
- "string.prototype.trimstart",
1022
- "@babel/plugin-syntax-typescript",
1023
- "jest-diff",
1024
- "define-lazy-prop",
1025
- "globalthis",
1026
- "which-boxed-primitive",
1027
- "@vitest/expect",
1028
- "sax",
1029
- "@floating-ui/react-dom",
1030
- "@vitest/pretty-format",
1031
- "internmap",
1032
- "@radix-ui/react-compose-refs",
1033
- "is-symbol",
1034
- "@eslint-community/eslint-utils",
1035
- "bl",
1036
- "serve-static",
1037
- "get-symbol-description",
1038
- "is-shared-array-buffer",
1039
- "functions-have-names",
1040
- "array-buffer-byte-length",
1041
- "socks-proxy-agent"
1042
- ];
801
+ // ../kit/src/config.ts
802
+ var init_config = __esm(() => {
803
+ init_args();
804
+ });
1043
805
 
1044
- // src/nearmiss.ts
1045
- var SEPARATORS = /[-_.]/g;
1046
- var MIN_LENGTH = 5;
1047
- function baseName(name) {
1048
- return name.slice(name.indexOf("/") + 1);
1049
- }
1050
- function scopeOf(name) {
1051
- return name.startsWith("@") ? name.slice(0, name.indexOf("/")) : "";
806
+ // ../kit/src/limit.ts
807
+ function limitOptions(fallback) {
808
+ return {
809
+ limit: { type: "string", description: `show at most this many rows, the rest counted (${fallback})` },
810
+ full: { type: "boolean", description: "show every row" }
811
+ };
1052
812
  }
1053
- function squash(name) {
1054
- return name.toLowerCase().replace(SEPARATORS, "");
813
+ function limitOf(values, fallback) {
814
+ if (values.full === true && values.limit !== undefined)
815
+ badUsage("--limit and --full exclude each other");
816
+ if (values.full === true || values.json === true && values.limit === undefined)
817
+ return Number.POSITIVE_INFINITY;
818
+ return wholeNumber(values.limit, "limit", fallback);
1055
819
  }
1056
- function resemblance(name, popular) {
1057
- if (scopeOf(name) !== scopeOf(popular) && baseName(name) === baseName(popular) && baseName(name).length >= MIN_LENGTH)
1058
- return `${popular} under another scope`;
1059
- if (squash(name) === squash(popular))
1060
- return `${popular} spelled with other separators or case`;
1061
- const edits = distance(name, popular);
1062
- const allowed = Math.min(name.length, popular.length) >= MIN_LENGTH * 2 ? 2 : 1;
1063
- return Math.min(name.length, popular.length) >= MIN_LENGTH && edits <= allowed ? `${popular}, ${edits} ${edits === 1 ? "edit" : "edits"} away` : undefined;
820
+ function moreFooter(more) {
821
+ return `${more} more, rerun with --full`;
1064
822
  }
1065
- function nearMisses(name, popular = popular_default) {
1066
- if (popular.includes(name))
1067
- return [];
1068
- const found = [];
1069
- for (const other of popular) {
1070
- const text = resemblance(name, other);
1071
- if (text !== undefined)
1072
- found.push({ text, edits: distance(name, other) });
1073
- }
1074
- return found.sort((a, b) => a.edits - b.edits).slice(0, 3).map((match) => match.text);
823
+ function capped(rows, limit) {
824
+ const more = rows.length - limit;
825
+ return more > 0 ? { shown: rows.slice(0, limit), footer: moreFooter(more) } : { shown: [...rows], footer: undefined };
1075
826
  }
827
+ var init_limit = __esm(() => {
828
+ init_args();
829
+ });
1076
830
 
1077
- // src/analyze.ts
1078
- var DEFAULT_MIN_AGE_DAYS = 14;
1079
- var DAY = 86400000;
1080
- var INSTALL_SCRIPTS = ["preinstall", "install", "postinstall"];
1081
- var GIT_PREFIX = /^git\+/;
1082
- var VERSION_SEPARATOR = /(?<=.)@/;
1083
- function parseSpec(text) {
1084
- const at = text.search(VERSION_SEPARATOR);
1085
- return at === -1 ? { name: text } : { name: text.slice(0, at), request: text.slice(at + 1) };
1086
- }
1087
- function isStable(version) {
1088
- return !version.includes("-");
1089
- }
1090
- function resolve(packument, request) {
1091
- const tags = packument["dist-tags"] ?? {};
1092
- const versions = Object.keys(packument.versions ?? {});
1093
- const wanted = request === undefined || request === "" ? "latest" : request;
1094
- if (tags[wanted] !== undefined)
1095
- return tags[wanted];
1096
- if (versions.includes(wanted))
1097
- return wanted;
1098
- return versions.filter((version) => Bun.semver.satisfies(version, wanted)).sort(Bun.semver.order).at(-1);
1099
- }
1100
- function licenseOf(license) {
1101
- return typeof license === "string" ? license : license?.type;
1102
- }
1103
- function repositoryOf(packument) {
1104
- const repository = typeof packument.repository === "string" ? packument.repository : packument.repository?.url;
1105
- return repository?.replace(GIT_PREFIX, "") ?? packument.homepage;
1106
- }
1107
- function ageDays(published, now) {
1108
- const at = Date.parse(published ?? "");
1109
- return Number.isNaN(at) ? undefined : (now - at) / DAY;
1110
- }
1111
- function installScriptsOf(version) {
1112
- return Object.fromEntries(INSTALL_SCRIPTS.flatMap((name) => version?.scripts?.[name] === undefined ? [] : [[name, version.scripts[name]]]));
1113
- }
1114
- function safeRelease(packument, now, minAgeDays) {
1115
- const old = Object.keys(packument.versions ?? {}).filter((version) => isStable(version) && (ageDays(packument.time?.[version], now) ?? 0) >= minAgeDays && packument.time?.[version] !== undefined);
1116
- const version = old.sort(Bun.semver.order).at(-1);
1117
- return version === undefined ? undefined : { version, published: packument.time?.[version] };
1118
- }
1119
- function analyze(input) {
1120
- const { spec, packument, registry, now = Date.now(), minAgeDays = DEFAULT_MIN_AGE_DAYS } = input;
1121
- const report = { name: spec.name, registry, exists: packument !== undefined, requested: spec.request, installScripts: {}, nearMisses: nearMisses(spec.name), warnings: [], blocked: false, downloads: input.downloads };
1122
- if (report.nearMisses.length > 0)
1123
- report.warnings.push(`name looks like ${report.nearMisses.join("; ")}, check it is the package meant`);
1124
- if (packument === undefined) {
1125
- report.blocked = true;
1126
- report.warnings.unshift(`${spec.name} is not on ${registry}, the name may be guessed`);
1127
- return report;
1128
- }
1129
- const latest = packument["dist-tags"]?.latest;
1130
- const version = resolve(packument, spec.request);
1131
- const entry = version === undefined ? undefined : packument.versions?.[version];
1132
- report.description = packument.description;
1133
- report.license = licenseOf(entry?.license) ?? licenseOf(packument.license);
1134
- report.repository = repositoryOf(packument);
1135
- report.latest = latest === undefined ? undefined : { version: latest, published: packument.time?.[latest] };
1136
- report.safe = safeRelease(packument, now, minAgeDays);
1137
- report.version = version;
1138
- report.published = version === undefined ? undefined : packument.time?.[version];
1139
- report.installScripts = installScriptsOf(entry);
1140
- report.deprecated = entry?.deprecated;
1141
- if (version === undefined) {
1142
- report.blocked = true;
1143
- report.warnings.push(`no version of ${spec.name} matches ${spec.request}`);
1144
- return report;
1145
- }
1146
- const age = ageDays(report.published, now);
1147
- if (age === undefined) {
1148
- report.warnings.push(`${registry} gives no publish date for ${version}, its age cannot be checked`);
1149
- } else if (age < minAgeDays) {
1150
- report.blocked = true;
1151
- report.warnings.push(`${version} was published ${age < 1 ? "less than a day" : `${Math.floor(age)} day${Math.floor(age) === 1 ? "" : "s"}`} ago, under ${minAgeDays} days${report.safe === undefined ? ", and no older stable version exists" : `, use ${spec.name}@${report.safe.version}`}`);
831
+ // ../kit/src/process.ts
832
+ import { constants } from "os";
833
+ import process5 from "process";
834
+ async function collect(stream, name, chunks) {
835
+ for await (const data of stream)
836
+ chunks.push({ stream: name, data });
837
+ }
838
+ function exitCodeOf(code, signal) {
839
+ if (code !== null)
840
+ return code;
841
+ if (typeof signal === "number")
842
+ return 128 + signal;
843
+ return signal === null ? 129 : 128 + constants.signals[signal];
844
+ }
845
+ function holdSignals(cleanup) {
846
+ let received;
847
+ let child;
848
+ const held = {
849
+ get signal() {
850
+ return received;
851
+ },
852
+ forward: (to) => {
853
+ child = to;
854
+ },
855
+ release: () => {
856
+ for (const signal of SIGNALS)
857
+ process5.off(signal, onSignal);
858
+ }
859
+ };
860
+ function onSignal(signal) {
861
+ received = signal;
862
+ if (child !== undefined) {
863
+ child.kill(signal);
864
+ return;
865
+ }
866
+ if (cleanup === undefined)
867
+ return;
868
+ held.release();
869
+ cleanup(signal);
870
+ process5.kill(process5.pid, signal);
1152
871
  }
1153
- const scripts = Object.keys(report.installScripts);
1154
- if (scripts.length > 0)
1155
- report.warnings.push(`${version} runs ${scripts.join(", ")} at install`);
1156
- if (report.deprecated !== undefined)
1157
- report.warnings.push(`${version} is deprecated: ${report.deprecated}`);
1158
- return report;
1159
- }
872
+ for (const signal of SIGNALS)
873
+ process5.on(signal, onSignal);
874
+ return held;
875
+ }
876
+ async function runCommand(argv, { cwd, env, stdin = "ignore" } = {}) {
877
+ const chunks = [];
878
+ const proc = Bun.spawn(argv, { ...cwd === undefined ? {} : { cwd }, ...env === undefined ? {} : { env }, stdin, stdout: "pipe", stderr: "pipe" });
879
+ await Promise.all([collect(proc.stdout, "stdout", chunks), collect(proc.stderr, "stderr", chunks)]);
880
+ await proc.exited;
881
+ const output = Buffer.concat(chunks.map(({ data }) => data));
882
+ return { code: exitCodeOf(proc.exitCode, proc.signalCode), chunks, output, text: output.toString() };
883
+ }
884
+ var SIGNALS;
885
+ var init_process = __esm(() => {
886
+ SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
887
+ });
1160
888
 
1161
- // src/config.ts
1162
- import { homedir } from "os";
1163
- import { dirname, join } from "path";
1164
- import process6 from "process";
889
+ // ../kit/src/index.ts
890
+ var init_src = __esm(() => {
891
+ init_args();
892
+ init_chart();
893
+ init_cli();
894
+ init_config();
895
+ init_format();
896
+ init_limit();
897
+ init_process();
898
+ init_style();
899
+ init_text();
900
+ });
1165
901
 
1166
902
  // src/registry.ts
1167
- var PUBLIC_REGISTRY = "https://registry.npmjs.org";
1168
- var DOWNLOADS_API = "https://api.npmjs.org/downloads/point/last-week";
1169
- var TRAILING_SLASHES = /\/+$/;
1170
903
  function isPublic(registry) {
1171
904
  return registry.url.replace(TRAILING_SLASHES, "") === PUBLIC_REGISTRY;
1172
905
  }
@@ -1192,14 +925,16 @@ async function fetchDownloads(name, fetcher = fetch) {
1192
925
  const body = await response.json();
1193
926
  return body.downloads;
1194
927
  }
928
+ var PUBLIC_REGISTRY = "https://registry.npmjs.org", DOWNLOADS_API = "https://api.npmjs.org/downloads/point/last-week", TRAILING_SLASHES;
929
+ var init_registry = __esm(() => {
930
+ init_src();
931
+ TRAILING_SLASHES = /\/+$/;
932
+ });
1195
933
 
1196
934
  // src/config.ts
1197
- var ENV_REFERENCE = /\$\{(\w+)\}|\$(\w+)/g;
1198
- var COMMENT = /^\s*[#;]/;
1199
- var SCOPE_REGISTRY = /^(@[^:]+):registry$/;
1200
- var AUTH_TOKEN = /^(\/\/.+?):_authToken$/;
1201
- var PROTOCOL = /^\w+:/;
1202
- var QUOTES = /^(["'])(.*)\1$/;
935
+ import { homedir } from "os";
936
+ import { dirname, join } from "path";
937
+ import process7 from "process";
1203
938
  function expand(value, env) {
1204
939
  let missing = false;
1205
940
  const expanded = value.replace(ENV_REFERENCE, (_, braced, bare) => {
@@ -1275,7 +1010,7 @@ async function readIfThere(path) {
1275
1010
  const file = Bun.file(path);
1276
1011
  return await file.exists() ? file.text() : undefined;
1277
1012
  }
1278
- async function loadConfigs(cwd = process6.cwd(), env = process6.env, home = homedir()) {
1013
+ async function loadConfigs(cwd = process7.cwd(), env = process7.env, home = homedir()) {
1279
1014
  const directories = [];
1280
1015
  for (let dir = cwd;!directories.includes(dir); dir = dirname(dir))
1281
1016
  directories.push(dir);
@@ -1292,22 +1027,775 @@ async function loadConfigs(cwd = process6.cwd(), env = process6.env, home = home
1292
1027
  }
1293
1028
  return configs;
1294
1029
  }
1030
+ function isSeverity(value) {
1031
+ return SEVERITIES.includes(value);
1032
+ }
1033
+ function parseSettings(text) {
1034
+ const raw = Bun.JSONC.parse(text);
1035
+ const settings = {};
1036
+ if (Array.isArray(raw?.licenses) && raw.licenses.every((each) => typeof each === "string"))
1037
+ settings.licenses = raw.licenses;
1038
+ if (isSeverity(raw?.blockSeverity))
1039
+ settings.blockSeverity = raw.blockSeverity;
1040
+ return settings;
1041
+ }
1042
+ async function loadSettings(cwd = process7.cwd(), home = homedir()) {
1043
+ const files = [];
1044
+ for (let dir = cwd;!files.includes(join(dir, SETTINGS_FILE)); dir = dirname(dir))
1045
+ files.push(join(dir, SETTINGS_FILE));
1046
+ files.push(join(home, ".config", "pkg", "config.json"));
1047
+ const settings = {};
1048
+ for (const file of files) {
1049
+ const text = await readIfThere(file);
1050
+ if (text === undefined)
1051
+ continue;
1052
+ const found = parseSettings(text);
1053
+ settings.licenses ??= found.licenses;
1054
+ settings.blockSeverity ??= found.blockSeverity;
1055
+ }
1056
+ return settings;
1057
+ }
1058
+ var ENV_REFERENCE, COMMENT, SCOPE_REGISTRY, AUTH_TOKEN, PROTOCOL, QUOTES, SEVERITIES, SETTINGS_FILE = ".pkgrc.json";
1059
+ var init_config2 = __esm(() => {
1060
+ init_registry();
1061
+ ENV_REFERENCE = /\$\{(\w+)\}|\$(\w+)/g;
1062
+ COMMENT = /^\s*[#;]/;
1063
+ SCOPE_REGISTRY = /^(@[^:]+):registry$/;
1064
+ AUTH_TOKEN = /^(\/\/.+?):_authToken$/;
1065
+ PROTOCOL = /^\w+:/;
1066
+ QUOTES = /^(["'])(.*)\1$/;
1067
+ SEVERITIES = ["low", "moderate", "high", "critical"];
1068
+ });
1295
1069
 
1296
- // src/commands/check.ts
1297
- var usage = `pkg <name>[@version]...
1070
+ // src/advisories.ts
1071
+ function severityRank(severity) {
1072
+ return SEVERITIES.indexOf(severity);
1073
+ }
1074
+ function fixedVersion(vulnerable, version) {
1075
+ const range = vulnerable.split("||").map((each) => each.trim()).find((each) => Bun.semver.satisfies(version, each));
1076
+ return range === undefined ? undefined : UPPER_BOUND.exec(range)?.[1];
1077
+ }
1078
+ async function fetchAdvisories(versions, registry, fetcher = fetch) {
1079
+ const url = `${registry.url.replace(TRAILING_SLASHES2, "")}${BULK_PATH}`;
1080
+ let response;
1081
+ try {
1082
+ response = await fetcher(url, {
1083
+ method: "POST",
1084
+ headers: { accept: "application/json", "content-type": "application/json", ...registry.token === undefined ? {} : { authorization: `Bearer ${registry.token}` } },
1085
+ body: JSON.stringify(versions)
1086
+ });
1087
+ } catch {
1088
+ return {};
1089
+ }
1090
+ if (!response.ok)
1091
+ return {};
1092
+ const body = await response.json();
1093
+ const found = {};
1094
+ for (const [name, raws] of Object.entries(body)) {
1095
+ found[name] = raws.filter((raw) => SEVERITIES.includes(raw.severity)).map((raw) => ({
1096
+ id: raw.id,
1097
+ ghsa: GHSA.exec(raw.url)?.[0],
1098
+ url: raw.url,
1099
+ title: raw.title,
1100
+ severity: raw.severity,
1101
+ vulnerable: raw.vulnerable_versions
1102
+ }));
1103
+ }
1104
+ return found;
1105
+ }
1106
+ function advisoriesFor(advisories, version) {
1107
+ return (advisories ?? []).filter((each) => Bun.semver.satisfies(version, each.vulnerable)).map((each) => ({ ...each, fixed: fixedVersion(each.vulnerable, version) }));
1108
+ }
1109
+ function filterAdvisories(advisories, level, ignore = []) {
1110
+ return advisories.filter((each) => severityRank(each.severity) >= severityRank(level) && !ignore.includes(each.ghsa ?? "") && !ignore.includes(String(each.id)));
1111
+ }
1112
+ var BULK_PATH = "/-/npm/v1/security/advisories/bulk", TRAILING_SLASHES2, GHSA, UPPER_BOUND;
1113
+ var init_advisories = __esm(() => {
1114
+ init_config2();
1115
+ TRAILING_SLASHES2 = /\/+$/;
1116
+ GHSA = /GHSA-[\w-]+$/;
1117
+ UPPER_BOUND = /(?:^|\s)<([\w.+-]+)/;
1118
+ });
1298
1119
 
1299
- 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.
1300
- Exits 1 when a package is missing or the version asked for is under the minimum age.`;
1301
- var options = {
1302
- json: jsonOption(),
1303
- "min-age": { type: "string", description: `days a version must be old (${DEFAULT_MIN_AGE_DAYS})` }
1304
- };
1120
+ // src/licenses.ts
1121
+ function isLicenseAllowed(expression, allowed) {
1122
+ const known = new Set(allowed.map((each) => each.toLowerCase()));
1123
+ return expression.replace(PARENS, " ").trim().split(OR_SPLIT).some((alternative) => alternative.split(AND_SPLIT).every((term) => known.has(term.replace(WITH_EXCEPTION, "").trim().toLowerCase())));
1124
+ }
1125
+ var OR_SPLIT, AND_SPLIT, WITH_EXCEPTION, PARENS;
1126
+ var init_licenses = __esm(() => {
1127
+ OR_SPLIT = /\s+OR\s+/i;
1128
+ AND_SPLIT = /\s+AND\s+/i;
1129
+ WITH_EXCEPTION = /\s+WITH\s+\S+$/i;
1130
+ PARENS = /[()]/g;
1131
+ });
1132
+
1133
+ // src/popular.json
1134
+ var popular_default;
1135
+ var init_popular = __esm(() => {
1136
+ popular_default = [
1137
+ "semver",
1138
+ "minimatch",
1139
+ "debug",
1140
+ "ansi-styles",
1141
+ "brace-expansion",
1142
+ "strip-ansi",
1143
+ "ansi-regex",
1144
+ "ms",
1145
+ "supports-color",
1146
+ "chalk",
1147
+ "commander",
1148
+ "lru-cache",
1149
+ "string-width",
1150
+ "wrap-ansi",
1151
+ "tslib",
1152
+ "picomatch",
1153
+ "emoji-regex",
1154
+ "glob",
1155
+ "type-fest",
1156
+ "color-name",
1157
+ "eslint-visitor-keys",
1158
+ "color-convert",
1159
+ "ajv",
1160
+ "minipass",
1161
+ "source-map",
1162
+ "balanced-match",
1163
+ "readable-stream",
1164
+ "which",
1165
+ "glob-parent",
1166
+ "escape-string-regexp",
1167
+ "has-flag",
1168
+ "find-up",
1169
+ "locate-path",
1170
+ "json-schema-traverse",
1171
+ "p-limit",
1172
+ "yallist",
1173
+ "safe-buffer",
1174
+ "uuid",
1175
+ "p-locate",
1176
+ "undici-types",
1177
+ "ignore",
1178
+ "iconv-lite",
1179
+ "signal-exit",
1180
+ "esbuild",
1181
+ "is-fullwidth-code-point",
1182
+ "js-yaml",
1183
+ "entities",
1184
+ "globals",
1185
+ "postcss",
1186
+ "isexe",
1187
+ "isarray",
1188
+ "path-key",
1189
+ "string_decoder",
1190
+ "argparse",
1191
+ "ws",
1192
+ "mime-db",
1193
+ "resolve",
1194
+ "agent-base",
1195
+ "@esbuild/linux-x64",
1196
+ "yargs-parser",
1197
+ "mime-types",
1198
+ "acorn",
1199
+ "estraverse",
1200
+ "cross-spawn",
1201
+ "react-is",
1202
+ "picocolors",
1203
+ "fs-extra",
1204
+ "hasown",
1205
+ "nanoid",
1206
+ "yargs",
1207
+ "resolve-from",
1208
+ "shebang-command",
1209
+ "pretty-format",
1210
+ "json5",
1211
+ "https-proxy-agent",
1212
+ "path-to-regexp",
1213
+ "path-exists",
1214
+ "punycode",
1215
+ "js-tokens",
1216
+ "cliui",
1217
+ "shebang-regex",
1218
+ "@babel/types",
1219
+ "chokidar",
1220
+ "strip-json-comments",
1221
+ "inherits",
1222
+ "webidl-conversions",
1223
+ "get-stream",
1224
+ "eslint-scope",
1225
+ "cookie",
1226
+ "@babel/parser",
1227
+ "qs",
1228
+ "is-number",
1229
+ "whatwg-url",
1230
+ "@types/estree",
1231
+ "tr46",
1232
+ "convert-source-map",
1233
+ "is-glob",
1234
+ "braces",
1235
+ "fast-deep-equal",
1236
+ "form-data",
1237
+ "lodash",
1238
+ "@babel/helper-validator-identifier",
1239
+ "electron-to-chromium",
1240
+ "fill-range",
1241
+ "function-bind",
1242
+ "readdirp",
1243
+ "escalade",
1244
+ "graceful-fs",
1245
+ "negotiator",
1246
+ "is-stream",
1247
+ "camelcase",
1248
+ "@babel/runtime",
1249
+ "yocto-queue",
1250
+ "to-regex-range",
1251
+ "node-fetch",
1252
+ "micromatch",
1253
+ "node-releases",
1254
+ "get-intrinsic",
1255
+ "universalify",
1256
+ "path-scurry",
1257
+ "jsesc",
1258
+ "browserslist",
1259
+ "es-errors",
1260
+ "statuses",
1261
+ "@radix-ui/react-primitive",
1262
+ "magic-string",
1263
+ "rimraf",
1264
+ "is-extglob",
1265
+ "@jridgewell/trace-mapping",
1266
+ "@jridgewell/resolve-uri",
1267
+ "http-errors",
1268
+ "onetime",
1269
+ "has-symbols",
1270
+ "es-define-property",
1271
+ "gopd",
1272
+ "util-deprecate",
1273
+ "object-assign",
1274
+ "jiti",
1275
+ "yaml",
1276
+ "dotenv",
1277
+ "@babel/generator",
1278
+ "@babel/template",
1279
+ "imurmurhash",
1280
+ "postcss-selector-parser",
1281
+ "fast-glob",
1282
+ "update-browserslist-db",
1283
+ "@types/node",
1284
+ "@babel/compat-data",
1285
+ "eventemitter3",
1286
+ "callsites",
1287
+ "http-proxy-agent",
1288
+ "detect-libc",
1289
+ "espree",
1290
+ "execa",
1291
+ "@babel/core",
1292
+ "@babel/helpers",
1293
+ "concat-map",
1294
+ "source-map-js",
1295
+ "tinyglobby",
1296
+ "call-bind-apply-helpers",
1297
+ "flat-cache",
1298
+ "fdir",
1299
+ "pify",
1300
+ "@jest/types",
1301
+ "normalize-path",
1302
+ "is-core-module",
1303
+ "eslint",
1304
+ "minimist",
1305
+ "estree-walker",
1306
+ "file-entry-cache",
1307
+ "object-inspect",
1308
+ "buffer",
1309
+ "uri-js",
1310
+ "import-fresh",
1311
+ "@babel/helper-module-transforms",
1312
+ "optionator",
1313
+ "flatted",
1314
+ "math-intrinsics",
1315
+ "safer-buffer",
1316
+ "y18n",
1317
+ "@babel/helper-module-imports",
1318
+ "mkdirp",
1319
+ "dunder-proto",
1320
+ "path-parse",
1321
+ "fastq",
1322
+ "levn",
1323
+ "@babel/helper-compilation-targets",
1324
+ "@babel/helper-string-parser",
1325
+ "keyv",
1326
+ "get-proto",
1327
+ "csstype",
1328
+ "npm-run-path",
1329
+ "fast-json-stable-stringify",
1330
+ "reusify",
1331
+ "@babel/helper-plugin-utils",
1332
+ "kind-of",
1333
+ "mime",
1334
+ "caniuse-lite",
1335
+ "lines-and-columns",
1336
+ "fast-levenshtein",
1337
+ "supports-preserve-symlinks-flag",
1338
+ "make-dir",
1339
+ "slash",
1340
+ "prelude-ls",
1341
+ "typescript",
1342
+ "strip-bom",
1343
+ "parent-module",
1344
+ "esutils",
1345
+ "ci-info",
1346
+ "@smithy/util-utf8",
1347
+ "type-check",
1348
+ "mimic-fn",
1349
+ "@babel/helper-validator-option",
1350
+ "@types/json-schema",
1351
+ "@rolldown/pluginutils",
1352
+ "side-channel-list",
1353
+ "json-buffer",
1354
+ "raw-body",
1355
+ "has-tostringtag",
1356
+ "wrappy",
1357
+ "diff",
1358
+ "jackspeak",
1359
+ "baseline-browser-mapping",
1360
+ "deep-is",
1361
+ "foreground-child",
1362
+ "@eslint/js",
1363
+ "anymatch",
1364
+ "natural-compare",
1365
+ "esquery",
1366
+ "@eslint-community/regexpp",
1367
+ "es-set-tostringtag",
1368
+ "acorn-jsx",
1369
+ "parse5",
1370
+ "finalhandler",
1371
+ "parse-json",
1372
+ "depd",
1373
+ "axios",
1374
+ "run-parallel",
1375
+ "source-map-support",
1376
+ "esrecurse",
1377
+ "call-bound",
1378
+ "content-disposition",
1379
+ "human-signals",
1380
+ "ts-api-utils",
1381
+ "ansi-escapes",
1382
+ "jest-util",
1383
+ "send",
1384
+ "@opentelemetry/core",
1385
+ "type-is",
1386
+ "encodeurl",
1387
+ "once",
1388
+ "cosmiconfig",
1389
+ "lodash.merge",
1390
+ "json-stable-stringify-without-jsonify",
1391
+ "open",
1392
+ "prettier",
1393
+ "@eslint/eslintrc",
1394
+ "is-arrayish",
1395
+ "@jridgewell/sourcemap-codec",
1396
+ "gensync",
1397
+ "word-wrap",
1398
+ "express",
1399
+ "arg",
1400
+ "jsonfile",
1401
+ "schema-utils",
1402
+ "@smithy/is-array-buffer",
1403
+ "@typescript-eslint/types",
1404
+ "chownr",
1405
+ "delayed-stream",
1406
+ "@smithy/util-buffer-from",
1407
+ "asynckit",
1408
+ "tapable",
1409
+ "enhanced-resolve",
1410
+ "aria-query",
1411
+ "indent-string",
1412
+ "bytes",
1413
+ "binary-extensions",
1414
+ "ini",
1415
+ "@radix-ui/react-context",
1416
+ "doctrine",
1417
+ "queue-microtask",
1418
+ "accepts",
1419
+ "merge2",
1420
+ "get-caller-file",
1421
+ "@humanwhocodes/retry",
1422
+ "@jridgewell/gen-mapping",
1423
+ "@typescript-eslint/typescript-estree",
1424
+ "jest-worker",
1425
+ "proxy-from-env",
1426
+ "clsx",
1427
+ "side-channel-map",
1428
+ "@typescript-eslint/visitor-keys",
1429
+ "fresh",
1430
+ "restore-cursor",
1431
+ "on-finished",
1432
+ "is-plain-obj",
1433
+ "ipaddr.js",
1434
+ "pathe",
1435
+ "@jest/schemas",
1436
+ "base64-js",
1437
+ "@smithy/types",
1438
+ "require-directory",
1439
+ "tough-cookie",
1440
+ "is-binary-path",
1441
+ "body-parser",
1442
+ "postcss-value-parser",
1443
+ "media-typer",
1444
+ "setprototypeof",
1445
+ "side-channel-weakmap",
1446
+ "@typescript-eslint/tsconfig-utils",
1447
+ "@isaacs/cliui",
1448
+ "@rollup/rollup-linux-x64-gnu",
1449
+ "is-wsl",
1450
+ "retry",
1451
+ "@aws-sdk/types",
1452
+ "@types/react-dom",
1453
+ "combined-stream",
1454
+ "es-object-atoms",
1455
+ "@eslint/core",
1456
+ "whatwg-mimetype",
1457
+ "domutils",
1458
+ "@rollup/rollup-linux-x64-musl",
1459
+ "core-util-is",
1460
+ "@typescript-eslint/scope-manager",
1461
+ "esprima",
1462
+ "loose-envify",
1463
+ "cookie-signature",
1464
+ "follow-redirects",
1465
+ "cli-cursor",
1466
+ "strip-final-newline",
1467
+ "@typescript-eslint/project-service",
1468
+ "eastasianwidth",
1469
+ "json-parse-even-better-errors",
1470
+ "sprintf-js",
1471
+ "path-type",
1472
+ "content-type",
1473
+ "es-module-lexer",
1474
+ "@nodelib/fs.scandir",
1475
+ "write-file-atomic",
1476
+ "@eslint/plugin-kit",
1477
+ "ieee754",
1478
+ "prop-types",
1479
+ "require-from-string",
1480
+ "dom-serializer",
1481
+ "call-bind",
1482
+ "@eslint/config-array",
1483
+ "has-property-descriptors",
1484
+ "@nodelib/fs.stat",
1485
+ "merge-descriptors",
1486
+ "slice-ansi",
1487
+ "rxjs",
1488
+ "p-map",
1489
+ "toidentifier",
1490
+ "globby",
1491
+ "domhandler",
1492
+ "async",
1493
+ "@babel/helper-globals",
1494
+ "pirates",
1495
+ "@opentelemetry/semantic-conventions",
1496
+ "@typescript-eslint/utils",
1497
+ "date-fns",
1498
+ "is-docker",
1499
+ "tar",
1500
+ "which-typed-array",
1501
+ "ajv-formats",
1502
+ "@opentelemetry/api-logs",
1503
+ "@opentelemetry/resources",
1504
+ "side-channel",
1505
+ "cjs-module-lexer",
1506
+ "range-parser",
1507
+ "@humanfs/node",
1508
+ "define-data-property",
1509
+ "node-addon-api",
1510
+ "pako",
1511
+ "lilconfig",
1512
+ "fast-uri",
1513
+ "ip-address",
1514
+ "fs.realpath",
1515
+ "@img/sharp-libvips-linuxmusl-x64",
1516
+ "cssesc",
1517
+ "@opentelemetry/instrumentation",
1518
+ "domelementtype",
1519
+ "hosted-git-info",
1520
+ "@eslint/object-schema",
1521
+ "etag",
1522
+ "@eslint/config-helpers",
1523
+ "package-json-from-dist",
1524
+ "@humanfs/core",
1525
+ "htmlparser2",
1526
+ "jest-message-util",
1527
+ "for-each",
1528
+ "pkg-dir",
1529
+ "unpipe",
1530
+ "buffer-from",
1531
+ "es-abstract",
1532
+ "is-unicode-supported",
1533
+ "@types/yargs",
1534
+ "is-callable",
1535
+ "fast-xml-parser",
1536
+ "istanbul-lib-instrument",
1537
+ "escape-html",
1538
+ "is-regex",
1539
+ "dom-accessibility-api",
1540
+ "css-tree",
1541
+ "error-ex",
1542
+ "ee-first",
1543
+ "@types/unist",
1544
+ "log-symbols",
1545
+ "path-is-absolute",
1546
+ "end-of-stream",
1547
+ "@vitest/utils",
1548
+ "object.assign",
1549
+ "object-keys",
1550
+ "tinyexec",
1551
+ "scheduler",
1552
+ "p-try",
1553
+ "process-nextick-args",
1554
+ "vary",
1555
+ "@babel/traverse",
1556
+ "@pkgjs/parseargs",
1557
+ "@types/babel__generator",
1558
+ "kleur",
1559
+ "zod",
1560
+ "merge-stream",
1561
+ "available-typed-arrays",
1562
+ "mute-stream",
1563
+ "is-typed-array",
1564
+ "safe-regex-test",
1565
+ "tsconfig-paths",
1566
+ "minizlib",
1567
+ "tar-stream",
1568
+ "@floating-ui/core",
1569
+ "jose",
1570
+ "deepmerge",
1571
+ "get-tsconfig",
1572
+ "set-function-length",
1573
+ "@vitest/spy",
1574
+ "css-select",
1575
+ "@types/babel__core",
1576
+ "forwarded",
1577
+ "react",
1578
+ "@typescript-eslint/parser",
1579
+ "ajv-keywords",
1580
+ "define-properties",
1581
+ "is-generator-function",
1582
+ "regexp.prototype.flags",
1583
+ "acorn-walk",
1584
+ "pump",
1585
+ "data-uri-to-buffer",
1586
+ "object-hash",
1587
+ "jsdom",
1588
+ "nopt",
1589
+ "@babel/plugin-syntax-jsx",
1590
+ "@floating-ui/dom",
1591
+ "tiny-invariant",
1592
+ "strip-indent",
1593
+ "d3-array",
1594
+ "chai",
1595
+ "@babel/code-frame",
1596
+ "@typescript-eslint/eslint-plugin",
1597
+ "proxy-addr",
1598
+ "parseurl",
1599
+ "@floating-ui/utils",
1600
+ "ora",
1601
+ "html-encoding-sniffer",
1602
+ "pnpm",
1603
+ "whatwg-encoding",
1604
+ "events",
1605
+ "@typescript-eslint/type-utils",
1606
+ "env-paths",
1607
+ "internal-slot",
1608
+ "string.prototype.trimend",
1609
+ "extend",
1610
+ "resolve-pkg-maps",
1611
+ "istanbul-lib-coverage",
1612
+ "react-dom",
1613
+ "is-number-object",
1614
+ "@radix-ui/primitive",
1615
+ "is-plain-object",
1616
+ "string.prototype.trimstart",
1617
+ "@babel/plugin-syntax-typescript",
1618
+ "jest-diff",
1619
+ "define-lazy-prop",
1620
+ "globalthis",
1621
+ "which-boxed-primitive",
1622
+ "@vitest/expect",
1623
+ "sax",
1624
+ "@floating-ui/react-dom",
1625
+ "@vitest/pretty-format",
1626
+ "internmap",
1627
+ "@radix-ui/react-compose-refs",
1628
+ "is-symbol",
1629
+ "@eslint-community/eslint-utils",
1630
+ "bl",
1631
+ "serve-static",
1632
+ "get-symbol-description",
1633
+ "is-shared-array-buffer",
1634
+ "functions-have-names",
1635
+ "array-buffer-byte-length",
1636
+ "socks-proxy-agent"
1637
+ ];
1638
+ });
1639
+
1640
+ // src/nearmiss.ts
1641
+ function baseName(name) {
1642
+ return name.slice(name.indexOf("/") + 1);
1643
+ }
1644
+ function scopeOf(name) {
1645
+ return name.startsWith("@") ? name.slice(0, name.indexOf("/")) : "";
1646
+ }
1647
+ function squash(name) {
1648
+ return name.toLowerCase().replace(SEPARATORS, "");
1649
+ }
1650
+ function resemblance(name, popular) {
1651
+ if (scopeOf(name) !== scopeOf(popular) && baseName(name) === baseName(popular) && baseName(name).length >= MIN_LENGTH)
1652
+ return `${popular} under another scope`;
1653
+ if (squash(name) === squash(popular))
1654
+ return `${popular} spelled with other separators or case`;
1655
+ const edits = distance(name, popular);
1656
+ const allowed = Math.min(name.length, popular.length) >= MIN_LENGTH * 2 ? 2 : 1;
1657
+ return Math.min(name.length, popular.length) >= MIN_LENGTH && edits <= allowed ? `${popular}, ${edits} ${edits === 1 ? "edit" : "edits"} away` : undefined;
1658
+ }
1659
+ function nearMisses(name, popular = popular_default) {
1660
+ if (popular.includes(name))
1661
+ return [];
1662
+ const found = [];
1663
+ for (const other of popular) {
1664
+ const text = resemblance(name, other);
1665
+ if (text !== undefined)
1666
+ found.push({ text, edits: distance(name, other) });
1667
+ }
1668
+ return found.sort((a, b) => a.edits - b.edits).slice(0, 3).map((match) => match.text);
1669
+ }
1670
+ var SEPARATORS, MIN_LENGTH = 5;
1671
+ var init_nearmiss = __esm(() => {
1672
+ init_src();
1673
+ init_popular();
1674
+ SEPARATORS = /[-_.]/g;
1675
+ });
1676
+
1677
+ // src/analyze.ts
1678
+ function parseSpec(text) {
1679
+ const at = text.search(VERSION_SEPARATOR);
1680
+ return at === -1 ? { name: text } : { name: text.slice(0, at), request: text.slice(at + 1) };
1681
+ }
1682
+ function isStable(version) {
1683
+ return !version.includes("-");
1684
+ }
1685
+ function resolve(packument, request) {
1686
+ const tags = packument["dist-tags"] ?? {};
1687
+ const versions = Object.keys(packument.versions ?? {});
1688
+ const wanted = request === undefined || request === "" ? "latest" : request;
1689
+ if (tags[wanted] !== undefined)
1690
+ return tags[wanted];
1691
+ if (versions.includes(wanted))
1692
+ return wanted;
1693
+ return versions.filter((version) => Bun.semver.satisfies(version, wanted)).sort(Bun.semver.order).at(-1);
1694
+ }
1695
+ function licenseOf(license) {
1696
+ return typeof license === "string" ? license : license?.type;
1697
+ }
1698
+ function repositoryOf(packument) {
1699
+ const repository = typeof packument.repository === "string" ? packument.repository : packument.repository?.url;
1700
+ return repository?.replace(GIT_PREFIX, "") ?? packument.homepage;
1701
+ }
1702
+ function ageDays(published, now) {
1703
+ const at = Date.parse(published ?? "");
1704
+ return Number.isNaN(at) ? undefined : (now - at) / DAY;
1705
+ }
1706
+ function installScriptsOf(version) {
1707
+ return Object.fromEntries(INSTALL_SCRIPTS.flatMap((name) => version?.scripts?.[name] === undefined ? [] : [[name, version.scripts[name]]]));
1708
+ }
1709
+ function safeRelease(packument, now, minAgeDays) {
1710
+ const old = Object.keys(packument.versions ?? {}).filter((version) => isStable(version) && (ageDays(packument.time?.[version], now) ?? 0) >= minAgeDays && packument.time?.[version] !== undefined);
1711
+ const version = old.sort(Bun.semver.order).at(-1);
1712
+ return version === undefined ? undefined : { version, published: packument.time?.[version] };
1713
+ }
1714
+ function analyze(input) {
1715
+ const { spec, packument, registry, now = Date.now(), minAgeDays = DEFAULT_MIN_AGE_DAYS } = input;
1716
+ const report = { name: spec.name, registry, exists: packument !== undefined, requested: spec.request, installScripts: {}, nearMisses: nearMisses(spec.name), advisories: input.advisories ?? [], warnings: [], blocked: false, downloads: input.downloads };
1717
+ if (report.nearMisses.length > 0)
1718
+ report.warnings.push(`name looks like ${report.nearMisses.join("; ")}, check it is the package meant`);
1719
+ if (packument === undefined) {
1720
+ report.blocked = true;
1721
+ report.warnings.unshift(`${spec.name} is not on ${registry}, the name may be guessed`);
1722
+ return report;
1723
+ }
1724
+ const latest = packument["dist-tags"]?.latest;
1725
+ const version = resolve(packument, spec.request);
1726
+ const entry = version === undefined ? undefined : packument.versions?.[version];
1727
+ report.description = packument.description;
1728
+ report.license = licenseOf(entry?.license) ?? licenseOf(packument.license);
1729
+ report.repository = repositoryOf(packument);
1730
+ report.latest = latest === undefined ? undefined : { version: latest, published: packument.time?.[latest] };
1731
+ report.safe = safeRelease(packument, now, minAgeDays);
1732
+ report.version = version;
1733
+ report.published = version === undefined ? undefined : packument.time?.[version];
1734
+ report.installScripts = installScriptsOf(entry);
1735
+ report.deprecated = entry?.deprecated;
1736
+ if (version === undefined) {
1737
+ report.blocked = true;
1738
+ report.warnings.push(`no version of ${spec.name} matches ${spec.request}`);
1739
+ return report;
1740
+ }
1741
+ const age = ageDays(report.published, now);
1742
+ if (age === undefined) {
1743
+ report.warnings.push(`${registry} gives no publish date for ${version}, its age cannot be checked`);
1744
+ } else if (age < minAgeDays) {
1745
+ report.blocked = true;
1746
+ report.warnings.push(`${version} was published ${age < 1 ? "less than a day" : `${Math.floor(age)} day${Math.floor(age) === 1 ? "" : "s"}`} ago, under ${minAgeDays} days${report.safe === undefined ? ", and no older stable version exists" : `, use ${spec.name}@${report.safe.version}`}`);
1747
+ }
1748
+ const scripts = Object.keys(report.installScripts);
1749
+ if (scripts.length > 0)
1750
+ report.warnings.push(`${version} runs ${scripts.join(", ")} at install`);
1751
+ if (report.deprecated !== undefined)
1752
+ report.warnings.push(`${version} is deprecated: ${report.deprecated}`);
1753
+ if (input.licenses !== undefined) {
1754
+ const isMissing = report.license === undefined || report.license === "";
1755
+ if (isMissing) {
1756
+ report.blocked = true;
1757
+ report.warnings.push(`${version} declares no licence, and the allowlist needs one`);
1758
+ } else if (!isLicenseAllowed(report.license ?? "", input.licenses)) {
1759
+ report.blocked = true;
1760
+ report.warnings.push(`licence ${report.license} is not in the allowlist (${input.licenses.join(", ")})`);
1761
+ }
1762
+ }
1763
+ if (input.blockSeverity !== undefined) {
1764
+ const blocking = filterAdvisories(report.advisories, input.blockSeverity);
1765
+ if (blocking.length > 0) {
1766
+ report.blocked = true;
1767
+ report.warnings.push(`${version} has ${blocking.length} advisor${blocking.length === 1 ? "y" : "ies"} at ${input.blockSeverity} or above: ${blocking.map((each) => each.ghsa ?? each.id).join(", ")}`);
1768
+ }
1769
+ }
1770
+ return report;
1771
+ }
1772
+ var DEFAULT_MIN_AGE_DAYS = 14, DAY = 86400000, INSTALL_SCRIPTS, GIT_PREFIX, VERSION_SEPARATOR;
1773
+ var init_analyze = __esm(() => {
1774
+ init_advisories();
1775
+ init_licenses();
1776
+ init_nearmiss();
1777
+ INSTALL_SCRIPTS = ["preinstall", "install", "postinstall"];
1778
+ GIT_PREFIX = /^git\+/;
1779
+ VERSION_SEPARATOR = /(?<=.)@/;
1780
+ });
1781
+
1782
+ // src/commands/check.ts
1783
+ var exports_check = {};
1784
+ __export(exports_check, {
1785
+ check: () => check
1786
+ });
1305
1787
  async function checkPackage(text, context) {
1306
1788
  const spec = parseSpec(text);
1307
1789
  const registry = registryFor(spec.name, context.configs);
1308
1790
  const packument = await fetchPackument(spec.name, registry, context.fetcher);
1309
1791
  const downloads = packument !== undefined && isPublic(registry) ? await fetchDownloads(spec.name, context.fetcher) : undefined;
1310
- return analyze({ spec, packument, downloads, registry: new URL(registry.url).host, now: context.now, minAgeDays: context.minAgeDays });
1792
+ const input = { spec, packument, downloads, registry: new URL(registry.url).host, now: context.now, minAgeDays: context.minAgeDays, licenses: context.settings?.licenses };
1793
+ const report = analyze(input);
1794
+ const { blockSeverity } = context.settings ?? {};
1795
+ if (blockSeverity === undefined || report.version === undefined)
1796
+ return report;
1797
+ const found = await fetchAdvisories({ [spec.name]: [report.version] }, registry, context.fetcher);
1798
+ return analyze({ ...input, blockSeverity, advisories: advisoriesFor(found[spec.name], report.version) });
1311
1799
  }
1312
1800
  function when(release, now) {
1313
1801
  return release?.published === undefined ? "" : `, published ${formatAge(release.published, now)} (${release.published.slice(0, 10)})`;
@@ -1340,7 +1828,7 @@ async function check(args) {
1340
1828
  fail(`a package name is needed
1341
1829
 
1342
1830
  ${usage}`);
1343
- const context = { configs: await loadConfigs(), minAgeDays: wholeNumber(values["min-age"], "min-age", DEFAULT_MIN_AGE_DAYS, 0) };
1831
+ const context = { configs: await loadConfigs(), settings: await loadSettings(), minAgeDays: wholeNumber(values["min-age"], "min-age", DEFAULT_MIN_AGE_DAYS, 0) };
1344
1832
  const reports = await Promise.all(positionals.map(async (text) => checkPackage(text, context)));
1345
1833
  if (values.json === true)
1346
1834
  printJson(reports.length === 1 ? reports[0] : reports);
@@ -1350,6 +1838,549 @@ ${usage}`);
1350
1838
  `));
1351
1839
  return reports.some((report) => report.blocked) ? 1 : 0;
1352
1840
  }
1841
+ var usage = `pkg [check] <name>[@version]...
1842
+
1843
+ 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.
1844
+
1845
+ A \`.pkgrc.json\` (or ~/.config/pkg/config.json) with \`licenses\` (SPDX ids) refuses a licence outside the list or a missing one, and \`blockSeverity\` (low, moderate, high, critical) refuses a version with an advisory at that level or above.
1846
+
1847
+ Exits 0 when every package passes, 1 when one is missing, the version asked for is under the minimum age, its licence is outside the allowlist or an advisory reaches the threshold, 2 on a usage error.`, options;
1848
+ var init_check = __esm(() => {
1849
+ init_src();
1850
+ init_advisories();
1851
+ init_analyze();
1852
+ init_config2();
1853
+ init_registry();
1854
+ options = {
1855
+ json: jsonOption(),
1856
+ "min-age": { type: "string", description: `days a version must be old (${DEFAULT_MIN_AGE_DAYS})` }
1857
+ };
1858
+ });
1859
+
1860
+ // src/lockfile.ts
1861
+ function parseBunLock(text) {
1862
+ const lock = Bun.JSONC.parse(text);
1863
+ const seen = new Map;
1864
+ for (const entry of Object.values(lock?.packages ?? {})) {
1865
+ const resolution = entry[0];
1866
+ if (typeof resolution !== "string")
1867
+ continue;
1868
+ const at = resolution.search(VERSION_SEPARATOR2);
1869
+ const name = resolution.slice(0, at);
1870
+ const version = resolution.slice(at + 1);
1871
+ if (at !== -1 && !NOT_REGISTRY.test(version))
1872
+ seen.set(`${name}@${version}`, { name, version });
1873
+ }
1874
+ return [...seen.values()].sort((a, b) => a.name.localeCompare(b.name) || Bun.semver.order(a.version, b.version));
1875
+ }
1876
+ var NOT_REGISTRY, VERSION_SEPARATOR2;
1877
+ var init_lockfile = __esm(() => {
1878
+ NOT_REGISTRY = /^(?:workspace|link|file|github|git|http|https|npm):|^[\w.-]+\/[\w.-]+$/;
1879
+ VERSION_SEPARATOR2 = /(?<=.)@/;
1880
+ });
1881
+
1882
+ // src/commands/audit.ts
1883
+ var exports_audit = {};
1884
+ __export(exports_audit, {
1885
+ audit: () => audit
1886
+ });
1887
+ import { join as join2, resolve as resolve2 } from "path";
1888
+ import process8 from "process";
1889
+ function hasFinding(audited) {
1890
+ return audited.blocked || audited.warnings.length > 0 || audited.advisories.length > 0;
1891
+ }
1892
+ async function auditPackages(packages, context) {
1893
+ const packuments = new Map;
1894
+ const lookup = async (name, registry) => {
1895
+ const key = `${registry.url}|${name}`;
1896
+ if (!packuments.has(key))
1897
+ packuments.set(key, fetchPackument(name, registry, context.fetcher));
1898
+ return packuments.get(key);
1899
+ };
1900
+ const registries = new Map;
1901
+ for (const { name, version } of packages) {
1902
+ const registry = registryFor(name, context.configs);
1903
+ const group = registries.get(registry.url) ?? { registry, versions: {} };
1904
+ group.versions[name] = [...group.versions[name] ?? [], version];
1905
+ registries.set(registry.url, group);
1906
+ }
1907
+ const advisories = {};
1908
+ for (const { registry, versions } of registries.values())
1909
+ Object.assign(advisories, await fetchAdvisories(versions, registry, context.fetcher));
1910
+ const audited = [];
1911
+ for (let start = 0;start < packages.length; start += BATCH) {
1912
+ audited.push(...await Promise.all(packages.slice(start, start + BATCH).map(async ({ name, version }) => {
1913
+ const registry = registryFor(name, context.configs);
1914
+ const found = filterAdvisories(advisoriesFor(advisories[name], version), context.level, context.ignore);
1915
+ const report = analyze({ spec: { name, request: version }, packument: await lookup(name, registry), registry: new URL(registry.url).host, now: context.now, minAgeDays: context.minAgeDays, licenses: context.settings.licenses });
1916
+ return { name, version, license: report.license, blocked: report.blocked || found.length > 0, warnings: report.warnings, advisories: found };
1917
+ })));
1918
+ }
1919
+ return audited;
1920
+ }
1921
+ function renderAudit(findings, total) {
1922
+ const blocks = findings.map(({ name, version, warnings, advisories }) => [
1923
+ `${name}@${version}`,
1924
+ ...warnings.map((warning) => ` warning: ${warning}`),
1925
+ ...advisories.map((each) => ` ${each.ghsa ?? each.id} ${each.severity}: ${each.title}${each.fixed === undefined ? "" : ` (fixed in ${each.fixed})`}`)
1926
+ ].join(`
1927
+ `));
1928
+ return [...blocks, `${findings.length} of ${total} packages with a finding, ${findings.filter((each) => each.blocked).length} blocking`].join(`
1929
+
1930
+ `);
1931
+ }
1932
+ async function audit(args) {
1933
+ const { values, positionals: [asked] } = parse(args, usage2, options2, { positionals: ["[dir]"] });
1934
+ const level = values["audit-level"] ?? "low";
1935
+ if (!isSeverity(level))
1936
+ fail(`--audit-level takes ${SEVERITIES.join(", ")}, not ${level}`);
1937
+ const dir = resolve2(asked ?? process8.cwd());
1938
+ const lock = Bun.file(join2(dir, "bun.lock"));
1939
+ if (!await lock.exists())
1940
+ fail(`no bun.lock in ${dir}`);
1941
+ const packages = parseBunLock(await lock.text());
1942
+ const context = {
1943
+ configs: await loadConfigs(dir),
1944
+ settings: await loadSettings(dir),
1945
+ minAgeDays: wholeNumber(values["min-age"], "min-age", DEFAULT_MIN_AGE_DAYS, 0),
1946
+ level,
1947
+ ignore: values.ignore ?? []
1948
+ };
1949
+ const findings = (await auditPackages(packages, context)).filter(hasFinding);
1950
+ if (values.json === true)
1951
+ printJson(findings);
1952
+ else
1953
+ console.log(renderAudit(findings, packages.length));
1954
+ return findings.some((each) => each.blocked) ? 1 : 0;
1955
+ }
1956
+ var usage2 = `pkg audit [dir]
1957
+
1958
+ 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.
1959
+ Findings are grouped per package, each registry package looked up once per run.
1960
+
1961
+ Exits 0 when nothing blocks, 1 when a package is missing, too fresh or outside the licence allowlist, or an advisory reaches --audit-level, 2 on a usage error or without a bun.lock.`, options2, BATCH = 8;
1962
+ var init_audit = __esm(() => {
1963
+ init_src();
1964
+ init_advisories();
1965
+ init_analyze();
1966
+ init_config2();
1967
+ init_lockfile();
1968
+ init_registry();
1969
+ options2 = {
1970
+ json: jsonOption("[{name, version, license, blocked, warnings, advisories}] for the packages with a finding"),
1971
+ "min-age": { type: "string", description: `days a version must be old (${DEFAULT_MIN_AGE_DAYS})` },
1972
+ "audit-level": { type: "string", description: "lowest advisory severity listed and failing: low, moderate, high, critical (low)" },
1973
+ ignore: { type: "string", multiple: true, description: "an advisory skipped by GHSA or numeric id, repeatable" }
1974
+ };
1975
+ });
1976
+
1977
+ // ../kit/src/progress.ts
1978
+ import process9 from "process";
1979
+ function liveRegion(render, stream = process9.stderr, env = process9.env) {
1980
+ if (!takesControlCodes(stream, env))
1981
+ return { redraw: () => {
1982
+ return;
1983
+ }, print: (text) => void stream.write(`${text}
1984
+ `), stop: () => {
1985
+ return;
1986
+ } };
1987
+ const write = stream.write.bind(stream);
1988
+ let frame = 0;
1989
+ let drawn = 0;
1990
+ const clear = () => {
1991
+ if (drawn > 0)
1992
+ write(`${CLEAR_LINE}${LINE_UP.repeat(drawn - 1)}`);
1993
+ drawn = 0;
1994
+ };
1995
+ const draw = () => {
1996
+ const width = (stream.columns === undefined || stream.columns === 0 ? 80 : stream.columns) - 1;
1997
+ const height = stream.rows === undefined || stream.rows === 0 ? 24 : stream.rows;
1998
+ const lines = render(FRAMES[frame++ % FRAMES.length]).slice(0, Math.max(1, height - 1)).map((line) => cutToWidth(line, width));
1999
+ if (lines.length === 0) {
2000
+ clear();
2001
+ return;
2002
+ }
2003
+ write(`${drawn > 0 ? `${CLEAR_LINE}${LINE_UP.repeat(drawn - 1)}` : CLEAR_LINE}${lines.join(`
2004
+ `)}`);
2005
+ drawn = lines.length;
2006
+ };
2007
+ const timer = setInterval(draw, FRAME_MS);
2008
+ const restore = interceptOutput(clear);
2009
+ const onExit = () => clear();
2010
+ const signals = holdSignals(stop);
2011
+ function stop() {
2012
+ clearInterval(timer);
2013
+ clear();
2014
+ restore();
2015
+ process9.off("exit", onExit);
2016
+ signals.release();
2017
+ }
2018
+ timer.unref();
2019
+ process9.on("exit", onExit);
2020
+ return {
2021
+ redraw: draw,
2022
+ print: (text) => {
2023
+ clear();
2024
+ write(`${text}
2025
+ `);
2026
+ draw();
2027
+ },
2028
+ stop
2029
+ };
2030
+ }
2031
+ function cutToWidth(line, width) {
2032
+ if (Bun.stringWidth(line) <= width)
2033
+ return line;
2034
+ let room = width;
2035
+ let kept = "";
2036
+ let index = 0;
2037
+ let linked = false;
2038
+ while (index < line.length) {
2039
+ ESCAPE_CODE.lastIndex = index;
2040
+ const escape = ESCAPE_CODE.exec(line);
2041
+ if (escape !== null) {
2042
+ kept += escape[0];
2043
+ linked ||= escape[0].startsWith(`${ESC}]`);
2044
+ index = ESCAPE_CODE.lastIndex;
2045
+ continue;
2046
+ }
2047
+ const char = String.fromCodePoint(line.codePointAt(index));
2048
+ const columns = Bun.stringWidth(char);
2049
+ if (columns > room)
2050
+ break;
2051
+ kept += char;
2052
+ room -= columns;
2053
+ index += char.length;
2054
+ }
2055
+ return `${kept}${RESET_STYLE}${linked ? CLOSE_LINK : ""}`;
2056
+ }
2057
+ function interceptOutput(clear) {
2058
+ const targets = [...CONSOLE_METHODS.map((name) => [console, name]), [process9.stdout, "write"], [process9.stderr, "write"]];
2059
+ const wrapped = targets.map(([target, name]) => {
2060
+ const original = Reflect.get(target, name);
2061
+ const wrapper = (...args) => {
2062
+ clear();
2063
+ return original.apply(target, args);
2064
+ };
2065
+ Reflect.set(target, name, wrapper);
2066
+ return { target, name, original, wrapper };
2067
+ });
2068
+ return () => {
2069
+ for (const { target, name, original, wrapper } of wrapped) {
2070
+ if (Reflect.get(target, name) === wrapper)
2071
+ Reflect.set(target, name, original);
2072
+ }
2073
+ };
2074
+ }
2075
+ var FRAMES, FRAME_MS = 80, CLEAR_LINE = "\r\x1B[2K", LINE_UP = "\x1B[1A\x1B[2K", ESC, ESCAPE_CODE, RESET_STYLE, CLOSE_LINK, CONSOLE_METHODS;
2076
+ var init_progress = __esm(() => {
2077
+ init_format();
2078
+ init_process();
2079
+ init_style();
2080
+ FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
2081
+ ESC = String.fromCharCode(27);
2082
+ ESCAPE_CODE = new RegExp(`${ESC}(?:\\[[\\x30-\\x3F]*[\\x20-\\x2F]*[\\x40-\\x7E]|\\][^\\u0007${ESC}]*(?:\\u0007|${ESC}\\\\))`, "y");
2083
+ RESET_STYLE = `${ESC}[0m`;
2084
+ CLOSE_LINK = `${ESC}]8;;${ESC}\\`;
2085
+ CONSOLE_METHODS = ["log", "info", "warn", "error", "debug", "dir", "dirxml", "table", "trace", "group", "groupCollapsed", "count", "timeEnd", "timeLog", "assert"];
2086
+ });
2087
+
2088
+ // ../kit/src/shell.ts
2089
+ var SEPARATORS2, PLAIN_BREAKERS, DOUBLE_QUOTED_ESCAPES, WRAPPERS;
2090
+ var init_shell = __esm(() => {
2091
+ SEPARATORS2 = new Set([`
2092
+ `, ";", "|"]);
2093
+ PLAIN_BREAKERS = new Set(["<", ">", "(", ")", "&", "|"]);
2094
+ DOUBLE_QUOTED_ESCAPES = new Set(["$", "`", '"', "\\"]);
2095
+ WRAPPERS = new Set(["command", "env", "sudo", "exec", "nohup", "time"]);
2096
+ });
2097
+
2098
+ // src/pin.ts
2099
+ function actions(byAction) {
2100
+ return new Map(Object.entries(byAction).flatMap(([action, names]) => names.map((name) => [name, action])));
2101
+ }
2102
+ var LOCKFILES, ACTIONS, OPTION_FLAGS, DIR_FLAGS, VALUE_FLAGS;
2103
+ var init_pin = __esm(() => {
2104
+ init_shell();
2105
+ LOCKFILES = [
2106
+ ["bun.lock", "bun"],
2107
+ ["bun.lockb", "bun"],
2108
+ ["pnpm-lock.yaml", "pnpm"],
2109
+ ["yarn.lock", "yarn"],
2110
+ ["package-lock.json", "npm"]
2111
+ ];
2112
+ ACTIONS = {
2113
+ bun: actions({ install: ["install", "i"], add: ["add", "a"], remove: ["remove", "rm"], update: ["update"] }),
2114
+ pnpm: actions({ install: ["install", "i"], add: ["add"], remove: ["remove", "rm"], update: ["update", "up"] }),
2115
+ yarn: new Map([...actions({ install: ["", "install"], add: ["add"], remove: ["remove"], update: ["upgrade"] }), ["upgrade-interactive", null], ["import", null]]),
2116
+ npm: actions({
2117
+ install: ["install", "i", "in", "ins", "inst", "insta", "instal", "isnt", "isnta", "isntal", "isntall"],
2118
+ add: ["add"],
2119
+ frozen: ["ci", "clean-install", "ic", "install-clean", "isntall-clean"],
2120
+ remove: ["uninstall", "unlink", "remove", "rm", "r", "un"],
2121
+ update: ["update", "u", "up", "upgrade", "udpate"]
2122
+ })
2123
+ };
2124
+ OPTION_FLAGS = new Map([
2125
+ ["-D", "dev"],
2126
+ ["--save-dev", "dev"],
2127
+ ["--dev", "dev"],
2128
+ ["-E", "exact"],
2129
+ ["--save-exact", "exact"],
2130
+ ["--exact", "exact"]
2131
+ ]);
2132
+ DIR_FLAGS = new Set(["--cwd", "-C", "--dir", "--prefix"]);
2133
+ VALUE_FLAGS = new Set([...DIR_FLAGS, "--filter", "-F"]);
2134
+ });
2135
+
2136
+ // src/consumers.ts
2137
+ import { existsSync, readdirSync, readFileSync } from "fs";
2138
+ import { dirname as dirname2, join as join3, relative } from "path";
2139
+ function packageFiles(dir, depth, found) {
2140
+ let entries;
2141
+ try {
2142
+ entries = readdirSync(dir, { withFileTypes: true });
2143
+ } catch {
2144
+ return found;
2145
+ }
2146
+ for (const entry of entries) {
2147
+ if (entry.isFile() && entry.name === "package.json")
2148
+ found.push(join3(dir, entry.name));
2149
+ else if (entry.isDirectory() && depth < MAX_DEPTH && !entry.name.startsWith(".") && !SKIPPED.has(entry.name))
2150
+ packageFiles(join3(dir, entry.name), depth + 1, found);
2151
+ }
2152
+ return found;
2153
+ }
2154
+ function managerFor(dir, root) {
2155
+ for (let at = dir;; at = dirname2(at)) {
2156
+ const lockfile = LOCKFILES.find(([file]) => existsSync(join3(at, file)));
2157
+ if (lockfile !== undefined)
2158
+ return lockfile[1];
2159
+ if (at === root || at === dirname2(at))
2160
+ return "bun";
2161
+ }
2162
+ }
2163
+ function findConsumers(name, root) {
2164
+ const consumers = [];
2165
+ for (const path of packageFiles(root, 0, []).sort()) {
2166
+ let manifest;
2167
+ try {
2168
+ manifest = JSON.parse(readFileSync(path, "utf8"));
2169
+ } catch {
2170
+ continue;
2171
+ }
2172
+ const kind = KINDS.find((each) => typeof manifest[each]?.[name] === "string");
2173
+ const spec = kind === undefined ? undefined : manifest[kind]?.[name];
2174
+ if (kind !== undefined && spec !== undefined)
2175
+ consumers.push({ dir: relative(root, dirname2(path)) || ".", path, kind, spec, manager: managerFor(dirname2(path), root) });
2176
+ }
2177
+ return consumers;
2178
+ }
2179
+ function isLocal(consumer) {
2180
+ return LOCAL_SPEC.test(consumer.spec);
2181
+ }
2182
+ function addCommand(consumer, name, version) {
2183
+ return ["bun", "add", ...KIND_FLAGS[consumer.kind], "--exact", "--no-cache", `${name}@${version}`];
2184
+ }
2185
+ var KINDS, SKIPPED, MAX_DEPTH = 5, LOCAL_SPEC, KIND_FLAGS;
2186
+ var init_consumers = __esm(() => {
2187
+ init_pin();
2188
+ KINDS = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
2189
+ SKIPPED = new Set(["node_modules", "dist", "build", "vendor", "target", "coverage"]);
2190
+ LOCAL_SPEC = /^(?:workspace|link|file|portal):/;
2191
+ KIND_FLAGS = { dependencies: [], devDependencies: ["--dev"], optionalDependencies: ["--optional"], peerDependencies: ["--peer"] };
2192
+ });
2193
+
2194
+ // src/commands/bump.ts
2195
+ var exports_bump = {};
2196
+ __export(exports_bump, {
2197
+ ROOT_OPTION: () => ROOT_OPTION,
2198
+ bump: () => bump
2199
+ });
2200
+ import { existsSync as existsSync2 } from "fs";
2201
+ import { homedir as homedir2 } from "os";
2202
+ import { dirname as dirname3, join as join4, relative as relative2 } from "path";
2203
+ async function servedVersion(name, version, settings) {
2204
+ const registry = registryFor(name, settings.configs);
2205
+ const host = new URL(registry.url).host;
2206
+ const started = Date.now();
2207
+ const region = liveRegion((spinner) => [`${spinner} waiting for ${host} to serve ${name}@${version} ${formatDuration(Date.now() - started)}`]);
2208
+ try {
2209
+ for (;; ) {
2210
+ const packument = await fetchPackument(name, registry, settings.fetcher);
2211
+ const latest = packument?.["dist-tags"]?.latest;
2212
+ if (version === undefined && latest !== undefined)
2213
+ return latest;
2214
+ if (version === undefined)
2215
+ fail(`${host} has no ${name}`, 1);
2216
+ if (packument?.versions?.[version] !== undefined)
2217
+ return version;
2218
+ if (Date.now() - started >= settings.timeout)
2219
+ fail(`${host} does not serve ${name}@${version} after ${formatDuration(settings.timeout)}`);
2220
+ region.redraw();
2221
+ await Bun.sleep(settings.poll ?? POLL);
2222
+ }
2223
+ } finally {
2224
+ region.stop();
2225
+ }
2226
+ }
2227
+ function lockfileOf(dir, root) {
2228
+ for (let at = dir;; at = dirname3(at)) {
2229
+ const found = ["bun.lock", "bun.lockb"].find((file) => existsSync2(join4(at, file)));
2230
+ if (found !== undefined)
2231
+ return relative2(dir, join4(at, found));
2232
+ if (at === root || at === dirname3(at))
2233
+ return;
2234
+ }
2235
+ }
2236
+ async function checkAndCommit(name, version, where, root, run) {
2237
+ const checked = await run(["check"], where);
2238
+ if (checked.code !== 0)
2239
+ return `check exited ${checked.code}: ${checked.text.trim().split(`
2240
+ `).at(-1) ?? ""}`;
2241
+ const lockfile = lockfileOf(where, root);
2242
+ const committed = await run(["gc", `chore(deps): bump ${name} to ${version}`, "--", "package.json", ...lockfile === undefined ? [] : [lockfile]], where);
2243
+ return committed.code === 0 ? undefined : `gc exited ${committed.code}: ${committed.text.trim().split(`
2244
+ `).at(-1) ?? ""}`;
2245
+ }
2246
+ async function bumpConsumers(name, version, settings) {
2247
+ const found = findConsumers(name, settings.root);
2248
+ const consumers = found.filter((each) => !isLocal(each));
2249
+ const local = found.length - consumers.length;
2250
+ const run = settings.run ?? (async (argv, cwd) => runCommand(argv, { cwd }));
2251
+ const committed = [];
2252
+ const failing = [];
2253
+ const skipped = [];
2254
+ let isClean = true;
2255
+ if (found.length === 0)
2256
+ note(`nothing under ${settings.root} depends on ${name}`);
2257
+ if (local > 0)
2258
+ note(`${local} workspace:, link: or file: dependenc${local === 1 ? "y" : "ies"}`, "left as they are");
2259
+ for (const consumer of consumers) {
2260
+ const argv = addCommand(consumer, name, version);
2261
+ const where = join4(settings.root, consumer.dir);
2262
+ if (consumer.spec === version) {
2263
+ skipped.push(consumer.dir);
2264
+ note(consumer.dir, `already on ${version}`);
2265
+ } else if (consumer.manager !== "bun") {
2266
+ skipped.push(consumer.dir);
2267
+ warn(consumer.dir, `${consumer.spec}, its lockfile pins ${consumer.manager}: put ${version} in by hand`);
2268
+ } else if (settings.isDryRun === true) {
2269
+ note(consumer.dir, `would run ${[argv.join(" "), ...settings.isAll === true ? ["check", `gc 'chore(deps): bump ${name} to ${version}'`] : []].join(", then ")}`);
2270
+ } else {
2271
+ const ran = await run(argv, where);
2272
+ if (ran.code !== 0) {
2273
+ isClean = false;
2274
+ failing.push(consumer.dir);
2275
+ problem(consumer.dir, `${argv.join(" ")} exited ${ran.code}: ${ran.text.trim().split(`
2276
+ `).at(-1) ?? ""}`);
2277
+ } else if (settings.isAll !== true) {
2278
+ ok(consumer.dir, `${consumer.spec} -> ${version}`);
2279
+ } else {
2280
+ const failure = await checkAndCommit(name, version, where, settings.root, run);
2281
+ if (failure === undefined) {
2282
+ committed.push(consumer.dir);
2283
+ ok(consumer.dir, `${consumer.spec} -> ${version}, checked and committed`);
2284
+ } else {
2285
+ isClean = false;
2286
+ failing.push(consumer.dir);
2287
+ problem(consumer.dir, `${consumer.spec} -> ${version}, left uncommitted: ${failure}`);
2288
+ }
2289
+ }
2290
+ }
2291
+ }
2292
+ if (settings.isAll === true && settings.isDryRun !== true)
2293
+ note("summary", `${committed.length} bumped and committed, ${failing.length} bumped and failing${failing.length > 0 ? ` (${failing.join(", ")})` : ""}, ${skipped.length + local} skipped`);
2294
+ return isClean;
2295
+ }
2296
+ async function bump(args) {
2297
+ const { values, positionals: [name, asked] } = parse(args, usage3, options3, { positionals: ["<name>", "[version]"] });
2298
+ const settings = {
2299
+ root: values.root ?? join4(homedir2(), "Workspace"),
2300
+ configs: await loadConfigs(),
2301
+ timeout: duration(values.timeout, "timeout", 10 * 60000),
2302
+ isDryRun: values["dry-run"] === true,
2303
+ isAll: values["all-consumers"] === true
2304
+ };
2305
+ const version = await servedVersion(name, asked, settings);
2306
+ return await bumpConsumers(name, version, settings) ? 0 : 1;
2307
+ }
2308
+ var usage3 = `pkg bump <name> [version]
2309
+
2310
+ Waits until the registry serves the version (the latest when none is given), 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.
2311
+ A workspace:, link: or file: dependency, a folder already on the version and one whose lockfile pins another manager are left as they are, each said so.
2312
+ With --all-consumers each folder whose install went through then runs its own \`check\` (the check bin) and is committed with \`gc 'chore(deps): bump <name> to <version>' -- package.json <lockfile>\` only when that passes; a failing one is left uncommitted and listed in the summary with the skipped ones, and nothing is ever pushed.
2313
+
2314
+ Exits 0 when every install ran or was left as it is (with --all-consumers, and every check passed and every commit landed), 1 when an install, a check or a commit fails or the registry has no such package, 2 when the version never shows within the timeout or on a usage error.`, ROOT_OPTION, options3, POLL = 5000;
2315
+ var init_bump = __esm(() => {
2316
+ init_src();
2317
+ init_progress();
2318
+ init_config2();
2319
+ init_consumers();
2320
+ init_registry();
2321
+ ROOT_OPTION = { type: "string", description: "the folder holding the repositories (~/Workspace)" };
2322
+ options3 = {
2323
+ root: ROOT_OPTION,
2324
+ timeout: { type: "string", short: "t", description: "how long to wait for the registry (10m): 30s, 5m, 1h" },
2325
+ "all-consumers": { type: "boolean", description: "after each install run the folder's check and commit it through gc when it passes" },
2326
+ "dry-run": { type: "boolean", description: "print what would run, changing nothing" }
2327
+ };
2328
+ });
2329
+
2330
+ // src/commands/consumers.ts
2331
+ var exports_consumers = {};
2332
+ __export(exports_consumers, {
2333
+ consumers: () => consumers
2334
+ });
2335
+ import { homedir as homedir3 } from "os";
2336
+ import { join as join5 } from "path";
2337
+ function consumers(args) {
2338
+ const { values, positionals: [name] } = parse(args, usage4, options4, { positionals: ["<name>"] });
2339
+ const root = values.root ?? join5(homedir3(), "Workspace");
2340
+ const { shown, footer } = capped(findConsumers(name, root), limitOf(values, CONSUMERS_LIMIT));
2341
+ if (values.json === true)
2342
+ printJson(shown);
2343
+ else if (shown.length === 0)
2344
+ console.log(`nothing under ${root} depends on ${name}`);
2345
+ else
2346
+ console.log([table([["FOLDER", "KIND", "VERSION", "MANAGER"], ...shown.map((each) => [each.dir, each.kind, each.spec, each.manager])], { header: true }), ...footer === undefined ? [] : [footer]].join(`
2347
+ `));
2348
+ return 0;
2349
+ }
2350
+ var usage4 = `pkg consumers <name>
2351
+
2352
+ 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).
2353
+
2354
+ Exits 0 when it listed them, 2 on a usage error.`, CONSUMERS_LIMIT = 30, options4;
2355
+ var init_consumers2 = __esm(() => {
2356
+ init_src();
2357
+ init_consumers();
2358
+ init_bump();
2359
+ options4 = {
2360
+ root: ROOT_OPTION,
2361
+ ...limitOptions(CONSUMERS_LIMIT),
2362
+ json: jsonOption("[{dir, path, kind, spec, manager}]")
2363
+ };
2364
+ });
2365
+
2366
+ // src/cli.ts
2367
+ init_src();
2368
+ import process10 from "process";
2369
+ // package.json
2370
+ var version = "0.4.0";
1353
2371
 
1354
2372
  // src/cli.ts
1355
- process7.exitCode = await runMain({ name: "pkg", version, run: check });
2373
+ process10.exitCode = await runCli({
2374
+ name: "pkg",
2375
+ version,
2376
+ about: "checks npm packages before they are added, and moves a lib's consumers onto a new release",
2377
+ replaces: "bun add on trust, and a bun info and sleep loop then a bun add per consumer",
2378
+ examples: [["pkg zod", "the name, the newest version two weeks old, its licence and scripts"], ["pkg bump @kaynooo/cli-kit --dry-run", "the consumers a release would move"]],
2379
+ defaultCommand: "check",
2380
+ commands: {
2381
+ check: { summary: "check packages before they are added (`pkg <name>` alone runs it)", run: async (args) => (await Promise.resolve().then(() => (init_check(), exports_check))).check(args) },
2382
+ audit: { summary: "check every package a bun.lock pins, with its known advisories", run: async (args) => (await Promise.resolve().then(() => (init_audit(), exports_audit))).audit(args) },
2383
+ bump: { summary: "wait for a release on the registry, then bun add it in every consumer", run: async (args) => (await Promise.resolve().then(() => (init_bump(), exports_bump))).bump(args) },
2384
+ consumers: { summary: "list the folders depending on a package, with the version each asks for", run: async (args) => (await Promise.resolve().then(() => (init_consumers2(), exports_consumers))).consumers(args) }
2385
+ }
2386
+ });