flowlint 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -97,7 +97,7 @@ var require_argument = __commonJS({
97
97
  this._name = name;
98
98
  break;
99
99
  }
100
- if (this._name.length > 3 && this._name.slice(-3) === "...") {
100
+ if (this._name.endsWith("...")) {
101
101
  this.variadic = true;
102
102
  this._name = this._name.slice(0, -3);
103
103
  }
@@ -113,11 +113,12 @@ var require_argument = __commonJS({
113
113
  /**
114
114
  * @package
115
115
  */
116
- _concatValue(value, previous) {
116
+ _collectValue(value, previous) {
117
117
  if (previous === this.defaultValue || !Array.isArray(previous)) {
118
118
  return [value];
119
119
  }
120
- return previous.concat(value);
120
+ previous.push(value);
121
+ return previous;
121
122
  }
122
123
  /**
123
124
  * Set the default value, and optionally supply the description to be displayed in the help.
@@ -156,7 +157,7 @@ var require_argument = __commonJS({
156
157
  );
157
158
  }
158
159
  if (this.variadic) {
159
- return this._concatValue(arg, previous);
160
+ return this._collectValue(arg, previous);
160
161
  }
161
162
  return arg;
162
163
  };
@@ -198,10 +199,22 @@ var require_help = __commonJS({
198
199
  var Help2 = class {
199
200
  constructor() {
200
201
  this.helpWidth = void 0;
202
+ this.minWidthToWrap = 40;
201
203
  this.sortSubcommands = false;
202
204
  this.sortOptions = false;
203
205
  this.showGlobalOptions = false;
204
206
  }
207
+ /**
208
+ * prepareContext is called by Commander after applying overrides from `Command.configureHelp()`
209
+ * and just before calling `formatHelp()`.
210
+ *
211
+ * Commander just uses the helpWidth and the rest is provided for optional use by more complex subclasses.
212
+ *
213
+ * @param {{ error?: boolean, helpWidth?: number, outputHasColors?: boolean }} contextOptions
214
+ */
215
+ prepareContext(contextOptions) {
216
+ this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
217
+ }
205
218
  /**
206
219
  * Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
207
220
  *
@@ -338,7 +351,12 @@ var require_help = __commonJS({
338
351
  */
339
352
  longestSubcommandTermLength(cmd, helper) {
340
353
  return helper.visibleCommands(cmd).reduce((max, command) => {
341
- return Math.max(max, helper.subcommandTerm(command).length);
354
+ return Math.max(
355
+ max,
356
+ this.displayWidth(
357
+ helper.styleSubcommandTerm(helper.subcommandTerm(command))
358
+ )
359
+ );
342
360
  }, 0);
343
361
  }
344
362
  /**
@@ -350,7 +368,10 @@ var require_help = __commonJS({
350
368
  */
351
369
  longestOptionTermLength(cmd, helper) {
352
370
  return helper.visibleOptions(cmd).reduce((max, option) => {
353
- return Math.max(max, helper.optionTerm(option).length);
371
+ return Math.max(
372
+ max,
373
+ this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option)))
374
+ );
354
375
  }, 0);
355
376
  }
356
377
  /**
@@ -362,7 +383,10 @@ var require_help = __commonJS({
362
383
  */
363
384
  longestGlobalOptionTermLength(cmd, helper) {
364
385
  return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
365
- return Math.max(max, helper.optionTerm(option).length);
386
+ return Math.max(
387
+ max,
388
+ this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option)))
389
+ );
366
390
  }, 0);
367
391
  }
368
392
  /**
@@ -374,7 +398,12 @@ var require_help = __commonJS({
374
398
  */
375
399
  longestArgumentTermLength(cmd, helper) {
376
400
  return helper.visibleArguments(cmd).reduce((max, argument) => {
377
- return Math.max(max, helper.argumentTerm(argument).length);
401
+ return Math.max(
402
+ max,
403
+ this.displayWidth(
404
+ helper.styleArgumentTerm(helper.argumentTerm(argument))
405
+ )
406
+ );
378
407
  }, 0);
379
408
  }
380
409
  /**
@@ -442,7 +471,11 @@ var require_help = __commonJS({
442
471
  extraInfo.push(`env: ${option.envVar}`);
443
472
  }
444
473
  if (extraInfo.length > 0) {
445
- return `${option.description} (${extraInfo.join(", ")})`;
474
+ const extraDescription = `(${extraInfo.join(", ")})`;
475
+ if (option.description) {
476
+ return `${option.description} ${extraDescription}`;
477
+ }
478
+ return extraDescription;
446
479
  }
447
480
  return option.description;
448
481
  }
@@ -466,14 +499,49 @@ var require_help = __commonJS({
466
499
  );
467
500
  }
468
501
  if (extraInfo.length > 0) {
469
- const extraDescripton = `(${extraInfo.join(", ")})`;
502
+ const extraDescription = `(${extraInfo.join(", ")})`;
470
503
  if (argument.description) {
471
- return `${argument.description} ${extraDescripton}`;
504
+ return `${argument.description} ${extraDescription}`;
472
505
  }
473
- return extraDescripton;
506
+ return extraDescription;
474
507
  }
475
508
  return argument.description;
476
509
  }
510
+ /**
511
+ * Format a list of items, given a heading and an array of formatted items.
512
+ *
513
+ * @param {string} heading
514
+ * @param {string[]} items
515
+ * @param {Help} helper
516
+ * @returns string[]
517
+ */
518
+ formatItemList(heading, items, helper) {
519
+ if (items.length === 0) return [];
520
+ return [helper.styleTitle(heading), ...items, ""];
521
+ }
522
+ /**
523
+ * Group items by their help group heading.
524
+ *
525
+ * @param {Command[] | Option[]} unsortedItems
526
+ * @param {Command[] | Option[]} visibleItems
527
+ * @param {Function} getGroup
528
+ * @returns {Map<string, Command[] | Option[]>}
529
+ */
530
+ groupItems(unsortedItems, visibleItems, getGroup) {
531
+ const result = /* @__PURE__ */ new Map();
532
+ unsortedItems.forEach((item) => {
533
+ const group = getGroup(item);
534
+ if (!result.has(group)) result.set(group, []);
535
+ });
536
+ visibleItems.forEach((item) => {
537
+ const group = getGroup(item);
538
+ if (!result.has(group)) {
539
+ result.set(group, []);
540
+ }
541
+ result.get(group).push(item);
542
+ });
543
+ return result;
544
+ }
477
545
  /**
478
546
  * Generate the built-in help text.
479
547
  *
@@ -483,75 +551,142 @@ var require_help = __commonJS({
483
551
  */
484
552
  formatHelp(cmd, helper) {
485
553
  const termWidth = helper.padWidth(cmd, helper);
486
- const helpWidth = helper.helpWidth || 80;
487
- const itemIndentWidth = 2;
488
- const itemSeparatorWidth = 2;
489
- function formatItem(term, description) {
490
- if (description) {
491
- const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
492
- return helper.wrap(
493
- fullText,
494
- helpWidth - itemIndentWidth,
495
- termWidth + itemSeparatorWidth
496
- );
497
- }
498
- return term;
499
- }
500
- function formatList(textArray) {
501
- return textArray.join("\n").replace(/^/gm, " ".repeat(itemIndentWidth));
554
+ const helpWidth = helper.helpWidth ?? 80;
555
+ function callFormatItem(term, description) {
556
+ return helper.formatItem(term, termWidth, description, helper);
502
557
  }
503
- let output = [`Usage: ${helper.commandUsage(cmd)}`, ""];
558
+ let output = [
559
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
560
+ ""
561
+ ];
504
562
  const commandDescription = helper.commandDescription(cmd);
505
563
  if (commandDescription.length > 0) {
506
564
  output = output.concat([
507
- helper.wrap(commandDescription, helpWidth, 0),
565
+ helper.boxWrap(
566
+ helper.styleCommandDescription(commandDescription),
567
+ helpWidth
568
+ ),
508
569
  ""
509
570
  ]);
510
571
  }
511
572
  const argumentList = helper.visibleArguments(cmd).map((argument) => {
512
- return formatItem(
513
- helper.argumentTerm(argument),
514
- helper.argumentDescription(argument)
573
+ return callFormatItem(
574
+ helper.styleArgumentTerm(helper.argumentTerm(argument)),
575
+ helper.styleArgumentDescription(helper.argumentDescription(argument))
515
576
  );
516
577
  });
517
- if (argumentList.length > 0) {
518
- output = output.concat(["Arguments:", formatList(argumentList), ""]);
519
- }
520
- const optionList = helper.visibleOptions(cmd).map((option) => {
521
- return formatItem(
522
- helper.optionTerm(option),
523
- helper.optionDescription(option)
524
- );
578
+ output = output.concat(
579
+ this.formatItemList("Arguments:", argumentList, helper)
580
+ );
581
+ const optionGroups = this.groupItems(
582
+ cmd.options,
583
+ helper.visibleOptions(cmd),
584
+ (option) => option.helpGroupHeading ?? "Options:"
585
+ );
586
+ optionGroups.forEach((options, group) => {
587
+ const optionList = options.map((option) => {
588
+ return callFormatItem(
589
+ helper.styleOptionTerm(helper.optionTerm(option)),
590
+ helper.styleOptionDescription(helper.optionDescription(option))
591
+ );
592
+ });
593
+ output = output.concat(this.formatItemList(group, optionList, helper));
525
594
  });
526
- if (optionList.length > 0) {
527
- output = output.concat(["Options:", formatList(optionList), ""]);
528
- }
529
- if (this.showGlobalOptions) {
595
+ if (helper.showGlobalOptions) {
530
596
  const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
531
- return formatItem(
532
- helper.optionTerm(option),
533
- helper.optionDescription(option)
597
+ return callFormatItem(
598
+ helper.styleOptionTerm(helper.optionTerm(option)),
599
+ helper.styleOptionDescription(helper.optionDescription(option))
534
600
  );
535
601
  });
536
- if (globalOptionList.length > 0) {
537
- output = output.concat([
538
- "Global Options:",
539
- formatList(globalOptionList),
540
- ""
541
- ]);
542
- }
543
- }
544
- const commandList = helper.visibleCommands(cmd).map((cmd2) => {
545
- return formatItem(
546
- helper.subcommandTerm(cmd2),
547
- helper.subcommandDescription(cmd2)
602
+ output = output.concat(
603
+ this.formatItemList("Global Options:", globalOptionList, helper)
548
604
  );
549
- });
550
- if (commandList.length > 0) {
551
- output = output.concat(["Commands:", formatList(commandList), ""]);
552
605
  }
606
+ const commandGroups = this.groupItems(
607
+ cmd.commands,
608
+ helper.visibleCommands(cmd),
609
+ (sub) => sub.helpGroup() || "Commands:"
610
+ );
611
+ commandGroups.forEach((commands, group) => {
612
+ const commandList = commands.map((sub) => {
613
+ return callFormatItem(
614
+ helper.styleSubcommandTerm(helper.subcommandTerm(sub)),
615
+ helper.styleSubcommandDescription(helper.subcommandDescription(sub))
616
+ );
617
+ });
618
+ output = output.concat(this.formatItemList(group, commandList, helper));
619
+ });
553
620
  return output.join("\n");
554
621
  }
622
+ /**
623
+ * Return display width of string, ignoring ANSI escape sequences. Used in padding and wrapping calculations.
624
+ *
625
+ * @param {string} str
626
+ * @returns {number}
627
+ */
628
+ displayWidth(str) {
629
+ return stripColor(str).length;
630
+ }
631
+ /**
632
+ * Style the title for displaying in the help. Called with 'Usage:', 'Options:', etc.
633
+ *
634
+ * @param {string} str
635
+ * @returns {string}
636
+ */
637
+ styleTitle(str) {
638
+ return str;
639
+ }
640
+ styleUsage(str) {
641
+ return str.split(" ").map((word) => {
642
+ if (word === "[options]") return this.styleOptionText(word);
643
+ if (word === "[command]") return this.styleSubcommandText(word);
644
+ if (word[0] === "[" || word[0] === "<")
645
+ return this.styleArgumentText(word);
646
+ return this.styleCommandText(word);
647
+ }).join(" ");
648
+ }
649
+ styleCommandDescription(str) {
650
+ return this.styleDescriptionText(str);
651
+ }
652
+ styleOptionDescription(str) {
653
+ return this.styleDescriptionText(str);
654
+ }
655
+ styleSubcommandDescription(str) {
656
+ return this.styleDescriptionText(str);
657
+ }
658
+ styleArgumentDescription(str) {
659
+ return this.styleDescriptionText(str);
660
+ }
661
+ styleDescriptionText(str) {
662
+ return str;
663
+ }
664
+ styleOptionTerm(str) {
665
+ return this.styleOptionText(str);
666
+ }
667
+ styleSubcommandTerm(str) {
668
+ return str.split(" ").map((word) => {
669
+ if (word === "[options]") return this.styleOptionText(word);
670
+ if (word[0] === "[" || word[0] === "<")
671
+ return this.styleArgumentText(word);
672
+ return this.styleSubcommandText(word);
673
+ }).join(" ");
674
+ }
675
+ styleArgumentTerm(str) {
676
+ return this.styleArgumentText(str);
677
+ }
678
+ styleOptionText(str) {
679
+ return str;
680
+ }
681
+ styleArgumentText(str) {
682
+ return str;
683
+ }
684
+ styleSubcommandText(str) {
685
+ return str;
686
+ }
687
+ styleCommandText(str) {
688
+ return str;
689
+ }
555
690
  /**
556
691
  * Calculate the pad width from the maximum term length.
557
692
  *
@@ -568,40 +703,94 @@ var require_help = __commonJS({
568
703
  );
569
704
  }
570
705
  /**
571
- * Wrap the given string to width characters per line, with lines after the first indented.
572
- * Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
706
+ * Detect manually wrapped and indented strings by checking for line break followed by whitespace.
573
707
  *
574
708
  * @param {string} str
575
- * @param {number} width
576
- * @param {number} indent
577
- * @param {number} [minColumnWidth=40]
578
- * @return {string}
709
+ * @returns {boolean}
710
+ */
711
+ preformatted(str) {
712
+ return /\n[^\S\r\n]/.test(str);
713
+ }
714
+ /**
715
+ * Format the "item", which consists of a term and description. Pad the term and wrap the description, indenting the following lines.
579
716
  *
717
+ * So "TTT", 5, "DDD DDDD DD DDD" might be formatted for this.helpWidth=17 like so:
718
+ * TTT DDD DDDD
719
+ * DD DDD
720
+ *
721
+ * @param {string} term
722
+ * @param {number} termWidth
723
+ * @param {string} description
724
+ * @param {Help} helper
725
+ * @returns {string}
580
726
  */
581
- wrap(str, width, indent, minColumnWidth = 40) {
582
- const indents = " \\f\\t\\v\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF";
583
- const manualIndent = new RegExp(`[\\n][${indents}]+`);
584
- if (str.match(manualIndent)) return str;
585
- const columnWidth = width - indent;
586
- if (columnWidth < minColumnWidth) return str;
587
- const leadingStr = str.slice(0, indent);
588
- const columnText = str.slice(indent).replace("\r\n", "\n");
589
- const indentString = " ".repeat(indent);
590
- const zeroWidthSpace = "\u200B";
591
- const breaks = `\\s${zeroWidthSpace}`;
592
- const regex = new RegExp(
593
- `
594
- |.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`,
595
- "g"
727
+ formatItem(term, termWidth, description, helper) {
728
+ const itemIndent = 2;
729
+ const itemIndentStr = " ".repeat(itemIndent);
730
+ if (!description) return itemIndentStr + term;
731
+ const paddedTerm = term.padEnd(
732
+ termWidth + term.length - helper.displayWidth(term)
596
733
  );
597
- const lines = columnText.match(regex) || [];
598
- return leadingStr + lines.map((line, i) => {
599
- if (line === "\n") return "";
600
- return (i > 0 ? indentString : "") + line.trimEnd();
601
- }).join("\n");
734
+ const spacerWidth = 2;
735
+ const helpWidth = this.helpWidth ?? 80;
736
+ const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
737
+ let formattedDescription;
738
+ if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) {
739
+ formattedDescription = description;
740
+ } else {
741
+ const wrappedDescription = helper.boxWrap(description, remainingWidth);
742
+ formattedDescription = wrappedDescription.replace(
743
+ /\n/g,
744
+ "\n" + " ".repeat(termWidth + spacerWidth)
745
+ );
746
+ }
747
+ return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
748
+ ${itemIndentStr}`);
749
+ }
750
+ /**
751
+ * Wrap a string at whitespace, preserving existing line breaks.
752
+ * Wrapping is skipped if the width is less than `minWidthToWrap`.
753
+ *
754
+ * @param {string} str
755
+ * @param {number} width
756
+ * @returns {string}
757
+ */
758
+ boxWrap(str, width) {
759
+ if (width < this.minWidthToWrap) return str;
760
+ const rawLines = str.split(/\r\n|\n/);
761
+ const chunkPattern = /[\s]*[^\s]+/g;
762
+ const wrappedLines = [];
763
+ rawLines.forEach((line) => {
764
+ const chunks = line.match(chunkPattern);
765
+ if (chunks === null) {
766
+ wrappedLines.push("");
767
+ return;
768
+ }
769
+ let sumChunks = [chunks.shift()];
770
+ let sumWidth = this.displayWidth(sumChunks[0]);
771
+ chunks.forEach((chunk) => {
772
+ const visibleWidth = this.displayWidth(chunk);
773
+ if (sumWidth + visibleWidth <= width) {
774
+ sumChunks.push(chunk);
775
+ sumWidth += visibleWidth;
776
+ return;
777
+ }
778
+ wrappedLines.push(sumChunks.join(""));
779
+ const nextChunk = chunk.trimStart();
780
+ sumChunks = [nextChunk];
781
+ sumWidth = this.displayWidth(nextChunk);
782
+ });
783
+ wrappedLines.push(sumChunks.join(""));
784
+ });
785
+ return wrappedLines.join("\n");
602
786
  }
603
787
  };
788
+ function stripColor(str) {
789
+ const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
790
+ return str.replace(sgrPattern, "");
791
+ }
604
792
  exports2.Help = Help2;
793
+ exports2.stripColor = stripColor;
605
794
  }
606
795
  });
607
796
 
@@ -640,6 +829,7 @@ var require_option = __commonJS({
640
829
  this.argChoices = void 0;
641
830
  this.conflictsWith = [];
642
831
  this.implied = void 0;
832
+ this.helpGroupHeading = void 0;
643
833
  }
644
834
  /**
645
835
  * Set the default value, and optionally supply the description to be displayed in the help.
@@ -750,11 +940,12 @@ var require_option = __commonJS({
750
940
  /**
751
941
  * @package
752
942
  */
753
- _concatValue(value, previous) {
943
+ _collectValue(value, previous) {
754
944
  if (previous === this.defaultValue || !Array.isArray(previous)) {
755
945
  return [value];
756
946
  }
757
- return previous.concat(value);
947
+ previous.push(value);
948
+ return previous;
758
949
  }
759
950
  /**
760
951
  * Only allow option value to be one of choices.
@@ -771,7 +962,7 @@ var require_option = __commonJS({
771
962
  );
772
963
  }
773
964
  if (this.variadic) {
774
- return this._concatValue(arg, previous);
965
+ return this._collectValue(arg, previous);
775
966
  }
776
967
  return arg;
777
968
  };
@@ -790,12 +981,25 @@ var require_option = __commonJS({
790
981
  }
791
982
  /**
792
983
  * Return option name, in a camelcase format that can be used
793
- * as a object attribute key.
984
+ * as an object attribute key.
794
985
  *
795
986
  * @return {string}
796
987
  */
797
988
  attributeName() {
798
- return camelcase(this.name().replace(/^no-/, ""));
989
+ if (this.negate) {
990
+ return camelcase(this.name().replace(/^no-/, ""));
991
+ }
992
+ return camelcase(this.name());
993
+ }
994
+ /**
995
+ * Set the help group heading.
996
+ *
997
+ * @param {string} heading
998
+ * @return {Option}
999
+ */
1000
+ helpGroup(heading) {
1001
+ this.helpGroupHeading = heading;
1002
+ return this;
799
1003
  }
800
1004
  /**
801
1005
  * Check if `arg` matches the short or long flag.
@@ -863,14 +1067,40 @@ var require_option = __commonJS({
863
1067
  function splitOptionFlags(flags) {
864
1068
  let shortFlag;
865
1069
  let longFlag;
866
- const flagParts = flags.split(/[ |,]+/);
867
- if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1]))
1070
+ const shortFlagExp = /^-[^-]$/;
1071
+ const longFlagExp = /^--[^-]/;
1072
+ const flagParts = flags.split(/[ |,]+/).concat("guard");
1073
+ if (shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();
1074
+ if (longFlagExp.test(flagParts[0])) longFlag = flagParts.shift();
1075
+ if (!shortFlag && shortFlagExp.test(flagParts[0]))
868
1076
  shortFlag = flagParts.shift();
869
- longFlag = flagParts.shift();
870
- if (!shortFlag && /^-[^-]$/.test(longFlag)) {
1077
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
871
1078
  shortFlag = longFlag;
872
- longFlag = void 0;
1079
+ longFlag = flagParts.shift();
873
1080
  }
1081
+ if (flagParts[0].startsWith("-")) {
1082
+ const unsupportedFlag = flagParts[0];
1083
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
1084
+ if (/^-[^-][^-]/.test(unsupportedFlag))
1085
+ throw new Error(
1086
+ `${baseError}
1087
+ - a short flag is a single dash and a single character
1088
+ - either use a single dash and a single character (for a short flag)
1089
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`
1090
+ );
1091
+ if (shortFlagExp.test(unsupportedFlag))
1092
+ throw new Error(`${baseError}
1093
+ - too many short flags`);
1094
+ if (longFlagExp.test(unsupportedFlag))
1095
+ throw new Error(`${baseError}
1096
+ - too many long flags`);
1097
+ throw new Error(`${baseError}
1098
+ - unrecognised flag format`);
1099
+ }
1100
+ if (shortFlag === void 0 && longFlag === void 0)
1101
+ throw new Error(
1102
+ `option creation failed due to no flags found in '${flags}'.`
1103
+ );
874
1104
  return { shortFlag, longFlag };
875
1105
  }
876
1106
  exports2.Option = Option2;
@@ -970,7 +1200,7 @@ var require_command = __commonJS({
970
1200
  var process2 = require("process");
971
1201
  var { Argument: Argument2, humanReadableArgName } = require_argument();
972
1202
  var { CommanderError: CommanderError2 } = require_error();
973
- var { Help: Help2 } = require_help();
1203
+ var { Help: Help2, stripColor } = require_help();
974
1204
  var { Option: Option2, DualOptions } = require_option();
975
1205
  var { suggestSimilar } = require_suggestSimilar();
976
1206
  var Command2 = class _Command extends EventEmitter2 {
@@ -985,7 +1215,7 @@ var require_command = __commonJS({
985
1215
  this.options = [];
986
1216
  this.parent = null;
987
1217
  this._allowUnknownOption = false;
988
- this._allowExcessArguments = true;
1218
+ this._allowExcessArguments = false;
989
1219
  this.registeredArguments = [];
990
1220
  this._args = this.registeredArguments;
991
1221
  this.args = [];
@@ -1012,18 +1242,25 @@ var require_command = __commonJS({
1012
1242
  this._lifeCycleHooks = {};
1013
1243
  this._showHelpAfterError = false;
1014
1244
  this._showSuggestionAfterError = true;
1245
+ this._savedState = null;
1015
1246
  this._outputConfiguration = {
1016
1247
  writeOut: (str) => process2.stdout.write(str),
1017
1248
  writeErr: (str) => process2.stderr.write(str),
1249
+ outputError: (str, write) => write(str),
1018
1250
  getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : void 0,
1019
1251
  getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : void 0,
1020
- outputError: (str, write) => write(str)
1252
+ getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
1253
+ getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
1254
+ stripColor: (str) => stripColor(str)
1021
1255
  };
1022
1256
  this._hidden = false;
1023
1257
  this._helpOption = void 0;
1024
1258
  this._addImplicitHelpCommand = void 0;
1025
1259
  this._helpCommand = void 0;
1026
1260
  this._helpConfiguration = {};
1261
+ this._helpGroupHeading = void 0;
1262
+ this._defaultCommandGroup = void 0;
1263
+ this._defaultOptionGroup = void 0;
1027
1264
  }
1028
1265
  /**
1029
1266
  * Copy settings that are useful to have in common across root command and subcommands.
@@ -1145,21 +1382,28 @@ var require_command = __commonJS({
1145
1382
  *
1146
1383
  * The configuration properties are all functions:
1147
1384
  *
1148
- * // functions to change where being written, stdout and stderr
1385
+ * // change how output being written, defaults to stdout and stderr
1149
1386
  * writeOut(str)
1150
1387
  * writeErr(str)
1151
- * // matching functions to specify width for wrapping help
1388
+ * // change how output being written for errors, defaults to writeErr
1389
+ * outputError(str, write) // used for displaying errors and not used for displaying help
1390
+ * // specify width for wrapping help
1152
1391
  * getOutHelpWidth()
1153
1392
  * getErrHelpWidth()
1154
- * // functions based on what is being written out
1155
- * outputError(str, write) // used for displaying errors, and not used for displaying help
1393
+ * // color support, currently only used with Help
1394
+ * getOutHasColors()
1395
+ * getErrHasColors()
1396
+ * stripColor() // used to remove ANSI escape codes if output does not have colors
1156
1397
  *
1157
1398
  * @param {object} [configuration] - configuration options
1158
1399
  * @return {(Command | object)} `this` command for chaining, or stored configuration
1159
1400
  */
1160
1401
  configureOutput(configuration) {
1161
1402
  if (configuration === void 0) return this._outputConfiguration;
1162
- Object.assign(this._outputConfiguration, configuration);
1403
+ this._outputConfiguration = {
1404
+ ...this._outputConfiguration,
1405
+ ...configuration
1406
+ };
1163
1407
  return this;
1164
1408
  }
1165
1409
  /**
@@ -1230,16 +1474,16 @@ var require_command = __commonJS({
1230
1474
  *
1231
1475
  * @param {string} name
1232
1476
  * @param {string} [description]
1233
- * @param {(Function|*)} [fn] - custom argument processing function
1477
+ * @param {(Function|*)} [parseArg] - custom argument processing function or default value
1234
1478
  * @param {*} [defaultValue]
1235
1479
  * @return {Command} `this` command for chaining
1236
1480
  */
1237
- argument(name, description, fn, defaultValue) {
1481
+ argument(name, description, parseArg, defaultValue) {
1238
1482
  const argument = this.createArgument(name, description);
1239
- if (typeof fn === "function") {
1240
- argument.default(defaultValue).argParser(fn);
1483
+ if (typeof parseArg === "function") {
1484
+ argument.default(defaultValue).argParser(parseArg);
1241
1485
  } else {
1242
- argument.default(fn);
1486
+ argument.default(parseArg);
1243
1487
  }
1244
1488
  this.addArgument(argument);
1245
1489
  return this;
@@ -1269,7 +1513,7 @@ var require_command = __commonJS({
1269
1513
  */
1270
1514
  addArgument(argument) {
1271
1515
  const previousArgument = this.registeredArguments.slice(-1)[0];
1272
- if (previousArgument && previousArgument.variadic) {
1516
+ if (previousArgument?.variadic) {
1273
1517
  throw new Error(
1274
1518
  `only the last argument can be variadic '${previousArgument.name()}'`
1275
1519
  );
@@ -1298,10 +1542,13 @@ var require_command = __commonJS({
1298
1542
  helpCommand(enableOrNameAndArgs, description) {
1299
1543
  if (typeof enableOrNameAndArgs === "boolean") {
1300
1544
  this._addImplicitHelpCommand = enableOrNameAndArgs;
1545
+ if (enableOrNameAndArgs && this._defaultCommandGroup) {
1546
+ this._initCommandGroup(this._getHelpCommand());
1547
+ }
1301
1548
  return this;
1302
1549
  }
1303
- enableOrNameAndArgs = enableOrNameAndArgs ?? "help [command]";
1304
- const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
1550
+ const nameAndArgs = enableOrNameAndArgs ?? "help [command]";
1551
+ const [, helpName, helpArgs] = nameAndArgs.match(/([^ ]+) *(.*)/);
1305
1552
  const helpDescription = description ?? "display help for command";
1306
1553
  const helpCommand = this.createCommand(helpName);
1307
1554
  helpCommand.helpOption(false);
@@ -1309,6 +1556,7 @@ var require_command = __commonJS({
1309
1556
  if (helpDescription) helpCommand.description(helpDescription);
1310
1557
  this._addImplicitHelpCommand = true;
1311
1558
  this._helpCommand = helpCommand;
1559
+ if (enableOrNameAndArgs || description) this._initCommandGroup(helpCommand);
1312
1560
  return this;
1313
1561
  }
1314
1562
  /**
@@ -1325,6 +1573,7 @@ var require_command = __commonJS({
1325
1573
  }
1326
1574
  this._addImplicitHelpCommand = true;
1327
1575
  this._helpCommand = helpCommand;
1576
+ this._initCommandGroup(helpCommand);
1328
1577
  return this;
1329
1578
  }
1330
1579
  /**
@@ -1473,6 +1722,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1473
1722
  throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
1474
1723
  - already used by option '${matchingOption.flags}'`);
1475
1724
  }
1725
+ this._initOptionGroup(option);
1476
1726
  this.options.push(option);
1477
1727
  }
1478
1728
  /**
@@ -1496,6 +1746,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1496
1746
  `cannot add command '${newCmd}' as already have command '${existingCmd}'`
1497
1747
  );
1498
1748
  }
1749
+ this._initCommandGroup(command);
1499
1750
  this.commands.push(command);
1500
1751
  }
1501
1752
  /**
@@ -1528,7 +1779,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1528
1779
  if (val !== null && option.parseArg) {
1529
1780
  val = this._callParseArg(option, val, oldValue, invalidValueMessage);
1530
1781
  } else if (val !== null && option.variadic) {
1531
- val = option._concatValue(val, oldValue);
1782
+ val = option._collectValue(val, oldValue);
1532
1783
  }
1533
1784
  if (val == null) {
1534
1785
  if (option.negate) {
@@ -1592,7 +1843,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1592
1843
  * @example
1593
1844
  * program
1594
1845
  * .option('-p, --pepper', 'add pepper')
1595
- * .option('-p, --pizza-type <TYPE>', 'type of pizza') // required option-argument
1846
+ * .option('--pt, --pizza-type <TYPE>', 'type of pizza') // required option-argument
1596
1847
  * .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
1597
1848
  * .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
1598
1849
  *
@@ -1859,6 +2110,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1859
2110
  * @return {Command} `this` command for chaining
1860
2111
  */
1861
2112
  parse(argv, parseOptions) {
2113
+ this._prepareForParse();
1862
2114
  const userArgs = this._prepareUserArgs(argv, parseOptions);
1863
2115
  this._parseCommand([], userArgs);
1864
2116
  return this;
@@ -1884,10 +2136,68 @@ Expecting one of '${allowedValues.join("', '")}'`);
1884
2136
  * @return {Promise}
1885
2137
  */
1886
2138
  async parseAsync(argv, parseOptions) {
2139
+ this._prepareForParse();
1887
2140
  const userArgs = this._prepareUserArgs(argv, parseOptions);
1888
2141
  await this._parseCommand([], userArgs);
1889
2142
  return this;
1890
2143
  }
2144
+ _prepareForParse() {
2145
+ if (this._savedState === null) {
2146
+ this.saveStateBeforeParse();
2147
+ } else {
2148
+ this.restoreStateBeforeParse();
2149
+ }
2150
+ }
2151
+ /**
2152
+ * Called the first time parse is called to save state and allow a restore before subsequent calls to parse.
2153
+ * Not usually called directly, but available for subclasses to save their custom state.
2154
+ *
2155
+ * This is called in a lazy way. Only commands used in parsing chain will have state saved.
2156
+ */
2157
+ saveStateBeforeParse() {
2158
+ this._savedState = {
2159
+ // name is stable if supplied by author, but may be unspecified for root command and deduced during parsing
2160
+ _name: this._name,
2161
+ // option values before parse have default values (including false for negated options)
2162
+ // shallow clones
2163
+ _optionValues: { ...this._optionValues },
2164
+ _optionValueSources: { ...this._optionValueSources }
2165
+ };
2166
+ }
2167
+ /**
2168
+ * Restore state before parse for calls after the first.
2169
+ * Not usually called directly, but available for subclasses to save their custom state.
2170
+ *
2171
+ * This is called in a lazy way. Only commands used in parsing chain will have state restored.
2172
+ */
2173
+ restoreStateBeforeParse() {
2174
+ if (this._storeOptionsAsProperties)
2175
+ throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
2176
+ - either make a new Command for each call to parse, or stop storing options as properties`);
2177
+ this._name = this._savedState._name;
2178
+ this._scriptPath = null;
2179
+ this.rawArgs = [];
2180
+ this._optionValues = { ...this._savedState._optionValues };
2181
+ this._optionValueSources = { ...this._savedState._optionValueSources };
2182
+ this.args = [];
2183
+ this.processedArgs = [];
2184
+ }
2185
+ /**
2186
+ * Throw if expected executable is missing. Add lots of help for author.
2187
+ *
2188
+ * @param {string} executableFile
2189
+ * @param {string} executableDir
2190
+ * @param {string} subcommandName
2191
+ */
2192
+ _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
2193
+ if (fs3.existsSync(executableFile)) return;
2194
+ const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
2195
+ const executableMissing = `'${executableFile}' does not exist
2196
+ - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
2197
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
2198
+ - ${executableDirMessage}`;
2199
+ throw new Error(executableMissing);
2200
+ }
1891
2201
  /**
1892
2202
  * Execute a sub-command executable.
1893
2203
  *
@@ -1915,7 +2225,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1915
2225
  let resolvedScriptPath;
1916
2226
  try {
1917
2227
  resolvedScriptPath = fs3.realpathSync(this._scriptPath);
1918
- } catch (err) {
2228
+ } catch {
1919
2229
  resolvedScriptPath = this._scriptPath;
1920
2230
  }
1921
2231
  executableDir = path5.resolve(
@@ -1950,6 +2260,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1950
2260
  proc2 = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1951
2261
  }
1952
2262
  } else {
2263
+ this._checkForMissingExecutable(
2264
+ executableFile,
2265
+ executableDir,
2266
+ subcommand._name
2267
+ );
1953
2268
  args.unshift(executableFile);
1954
2269
  args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1955
2270
  proc2 = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
@@ -1981,12 +2296,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1981
2296
  });
1982
2297
  proc2.on("error", (err) => {
1983
2298
  if (err.code === "ENOENT") {
1984
- const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
1985
- const executableMissing = `'${executableFile}' does not exist
1986
- - if '${subcommand._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1987
- - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1988
- - ${executableDirMessage}`;
1989
- throw new Error(executableMissing);
2299
+ this._checkForMissingExecutable(
2300
+ executableFile,
2301
+ executableDir,
2302
+ subcommand._name
2303
+ );
1990
2304
  } else if (err.code === "EACCES") {
1991
2305
  throw new Error(`'${executableFile}' not executable`);
1992
2306
  }
@@ -2010,6 +2324,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2010
2324
  _dispatchSubcommand(commandName, operands, unknown) {
2011
2325
  const subCommand = this._findCommand(commandName);
2012
2326
  if (!subCommand) this.help({ error: true });
2327
+ subCommand._prepareForParse();
2013
2328
  let promiseChain;
2014
2329
  promiseChain = this._chainOrCallSubCommandHook(
2015
2330
  promiseChain,
@@ -2116,7 +2431,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2116
2431
  * @private
2117
2432
  */
2118
2433
  _chainOrCall(promise, fn) {
2119
- if (promise && promise.then && typeof promise.then === "function") {
2434
+ if (promise?.then && typeof promise.then === "function") {
2120
2435
  return promise.then(() => fn());
2121
2436
  }
2122
2437
  return fn();
@@ -2221,7 +2536,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2221
2536
  promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
2222
2537
  return promiseChain;
2223
2538
  }
2224
- if (this.parent && this.parent.listenerCount(commandEvent)) {
2539
+ if (this.parent?.listenerCount(commandEvent)) {
2225
2540
  checkForUnknownOptions();
2226
2541
  this._processArguments();
2227
2542
  this.parent.emit(commandEvent, operands, unknown);
@@ -2322,6 +2637,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
2322
2637
  * Parse options from `argv` removing known options,
2323
2638
  * and return argv split into operands and unknown arguments.
2324
2639
  *
2640
+ * Side effects: modifies command by storing options. Does not reset state if called again.
2641
+ *
2325
2642
  * Examples:
2326
2643
  *
2327
2644
  * argv => operands, unknown
@@ -2330,26 +2647,34 @@ Expecting one of '${allowedValues.join("', '")}'`);
2330
2647
  * sub --unknown uuu op => [sub], [--unknown uuu op]
2331
2648
  * sub -- --unknown uuu op => [sub --unknown uuu op], []
2332
2649
  *
2333
- * @param {string[]} argv
2650
+ * @param {string[]} args
2334
2651
  * @return {{operands: string[], unknown: string[]}}
2335
2652
  */
2336
- parseOptions(argv) {
2653
+ parseOptions(args) {
2337
2654
  const operands = [];
2338
2655
  const unknown = [];
2339
2656
  let dest = operands;
2340
- const args = argv.slice();
2341
2657
  function maybeOption(arg) {
2342
2658
  return arg.length > 1 && arg[0] === "-";
2343
2659
  }
2660
+ const negativeNumberArg = (arg) => {
2661
+ if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg)) return false;
2662
+ return !this._getCommandAndAncestors().some(
2663
+ (cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short))
2664
+ );
2665
+ };
2344
2666
  let activeVariadicOption = null;
2345
- while (args.length) {
2346
- const arg = args.shift();
2667
+ let activeGroup = null;
2668
+ let i = 0;
2669
+ while (i < args.length || activeGroup) {
2670
+ const arg = activeGroup ?? args[i++];
2671
+ activeGroup = null;
2347
2672
  if (arg === "--") {
2348
2673
  if (dest === unknown) dest.push(arg);
2349
- dest.push(...args);
2674
+ dest.push(...args.slice(i));
2350
2675
  break;
2351
2676
  }
2352
- if (activeVariadicOption && !maybeOption(arg)) {
2677
+ if (activeVariadicOption && (!maybeOption(arg) || negativeNumberArg(arg))) {
2353
2678
  this.emit(`option:${activeVariadicOption.name()}`, arg);
2354
2679
  continue;
2355
2680
  }
@@ -2358,13 +2683,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
2358
2683
  const option = this._findOption(arg);
2359
2684
  if (option) {
2360
2685
  if (option.required) {
2361
- const value = args.shift();
2686
+ const value = args[i++];
2362
2687
  if (value === void 0) this.optionMissingArgument(option);
2363
2688
  this.emit(`option:${option.name()}`, value);
2364
2689
  } else if (option.optional) {
2365
2690
  let value = null;
2366
- if (args.length > 0 && !maybeOption(args[0])) {
2367
- value = args.shift();
2691
+ if (i < args.length && (!maybeOption(args[i]) || negativeNumberArg(args[i]))) {
2692
+ value = args[i++];
2368
2693
  }
2369
2694
  this.emit(`option:${option.name()}`, value);
2370
2695
  } else {
@@ -2381,7 +2706,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2381
2706
  this.emit(`option:${option.name()}`, arg.slice(2));
2382
2707
  } else {
2383
2708
  this.emit(`option:${option.name()}`);
2384
- args.unshift(`-${arg.slice(2)}`);
2709
+ activeGroup = `-${arg.slice(2)}`;
2385
2710
  }
2386
2711
  continue;
2387
2712
  }
@@ -2394,27 +2719,24 @@ Expecting one of '${allowedValues.join("', '")}'`);
2394
2719
  continue;
2395
2720
  }
2396
2721
  }
2397
- if (maybeOption(arg)) {
2722
+ if (dest === operands && maybeOption(arg) && !(this.commands.length === 0 && negativeNumberArg(arg))) {
2398
2723
  dest = unknown;
2399
2724
  }
2400
2725
  if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
2401
2726
  if (this._findCommand(arg)) {
2402
2727
  operands.push(arg);
2403
- if (args.length > 0) unknown.push(...args);
2728
+ unknown.push(...args.slice(i));
2404
2729
  break;
2405
2730
  } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
2406
- operands.push(arg);
2407
- if (args.length > 0) operands.push(...args);
2731
+ operands.push(arg, ...args.slice(i));
2408
2732
  break;
2409
2733
  } else if (this._defaultCommandName) {
2410
- unknown.push(arg);
2411
- if (args.length > 0) unknown.push(...args);
2734
+ unknown.push(arg, ...args.slice(i));
2412
2735
  break;
2413
2736
  }
2414
2737
  }
2415
2738
  if (this._passThroughOptions) {
2416
- dest.push(arg);
2417
- if (args.length > 0) dest.push(...args);
2739
+ dest.push(arg, ...args.slice(i));
2418
2740
  break;
2419
2741
  }
2420
2742
  dest.push(arg);
@@ -2766,6 +3088,69 @@ Expecting one of '${allowedValues.join("', '")}'`);
2766
3088
  this._name = str;
2767
3089
  return this;
2768
3090
  }
3091
+ /**
3092
+ * Set/get the help group heading for this subcommand in parent command's help.
3093
+ *
3094
+ * @param {string} [heading]
3095
+ * @return {Command | string}
3096
+ */
3097
+ helpGroup(heading) {
3098
+ if (heading === void 0) return this._helpGroupHeading ?? "";
3099
+ this._helpGroupHeading = heading;
3100
+ return this;
3101
+ }
3102
+ /**
3103
+ * Set/get the default help group heading for subcommands added to this command.
3104
+ * (This does not override a group set directly on the subcommand using .helpGroup().)
3105
+ *
3106
+ * @example
3107
+ * program.commandsGroup('Development Commands:);
3108
+ * program.command('watch')...
3109
+ * program.command('lint')...
3110
+ * ...
3111
+ *
3112
+ * @param {string} [heading]
3113
+ * @returns {Command | string}
3114
+ */
3115
+ commandsGroup(heading) {
3116
+ if (heading === void 0) return this._defaultCommandGroup ?? "";
3117
+ this._defaultCommandGroup = heading;
3118
+ return this;
3119
+ }
3120
+ /**
3121
+ * Set/get the default help group heading for options added to this command.
3122
+ * (This does not override a group set directly on the option using .helpGroup().)
3123
+ *
3124
+ * @example
3125
+ * program
3126
+ * .optionsGroup('Development Options:')
3127
+ * .option('-d, --debug', 'output extra debugging')
3128
+ * .option('-p, --profile', 'output profiling information')
3129
+ *
3130
+ * @param {string} [heading]
3131
+ * @returns {Command | string}
3132
+ */
3133
+ optionsGroup(heading) {
3134
+ if (heading === void 0) return this._defaultOptionGroup ?? "";
3135
+ this._defaultOptionGroup = heading;
3136
+ return this;
3137
+ }
3138
+ /**
3139
+ * @param {Option} option
3140
+ * @private
3141
+ */
3142
+ _initOptionGroup(option) {
3143
+ if (this._defaultOptionGroup && !option.helpGroupHeading)
3144
+ option.helpGroup(this._defaultOptionGroup);
3145
+ }
3146
+ /**
3147
+ * @param {Command} cmd
3148
+ * @private
3149
+ */
3150
+ _initCommandGroup(cmd) {
3151
+ if (this._defaultCommandGroup && !cmd.helpGroup())
3152
+ cmd.helpGroup(this._defaultCommandGroup);
3153
+ }
2769
3154
  /**
2770
3155
  * Set the name of the command from script filename, such as process.argv[1],
2771
3156
  * or require.main.filename, or __filename.
@@ -2806,26 +3191,47 @@ Expecting one of '${allowedValues.join("', '")}'`);
2806
3191
  */
2807
3192
  helpInformation(contextOptions) {
2808
3193
  const helper = this.createHelp();
2809
- if (helper.helpWidth === void 0) {
2810
- helper.helpWidth = contextOptions && contextOptions.error ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
2811
- }
2812
- return helper.formatHelp(this, helper);
3194
+ const context = this._getOutputContext(contextOptions);
3195
+ helper.prepareContext({
3196
+ error: context.error,
3197
+ helpWidth: context.helpWidth,
3198
+ outputHasColors: context.hasColors
3199
+ });
3200
+ const text = helper.formatHelp(this, helper);
3201
+ if (context.hasColors) return text;
3202
+ return this._outputConfiguration.stripColor(text);
2813
3203
  }
2814
3204
  /**
3205
+ * @typedef HelpContext
3206
+ * @type {object}
3207
+ * @property {boolean} error
3208
+ * @property {number} helpWidth
3209
+ * @property {boolean} hasColors
3210
+ * @property {function} write - includes stripColor if needed
3211
+ *
3212
+ * @returns {HelpContext}
2815
3213
  * @private
2816
3214
  */
2817
- _getHelpContext(contextOptions) {
3215
+ _getOutputContext(contextOptions) {
2818
3216
  contextOptions = contextOptions || {};
2819
- const context = { error: !!contextOptions.error };
2820
- let write;
2821
- if (context.error) {
2822
- write = (arg) => this._outputConfiguration.writeErr(arg);
3217
+ const error = !!contextOptions.error;
3218
+ let baseWrite;
3219
+ let hasColors;
3220
+ let helpWidth;
3221
+ if (error) {
3222
+ baseWrite = (str) => this._outputConfiguration.writeErr(str);
3223
+ hasColors = this._outputConfiguration.getErrHasColors();
3224
+ helpWidth = this._outputConfiguration.getErrHelpWidth();
2823
3225
  } else {
2824
- write = (arg) => this._outputConfiguration.writeOut(arg);
3226
+ baseWrite = (str) => this._outputConfiguration.writeOut(str);
3227
+ hasColors = this._outputConfiguration.getOutHasColors();
3228
+ helpWidth = this._outputConfiguration.getOutHelpWidth();
2825
3229
  }
2826
- context.write = contextOptions.write || write;
2827
- context.command = this;
2828
- return context;
3230
+ const write = (str) => {
3231
+ if (!hasColors) str = this._outputConfiguration.stripColor(str);
3232
+ return baseWrite(str);
3233
+ };
3234
+ return { error, write, hasColors, helpWidth };
2829
3235
  }
2830
3236
  /**
2831
3237
  * Output help information for this command.
@@ -2840,23 +3246,28 @@ Expecting one of '${allowedValues.join("', '")}'`);
2840
3246
  deprecatedCallback = contextOptions;
2841
3247
  contextOptions = void 0;
2842
3248
  }
2843
- const context = this._getHelpContext(contextOptions);
2844
- this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", context));
2845
- this.emit("beforeHelp", context);
2846
- let helpInformation = this.helpInformation(context);
3249
+ const outputContext = this._getOutputContext(contextOptions);
3250
+ const eventContext = {
3251
+ error: outputContext.error,
3252
+ write: outputContext.write,
3253
+ command: this
3254
+ };
3255
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
3256
+ this.emit("beforeHelp", eventContext);
3257
+ let helpInformation = this.helpInformation({ error: outputContext.error });
2847
3258
  if (deprecatedCallback) {
2848
3259
  helpInformation = deprecatedCallback(helpInformation);
2849
3260
  if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
2850
3261
  throw new Error("outputHelp callback must return a string or a Buffer");
2851
3262
  }
2852
3263
  }
2853
- context.write(helpInformation);
3264
+ outputContext.write(helpInformation);
2854
3265
  if (this._getHelpOption()?.long) {
2855
3266
  this.emit(this._getHelpOption().long);
2856
3267
  }
2857
- this.emit("afterHelp", context);
3268
+ this.emit("afterHelp", eventContext);
2858
3269
  this._getCommandAndAncestors().forEach(
2859
- (command) => command.emit("afterAllHelp", context)
3270
+ (command) => command.emit("afterAllHelp", eventContext)
2860
3271
  );
2861
3272
  }
2862
3273
  /**
@@ -2874,15 +3285,20 @@ Expecting one of '${allowedValues.join("', '")}'`);
2874
3285
  helpOption(flags, description) {
2875
3286
  if (typeof flags === "boolean") {
2876
3287
  if (flags) {
2877
- this._helpOption = this._helpOption ?? void 0;
3288
+ if (this._helpOption === null) this._helpOption = void 0;
3289
+ if (this._defaultOptionGroup) {
3290
+ this._initOptionGroup(this._getHelpOption());
3291
+ }
2878
3292
  } else {
2879
3293
  this._helpOption = null;
2880
3294
  }
2881
3295
  return this;
2882
3296
  }
2883
- flags = flags ?? "-h, --help";
2884
- description = description ?? "display help for command";
2885
- this._helpOption = this.createOption(flags, description);
3297
+ this._helpOption = this.createOption(
3298
+ flags ?? "-h, --help",
3299
+ description ?? "display help for command"
3300
+ );
3301
+ if (flags || description) this._initOptionGroup(this._helpOption);
2886
3302
  return this;
2887
3303
  }
2888
3304
  /**
@@ -2907,6 +3323,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2907
3323
  */
2908
3324
  addHelpOption(option) {
2909
3325
  this._helpOption = option;
3326
+ this._initOptionGroup(option);
2910
3327
  return this;
2911
3328
  }
2912
3329
  /**
@@ -2918,12 +3335,20 @@ Expecting one of '${allowedValues.join("', '")}'`);
2918
3335
  */
2919
3336
  help(contextOptions) {
2920
3337
  this.outputHelp(contextOptions);
2921
- let exitCode = process2.exitCode || 0;
3338
+ let exitCode = Number(process2.exitCode ?? 0);
2922
3339
  if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
2923
3340
  exitCode = 1;
2924
3341
  }
2925
3342
  this._exit(exitCode, "commander.help", "(outputHelp)");
2926
3343
  }
3344
+ /**
3345
+ * // Do a little typing to coordinate emit and listener for the help text events.
3346
+ * @typedef HelpTextEventContext
3347
+ * @type {object}
3348
+ * @property {boolean} error
3349
+ * @property {Command} command
3350
+ * @property {function} write
3351
+ */
2927
3352
  /**
2928
3353
  * Add additional text to be displayed with the built-in help.
2929
3354
  *
@@ -2999,7 +3424,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
2999
3424
  return arg;
3000
3425
  });
3001
3426
  }
3427
+ function useColor() {
3428
+ if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
3429
+ return false;
3430
+ if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== void 0)
3431
+ return true;
3432
+ return void 0;
3433
+ }
3002
3434
  exports2.Command = Command2;
3435
+ exports2.useColor = useColor;
3003
3436
  }
3004
3437
  });
3005
3438
 
@@ -3026,215 +3459,6 @@ var require_commander = __commonJS({
3026
3459
  }
3027
3460
  });
3028
3461
 
3029
- // node_modules/balanced-match/index.js
3030
- var require_balanced_match = __commonJS({
3031
- "node_modules/balanced-match/index.js"(exports2, module2) {
3032
- "use strict";
3033
- module2.exports = balanced;
3034
- function balanced(a, b, str) {
3035
- if (a instanceof RegExp) a = maybeMatch(a, str);
3036
- if (b instanceof RegExp) b = maybeMatch(b, str);
3037
- var r = range(a, b, str);
3038
- return r && {
3039
- start: r[0],
3040
- end: r[1],
3041
- pre: str.slice(0, r[0]),
3042
- body: str.slice(r[0] + a.length, r[1]),
3043
- post: str.slice(r[1] + b.length)
3044
- };
3045
- }
3046
- function maybeMatch(reg, str) {
3047
- var m = str.match(reg);
3048
- return m ? m[0] : null;
3049
- }
3050
- balanced.range = range;
3051
- function range(a, b, str) {
3052
- var begs, beg, left, right, result;
3053
- var ai = str.indexOf(a);
3054
- var bi = str.indexOf(b, ai + 1);
3055
- var i = ai;
3056
- if (ai >= 0 && bi > 0) {
3057
- if (a === b) {
3058
- return [ai, bi];
3059
- }
3060
- begs = [];
3061
- left = str.length;
3062
- while (i >= 0 && !result) {
3063
- if (i == ai) {
3064
- begs.push(i);
3065
- ai = str.indexOf(a, i + 1);
3066
- } else if (begs.length == 1) {
3067
- result = [begs.pop(), bi];
3068
- } else {
3069
- beg = begs.pop();
3070
- if (beg < left) {
3071
- left = beg;
3072
- right = bi;
3073
- }
3074
- bi = str.indexOf(b, i + 1);
3075
- }
3076
- i = ai < bi && ai >= 0 ? ai : bi;
3077
- }
3078
- if (begs.length) {
3079
- result = [left, right];
3080
- }
3081
- }
3082
- return result;
3083
- }
3084
- }
3085
- });
3086
-
3087
- // node_modules/brace-expansion/index.js
3088
- var require_brace_expansion = __commonJS({
3089
- "node_modules/brace-expansion/index.js"(exports2, module2) {
3090
- "use strict";
3091
- var balanced = require_balanced_match();
3092
- module2.exports = expandTop;
3093
- var escSlash = "\0SLASH" + Math.random() + "\0";
3094
- var escOpen = "\0OPEN" + Math.random() + "\0";
3095
- var escClose = "\0CLOSE" + Math.random() + "\0";
3096
- var escComma = "\0COMMA" + Math.random() + "\0";
3097
- var escPeriod = "\0PERIOD" + Math.random() + "\0";
3098
- function numeric(str) {
3099
- return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
3100
- }
3101
- function escapeBraces(str) {
3102
- return str.split("\\\\").join(escSlash).split("\\{").join(escOpen).split("\\}").join(escClose).split("\\,").join(escComma).split("\\.").join(escPeriod);
3103
- }
3104
- function unescapeBraces(str) {
3105
- return str.split(escSlash).join("\\").split(escOpen).join("{").split(escClose).join("}").split(escComma).join(",").split(escPeriod).join(".");
3106
- }
3107
- function parseCommaParts(str) {
3108
- if (!str)
3109
- return [""];
3110
- var parts = [];
3111
- var m = balanced("{", "}", str);
3112
- if (!m)
3113
- return str.split(",");
3114
- var pre = m.pre;
3115
- var body = m.body;
3116
- var post = m.post;
3117
- var p = pre.split(",");
3118
- p[p.length - 1] += "{" + body + "}";
3119
- var postParts = parseCommaParts(post);
3120
- if (post.length) {
3121
- p[p.length - 1] += postParts.shift();
3122
- p.push.apply(p, postParts);
3123
- }
3124
- parts.push.apply(parts, p);
3125
- return parts;
3126
- }
3127
- function expandTop(str) {
3128
- if (!str)
3129
- return [];
3130
- if (str.substr(0, 2) === "{}") {
3131
- str = "\\{\\}" + str.substr(2);
3132
- }
3133
- return expand2(escapeBraces(str), true).map(unescapeBraces);
3134
- }
3135
- function embrace(str) {
3136
- return "{" + str + "}";
3137
- }
3138
- function isPadded(el) {
3139
- return /^-?0\d/.test(el);
3140
- }
3141
- function lte(i, y) {
3142
- return i <= y;
3143
- }
3144
- function gte(i, y) {
3145
- return i >= y;
3146
- }
3147
- function expand2(str, isTop) {
3148
- var expansions = [];
3149
- var m = balanced("{", "}", str);
3150
- if (!m) return [str];
3151
- var pre = m.pre;
3152
- var post = m.post.length ? expand2(m.post, false) : [""];
3153
- if (/\$$/.test(m.pre)) {
3154
- for (var k = 0; k < post.length; k++) {
3155
- var expansion = pre + "{" + m.body + "}" + post[k];
3156
- expansions.push(expansion);
3157
- }
3158
- } else {
3159
- var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
3160
- var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
3161
- var isSequence = isNumericSequence || isAlphaSequence;
3162
- var isOptions = m.body.indexOf(",") >= 0;
3163
- if (!isSequence && !isOptions) {
3164
- if (m.post.match(/,(?!,).*\}/)) {
3165
- str = m.pre + "{" + m.body + escClose + m.post;
3166
- return expand2(str);
3167
- }
3168
- return [str];
3169
- }
3170
- var n;
3171
- if (isSequence) {
3172
- n = m.body.split(/\.\./);
3173
- } else {
3174
- n = parseCommaParts(m.body);
3175
- if (n.length === 1) {
3176
- n = expand2(n[0], false).map(embrace);
3177
- if (n.length === 1) {
3178
- return post.map(function(p) {
3179
- return m.pre + n[0] + p;
3180
- });
3181
- }
3182
- }
3183
- }
3184
- var N;
3185
- if (isSequence) {
3186
- var x = numeric(n[0]);
3187
- var y = numeric(n[1]);
3188
- var width = Math.max(n[0].length, n[1].length);
3189
- var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
3190
- var test = lte;
3191
- var reverse = y < x;
3192
- if (reverse) {
3193
- incr *= -1;
3194
- test = gte;
3195
- }
3196
- var pad = n.some(isPadded);
3197
- N = [];
3198
- for (var i = x; test(i, y); i += incr) {
3199
- var c;
3200
- if (isAlphaSequence) {
3201
- c = String.fromCharCode(i);
3202
- if (c === "\\")
3203
- c = "";
3204
- } else {
3205
- c = String(i);
3206
- if (pad) {
3207
- var need = width - c.length;
3208
- if (need > 0) {
3209
- var z = new Array(need + 1).join("0");
3210
- if (i < 0)
3211
- c = "-" + z + c.slice(1);
3212
- else
3213
- c = z + c;
3214
- }
3215
- }
3216
- }
3217
- N.push(c);
3218
- }
3219
- } else {
3220
- N = [];
3221
- for (var j = 0; j < n.length; j++) {
3222
- N.push.apply(N, expand2(n[j], false));
3223
- }
3224
- }
3225
- for (var j = 0; j < N.length; j++) {
3226
- for (var k = 0; k < post.length; k++) {
3227
- var expansion = pre + N[j] + post[k];
3228
- if (!isTop || isSequence || expansion)
3229
- expansions.push(expansion);
3230
- }
3231
- }
3232
- }
3233
- return expansions;
3234
- }
3235
- }
3236
- });
3237
-
3238
3462
  // node_modules/picocolors/picocolors.js
3239
3463
  var require_picocolors = __commonJS({
3240
3464
  "node_modules/picocolors/picocolors.js"(exports2, module2) {
@@ -8109,7 +8333,7 @@ var require_compose_scalar = __commonJS({
8109
8333
  var resolveBlockScalar = require_resolve_block_scalar();
8110
8334
  var resolveFlowScalar = require_resolve_flow_scalar();
8111
8335
  function composeScalar(ctx, token, tagToken, onError) {
8112
- const { value, type, comment, range } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
8336
+ const { value, type, comment, range: range2 } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
8113
8337
  const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null;
8114
8338
  let tag;
8115
8339
  if (ctx.options.stringKeys && ctx.atKey) {
@@ -8129,7 +8353,7 @@ var require_compose_scalar = __commonJS({
8129
8353
  onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
8130
8354
  scalar = new Scalar.Scalar(value);
8131
8355
  }
8132
- scalar.range = range;
8356
+ scalar.range = range2;
8133
8357
  scalar.source = value;
8134
8358
  if (type)
8135
8359
  scalar.type = type;
@@ -17378,8 +17602,216 @@ var {
17378
17602
  var fs = __toESM(require("fs"));
17379
17603
  var path3 = __toESM(require("path"));
17380
17604
 
17381
- // node_modules/minimatch/dist/esm/index.js
17382
- var import_brace_expansion = __toESM(require_brace_expansion(), 1);
17605
+ // node_modules/@isaacs/balanced-match/dist/esm/index.js
17606
+ var balanced = (a, b, str) => {
17607
+ const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
17608
+ const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
17609
+ const r = ma !== null && mb != null && range(ma, mb, str);
17610
+ return r && {
17611
+ start: r[0],
17612
+ end: r[1],
17613
+ pre: str.slice(0, r[0]),
17614
+ body: str.slice(r[0] + ma.length, r[1]),
17615
+ post: str.slice(r[1] + mb.length)
17616
+ };
17617
+ };
17618
+ var maybeMatch = (reg, str) => {
17619
+ const m = str.match(reg);
17620
+ return m ? m[0] : null;
17621
+ };
17622
+ var range = (a, b, str) => {
17623
+ let begs, beg, left, right = void 0, result;
17624
+ let ai = str.indexOf(a);
17625
+ let bi = str.indexOf(b, ai + 1);
17626
+ let i = ai;
17627
+ if (ai >= 0 && bi > 0) {
17628
+ if (a === b) {
17629
+ return [ai, bi];
17630
+ }
17631
+ begs = [];
17632
+ left = str.length;
17633
+ while (i >= 0 && !result) {
17634
+ if (i === ai) {
17635
+ begs.push(i);
17636
+ ai = str.indexOf(a, i + 1);
17637
+ } else if (begs.length === 1) {
17638
+ const r = begs.pop();
17639
+ if (r !== void 0)
17640
+ result = [r, bi];
17641
+ } else {
17642
+ beg = begs.pop();
17643
+ if (beg !== void 0 && beg < left) {
17644
+ left = beg;
17645
+ right = bi;
17646
+ }
17647
+ bi = str.indexOf(b, i + 1);
17648
+ }
17649
+ i = ai < bi && ai >= 0 ? ai : bi;
17650
+ }
17651
+ if (begs.length && right !== void 0) {
17652
+ result = [left, right];
17653
+ }
17654
+ }
17655
+ return result;
17656
+ };
17657
+
17658
+ // node_modules/@isaacs/brace-expansion/dist/esm/index.js
17659
+ var escSlash = "\0SLASH" + Math.random() + "\0";
17660
+ var escOpen = "\0OPEN" + Math.random() + "\0";
17661
+ var escClose = "\0CLOSE" + Math.random() + "\0";
17662
+ var escComma = "\0COMMA" + Math.random() + "\0";
17663
+ var escPeriod = "\0PERIOD" + Math.random() + "\0";
17664
+ var escSlashPattern = new RegExp(escSlash, "g");
17665
+ var escOpenPattern = new RegExp(escOpen, "g");
17666
+ var escClosePattern = new RegExp(escClose, "g");
17667
+ var escCommaPattern = new RegExp(escComma, "g");
17668
+ var escPeriodPattern = new RegExp(escPeriod, "g");
17669
+ var slashPattern = /\\\\/g;
17670
+ var openPattern = /\\{/g;
17671
+ var closePattern = /\\}/g;
17672
+ var commaPattern = /\\,/g;
17673
+ var periodPattern = /\\./g;
17674
+ function numeric(str) {
17675
+ return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
17676
+ }
17677
+ function escapeBraces(str) {
17678
+ return str.replace(slashPattern, escSlash).replace(openPattern, escOpen).replace(closePattern, escClose).replace(commaPattern, escComma).replace(periodPattern, escPeriod);
17679
+ }
17680
+ function unescapeBraces(str) {
17681
+ return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, ".");
17682
+ }
17683
+ function parseCommaParts(str) {
17684
+ if (!str) {
17685
+ return [""];
17686
+ }
17687
+ const parts = [];
17688
+ const m = balanced("{", "}", str);
17689
+ if (!m) {
17690
+ return str.split(",");
17691
+ }
17692
+ const { pre, body, post } = m;
17693
+ const p = pre.split(",");
17694
+ p[p.length - 1] += "{" + body + "}";
17695
+ const postParts = parseCommaParts(post);
17696
+ if (post.length) {
17697
+ ;
17698
+ p[p.length - 1] += postParts.shift();
17699
+ p.push.apply(p, postParts);
17700
+ }
17701
+ parts.push.apply(parts, p);
17702
+ return parts;
17703
+ }
17704
+ function expand(str) {
17705
+ if (!str) {
17706
+ return [];
17707
+ }
17708
+ if (str.slice(0, 2) === "{}") {
17709
+ str = "\\{\\}" + str.slice(2);
17710
+ }
17711
+ return expand_(escapeBraces(str), true).map(unescapeBraces);
17712
+ }
17713
+ function embrace(str) {
17714
+ return "{" + str + "}";
17715
+ }
17716
+ function isPadded(el) {
17717
+ return /^-?0\d/.test(el);
17718
+ }
17719
+ function lte(i, y) {
17720
+ return i <= y;
17721
+ }
17722
+ function gte(i, y) {
17723
+ return i >= y;
17724
+ }
17725
+ function expand_(str, isTop) {
17726
+ const expansions = [];
17727
+ const m = balanced("{", "}", str);
17728
+ if (!m)
17729
+ return [str];
17730
+ const pre = m.pre;
17731
+ const post = m.post.length ? expand_(m.post, false) : [""];
17732
+ if (/\$$/.test(m.pre)) {
17733
+ for (let k = 0; k < post.length; k++) {
17734
+ const expansion = pre + "{" + m.body + "}" + post[k];
17735
+ expansions.push(expansion);
17736
+ }
17737
+ } else {
17738
+ const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
17739
+ const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
17740
+ const isSequence = isNumericSequence || isAlphaSequence;
17741
+ const isOptions = m.body.indexOf(",") >= 0;
17742
+ if (!isSequence && !isOptions) {
17743
+ if (m.post.match(/,(?!,).*\}/)) {
17744
+ str = m.pre + "{" + m.body + escClose + m.post;
17745
+ return expand_(str);
17746
+ }
17747
+ return [str];
17748
+ }
17749
+ let n;
17750
+ if (isSequence) {
17751
+ n = m.body.split(/\.\./);
17752
+ } else {
17753
+ n = parseCommaParts(m.body);
17754
+ if (n.length === 1 && n[0] !== void 0) {
17755
+ n = expand_(n[0], false).map(embrace);
17756
+ if (n.length === 1) {
17757
+ return post.map((p) => m.pre + n[0] + p);
17758
+ }
17759
+ }
17760
+ }
17761
+ let N;
17762
+ if (isSequence && n[0] !== void 0 && n[1] !== void 0) {
17763
+ const x = numeric(n[0]);
17764
+ const y = numeric(n[1]);
17765
+ const width = Math.max(n[0].length, n[1].length);
17766
+ let incr = n.length === 3 && n[2] !== void 0 ? Math.abs(numeric(n[2])) : 1;
17767
+ let test = lte;
17768
+ const reverse = y < x;
17769
+ if (reverse) {
17770
+ incr *= -1;
17771
+ test = gte;
17772
+ }
17773
+ const pad = n.some(isPadded);
17774
+ N = [];
17775
+ for (let i = x; test(i, y); i += incr) {
17776
+ let c;
17777
+ if (isAlphaSequence) {
17778
+ c = String.fromCharCode(i);
17779
+ if (c === "\\") {
17780
+ c = "";
17781
+ }
17782
+ } else {
17783
+ c = String(i);
17784
+ if (pad) {
17785
+ const need = width - c.length;
17786
+ if (need > 0) {
17787
+ const z = new Array(need + 1).join("0");
17788
+ if (i < 0) {
17789
+ c = "-" + z + c.slice(1);
17790
+ } else {
17791
+ c = z + c;
17792
+ }
17793
+ }
17794
+ }
17795
+ }
17796
+ N.push(c);
17797
+ }
17798
+ } else {
17799
+ N = [];
17800
+ for (let j = 0; j < n.length; j++) {
17801
+ N.push.apply(N, expand_(n[j], false));
17802
+ }
17803
+ }
17804
+ for (let j = 0; j < N.length; j++) {
17805
+ for (let k = 0; k < post.length; k++) {
17806
+ const expansion = pre + N[j] + post[k];
17807
+ if (!isTop || isSequence || expansion) {
17808
+ expansions.push(expansion);
17809
+ }
17810
+ }
17811
+ }
17812
+ }
17813
+ return expansions;
17814
+ }
17383
17815
 
17384
17816
  // node_modules/minimatch/dist/esm/assert-valid-pattern.js
17385
17817
  var MAX_PATTERN_LENGTH = 1024 * 64;
@@ -17502,8 +17934,11 @@ var parseClass = (glob2, position) => {
17502
17934
  };
17503
17935
 
17504
17936
  // node_modules/minimatch/dist/esm/unescape.js
17505
- var unescape2 = (s, { windowsPathsNoEscape = false } = {}) => {
17506
- return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
17937
+ var unescape2 = (s, { windowsPathsNoEscape = false, magicalBraces = true } = {}) => {
17938
+ if (magicalBraces) {
17939
+ return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
17940
+ }
17941
+ return windowsPathsNoEscape ? s.replace(/\[([^\/\\{}])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\{}])\]/g, "$1$2").replace(/\\([^\/{}])/g, "$1");
17507
17942
  };
17508
17943
 
17509
17944
  // node_modules/minimatch/dist/esm/ast.js
@@ -17857,7 +18292,7 @@ var AST = class _AST {
17857
18292
  if (this.#root === this)
17858
18293
  this.#fillNegs();
17859
18294
  if (!this.type) {
17860
- const noEmpty = this.isStart() && this.isEnd();
18295
+ const noEmpty = this.isStart() && this.isEnd() && !this.#parts.some((s) => typeof s !== "string");
17861
18296
  const src = this.#parts.map((p) => {
17862
18297
  const [re, _, hasMagic2, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
17863
18298
  this.#hasMagic = this.#hasMagic || hasMagic2;
@@ -17967,10 +18402,7 @@ var AST = class _AST {
17967
18402
  }
17968
18403
  }
17969
18404
  if (c === "*") {
17970
- if (noEmpty && glob2 === "*")
17971
- re += starNoEmpty;
17972
- else
17973
- re += star;
18405
+ re += noEmpty && glob2 === "*" ? starNoEmpty : star;
17974
18406
  hasMagic2 = true;
17975
18407
  continue;
17976
18408
  }
@@ -17986,7 +18418,10 @@ var AST = class _AST {
17986
18418
  };
17987
18419
 
17988
18420
  // node_modules/minimatch/dist/esm/escape.js
17989
- var escape2 = (s, { windowsPathsNoEscape = false } = {}) => {
18421
+ var escape2 = (s, { windowsPathsNoEscape = false, magicalBraces = false } = {}) => {
18422
+ if (magicalBraces) {
18423
+ return windowsPathsNoEscape ? s.replace(/[?*()[\]{}]/g, "[$&]") : s.replace(/[?*()[\]\\{}]/g, "\\$&");
18424
+ }
17990
18425
  return windowsPathsNoEscape ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&");
17991
18426
  };
17992
18427
 
@@ -18106,7 +18541,7 @@ var braceExpand = (pattern, options = {}) => {
18106
18541
  if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
18107
18542
  return [pattern];
18108
18543
  }
18109
- return (0, import_brace_expansion.default)(pattern);
18544
+ return expand(pattern);
18110
18545
  };
18111
18546
  minimatch.braceExpand = braceExpand;
18112
18547
  var makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
@@ -18627,16 +19062,27 @@ var Minimatch = class {
18627
19062
  pp[i] = twoStar;
18628
19063
  }
18629
19064
  } else if (next === void 0) {
18630
- pp[i - 1] = prev + "(?:\\/|" + twoStar + ")?";
19065
+ pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + ")?";
18631
19066
  } else if (next !== GLOBSTAR) {
18632
19067
  pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next;
18633
19068
  pp[i + 1] = GLOBSTAR;
18634
19069
  }
18635
19070
  });
18636
- return pp.filter((p) => p !== GLOBSTAR).join("/");
19071
+ const filtered = pp.filter((p) => p !== GLOBSTAR);
19072
+ if (this.partial && filtered.length >= 1) {
19073
+ const prefixes = [];
19074
+ for (let i = 1; i <= filtered.length; i++) {
19075
+ prefixes.push(filtered.slice(0, i).join("/"));
19076
+ }
19077
+ return "(?:" + prefixes.join("|") + ")";
19078
+ }
19079
+ return filtered.join("/");
18637
19080
  }).join("|");
18638
19081
  const [open, close] = set.length > 1 ? ["(?:", ")"] : ["", ""];
18639
19082
  re = "^" + open + re + close + "$";
19083
+ if (this.partial) {
19084
+ re = "^(?:\\/|" + open + re.slice(1, -1) + close + ")$";
19085
+ }
18640
19086
  if (this.negate)
18641
19087
  re = "^(?!" + re + ").+$";
18642
19088
  try {
@@ -18712,7 +19158,7 @@ minimatch.unescape = unescape2;
18712
19158
  var import_node_url2 = require("url");
18713
19159
 
18714
19160
  // node_modules/lru-cache/dist/esm/index.js
18715
- var perf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
19161
+ var defaultPerf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
18716
19162
  var warned = /* @__PURE__ */ new Set();
18717
19163
  var PROCESS = typeof process === "object" && !!process ? process : {};
18718
19164
  var emitWarning = (msg, type, code, fn) => {
@@ -18796,9 +19242,17 @@ var LRUCache = class _LRUCache {
18796
19242
  #max;
18797
19243
  #maxSize;
18798
19244
  #dispose;
19245
+ #onInsert;
18799
19246
  #disposeAfter;
18800
19247
  #fetchMethod;
18801
19248
  #memoMethod;
19249
+ #perf;
19250
+ /**
19251
+ * {@link LRUCache.OptionsBase.perf}
19252
+ */
19253
+ get perf() {
19254
+ return this.#perf;
19255
+ }
18802
19256
  /**
18803
19257
  * {@link LRUCache.OptionsBase.ttl}
18804
19258
  */
@@ -18874,9 +19328,11 @@ var LRUCache = class _LRUCache {
18874
19328
  #sizes;
18875
19329
  #starts;
18876
19330
  #ttls;
19331
+ #autopurgeTimers;
18877
19332
  #hasDispose;
18878
19333
  #hasFetchMethod;
18879
19334
  #hasDisposeAfter;
19335
+ #hasOnInsert;
18880
19336
  /**
18881
19337
  * Do not call this method unless you need to inspect the
18882
19338
  * inner workings of the cache. If anything returned by this
@@ -18891,6 +19347,7 @@ var LRUCache = class _LRUCache {
18891
19347
  // properties
18892
19348
  starts: c.#starts,
18893
19349
  ttls: c.#ttls,
19350
+ autopurgeTimers: c.#autopurgeTimers,
18894
19351
  sizes: c.#sizes,
18895
19352
  keyMap: c.#keyMap,
18896
19353
  keyList: c.#keyList,
@@ -18953,6 +19410,12 @@ var LRUCache = class _LRUCache {
18953
19410
  get dispose() {
18954
19411
  return this.#dispose;
18955
19412
  }
19413
+ /**
19414
+ * {@link LRUCache.OptionsBase.onInsert} (read-only)
19415
+ */
19416
+ get onInsert() {
19417
+ return this.#onInsert;
19418
+ }
18956
19419
  /**
18957
19420
  * {@link LRUCache.OptionsBase.disposeAfter} (read-only)
18958
19421
  */
@@ -18960,7 +19423,13 @@ var LRUCache = class _LRUCache {
18960
19423
  return this.#disposeAfter;
18961
19424
  }
18962
19425
  constructor(options) {
18963
- const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort } = options;
19426
+ const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, onInsert, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort, perf } = options;
19427
+ if (perf !== void 0) {
19428
+ if (typeof perf?.now !== "function") {
19429
+ throw new TypeError("perf option must have a now() method if specified");
19430
+ }
19431
+ }
19432
+ this.#perf = perf ?? defaultPerf;
18964
19433
  if (max !== 0 && !isPosInt(max)) {
18965
19434
  throw new TypeError("max option must be a nonnegative integer");
18966
19435
  }
@@ -19002,6 +19471,9 @@ var LRUCache = class _LRUCache {
19002
19471
  if (typeof dispose === "function") {
19003
19472
  this.#dispose = dispose;
19004
19473
  }
19474
+ if (typeof onInsert === "function") {
19475
+ this.#onInsert = onInsert;
19476
+ }
19005
19477
  if (typeof disposeAfter === "function") {
19006
19478
  this.#disposeAfter = disposeAfter;
19007
19479
  this.#disposed = [];
@@ -19010,6 +19482,7 @@ var LRUCache = class _LRUCache {
19010
19482
  this.#disposed = void 0;
19011
19483
  }
19012
19484
  this.#hasDispose = !!this.#dispose;
19485
+ this.#hasOnInsert = !!this.#onInsert;
19013
19486
  this.#hasDisposeAfter = !!this.#disposeAfter;
19014
19487
  this.noDisposeOnSet = !!noDisposeOnSet;
19015
19488
  this.noUpdateTTL = !!noUpdateTTL;
@@ -19065,10 +19538,16 @@ var LRUCache = class _LRUCache {
19065
19538
  const starts = new ZeroArray(this.#max);
19066
19539
  this.#ttls = ttls;
19067
19540
  this.#starts = starts;
19068
- this.#setItemTTL = (index, ttl, start = perf.now()) => {
19541
+ const purgeTimers = this.ttlAutopurge ? new Array(this.#max) : void 0;
19542
+ this.#autopurgeTimers = purgeTimers;
19543
+ this.#setItemTTL = (index, ttl, start = this.#perf.now()) => {
19069
19544
  starts[index] = ttl !== 0 ? start : 0;
19070
19545
  ttls[index] = ttl;
19071
- if (ttl !== 0 && this.ttlAutopurge) {
19546
+ if (purgeTimers?.[index]) {
19547
+ clearTimeout(purgeTimers[index]);
19548
+ purgeTimers[index] = void 0;
19549
+ }
19550
+ if (ttl !== 0 && purgeTimers) {
19072
19551
  const t = setTimeout(() => {
19073
19552
  if (this.#isStale(index)) {
19074
19553
  this.#delete(this.#keyList[index], "expire");
@@ -19077,10 +19556,11 @@ var LRUCache = class _LRUCache {
19077
19556
  if (t.unref) {
19078
19557
  t.unref();
19079
19558
  }
19559
+ purgeTimers[index] = t;
19080
19560
  }
19081
19561
  };
19082
19562
  this.#updateItemAge = (index) => {
19083
- starts[index] = ttls[index] !== 0 ? perf.now() : 0;
19563
+ starts[index] = ttls[index] !== 0 ? this.#perf.now() : 0;
19084
19564
  };
19085
19565
  this.#statusTTL = (status, index) => {
19086
19566
  if (ttls[index]) {
@@ -19097,7 +19577,7 @@ var LRUCache = class _LRUCache {
19097
19577
  };
19098
19578
  let cachedNow = 0;
19099
19579
  const getNow = () => {
19100
- const n = perf.now();
19580
+ const n = this.#perf.now();
19101
19581
  if (this.ttlResolution > 0) {
19102
19582
  cachedNow = n;
19103
19583
  const t = setTimeout(() => cachedNow = 0, this.ttlResolution);
@@ -19400,7 +19880,7 @@ var LRUCache = class _LRUCache {
19400
19880
  const ttl = this.#ttls[i];
19401
19881
  const start = this.#starts[i];
19402
19882
  if (ttl && start) {
19403
- const remain = ttl - (perf.now() - start);
19883
+ const remain = ttl - (this.#perf.now() - start);
19404
19884
  entry.ttl = remain;
19405
19885
  entry.start = Date.now();
19406
19886
  }
@@ -19412,7 +19892,7 @@ var LRUCache = class _LRUCache {
19412
19892
  }
19413
19893
  /**
19414
19894
  * Return an array of [key, {@link LRUCache.Entry}] tuples which can be
19415
- * passed to {@link LRLUCache#load}.
19895
+ * passed to {@link LRUCache#load}.
19416
19896
  *
19417
19897
  * The `start` fields are calculated relative to a portable `Date.now()`
19418
19898
  * timestamp, even if `performance.now()` is available.
@@ -19434,7 +19914,7 @@ var LRUCache = class _LRUCache {
19434
19914
  const entry = { value };
19435
19915
  if (this.#ttls && this.#starts) {
19436
19916
  entry.ttl = this.#ttls[i];
19437
- const age = perf.now() - this.#starts[i];
19917
+ const age = this.#perf.now() - this.#starts[i];
19438
19918
  entry.start = Math.floor(Date.now() - age);
19439
19919
  }
19440
19920
  if (this.#sizes) {
@@ -19458,7 +19938,7 @@ var LRUCache = class _LRUCache {
19458
19938
  for (const [key, entry] of arr) {
19459
19939
  if (entry.start) {
19460
19940
  const age = Date.now() - entry.start;
19461
- entry.start = perf.now() - age;
19941
+ entry.start = this.#perf.now() - age;
19462
19942
  }
19463
19943
  this.set(key, entry.value, entry);
19464
19944
  }
@@ -19523,6 +20003,9 @@ var LRUCache = class _LRUCache {
19523
20003
  if (status)
19524
20004
  status.set = "add";
19525
20005
  noUpdateTTL = false;
20006
+ if (this.#hasOnInsert) {
20007
+ this.#onInsert?.(v, k, "add");
20008
+ }
19526
20009
  } else {
19527
20010
  this.#moveToTail(index);
19528
20011
  const oldVal = this.#valList[index];
@@ -19558,6 +20041,9 @@ var LRUCache = class _LRUCache {
19558
20041
  } else if (status) {
19559
20042
  status.set = "update";
19560
20043
  }
20044
+ if (this.#hasOnInsert) {
20045
+ this.onInsert?.(v, k, v === oldVal ? "update" : "replace");
20046
+ }
19561
20047
  }
19562
20048
  if (ttl !== 0 && !this.#ttls) {
19563
20049
  this.#initializeTTLTracking();
@@ -19620,6 +20106,10 @@ var LRUCache = class _LRUCache {
19620
20106
  }
19621
20107
  }
19622
20108
  this.#removeItemSize(head);
20109
+ if (this.#autopurgeTimers?.[head]) {
20110
+ clearTimeout(this.#autopurgeTimers[head]);
20111
+ this.#autopurgeTimers[head] = void 0;
20112
+ }
19623
20113
  if (free) {
19624
20114
  this.#keyList[head] = void 0;
19625
20115
  this.#valList[head] = void 0;
@@ -19725,9 +20215,10 @@ var LRUCache = class _LRUCache {
19725
20215
  return fetchFail(ac.signal.reason);
19726
20216
  }
19727
20217
  const bf2 = p;
19728
- if (this.#valList[index] === p) {
20218
+ const vl = this.#valList[index];
20219
+ if (vl === p || ignoreAbort && updateCache && vl === void 0) {
19729
20220
  if (v2 === void 0) {
19730
- if (bf2.__staleWhileFetching) {
20221
+ if (bf2.__staleWhileFetching !== void 0) {
19731
20222
  this.#valList[index] = bf2.__staleWhileFetching;
19732
20223
  } else {
19733
20224
  this.#delete(k, "fetch");
@@ -19990,6 +20481,10 @@ var LRUCache = class _LRUCache {
19990
20481
  if (this.#size !== 0) {
19991
20482
  const index = this.#keyMap.get(k);
19992
20483
  if (index !== void 0) {
20484
+ if (this.#autopurgeTimers?.[index]) {
20485
+ clearTimeout(this.#autopurgeTimers?.[index]);
20486
+ this.#autopurgeTimers[index] = void 0;
20487
+ }
19993
20488
  deleted = true;
19994
20489
  if (this.#size === 1) {
19995
20490
  this.#clear(reason);
@@ -20060,6 +20555,11 @@ var LRUCache = class _LRUCache {
20060
20555
  if (this.#ttls && this.#starts) {
20061
20556
  this.#ttls.fill(0);
20062
20557
  this.#starts.fill(0);
20558
+ for (const t of this.#autopurgeTimers ?? []) {
20559
+ if (t !== void 0)
20560
+ clearTimeout(t);
20561
+ }
20562
+ this.#autopurgeTimers?.fill(void 0);
20063
20563
  }
20064
20564
  if (this.#sizes) {
20065
20565
  this.#sizes.fill(0);
@@ -21009,7 +21509,7 @@ var ENOREALPATH = 512;
21009
21509
  var ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH;
21010
21510
  var TYPEMASK = 1023;
21011
21511
  var entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN;
21012
- var normalizeCache = /* @__PURE__ */ new Map();
21512
+ var normalizeCache = new LRUCache({ max: 2 ** 12 });
21013
21513
  var normalize = (s) => {
21014
21514
  const c = normalizeCache.get(s);
21015
21515
  if (c)
@@ -21018,7 +21518,7 @@ var normalize = (s) => {
21018
21518
  normalizeCache.set(s, n);
21019
21519
  return n;
21020
21520
  };
21021
- var normalizeNocaseCache = /* @__PURE__ */ new Map();
21521
+ var normalizeNocaseCache = new LRUCache({ max: 2 ** 12 });
21022
21522
  var normalizeNocase = (s) => {
21023
21523
  const c = normalizeNocaseCache.get(s);
21024
21524
  if (c)
@@ -21175,13 +21675,17 @@ var PathBase = class {
21175
21675
  get parentPath() {
21176
21676
  return (this.parent || this).fullpath();
21177
21677
  }
21678
+ /* c8 ignore start */
21178
21679
  /**
21179
21680
  * Deprecated alias for Dirent['parentPath'] Somewhat counterintuitively,
21180
21681
  * this property refers to the *parent* path, not the path object itself.
21682
+ *
21683
+ * @deprecated
21181
21684
  */
21182
21685
  get path() {
21183
21686
  return this.parentPath;
21184
21687
  }
21688
+ /* c8 ignore stop */
21185
21689
  /**
21186
21690
  * Do not create new Path objects directly. They should always be accessed
21187
21691
  * via the PathScurry class or other methods on the Path class.
@@ -24882,7 +25386,7 @@ function countFindingsBySeverity(findings) {
24882
25386
  var path2 = __toESM(require("path"));
24883
25387
  function formatJunit(findings) {
24884
25388
  const byFile = findings.reduce((acc, finding) => {
24885
- const file = finding.path || "unknown";
25389
+ const file = finding.location?.file || "unknown";
24886
25390
  if (!acc[file]) acc[file] = [];
24887
25391
  acc[file].push(finding);
24888
25392
  return acc;
@@ -24894,9 +25398,12 @@ function formatJunit(findings) {
24894
25398
  xml += ` <testsuite name="${filename}" tests="${failures}" failures="${failures}" errors="0" skipped="0" timestamp="${(/* @__PURE__ */ new Date()).toISOString()}" time="0" hostname="flowlint">
24895
25399
  `;
24896
25400
  for (const finding of fileFindings) {
24897
- xml += ` <testcase classname="${file}" name="${finding.rule}" time="0">
25401
+ const line = finding.location?.range?.start?.line || 0;
25402
+ const rule = finding.ruleId || "unknown-rule";
25403
+ const msg = finding.message || "";
25404
+ xml += ` <testcase classname="${file}" name="${rule}" time="0">
24898
25405
  `;
24899
- xml += ` <failure message="${escapeXml(finding.message)}" type="${finding.severity}">Line ${finding.line || 0}: ${escapeXml(finding.raw_details || "")}</failure>
25406
+ xml += ` <failure message="${escapeXml(msg)}" type="${finding.severity}">Line ${line}: ${escapeXml(msg)}</failure>
24900
25407
  `;
24901
25408
  xml += ` </testcase>
24902
25409
  `;
@@ -25118,7 +25625,7 @@ var initCommand = new Command("init").description("Initialize FlowLint configura
25118
25625
 
25119
25626
  // src/cli.ts
25120
25627
  var program2 = new Command();
25121
- program2.name("flowlint").description("Static analysis tool for n8n workflows").version("0.7.0");
25628
+ program2.name("flowlint").description("Static analysis tool for n8n workflows").version("0.7.2");
25122
25629
  program2.addCommand(scanCommand);
25123
25630
  program2.addCommand(initCommand);
25124
25631
  program2.parse(process.argv);