@sveltejs/kit 1.0.0-next.168 → 1.0.0-next.171

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.
@@ -1,17 +1,16 @@
1
- import require$$0, { EventEmitter } from 'events';
1
+ import require$$0$2, { EventEmitter } from 'events';
2
2
  import fs__default from 'fs';
3
3
  import path__default from 'path';
4
4
  import { URL } from 'url';
5
5
  import { svelte } from '@sveltejs/vite-plugin-svelte';
6
- import { c as createCommonjsModule } from './_commonjsHelpers.js';
7
- import util from 'util';
8
- import os from 'os';
9
- import http from 'http';
10
- import https from 'https';
6
+ import require$$0$1 from 'util';
7
+ import require$$0 from 'os';
8
+ import http$1 from 'http';
9
+ import https$1 from 'https';
11
10
  import require$$1 from 'child_process';
12
- import require$$0$1 from 'domain';
11
+ import require$$0$3 from 'domain';
13
12
  import 'querystring';
14
- import vm from 'vm';
13
+ import require$$10 from 'vm';
15
14
  import CheapWatch from 'cheap-watch';
16
15
  import { r as rimraf, c as copy_assets, p as print_config_conflicts, a as resolve_entry, $ } from '../cli.js';
17
16
  import vite from 'vite';
@@ -19,7 +18,6 @@ import { respond } from '../ssr.js';
19
18
  import { d as deep_merge, c as create_manifest_data, a as create_app } from './index2.js';
20
19
  import { __fetch_polyfill } from '../install-fetch.js';
21
20
  import { getRawBody } from '../node.js';
22
- import { g as get_server } from './index3.js';
23
21
  import { S as SVELTE_KIT, a as SVELTE_KIT_ASSETS } from './constants.js';
24
22
  import { c as coalesce_to_error } from './error.js';
25
23
  import 'sade';
@@ -30,6 +28,14 @@ import 'zlib';
30
28
  import 'stream';
31
29
  import 'crypto';
32
30
 
31
+ var amphtmlValidator = {};
32
+
33
+ var safe = {exports: {}};
34
+
35
+ var colors$1 = {exports: {}};
36
+
37
+ var styles = {exports: {}};
38
+
33
39
  /*
34
40
  The MIT License (MIT)
35
41
 
@@ -55,7 +61,7 @@ THE SOFTWARE.
55
61
 
56
62
  */
57
63
 
58
- var styles_1 = createCommonjsModule(function (module) {
64
+ (function (module) {
59
65
  var styles = {};
60
66
  module['exports'] = styles;
61
67
 
@@ -126,7 +132,7 @@ Object.keys(codes).forEach(function(key) {
126
132
  style.open = '\u001b[' + val[0] + 'm';
127
133
  style.close = '\u001b[' + val[1] + 'm';
128
134
  });
129
- });
135
+ }(styles));
130
136
 
131
137
  /*
132
138
  MIT License
@@ -152,7 +158,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
152
158
  SOFTWARE.
153
159
  */
154
160
 
155
- var hasFlag = function(flag, argv) {
161
+ var hasFlag$1 = function(flag, argv) {
156
162
  argv = argv || process.argv;
157
163
 
158
164
  var terminatorPos = argv.indexOf('--');
@@ -187,8 +193,8 @@ THE SOFTWARE.
187
193
 
188
194
  */
189
195
 
190
-
191
-
196
+ var os = require$$0;
197
+ var hasFlag = hasFlag$1;
192
198
 
193
199
  var env = process.env;
194
200
 
@@ -312,7 +318,9 @@ var supportsColors = {
312
318
  stderr: getSupportLevel(process.stderr),
313
319
  };
314
320
 
315
- var trap = createCommonjsModule(function (module) {
321
+ var trap = {exports: {}};
322
+
323
+ (function (module) {
316
324
  module['exports'] = function runTheTrap(text, options) {
317
325
  var result = '';
318
326
  text = text || 'Run the trap, drop the bass';
@@ -359,9 +367,11 @@ module['exports'] = function runTheTrap(text, options) {
359
367
  });
360
368
  return result;
361
369
  };
362
- });
370
+ }(trap));
371
+
372
+ var zalgo = {exports: {}};
363
373
 
364
- var zalgo = createCommonjsModule(function (module) {
374
+ (function (module) {
365
375
  // please no
366
376
  module['exports'] = function zalgo(text, options) {
367
377
  text = text || ' he is here ';
@@ -471,9 +481,11 @@ module['exports'] = function zalgo(text, options) {
471
481
  // don't summon him
472
482
  return heComes(text, options);
473
483
  };
474
- });
484
+ }(zalgo));
485
+
486
+ var america = {exports: {}};
475
487
 
476
- var america = createCommonjsModule(function (module) {
488
+ (function (module) {
477
489
  module['exports'] = function(colors) {
478
490
  return function(letter, i, exploded) {
479
491
  if (letter === ' ') return letter;
@@ -484,17 +496,21 @@ module['exports'] = function(colors) {
484
496
  }
485
497
  };
486
498
  };
487
- });
499
+ }(america));
500
+
501
+ var zebra = {exports: {}};
488
502
 
489
- var zebra = createCommonjsModule(function (module) {
503
+ (function (module) {
490
504
  module['exports'] = function(colors) {
491
505
  return function(letter, i, exploded) {
492
506
  return i % 2 === 0 ? letter : colors.inverse(letter);
493
507
  };
494
508
  };
495
- });
509
+ }(zebra));
510
+
511
+ var rainbow = {exports: {}};
496
512
 
497
- var rainbow = createCommonjsModule(function (module) {
513
+ (function (module) {
498
514
  module['exports'] = function(colors) {
499
515
  // RoY G BiV
500
516
  var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta'];
@@ -506,9 +522,11 @@ module['exports'] = function(colors) {
506
522
  }
507
523
  };
508
524
  };
509
- });
525
+ }(rainbow));
526
+
527
+ var random = {exports: {}};
510
528
 
511
- var random = createCommonjsModule(function (module) {
529
+ (function (module) {
512
530
  module['exports'] = function(colors) {
513
531
  var available = ['underline', 'inverse', 'grey', 'yellow', 'red', 'green',
514
532
  'blue', 'white', 'cyan', 'magenta', 'brightYellow', 'brightRed',
@@ -520,7 +538,7 @@ module['exports'] = function(colors) {
520
538
  ](letter);
521
539
  };
522
540
  };
523
- });
541
+ }(random));
524
542
 
525
543
  /*
526
544
 
@@ -552,14 +570,14 @@ THE SOFTWARE.
552
570
 
553
571
  */
554
572
 
555
- var colors_1 = createCommonjsModule(function (module) {
573
+ (function (module) {
556
574
  var colors = {};
557
575
  module['exports'] = colors;
558
576
 
559
577
  colors.themes = {};
560
578
 
561
-
562
- var ansiStyles = colors.styles = styles_1;
579
+ var util = require$$0$1;
580
+ var ansiStyles = colors.styles = styles.exports;
563
581
  var defineProps = Object.defineProperties;
564
582
  var newLineRegex = new RegExp(/[\r\n]+/g);
565
583
 
@@ -618,7 +636,7 @@ function build(_styles) {
618
636
  return builder;
619
637
  }
620
638
 
621
- var styles = (function() {
639
+ var styles$1 = (function() {
622
640
  var ret = {};
623
641
  ansiStyles.grey = ansiStyles.gray;
624
642
  Object.keys(ansiStyles).forEach(function(key) {
@@ -633,7 +651,7 @@ var styles = (function() {
633
651
  return ret;
634
652
  })();
635
653
 
636
- var proto = defineProps(function colors() {}, styles);
654
+ var proto = defineProps(function colors() {}, styles$1);
637
655
 
638
656
  function applyStyle() {
639
657
  var args = Array.prototype.slice.call(arguments);
@@ -698,7 +716,7 @@ colors.setTheme = function(theme) {
698
716
 
699
717
  function init() {
700
718
  var ret = {};
701
- Object.keys(styles).forEach(function(name) {
719
+ Object.keys(styles$1).forEach(function(name) {
702
720
  ret[name] = {
703
721
  get: function() {
704
722
  return build([name]);
@@ -715,15 +733,15 @@ var sequencer = function sequencer(map, str) {
715
733
  };
716
734
 
717
735
  // custom formatter methods
718
- colors.trap = trap;
719
- colors.zalgo = zalgo;
736
+ colors.trap = trap.exports;
737
+ colors.zalgo = zalgo.exports;
720
738
 
721
739
  // maps
722
740
  colors.maps = {};
723
- colors.maps.america = america(colors);
724
- colors.maps.zebra = zebra(colors);
725
- colors.maps.rainbow = rainbow(colors);
726
- colors.maps.random = random(colors);
741
+ colors.maps.america = america.exports(colors);
742
+ colors.maps.zebra = zebra.exports(colors);
743
+ colors.maps.rainbow = rainbow.exports(colors);
744
+ colors.maps.random = random.exports(colors);
727
745
 
728
746
  for (var map in colors.maps) {
729
747
  (function(map) {
@@ -734,9 +752,9 @@ for (var map in colors.maps) {
734
752
  }
735
753
 
736
754
  defineProps(colors, init());
737
- });
755
+ }(colors$1));
738
756
 
739
- var safe = createCommonjsModule(function (module) {
757
+ (function (module) {
740
758
  //
741
759
  // Remark: Requiring this file will use the "safe" colors API,
742
760
  // which will not touch String.prototype.
@@ -745,1243 +763,2227 @@ var safe = createCommonjsModule(function (module) {
745
763
  // colors.red("foo")
746
764
  //
747
765
  //
766
+ var colors = colors$1.exports;
767
+ module['exports'] = colors;
768
+ }(safe));
748
769
 
749
- module['exports'] = colors_1;
750
- });
770
+ var commander = {exports: {}};
751
771
 
752
772
  /**
753
773
  * Module dependencies.
754
774
  */
755
775
 
756
- var commander = createCommonjsModule(function (module, exports) {
757
- var EventEmitter = require$$0.EventEmitter;
758
- var spawn = require$$1.spawn;
759
-
760
- var dirname = path__default.dirname;
761
- var basename = path__default.basename;
776
+ (function (module, exports) {
777
+ const EventEmitter = require$$0$2.EventEmitter;
778
+ const childProcess = require$$1;
779
+ const path = path__default;
780
+ const fs = fs__default;
762
781
 
782
+ // @ts-check
763
783
 
764
- /**
765
- * Inherit `Command` from `EventEmitter.prototype`.
766
- */
767
-
768
- util.inherits(Command, EventEmitter);
769
-
770
- /**
771
- * Expose the root command.
772
- */
784
+ // Although this is a class, methods are static in style to allow override using subclass or just functions.
785
+ class Help {
786
+ constructor() {
787
+ this.helpWidth = undefined;
788
+ this.sortSubcommands = false;
789
+ this.sortOptions = false;
790
+ }
773
791
 
774
- exports = module.exports = new Command();
792
+ /**
793
+ * Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
794
+ *
795
+ * @param {Command} cmd
796
+ * @returns {Command[]}
797
+ */
775
798
 
776
- /**
777
- * Expose `Command`.
778
- */
799
+ visibleCommands(cmd) {
800
+ const visibleCommands = cmd.commands.filter(cmd => !cmd._hidden);
801
+ if (cmd._hasImplicitHelpCommand()) {
802
+ // Create a command matching the implicit help command.
803
+ const args = cmd._helpCommandnameAndArgs.split(/ +/);
804
+ const helpCommand = cmd.createCommand(args.shift())
805
+ .helpOption(false);
806
+ helpCommand.description(cmd._helpCommandDescription);
807
+ helpCommand._parseExpectedArgs(args);
808
+ visibleCommands.push(helpCommand);
809
+ }
810
+ if (this.sortSubcommands) {
811
+ visibleCommands.sort((a, b) => {
812
+ return a.name().localeCompare(b.name());
813
+ });
814
+ }
815
+ return visibleCommands;
816
+ }
779
817
 
780
- exports.Command = Command;
818
+ /**
819
+ * Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one.
820
+ *
821
+ * @param {Command} cmd
822
+ * @returns {Option[]}
823
+ */
781
824
 
782
- /**
783
- * Expose `Option`.
784
- */
825
+ visibleOptions(cmd) {
826
+ const visibleOptions = cmd.options.filter((option) => !option.hidden);
827
+ // Implicit help
828
+ const showShortHelpFlag = cmd._hasHelpOption && cmd._helpShortFlag && !cmd._findOption(cmd._helpShortFlag);
829
+ const showLongHelpFlag = cmd._hasHelpOption && !cmd._findOption(cmd._helpLongFlag);
830
+ if (showShortHelpFlag || showLongHelpFlag) {
831
+ let helpOption;
832
+ if (!showShortHelpFlag) {
833
+ helpOption = cmd.createOption(cmd._helpLongFlag, cmd._helpDescription);
834
+ } else if (!showLongHelpFlag) {
835
+ helpOption = cmd.createOption(cmd._helpShortFlag, cmd._helpDescription);
836
+ } else {
837
+ helpOption = cmd.createOption(cmd._helpFlags, cmd._helpDescription);
838
+ }
839
+ visibleOptions.push(helpOption);
840
+ }
841
+ if (this.sortOptions) {
842
+ const getSortKey = (option) => {
843
+ // WYSIWYG for order displayed in help with short before long, no special handling for negated.
844
+ return option.short ? option.short.replace(/^-/, '') : option.long.replace(/^--/, '');
845
+ };
846
+ visibleOptions.sort((a, b) => {
847
+ return getSortKey(a).localeCompare(getSortKey(b));
848
+ });
849
+ }
850
+ return visibleOptions;
851
+ }
785
852
 
786
- exports.Option = Option;
853
+ /**
854
+ * Get an array of the arguments which have descriptions.
855
+ *
856
+ * @param {Command} cmd
857
+ * @returns {{ term: string, description:string }[]}
858
+ */
787
859
 
788
- /**
789
- * Initialize a new `Option` with the given `flags` and `description`.
790
- *
791
- * @param {String} flags
792
- * @param {String} description
793
- * @api public
794
- */
860
+ visibleArguments(cmd) {
861
+ if (cmd._argsDescription && cmd._args.length) {
862
+ return cmd._args.map((argument) => {
863
+ return { term: argument.name, description: cmd._argsDescription[argument.name] || '' };
864
+ }, 0);
865
+ }
866
+ return [];
867
+ }
795
868
 
796
- function Option(flags, description) {
797
- this.flags = flags;
798
- this.required = ~flags.indexOf('<');
799
- this.optional = ~flags.indexOf('[');
800
- this.bool = !~flags.indexOf('-no-');
801
- flags = flags.split(/[ ,|]+/);
802
- if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift();
803
- this.long = flags.shift();
804
- this.description = description || '';
805
- }
869
+ /**
870
+ * Get the command term to show in the list of subcommands.
871
+ *
872
+ * @param {Command} cmd
873
+ * @returns {string}
874
+ */
806
875
 
807
- /**
808
- * Return option name.
809
- *
810
- * @return {String}
811
- * @api private
812
- */
876
+ subcommandTerm(cmd) {
877
+ // Legacy. Ignores custom usage string, and nested commands.
878
+ const args = cmd._args.map(arg => humanReadableArgName(arg)).join(' ');
879
+ return cmd._name +
880
+ (cmd._aliases[0] ? '|' + cmd._aliases[0] : '') +
881
+ (cmd.options.length ? ' [options]' : '') + // simplistic check for non-help option
882
+ (args ? ' ' + args : '');
883
+ }
813
884
 
814
- Option.prototype.name = function() {
815
- return this.long
816
- .replace('--', '')
817
- .replace('no-', '');
818
- };
885
+ /**
886
+ * Get the option term to show in the list of options.
887
+ *
888
+ * @param {Option} option
889
+ * @returns {string}
890
+ */
819
891
 
820
- /**
821
- * Return option name, in a camelcase format that can be used
822
- * as a object attribute key.
823
- *
824
- * @return {String}
825
- * @api private
826
- */
892
+ optionTerm(option) {
893
+ return option.flags;
894
+ }
827
895
 
828
- Option.prototype.attributeName = function() {
829
- return camelcase(this.name());
830
- };
896
+ /**
897
+ * Get the longest command term length.
898
+ *
899
+ * @param {Command} cmd
900
+ * @param {Help} helper
901
+ * @returns {number}
902
+ */
831
903
 
832
- /**
833
- * Check if `arg` matches the short or long flag.
834
- *
835
- * @param {String} arg
836
- * @return {Boolean}
837
- * @api private
838
- */
904
+ longestSubcommandTermLength(cmd, helper) {
905
+ return helper.visibleCommands(cmd).reduce((max, command) => {
906
+ return Math.max(max, helper.subcommandTerm(command).length);
907
+ }, 0);
908
+ };
839
909
 
840
- Option.prototype.is = function(arg) {
841
- return this.short === arg || this.long === arg;
842
- };
910
+ /**
911
+ * Get the longest option term length.
912
+ *
913
+ * @param {Command} cmd
914
+ * @param {Help} helper
915
+ * @returns {number}
916
+ */
843
917
 
844
- /**
845
- * Initialize a new `Command`.
846
- *
847
- * @param {String} name
848
- * @api public
849
- */
918
+ longestOptionTermLength(cmd, helper) {
919
+ return helper.visibleOptions(cmd).reduce((max, option) => {
920
+ return Math.max(max, helper.optionTerm(option).length);
921
+ }, 0);
922
+ };
850
923
 
851
- function Command(name) {
852
- this.commands = [];
853
- this.options = [];
854
- this._execs = {};
855
- this._allowUnknownOption = false;
856
- this._args = [];
857
- this._name = name || '';
858
- }
924
+ /**
925
+ * Get the longest argument term length.
926
+ *
927
+ * @param {Command} cmd
928
+ * @param {Help} helper
929
+ * @returns {number}
930
+ */
859
931
 
860
- /**
861
- * Add command `name`.
862
- *
863
- * The `.action()` callback is invoked when the
864
- * command `name` is specified via __ARGV__,
865
- * and the remaining arguments are applied to the
866
- * function for access.
867
- *
868
- * When the `name` is "*" an un-matched command
869
- * will be passed as the first arg, followed by
870
- * the rest of __ARGV__ remaining.
871
- *
872
- * Examples:
873
- *
874
- * program
875
- * .version('0.0.1')
876
- * .option('-C, --chdir <path>', 'change the working directory')
877
- * .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
878
- * .option('-T, --no-tests', 'ignore test hook')
879
- *
880
- * program
881
- * .command('setup')
882
- * .description('run remote setup commands')
883
- * .action(function() {
884
- * console.log('setup');
885
- * });
886
- *
887
- * program
888
- * .command('exec <cmd>')
889
- * .description('run the given remote command')
890
- * .action(function(cmd) {
891
- * console.log('exec "%s"', cmd);
892
- * });
893
- *
894
- * program
895
- * .command('teardown <dir> [otherDirs...]')
896
- * .description('run teardown commands')
897
- * .action(function(dir, otherDirs) {
898
- * console.log('dir "%s"', dir);
899
- * if (otherDirs) {
900
- * otherDirs.forEach(function (oDir) {
901
- * console.log('dir "%s"', oDir);
902
- * });
903
- * }
904
- * });
905
- *
906
- * program
907
- * .command('*')
908
- * .description('deploy the given env')
909
- * .action(function(env) {
910
- * console.log('deploying "%s"', env);
911
- * });
912
- *
913
- * program.parse(process.argv);
914
- *
915
- * @param {String} name
916
- * @param {String} [desc] for git-style sub-commands
917
- * @return {Command} the new command
918
- * @api public
919
- */
932
+ longestArgumentTermLength(cmd, helper) {
933
+ return helper.visibleArguments(cmd).reduce((max, argument) => {
934
+ return Math.max(max, argument.term.length);
935
+ }, 0);
936
+ };
920
937
 
921
- Command.prototype.command = function(name, desc, opts) {
922
- if (typeof desc === 'object' && desc !== null) {
923
- opts = desc;
924
- desc = null;
925
- }
926
- opts = opts || {};
927
- var args = name.split(/ +/);
928
- var cmd = new Command(args.shift());
938
+ /**
939
+ * Get the command usage to be displayed at the top of the built-in help.
940
+ *
941
+ * @param {Command} cmd
942
+ * @returns {string}
943
+ */
929
944
 
930
- if (desc) {
931
- cmd.description(desc);
932
- this.executables = true;
933
- this._execs[cmd._name] = true;
934
- if (opts.isDefault) this.defaultExecutable = cmd._name;
945
+ commandUsage(cmd) {
946
+ // Usage
947
+ let cmdName = cmd._name;
948
+ if (cmd._aliases[0]) {
949
+ cmdName = cmdName + '|' + cmd._aliases[0];
950
+ }
951
+ let parentCmdNames = '';
952
+ for (let parentCmd = cmd.parent; parentCmd; parentCmd = parentCmd.parent) {
953
+ parentCmdNames = parentCmd.name() + ' ' + parentCmdNames;
954
+ }
955
+ return parentCmdNames + cmdName + ' ' + cmd.usage();
935
956
  }
936
- cmd._noHelp = !!opts.noHelp;
937
- this.commands.push(cmd);
938
- cmd.parseExpectedArgs(args);
939
- cmd.parent = this;
940
-
941
- if (desc) return this;
942
- return cmd;
943
- };
944
-
945
- /**
946
- * Define argument syntax for the top-level command.
947
- *
948
- * @api public
949
- */
950
957
 
951
- Command.prototype.arguments = function(desc) {
952
- return this.parseExpectedArgs(desc.split(/ +/));
953
- };
958
+ /**
959
+ * Get the description for the command.
960
+ *
961
+ * @param {Command} cmd
962
+ * @returns {string}
963
+ */
954
964
 
955
- /**
956
- * Add an implicit `help [cmd]` subcommand
957
- * which invokes `--help` for the given command.
958
- *
959
- * @api private
960
- */
965
+ commandDescription(cmd) {
966
+ // @ts-ignore: overloaded return type
967
+ return cmd.description();
968
+ }
961
969
 
962
- Command.prototype.addImplicitHelpCommand = function() {
963
- this.command('help [cmd]', 'display help for [cmd]');
964
- };
970
+ /**
971
+ * Get the command description to show in the list of subcommands.
972
+ *
973
+ * @param {Command} cmd
974
+ * @returns {string}
975
+ */
965
976
 
966
- /**
967
- * Parse expected `args`.
968
- *
969
- * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
970
- *
971
- * @param {Array} args
972
- * @return {Command} for chaining
973
- * @api public
974
- */
977
+ subcommandDescription(cmd) {
978
+ // @ts-ignore: overloaded return type
979
+ return cmd.description();
980
+ }
975
981
 
976
- Command.prototype.parseExpectedArgs = function(args) {
977
- if (!args.length) return;
978
- var self = this;
979
- args.forEach(function(arg) {
980
- var argDetails = {
981
- required: false,
982
- name: '',
983
- variadic: false
984
- };
982
+ /**
983
+ * Get the option description to show in the list of options.
984
+ *
985
+ * @param {Option} option
986
+ * @return {string}
987
+ */
985
988
 
986
- switch (arg[0]) {
987
- case '<':
988
- argDetails.required = true;
989
- argDetails.name = arg.slice(1, -1);
990
- break;
991
- case '[':
992
- argDetails.name = arg.slice(1, -1);
993
- break;
989
+ optionDescription(option) {
990
+ if (option.negate) {
991
+ return option.description;
994
992
  }
995
-
996
- if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {
997
- argDetails.variadic = true;
998
- argDetails.name = argDetails.name.slice(0, -3);
993
+ const extraInfo = [];
994
+ if (option.argChoices) {
995
+ extraInfo.push(
996
+ // use stringify to match the display of the default value
997
+ `choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(', ')}`);
999
998
  }
1000
- if (argDetails.name) {
1001
- self._args.push(argDetails);
999
+ if (option.defaultValue !== undefined) {
1000
+ extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
1002
1001
  }
1003
- });
1004
- return this;
1005
- };
1006
-
1007
- /**
1008
- * Register callback `fn` for the command.
1009
- *
1010
- * Examples:
1011
- *
1012
- * program
1013
- * .command('help')
1014
- * .description('display verbose help')
1015
- * .action(function() {
1016
- * // output help here
1017
- * });
1018
- *
1019
- * @param {Function} fn
1020
- * @return {Command} for chaining
1021
- * @api public
1022
- */
1023
-
1024
- Command.prototype.action = function(fn) {
1025
- var self = this;
1026
- var listener = function(args, unknown) {
1027
- // Parse any so-far unknown options
1028
- args = args || [];
1029
- unknown = unknown || [];
1030
-
1031
- var parsed = self.parseOptions(unknown);
1032
-
1033
- // Output help if necessary
1034
- outputHelpIfNecessary(self, parsed.unknown);
1035
-
1036
- // If there are still any unknown options, then we simply
1037
- // die, unless someone asked for help, in which case we give it
1038
- // to them, and then we die.
1039
- if (parsed.unknown.length > 0) {
1040
- self.unknownOption(parsed.unknown[0]);
1002
+ if (extraInfo.length > 0) {
1003
+ return `${option.description} (${extraInfo.join(', ')})`;
1041
1004
  }
1005
+ return option.description;
1006
+ };
1042
1007
 
1043
- // Leftover arguments need to be pushed back. Fixes issue #56
1044
- if (parsed.args.length) args = parsed.args.concat(args);
1045
-
1046
- self._args.forEach(function(arg, i) {
1047
- if (arg.required && args[i] == null) {
1048
- self.missingArgument(arg.name);
1049
- } else if (arg.variadic) {
1050
- if (i !== self._args.length - 1) {
1051
- self.variadicArgNotLast(arg.name);
1052
- }
1008
+ /**
1009
+ * Generate the built-in help text.
1010
+ *
1011
+ * @param {Command} cmd
1012
+ * @param {Help} helper
1013
+ * @returns {string}
1014
+ */
1053
1015
 
1054
- args[i] = args.splice(i);
1016
+ formatHelp(cmd, helper) {
1017
+ const termWidth = helper.padWidth(cmd, helper);
1018
+ const helpWidth = helper.helpWidth || 80;
1019
+ const itemIndentWidth = 2;
1020
+ const itemSeparatorWidth = 2; // between term and description
1021
+ function formatItem(term, description) {
1022
+ if (description) {
1023
+ const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
1024
+ return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth);
1055
1025
  }
1056
- });
1057
-
1058
- // Always append ourselves to the end of the arguments,
1059
- // to make sure we match the number of arguments the user
1060
- // expects
1061
- if (self._args.length) {
1062
- args[self._args.length] = self;
1063
- } else {
1064
- args.push(self);
1026
+ return term;
1027
+ } function formatList(textArray) {
1028
+ return textArray.join('\n').replace(/^/gm, ' '.repeat(itemIndentWidth));
1065
1029
  }
1066
1030
 
1067
- fn.apply(self, args);
1068
- };
1069
- var parent = this.parent || this;
1070
- var name = parent === this ? '*' : this._name;
1071
- parent.on('command:' + name, listener);
1072
- if (this._alias) parent.on('command:' + this._alias, listener);
1073
- return this;
1074
- };
1075
-
1076
- /**
1077
- * Define option with `flags`, `description` and optional
1078
- * coercion `fn`.
1079
- *
1080
- * The `flags` string should contain both the short and long flags,
1081
- * separated by comma, a pipe or space. The following are all valid
1082
- * all will output this way when `--help` is used.
1083
- *
1084
- * "-p, --pepper"
1085
- * "-p|--pepper"
1086
- * "-p --pepper"
1087
- *
1088
- * Examples:
1089
- *
1090
- * // simple boolean defaulting to false
1091
- * program.option('-p, --pepper', 'add pepper');
1092
- *
1093
- * --pepper
1094
- * program.pepper
1095
- * // => Boolean
1096
- *
1097
- * // simple boolean defaulting to true
1098
- * program.option('-C, --no-cheese', 'remove cheese');
1099
- *
1100
- * program.cheese
1101
- * // => true
1102
- *
1103
- * --no-cheese
1104
- * program.cheese
1105
- * // => false
1106
- *
1107
- * // required argument
1108
- * program.option('-C, --chdir <path>', 'change the working directory');
1109
- *
1110
- * --chdir /tmp
1111
- * program.chdir
1112
- * // => "/tmp"
1113
- *
1114
- * // optional argument
1115
- * program.option('-c, --cheese [type]', 'add cheese [marble]');
1116
- *
1117
- * @param {String} flags
1118
- * @param {String} description
1119
- * @param {Function|*} [fn] or default
1120
- * @param {*} [defaultValue]
1121
- * @return {Command} for chaining
1122
- * @api public
1123
- */
1124
-
1125
- Command.prototype.option = function(flags, description, fn, defaultValue) {
1126
- var self = this,
1127
- option = new Option(flags, description),
1128
- oname = option.name(),
1129
- name = option.attributeName();
1031
+ // Usage
1032
+ let output = [`Usage: ${helper.commandUsage(cmd)}`, ''];
1130
1033
 
1131
- // default as 3rd arg
1132
- if (typeof fn !== 'function') {
1133
- if (fn instanceof RegExp) {
1134
- var regex = fn;
1135
- fn = function(val, def) {
1136
- var m = regex.exec(val);
1137
- return m ? m[0] : def;
1138
- };
1139
- } else {
1140
- defaultValue = fn;
1141
- fn = null;
1034
+ // Description
1035
+ const commandDescription = helper.commandDescription(cmd);
1036
+ if (commandDescription.length > 0) {
1037
+ output = output.concat([commandDescription, '']);
1142
1038
  }
1143
- }
1144
1039
 
1145
- // preassign default value only for --no-*, [optional], or <required>
1146
- if (!option.bool || option.optional || option.required) {
1147
- // when --no-* we make sure default is true
1148
- if (!option.bool) defaultValue = true;
1149
- // preassign only if we have a default
1150
- if (defaultValue !== undefined) {
1151
- self[name] = defaultValue;
1152
- option.defaultValue = defaultValue;
1040
+ // Arguments
1041
+ const argumentList = helper.visibleArguments(cmd).map((argument) => {
1042
+ return formatItem(argument.term, argument.description);
1043
+ });
1044
+ if (argumentList.length > 0) {
1045
+ output = output.concat(['Arguments:', formatList(argumentList), '']);
1153
1046
  }
1154
- }
1155
-
1156
- // register the option
1157
- this.options.push(option);
1158
1047
 
1159
- // when it's passed assign the value
1160
- // and conditionally invoke the callback
1161
- this.on('option:' + oname, function(val) {
1162
- // coercion
1163
- if (val !== null && fn) {
1164
- val = fn(val, self[name] === undefined ? defaultValue : self[name]);
1048
+ // Options
1049
+ const optionList = helper.visibleOptions(cmd).map((option) => {
1050
+ return formatItem(helper.optionTerm(option), helper.optionDescription(option));
1051
+ });
1052
+ if (optionList.length > 0) {
1053
+ output = output.concat(['Options:', formatList(optionList), '']);
1165
1054
  }
1166
1055
 
1167
- // unassigned or bool
1168
- if (typeof self[name] === 'boolean' || typeof self[name] === 'undefined') {
1169
- // if no value, bool true, and we have a default, then use it!
1170
- if (val == null) {
1171
- self[name] = option.bool
1172
- ? defaultValue || true
1173
- : false;
1174
- } else {
1175
- self[name] = val;
1176
- }
1177
- } else if (val !== null) {
1178
- // reassign
1179
- self[name] = val;
1056
+ // Commands
1057
+ const commandList = helper.visibleCommands(cmd).map((cmd) => {
1058
+ return formatItem(helper.subcommandTerm(cmd), helper.subcommandDescription(cmd));
1059
+ });
1060
+ if (commandList.length > 0) {
1061
+ output = output.concat(['Commands:', formatList(commandList), '']);
1180
1062
  }
1181
- });
1182
1063
 
1183
- return this;
1184
- };
1064
+ return output.join('\n');
1065
+ }
1185
1066
 
1186
- /**
1187
- * Allow unknown options on the command line.
1188
- *
1189
- * @param {Boolean} arg if `true` or omitted, no error will be thrown
1190
- * for unknown options.
1191
- * @api public
1192
- */
1193
- Command.prototype.allowUnknownOption = function(arg) {
1194
- this._allowUnknownOption = arguments.length === 0 || arg;
1195
- return this;
1196
- };
1067
+ /**
1068
+ * Calculate the pad width from the maximum term length.
1069
+ *
1070
+ * @param {Command} cmd
1071
+ * @param {Help} helper
1072
+ * @returns {number}
1073
+ */
1197
1074
 
1198
- /**
1199
- * Parse `argv`, settings options and invoking commands when defined.
1200
- *
1201
- * @param {Array} argv
1202
- * @return {Command} for chaining
1203
- * @api public
1204
- */
1075
+ padWidth(cmd, helper) {
1076
+ return Math.max(
1077
+ helper.longestOptionTermLength(cmd, helper),
1078
+ helper.longestSubcommandTermLength(cmd, helper),
1079
+ helper.longestArgumentTermLength(cmd, helper)
1080
+ );
1081
+ };
1205
1082
 
1206
- Command.prototype.parse = function(argv) {
1207
- // implicit help
1208
- if (this.executables) this.addImplicitHelpCommand();
1083
+ /**
1084
+ * Wrap the given string to width characters per line, with lines after the first indented.
1085
+ * Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
1086
+ *
1087
+ * @param {string} str
1088
+ * @param {number} width
1089
+ * @param {number} indent
1090
+ * @param {number} [minColumnWidth=40]
1091
+ * @return {string}
1092
+ *
1093
+ */
1209
1094
 
1210
- // store raw args
1211
- this.rawArgs = argv;
1095
+ wrap(str, width, indent, minColumnWidth = 40) {
1096
+ // Detect manually wrapped and indented strings by searching for line breaks
1097
+ // followed by multiple spaces/tabs.
1098
+ if (str.match(/[\n]\s+/)) return str;
1099
+ // Do not wrap if not enough room for a wrapped column of text (as could end up with a word per line).
1100
+ const columnWidth = width - indent;
1101
+ if (columnWidth < minColumnWidth) return str;
1102
+
1103
+ const leadingStr = str.substr(0, indent);
1104
+ const columnText = str.substr(indent);
1105
+
1106
+ const indentString = ' '.repeat(indent);
1107
+ const regex = new RegExp('.{1,' + (columnWidth - 1) + '}([\\s\u200B]|$)|[^\\s\u200B]+?([\\s\u200B]|$)', 'g');
1108
+ const lines = columnText.match(regex) || [];
1109
+ return leadingStr + lines.map((line, i) => {
1110
+ if (line.slice(-1) === '\n') {
1111
+ line = line.slice(0, line.length - 1);
1112
+ }
1113
+ return ((i > 0) ? indentString : '') + line.trimRight();
1114
+ }).join('\n');
1115
+ }
1116
+ }
1212
1117
 
1213
- // guess name
1214
- this._name = this._name || basename(argv[1], '.js');
1118
+ class Option {
1119
+ /**
1120
+ * Initialize a new `Option` with the given `flags` and `description`.
1121
+ *
1122
+ * @param {string} flags
1123
+ * @param {string} [description]
1124
+ */
1215
1125
 
1216
- // github-style sub-commands with no sub-command
1217
- if (this.executables && argv.length < 3 && !this.defaultExecutable) {
1218
- // this user needs help
1219
- argv.push('--help');
1126
+ constructor(flags, description) {
1127
+ this.flags = flags;
1128
+ this.description = description || '';
1129
+
1130
+ this.required = flags.includes('<'); // A value must be supplied when the option is specified.
1131
+ this.optional = flags.includes('['); // A value is optional when the option is specified.
1132
+ // variadic test ignores <value,...> et al which might be used to describe custom splitting of single argument
1133
+ this.variadic = /\w\.\.\.[>\]]$/.test(flags); // The option can take multiple values.
1134
+ this.mandatory = false; // The option must have a value after parsing, which usually means it must be specified on command line.
1135
+ const optionFlags = _parseOptionFlags(flags);
1136
+ this.short = optionFlags.shortFlag;
1137
+ this.long = optionFlags.longFlag;
1138
+ this.negate = false;
1139
+ if (this.long) {
1140
+ this.negate = this.long.startsWith('--no-');
1141
+ }
1142
+ this.defaultValue = undefined;
1143
+ this.defaultValueDescription = undefined;
1144
+ this.parseArg = undefined;
1145
+ this.hidden = false;
1146
+ this.argChoices = undefined;
1220
1147
  }
1221
1148
 
1222
- // process argv
1223
- var parsed = this.parseOptions(this.normalize(argv.slice(2)));
1224
- var args = this.args = parsed.args;
1149
+ /**
1150
+ * Set the default value, and optionally supply the description to be displayed in the help.
1151
+ *
1152
+ * @param {any} value
1153
+ * @param {string} [description]
1154
+ * @return {Option}
1155
+ */
1225
1156
 
1226
- var result = this.parseArgs(this.args, parsed.unknown);
1157
+ default(value, description) {
1158
+ this.defaultValue = value;
1159
+ this.defaultValueDescription = description;
1160
+ return this;
1161
+ };
1227
1162
 
1228
- // executable sub-commands
1229
- var name = result.args[0];
1163
+ /**
1164
+ * Set the custom handler for processing CLI option arguments into option values.
1165
+ *
1166
+ * @param {Function} [fn]
1167
+ * @return {Option}
1168
+ */
1230
1169
 
1231
- var aliasCommand = null;
1232
- // check alias of sub commands
1233
- if (name) {
1234
- aliasCommand = this.commands.filter(function(command) {
1235
- return command.alias() === name;
1236
- })[0];
1237
- }
1170
+ argParser(fn) {
1171
+ this.parseArg = fn;
1172
+ return this;
1173
+ };
1238
1174
 
1239
- if (this._execs[name] && typeof this._execs[name] !== 'function') {
1240
- return this.executeSubCommand(argv, args, parsed.unknown);
1241
- } else if (aliasCommand) {
1242
- // is alias of a subCommand
1243
- args[0] = aliasCommand._name;
1244
- return this.executeSubCommand(argv, args, parsed.unknown);
1245
- } else if (this.defaultExecutable) {
1246
- // use the default subcommand
1247
- args.unshift(this.defaultExecutable);
1248
- return this.executeSubCommand(argv, args, parsed.unknown);
1249
- }
1175
+ /**
1176
+ * Whether the option is mandatory and must have a value after parsing.
1177
+ *
1178
+ * @param {boolean} [mandatory=true]
1179
+ * @return {Option}
1180
+ */
1250
1181
 
1251
- return result;
1252
- };
1182
+ makeOptionMandatory(mandatory = true) {
1183
+ this.mandatory = !!mandatory;
1184
+ return this;
1185
+ };
1253
1186
 
1254
- /**
1255
- * Execute a sub-command executable.
1256
- *
1257
- * @param {Array} argv
1258
- * @param {Array} args
1259
- * @param {Array} unknown
1260
- * @api private
1261
- */
1187
+ /**
1188
+ * Hide option in help.
1189
+ *
1190
+ * @param {boolean} [hide=true]
1191
+ * @return {Option}
1192
+ */
1193
+
1194
+ hideHelp(hide = true) {
1195
+ this.hidden = !!hide;
1196
+ return this;
1197
+ };
1262
1198
 
1263
- Command.prototype.executeSubCommand = function(argv, args, unknown) {
1264
- args = args.concat(unknown);
1199
+ /**
1200
+ * @api private
1201
+ */
1265
1202
 
1266
- if (!args.length) this.help();
1267
- if (args[0] === 'help' && args.length === 1) this.help();
1203
+ _concatValue(value, previous) {
1204
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
1205
+ return [value];
1206
+ }
1268
1207
 
1269
- // <cmd> --help
1270
- if (args[0] === 'help') {
1271
- args[0] = args[1];
1272
- args[1] = '--help';
1208
+ return previous.concat(value);
1273
1209
  }
1274
1210
 
1275
- // executable
1276
- var f = argv[1];
1277
- // name of the subcommand, link `pm-install`
1278
- var bin = basename(f, '.js') + '-' + args[0];
1211
+ /**
1212
+ * Only allow option value to be one of choices.
1213
+ *
1214
+ * @param {string[]} values
1215
+ * @return {Option}
1216
+ */
1279
1217
 
1280
- // In case of globally installed, get the base dir where executable
1281
- // subcommand file should be located at
1282
- var baseDir,
1283
- link = fs__default.lstatSync(f).isSymbolicLink() ? fs__default.readlinkSync(f) : f;
1218
+ choices(values) {
1219
+ this.argChoices = values;
1220
+ this.parseArg = (arg, previous) => {
1221
+ if (!values.includes(arg)) {
1222
+ throw new InvalidOptionArgumentError(`Allowed choices are ${values.join(', ')}.`);
1223
+ }
1224
+ if (this.variadic) {
1225
+ return this._concatValue(arg, previous);
1226
+ }
1227
+ return arg;
1228
+ };
1229
+ return this;
1230
+ };
1284
1231
 
1285
- // when symbolink is relative path
1286
- if (link !== f && link.charAt(0) !== '/') {
1287
- link = path__default.join(dirname(f), link);
1288
- }
1289
- baseDir = dirname(link);
1232
+ /**
1233
+ * Return option name.
1234
+ *
1235
+ * @return {string}
1236
+ */
1290
1237
 
1291
- // prefer local `./<bin>` to bin in the $PATH
1292
- var localBin = path__default.join(baseDir, bin);
1238
+ name() {
1239
+ if (this.long) {
1240
+ return this.long.replace(/^--/, '');
1241
+ }
1242
+ return this.short.replace(/^-/, '');
1243
+ };
1293
1244
 
1294
- // whether bin file is a js script with explicit `.js` extension
1295
- var isExplicitJS = false;
1296
- if (exists(localBin + '.js')) {
1297
- bin = localBin + '.js';
1298
- isExplicitJS = true;
1299
- } else if (exists(localBin)) {
1300
- bin = localBin;
1301
- }
1245
+ /**
1246
+ * Return option name, in a camelcase format that can be used
1247
+ * as a object attribute key.
1248
+ *
1249
+ * @return {string}
1250
+ * @api private
1251
+ */
1302
1252
 
1303
- args = args.slice(1);
1253
+ attributeName() {
1254
+ return camelcase(this.name().replace(/^no-/, ''));
1255
+ };
1304
1256
 
1305
- var proc;
1306
- if (process.platform !== 'win32') {
1307
- if (isExplicitJS) {
1308
- args.unshift(bin);
1309
- // add executable arguments to spawn
1310
- args = (process.execArgv || []).concat(args);
1257
+ /**
1258
+ * Check if `arg` matches the short or long flag.
1259
+ *
1260
+ * @param {string} arg
1261
+ * @return {boolean}
1262
+ * @api private
1263
+ */
1311
1264
 
1312
- proc = spawn(process.argv[0], args, { stdio: 'inherit', customFds: [0, 1, 2] });
1313
- } else {
1314
- proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] });
1265
+ is(arg) {
1266
+ return this.short === arg || this.long === arg;
1267
+ };
1268
+ }
1269
+
1270
+ /**
1271
+ * CommanderError class
1272
+ * @class
1273
+ */
1274
+ class CommanderError extends Error {
1275
+ /**
1276
+ * Constructs the CommanderError class
1277
+ * @param {number} exitCode suggested exit code which could be used with process.exit
1278
+ * @param {string} code an id string representing the error
1279
+ * @param {string} message human-readable description of the error
1280
+ * @constructor
1281
+ */
1282
+ constructor(exitCode, code, message) {
1283
+ super(message);
1284
+ // properly capture stack trace in Node.js
1285
+ Error.captureStackTrace(this, this.constructor);
1286
+ this.name = this.constructor.name;
1287
+ this.code = code;
1288
+ this.exitCode = exitCode;
1289
+ this.nestedError = undefined;
1290
+ }
1291
+ }
1292
+
1293
+ /**
1294
+ * InvalidOptionArgumentError class
1295
+ * @class
1296
+ */
1297
+ class InvalidOptionArgumentError extends CommanderError {
1298
+ /**
1299
+ * Constructs the InvalidOptionArgumentError class
1300
+ * @param {string} [message] explanation of why argument is invalid
1301
+ * @constructor
1302
+ */
1303
+ constructor(message) {
1304
+ super(1, 'commander.invalidOptionArgument', message);
1305
+ // properly capture stack trace in Node.js
1306
+ Error.captureStackTrace(this, this.constructor);
1307
+ this.name = this.constructor.name;
1308
+ }
1309
+ }
1310
+
1311
+ class Command extends EventEmitter {
1312
+ /**
1313
+ * Initialize a new `Command`.
1314
+ *
1315
+ * @param {string} [name]
1316
+ */
1317
+
1318
+ constructor(name) {
1319
+ super();
1320
+ this.commands = [];
1321
+ this.options = [];
1322
+ this.parent = null;
1323
+ this._allowUnknownOption = false;
1324
+ this._allowExcessArguments = true;
1325
+ this._args = [];
1326
+ this.rawArgs = null;
1327
+ this._scriptPath = null;
1328
+ this._name = name || '';
1329
+ this._optionValues = {};
1330
+ this._storeOptionsAsProperties = false;
1331
+ this._actionResults = [];
1332
+ this._actionHandler = null;
1333
+ this._executableHandler = false;
1334
+ this._executableFile = null; // custom name for executable
1335
+ this._defaultCommandName = null;
1336
+ this._exitCallback = null;
1337
+ this._aliases = [];
1338
+ this._combineFlagAndOptionalValue = true;
1339
+ this._description = '';
1340
+ this._argsDescription = undefined;
1341
+ this._enablePositionalOptions = false;
1342
+ this._passThroughOptions = false;
1343
+
1344
+ // see .configureOutput() for docs
1345
+ this._outputConfiguration = {
1346
+ writeOut: (str) => process.stdout.write(str),
1347
+ writeErr: (str) => process.stderr.write(str),
1348
+ getOutHelpWidth: () => process.stdout.isTTY ? process.stdout.columns : undefined,
1349
+ getErrHelpWidth: () => process.stderr.isTTY ? process.stderr.columns : undefined,
1350
+ outputError: (str, write) => write(str)
1351
+ };
1352
+
1353
+ this._hidden = false;
1354
+ this._hasHelpOption = true;
1355
+ this._helpFlags = '-h, --help';
1356
+ this._helpDescription = 'display help for command';
1357
+ this._helpShortFlag = '-h';
1358
+ this._helpLongFlag = '--help';
1359
+ this._addImplicitHelpCommand = undefined; // Deliberately undefined, not decided whether true or false
1360
+ this._helpCommandName = 'help';
1361
+ this._helpCommandnameAndArgs = 'help [command]';
1362
+ this._helpCommandDescription = 'display help for command';
1363
+ this._helpConfiguration = {};
1364
+ }
1365
+
1366
+ /**
1367
+ * Define a command.
1368
+ *
1369
+ * There are two styles of command: pay attention to where to put the description.
1370
+ *
1371
+ * Examples:
1372
+ *
1373
+ * // Command implemented using action handler (description is supplied separately to `.command`)
1374
+ * program
1375
+ * .command('clone <source> [destination]')
1376
+ * .description('clone a repository into a newly created directory')
1377
+ * .action((source, destination) => {
1378
+ * console.log('clone command called');
1379
+ * });
1380
+ *
1381
+ * // Command implemented using separate executable file (description is second parameter to `.command`)
1382
+ * program
1383
+ * .command('start <service>', 'start named service')
1384
+ * .command('stop [service]', 'stop named service, or all if no name supplied');
1385
+ *
1386
+ * @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
1387
+ * @param {Object|string} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
1388
+ * @param {Object} [execOpts] - configuration options (for executable)
1389
+ * @return {Command} returns new command for action handler, or `this` for executable command
1390
+ */
1391
+
1392
+ command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
1393
+ let desc = actionOptsOrExecDesc;
1394
+ let opts = execOpts;
1395
+ if (typeof desc === 'object' && desc !== null) {
1396
+ opts = desc;
1397
+ desc = null;
1315
1398
  }
1316
- } else {
1317
- args.unshift(bin);
1318
- proc = spawn(process.execPath, args, { stdio: 'inherit' });
1399
+ opts = opts || {};
1400
+ const args = nameAndArgs.split(/ +/);
1401
+ const cmd = this.createCommand(args.shift());
1402
+
1403
+ if (desc) {
1404
+ cmd.description(desc);
1405
+ cmd._executableHandler = true;
1406
+ }
1407
+ if (opts.isDefault) this._defaultCommandName = cmd._name;
1408
+
1409
+ cmd._outputConfiguration = this._outputConfiguration;
1410
+
1411
+ cmd._hidden = !!(opts.noHelp || opts.hidden); // noHelp is deprecated old name for hidden
1412
+ cmd._hasHelpOption = this._hasHelpOption;
1413
+ cmd._helpFlags = this._helpFlags;
1414
+ cmd._helpDescription = this._helpDescription;
1415
+ cmd._helpShortFlag = this._helpShortFlag;
1416
+ cmd._helpLongFlag = this._helpLongFlag;
1417
+ cmd._helpCommandName = this._helpCommandName;
1418
+ cmd._helpCommandnameAndArgs = this._helpCommandnameAndArgs;
1419
+ cmd._helpCommandDescription = this._helpCommandDescription;
1420
+ cmd._helpConfiguration = this._helpConfiguration;
1421
+ cmd._exitCallback = this._exitCallback;
1422
+ cmd._storeOptionsAsProperties = this._storeOptionsAsProperties;
1423
+ cmd._combineFlagAndOptionalValue = this._combineFlagAndOptionalValue;
1424
+ cmd._allowExcessArguments = this._allowExcessArguments;
1425
+ cmd._enablePositionalOptions = this._enablePositionalOptions;
1426
+
1427
+ cmd._executableFile = opts.executableFile || null; // Custom name for executable file, set missing to null to match constructor
1428
+ this.commands.push(cmd);
1429
+ cmd._parseExpectedArgs(args);
1430
+ cmd.parent = this;
1431
+
1432
+ if (desc) return this;
1433
+ return cmd;
1434
+ };
1435
+
1436
+ /**
1437
+ * Factory routine to create a new unattached command.
1438
+ *
1439
+ * See .command() for creating an attached subcommand, which uses this routine to
1440
+ * create the command. You can override createCommand to customise subcommands.
1441
+ *
1442
+ * @param {string} [name]
1443
+ * @return {Command} new command
1444
+ */
1445
+
1446
+ createCommand(name) {
1447
+ return new Command(name);
1448
+ };
1449
+
1450
+ /**
1451
+ * You can customise the help with a subclass of Help by overriding createHelp,
1452
+ * or by overriding Help properties using configureHelp().
1453
+ *
1454
+ * @return {Help}
1455
+ */
1456
+
1457
+ createHelp() {
1458
+ return Object.assign(new Help(), this.configureHelp());
1459
+ };
1460
+
1461
+ /**
1462
+ * You can customise the help by overriding Help properties using configureHelp(),
1463
+ * or with a subclass of Help by overriding createHelp().
1464
+ *
1465
+ * @param {Object} [configuration] - configuration options
1466
+ * @return {Command|Object} `this` command for chaining, or stored configuration
1467
+ */
1468
+
1469
+ configureHelp(configuration) {
1470
+ if (configuration === undefined) return this._helpConfiguration;
1471
+
1472
+ this._helpConfiguration = configuration;
1473
+ return this;
1474
+ }
1475
+
1476
+ /**
1477
+ * The default output goes to stdout and stderr. You can customise this for special
1478
+ * applications. You can also customise the display of errors by overriding outputError.
1479
+ *
1480
+ * The configuration properties are all functions:
1481
+ *
1482
+ * // functions to change where being written, stdout and stderr
1483
+ * writeOut(str)
1484
+ * writeErr(str)
1485
+ * // matching functions to specify width for wrapping help
1486
+ * getOutHelpWidth()
1487
+ * getErrHelpWidth()
1488
+ * // functions based on what is being written out
1489
+ * outputError(str, write) // used for displaying errors, and not used for displaying help
1490
+ *
1491
+ * @param {Object} [configuration] - configuration options
1492
+ * @return {Command|Object} `this` command for chaining, or stored configuration
1493
+ */
1494
+
1495
+ configureOutput(configuration) {
1496
+ if (configuration === undefined) return this._outputConfiguration;
1497
+
1498
+ Object.assign(this._outputConfiguration, configuration);
1499
+ return this;
1319
1500
  }
1320
1501
 
1321
- var signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];
1322
- signals.forEach(function(signal) {
1323
- process.on(signal, function() {
1324
- if (proc.killed === false && proc.exitCode === null) {
1325
- proc.kill(signal);
1502
+ /**
1503
+ * Add a prepared subcommand.
1504
+ *
1505
+ * See .command() for creating an attached subcommand which inherits settings from its parent.
1506
+ *
1507
+ * @param {Command} cmd - new subcommand
1508
+ * @param {Object} [opts] - configuration options
1509
+ * @return {Command} `this` command for chaining
1510
+ */
1511
+
1512
+ addCommand(cmd, opts) {
1513
+ if (!cmd._name) throw new Error('Command passed to .addCommand() must have a name');
1514
+
1515
+ // To keep things simple, block automatic name generation for deeply nested executables.
1516
+ // Fail fast and detect when adding rather than later when parsing.
1517
+ function checkExplicitNames(commandArray) {
1518
+ commandArray.forEach((cmd) => {
1519
+ if (cmd._executableHandler && !cmd._executableFile) {
1520
+ throw new Error(`Must specify executableFile for deeply nested executable: ${cmd.name()}`);
1521
+ }
1522
+ checkExplicitNames(cmd.commands);
1523
+ });
1524
+ }
1525
+ checkExplicitNames(cmd.commands);
1526
+
1527
+ opts = opts || {};
1528
+ if (opts.isDefault) this._defaultCommandName = cmd._name;
1529
+ if (opts.noHelp || opts.hidden) cmd._hidden = true; // modifying passed command due to existing implementation
1530
+
1531
+ this.commands.push(cmd);
1532
+ cmd.parent = this;
1533
+ return this;
1534
+ };
1535
+
1536
+ /**
1537
+ * Define argument syntax for the command.
1538
+ */
1539
+
1540
+ arguments(desc) {
1541
+ return this._parseExpectedArgs(desc.split(/ +/));
1542
+ };
1543
+
1544
+ /**
1545
+ * Override default decision whether to add implicit help command.
1546
+ *
1547
+ * addHelpCommand() // force on
1548
+ * addHelpCommand(false); // force off
1549
+ * addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
1550
+ *
1551
+ * @return {Command} `this` command for chaining
1552
+ */
1553
+
1554
+ addHelpCommand(enableOrNameAndArgs, description) {
1555
+ if (enableOrNameAndArgs === false) {
1556
+ this._addImplicitHelpCommand = false;
1557
+ } else {
1558
+ this._addImplicitHelpCommand = true;
1559
+ if (typeof enableOrNameAndArgs === 'string') {
1560
+ this._helpCommandName = enableOrNameAndArgs.split(' ')[0];
1561
+ this._helpCommandnameAndArgs = enableOrNameAndArgs;
1562
+ }
1563
+ this._helpCommandDescription = description || this._helpCommandDescription;
1564
+ }
1565
+ return this;
1566
+ };
1567
+
1568
+ /**
1569
+ * @return {boolean}
1570
+ * @api private
1571
+ */
1572
+
1573
+ _hasImplicitHelpCommand() {
1574
+ if (this._addImplicitHelpCommand === undefined) {
1575
+ return this.commands.length && !this._actionHandler && !this._findCommand('help');
1576
+ }
1577
+ return this._addImplicitHelpCommand;
1578
+ };
1579
+
1580
+ /**
1581
+ * Parse expected `args`.
1582
+ *
1583
+ * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
1584
+ *
1585
+ * @param {Array} args
1586
+ * @return {Command} `this` command for chaining
1587
+ * @api private
1588
+ */
1589
+
1590
+ _parseExpectedArgs(args) {
1591
+ if (!args.length) return;
1592
+ args.forEach((arg) => {
1593
+ const argDetails = {
1594
+ required: false,
1595
+ name: '',
1596
+ variadic: false
1597
+ };
1598
+
1599
+ switch (arg[0]) {
1600
+ case '<':
1601
+ argDetails.required = true;
1602
+ argDetails.name = arg.slice(1, -1);
1603
+ break;
1604
+ case '[':
1605
+ argDetails.name = arg.slice(1, -1);
1606
+ break;
1607
+ }
1608
+
1609
+ if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {
1610
+ argDetails.variadic = true;
1611
+ argDetails.name = argDetails.name.slice(0, -3);
1612
+ }
1613
+ if (argDetails.name) {
1614
+ this._args.push(argDetails);
1326
1615
  }
1327
1616
  });
1328
- });
1329
- proc.on('close', process.exit.bind(process));
1330
- proc.on('error', function(err) {
1331
- if (err.code === 'ENOENT') {
1332
- console.error('\n %s(1) does not exist, try --help\n', bin);
1333
- } else if (err.code === 'EACCES') {
1334
- console.error('\n %s(1) not executable. try chmod or run with root\n', bin);
1617
+ this._args.forEach((arg, i) => {
1618
+ if (arg.variadic && i < this._args.length - 1) {
1619
+ throw new Error(`only the last argument can be variadic '${arg.name}'`);
1620
+ }
1621
+ });
1622
+ return this;
1623
+ };
1624
+
1625
+ /**
1626
+ * Register callback to use as replacement for calling process.exit.
1627
+ *
1628
+ * @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing
1629
+ * @return {Command} `this` command for chaining
1630
+ */
1631
+
1632
+ exitOverride(fn) {
1633
+ if (fn) {
1634
+ this._exitCallback = fn;
1635
+ } else {
1636
+ this._exitCallback = (err) => {
1637
+ if (err.code !== 'commander.executeSubCommandAsync') {
1638
+ throw err;
1639
+ }
1640
+ };
1335
1641
  }
1336
- process.exit(1);
1337
- });
1642
+ return this;
1643
+ };
1338
1644
 
1339
- // Store the reference to the child process
1340
- this.runningCommand = proc;
1341
- };
1645
+ /**
1646
+ * Call process.exit, and _exitCallback if defined.
1647
+ *
1648
+ * @param {number} exitCode exit code for using with process.exit
1649
+ * @param {string} code an id string representing the error
1650
+ * @param {string} message human-readable description of the error
1651
+ * @return never
1652
+ * @api private
1653
+ */
1342
1654
 
1343
- /**
1344
- * Normalize `args`, splitting joined short flags. For example
1345
- * the arg "-abc" is equivalent to "-a -b -c".
1346
- * This also normalizes equal sign and splits "--abc=def" into "--abc def".
1347
- *
1348
- * @param {Array} args
1349
- * @return {Array}
1350
- * @api private
1351
- */
1655
+ _exit(exitCode, code, message) {
1656
+ if (this._exitCallback) {
1657
+ this._exitCallback(new CommanderError(exitCode, code, message));
1658
+ // Expecting this line is not reached.
1659
+ }
1660
+ process.exit(exitCode);
1661
+ };
1352
1662
 
1353
- Command.prototype.normalize = function(args) {
1354
- var ret = [],
1355
- arg,
1356
- lastOpt,
1357
- index;
1358
-
1359
- for (var i = 0, len = args.length; i < len; ++i) {
1360
- arg = args[i];
1361
- if (i > 0) {
1362
- lastOpt = this.optionFor(args[i - 1]);
1363
- }
1364
-
1365
- if (arg === '--') {
1366
- // Honor option terminator
1367
- ret = ret.concat(args.slice(i));
1368
- break;
1369
- } else if (lastOpt && lastOpt.required) {
1370
- ret.push(arg);
1371
- } else if (arg.length > 1 && arg[0] === '-' && arg[1] !== '-') {
1372
- arg.slice(1).split('').forEach(function(c) {
1373
- ret.push('-' + c);
1374
- });
1375
- } else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) {
1376
- ret.push(arg.slice(0, index), arg.slice(index + 1));
1663
+ /**
1664
+ * Register callback `fn` for the command.
1665
+ *
1666
+ * Examples:
1667
+ *
1668
+ * program
1669
+ * .command('help')
1670
+ * .description('display verbose help')
1671
+ * .action(function() {
1672
+ * // output help here
1673
+ * });
1674
+ *
1675
+ * @param {Function} fn
1676
+ * @return {Command} `this` command for chaining
1677
+ */
1678
+
1679
+ action(fn) {
1680
+ const listener = (args) => {
1681
+ // The .action callback takes an extra parameter which is the command or options.
1682
+ const expectedArgsCount = this._args.length;
1683
+ const actionArgs = args.slice(0, expectedArgsCount);
1684
+ if (this._storeOptionsAsProperties) {
1685
+ actionArgs[expectedArgsCount] = this; // backwards compatible "options"
1686
+ } else {
1687
+ actionArgs[expectedArgsCount] = this.opts();
1688
+ }
1689
+ actionArgs.push(this);
1690
+
1691
+ const actionResult = fn.apply(this, actionArgs);
1692
+ // Remember result in case it is async. Assume parseAsync getting called on root.
1693
+ let rootCommand = this;
1694
+ while (rootCommand.parent) {
1695
+ rootCommand = rootCommand.parent;
1696
+ }
1697
+ rootCommand._actionResults.push(actionResult);
1698
+ };
1699
+ this._actionHandler = listener;
1700
+ return this;
1701
+ };
1702
+
1703
+ /**
1704
+ * Factory routine to create a new unattached option.
1705
+ *
1706
+ * See .option() for creating an attached option, which uses this routine to
1707
+ * create the option. You can override createOption to return a custom option.
1708
+ *
1709
+ * @param {string} flags
1710
+ * @param {string} [description]
1711
+ * @return {Option} new option
1712
+ */
1713
+
1714
+ createOption(flags, description) {
1715
+ return new Option(flags, description);
1716
+ };
1717
+
1718
+ /**
1719
+ * Add an option.
1720
+ *
1721
+ * @param {Option} option
1722
+ * @return {Command} `this` command for chaining
1723
+ */
1724
+ addOption(option) {
1725
+ const oname = option.name();
1726
+ const name = option.attributeName();
1727
+
1728
+ let defaultValue = option.defaultValue;
1729
+
1730
+ // preassign default value for --no-*, [optional], <required>, or plain flag if boolean value
1731
+ if (option.negate || option.optional || option.required || typeof defaultValue === 'boolean') {
1732
+ // when --no-foo we make sure default is true, unless a --foo option is already defined
1733
+ if (option.negate) {
1734
+ const positiveLongFlag = option.long.replace(/^--no-/, '--');
1735
+ defaultValue = this._findOption(positiveLongFlag) ? this._getOptionValue(name) : true;
1736
+ }
1737
+ // preassign only if we have a default
1738
+ if (defaultValue !== undefined) {
1739
+ this._setOptionValue(name, defaultValue);
1740
+ }
1741
+ }
1742
+
1743
+ // register the option
1744
+ this.options.push(option);
1745
+
1746
+ // when it's passed assign the value
1747
+ // and conditionally invoke the callback
1748
+ this.on('option:' + oname, (val) => {
1749
+ const oldValue = this._getOptionValue(name);
1750
+
1751
+ // custom processing
1752
+ if (val !== null && option.parseArg) {
1753
+ try {
1754
+ val = option.parseArg(val, oldValue === undefined ? defaultValue : oldValue);
1755
+ } catch (err) {
1756
+ if (err.code === 'commander.invalidOptionArgument') {
1757
+ const message = `error: option '${option.flags}' argument '${val}' is invalid. ${err.message}`;
1758
+ this._displayError(err.exitCode, err.code, message);
1759
+ }
1760
+ throw err;
1761
+ }
1762
+ } else if (val !== null && option.variadic) {
1763
+ val = option._concatValue(val, oldValue);
1764
+ }
1765
+
1766
+ // unassigned or boolean value
1767
+ if (typeof oldValue === 'boolean' || typeof oldValue === 'undefined') {
1768
+ // if no value, negate false, and we have a default, then use it!
1769
+ if (val == null) {
1770
+ this._setOptionValue(name, option.negate
1771
+ ? false
1772
+ : defaultValue || true);
1773
+ } else {
1774
+ this._setOptionValue(name, val);
1775
+ }
1776
+ } else if (val !== null) {
1777
+ // reassign
1778
+ this._setOptionValue(name, option.negate ? false : val);
1779
+ }
1780
+ });
1781
+
1782
+ return this;
1783
+ }
1784
+
1785
+ /**
1786
+ * Internal implementation shared by .option() and .requiredOption()
1787
+ *
1788
+ * @api private
1789
+ */
1790
+ _optionEx(config, flags, description, fn, defaultValue) {
1791
+ const option = this.createOption(flags, description);
1792
+ option.makeOptionMandatory(!!config.mandatory);
1793
+ if (typeof fn === 'function') {
1794
+ option.default(defaultValue).argParser(fn);
1795
+ } else if (fn instanceof RegExp) {
1796
+ // deprecated
1797
+ const regex = fn;
1798
+ fn = (val, def) => {
1799
+ const m = regex.exec(val);
1800
+ return m ? m[0] : def;
1801
+ };
1802
+ option.default(defaultValue).argParser(fn);
1377
1803
  } else {
1378
- ret.push(arg);
1804
+ option.default(fn);
1379
1805
  }
1806
+
1807
+ return this.addOption(option);
1380
1808
  }
1381
1809
 
1382
- return ret;
1383
- };
1810
+ /**
1811
+ * Define option with `flags`, `description` and optional
1812
+ * coercion `fn`.
1813
+ *
1814
+ * The `flags` string contains the short and/or long flags,
1815
+ * separated by comma, a pipe or space. The following are all valid
1816
+ * all will output this way when `--help` is used.
1817
+ *
1818
+ * "-p, --pepper"
1819
+ * "-p|--pepper"
1820
+ * "-p --pepper"
1821
+ *
1822
+ * Examples:
1823
+ *
1824
+ * // simple boolean defaulting to undefined
1825
+ * program.option('-p, --pepper', 'add pepper');
1826
+ *
1827
+ * program.pepper
1828
+ * // => undefined
1829
+ *
1830
+ * --pepper
1831
+ * program.pepper
1832
+ * // => true
1833
+ *
1834
+ * // simple boolean defaulting to true (unless non-negated option is also defined)
1835
+ * program.option('-C, --no-cheese', 'remove cheese');
1836
+ *
1837
+ * program.cheese
1838
+ * // => true
1839
+ *
1840
+ * --no-cheese
1841
+ * program.cheese
1842
+ * // => false
1843
+ *
1844
+ * // required argument
1845
+ * program.option('-C, --chdir <path>', 'change the working directory');
1846
+ *
1847
+ * --chdir /tmp
1848
+ * program.chdir
1849
+ * // => "/tmp"
1850
+ *
1851
+ * // optional argument
1852
+ * program.option('-c, --cheese [type]', 'add cheese [marble]');
1853
+ *
1854
+ * @param {string} flags
1855
+ * @param {string} [description]
1856
+ * @param {Function|*} [fn] - custom option processing function or default value
1857
+ * @param {*} [defaultValue]
1858
+ * @return {Command} `this` command for chaining
1859
+ */
1384
1860
 
1385
- /**
1386
- * Parse command `args`.
1387
- *
1388
- * When listener(s) are available those
1389
- * callbacks are invoked, otherwise the "*"
1390
- * event is emitted and those actions are invoked.
1391
- *
1392
- * @param {Array} args
1393
- * @return {Command} for chaining
1394
- * @api private
1395
- */
1861
+ option(flags, description, fn, defaultValue) {
1862
+ return this._optionEx({}, flags, description, fn, defaultValue);
1863
+ };
1864
+
1865
+ /**
1866
+ * Add a required option which must have a value after parsing. This usually means
1867
+ * the option must be specified on the command line. (Otherwise the same as .option().)
1868
+ *
1869
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
1870
+ *
1871
+ * @param {string} flags
1872
+ * @param {string} [description]
1873
+ * @param {Function|*} [fn] - custom option processing function or default value
1874
+ * @param {*} [defaultValue]
1875
+ * @return {Command} `this` command for chaining
1876
+ */
1877
+
1878
+ requiredOption(flags, description, fn, defaultValue) {
1879
+ return this._optionEx({ mandatory: true }, flags, description, fn, defaultValue);
1880
+ };
1396
1881
 
1397
- Command.prototype.parseArgs = function(args, unknown) {
1398
- var name;
1882
+ /**
1883
+ * Alter parsing of short flags with optional values.
1884
+ *
1885
+ * Examples:
1886
+ *
1887
+ * // for `.option('-f,--flag [value]'):
1888
+ * .combineFlagAndOptionalValue(true) // `-f80` is treated like `--flag=80`, this is the default behaviour
1889
+ * .combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
1890
+ *
1891
+ * @param {Boolean} [combine=true] - if `true` or omitted, an optional value can be specified directly after the flag.
1892
+ */
1893
+ combineFlagAndOptionalValue(combine = true) {
1894
+ this._combineFlagAndOptionalValue = !!combine;
1895
+ return this;
1896
+ };
1399
1897
 
1400
- if (args.length) {
1401
- name = args[0];
1402
- if (this.listeners('command:' + name).length) {
1403
- this.emit('command:' + args.shift(), args, unknown);
1404
- } else {
1405
- this.emit('command:*', args);
1898
+ /**
1899
+ * Allow unknown options on the command line.
1900
+ *
1901
+ * @param {Boolean} [allowUnknown=true] - if `true` or omitted, no error will be thrown
1902
+ * for unknown options.
1903
+ */
1904
+ allowUnknownOption(allowUnknown = true) {
1905
+ this._allowUnknownOption = !!allowUnknown;
1906
+ return this;
1907
+ };
1908
+
1909
+ /**
1910
+ * Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
1911
+ *
1912
+ * @param {Boolean} [allowExcess=true] - if `true` or omitted, no error will be thrown
1913
+ * for excess arguments.
1914
+ */
1915
+ allowExcessArguments(allowExcess = true) {
1916
+ this._allowExcessArguments = !!allowExcess;
1917
+ return this;
1918
+ };
1919
+
1920
+ /**
1921
+ * Enable positional options. Positional means global options are specified before subcommands which lets
1922
+ * subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
1923
+ * The default behaviour is non-positional and global options may appear anywhere on the command line.
1924
+ *
1925
+ * @param {Boolean} [positional=true]
1926
+ */
1927
+ enablePositionalOptions(positional = true) {
1928
+ this._enablePositionalOptions = !!positional;
1929
+ return this;
1930
+ };
1931
+
1932
+ /**
1933
+ * Pass through options that come after command-arguments rather than treat them as command-options,
1934
+ * so actual command-options come before command-arguments. Turning this on for a subcommand requires
1935
+ * positional options to have been enabled on the program (parent commands).
1936
+ * The default behaviour is non-positional and options may appear before or after command-arguments.
1937
+ *
1938
+ * @param {Boolean} [passThrough=true]
1939
+ * for unknown options.
1940
+ */
1941
+ passThroughOptions(passThrough = true) {
1942
+ this._passThroughOptions = !!passThrough;
1943
+ if (!!this.parent && passThrough && !this.parent._enablePositionalOptions) {
1944
+ throw new Error('passThroughOptions can not be used without turning on enablePositionalOptions for parent command(s)');
1406
1945
  }
1407
- } else {
1408
- outputHelpIfNecessary(this, unknown);
1946
+ return this;
1947
+ };
1409
1948
 
1410
- // If there were no args and we have unknown options,
1411
- // then they are extraneous and we need to error.
1412
- if (unknown.length > 0) {
1413
- this.unknownOption(unknown[0]);
1949
+ /**
1950
+ * Whether to store option values as properties on command object,
1951
+ * or store separately (specify false). In both cases the option values can be accessed using .opts().
1952
+ *
1953
+ * @param {boolean} [storeAsProperties=true]
1954
+ * @return {Command} `this` command for chaining
1955
+ */
1956
+
1957
+ storeOptionsAsProperties(storeAsProperties = true) {
1958
+ this._storeOptionsAsProperties = !!storeAsProperties;
1959
+ if (this.options.length) {
1960
+ throw new Error('call .storeOptionsAsProperties() before adding options');
1414
1961
  }
1415
- }
1962
+ return this;
1963
+ };
1416
1964
 
1417
- return this;
1418
- };
1965
+ /**
1966
+ * Store option value
1967
+ *
1968
+ * @param {string} key
1969
+ * @param {Object} value
1970
+ * @api private
1971
+ */
1419
1972
 
1420
- /**
1421
- * Return an option matching `arg` if any.
1422
- *
1423
- * @param {String} arg
1424
- * @return {Option}
1425
- * @api private
1426
- */
1973
+ _setOptionValue(key, value) {
1974
+ if (this._storeOptionsAsProperties) {
1975
+ this[key] = value;
1976
+ } else {
1977
+ this._optionValues[key] = value;
1978
+ }
1979
+ };
1980
+
1981
+ /**
1982
+ * Retrieve option value
1983
+ *
1984
+ * @param {string} key
1985
+ * @return {Object} value
1986
+ * @api private
1987
+ */
1427
1988
 
1428
- Command.prototype.optionFor = function(arg) {
1429
- for (var i = 0, len = this.options.length; i < len; ++i) {
1430
- if (this.options[i].is(arg)) {
1431
- return this.options[i];
1989
+ _getOptionValue(key) {
1990
+ if (this._storeOptionsAsProperties) {
1991
+ return this[key];
1432
1992
  }
1433
- }
1434
- };
1993
+ return this._optionValues[key];
1994
+ };
1435
1995
 
1436
- /**
1437
- * Parse options from `argv` returning `argv`
1438
- * void of these options.
1439
- *
1440
- * @param {Array} argv
1441
- * @return {Array}
1442
- * @api public
1443
- */
1996
+ /**
1997
+ * Parse `argv`, setting options and invoking commands when defined.
1998
+ *
1999
+ * The default expectation is that the arguments are from node and have the application as argv[0]
2000
+ * and the script being run in argv[1], with user parameters after that.
2001
+ *
2002
+ * Examples:
2003
+ *
2004
+ * program.parse(process.argv);
2005
+ * program.parse(); // implicitly use process.argv and auto-detect node vs electron conventions
2006
+ * program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
2007
+ *
2008
+ * @param {string[]} [argv] - optional, defaults to process.argv
2009
+ * @param {Object} [parseOptions] - optionally specify style of options with from: node/user/electron
2010
+ * @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'
2011
+ * @return {Command} `this` command for chaining
2012
+ */
1444
2013
 
1445
- Command.prototype.parseOptions = function(argv) {
1446
- var args = [],
1447
- len = argv.length,
1448
- literal,
1449
- option,
1450
- arg;
1451
-
1452
- var unknownOptions = [];
1453
-
1454
- // parse options
1455
- for (var i = 0; i < len; ++i) {
1456
- arg = argv[i];
1457
-
1458
- // literal args after --
1459
- if (literal) {
1460
- args.push(arg);
1461
- continue;
1462
- }
1463
-
1464
- if (arg === '--') {
1465
- literal = true;
1466
- continue;
1467
- }
1468
-
1469
- // find matching Option
1470
- option = this.optionFor(arg);
1471
-
1472
- // option is defined
1473
- if (option) {
1474
- // requires arg
1475
- if (option.required) {
1476
- arg = argv[++i];
1477
- if (arg == null) return this.optionMissingArgument(option);
1478
- this.emit('option:' + option.name(), arg);
1479
- // optional arg
1480
- } else if (option.optional) {
1481
- arg = argv[i + 1];
1482
- if (arg == null || (arg[0] === '-' && arg !== '-')) {
1483
- arg = null;
2014
+ parse(argv, parseOptions) {
2015
+ if (argv !== undefined && !Array.isArray(argv)) {
2016
+ throw new Error('first parameter to parse must be array or undefined');
2017
+ }
2018
+ parseOptions = parseOptions || {};
2019
+
2020
+ // Default to using process.argv
2021
+ if (argv === undefined) {
2022
+ argv = process.argv;
2023
+ // @ts-ignore: unknown property
2024
+ if (process.versions && process.versions.electron) {
2025
+ parseOptions.from = 'electron';
2026
+ }
2027
+ }
2028
+ this.rawArgs = argv.slice();
2029
+
2030
+ // make it a little easier for callers by supporting various argv conventions
2031
+ let userArgs;
2032
+ switch (parseOptions.from) {
2033
+ case undefined:
2034
+ case 'node':
2035
+ this._scriptPath = argv[1];
2036
+ userArgs = argv.slice(2);
2037
+ break;
2038
+ case 'electron':
2039
+ // @ts-ignore: unknown property
2040
+ if (process.defaultApp) {
2041
+ this._scriptPath = argv[1];
2042
+ userArgs = argv.slice(2);
1484
2043
  } else {
1485
- ++i;
2044
+ userArgs = argv.slice(1);
2045
+ }
2046
+ break;
2047
+ case 'user':
2048
+ userArgs = argv.slice(0);
2049
+ break;
2050
+ default:
2051
+ throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
2052
+ }
2053
+ if (!this._scriptPath && require.main) {
2054
+ this._scriptPath = require.main.filename;
2055
+ }
2056
+
2057
+ // Guess name, used in usage in help.
2058
+ this._name = this._name || (this._scriptPath && path.basename(this._scriptPath, path.extname(this._scriptPath)));
2059
+
2060
+ // Let's go!
2061
+ this._parseCommand([], userArgs);
2062
+
2063
+ return this;
2064
+ };
2065
+
2066
+ /**
2067
+ * Parse `argv`, setting options and invoking commands when defined.
2068
+ *
2069
+ * Use parseAsync instead of parse if any of your action handlers are async. Returns a Promise.
2070
+ *
2071
+ * The default expectation is that the arguments are from node and have the application as argv[0]
2072
+ * and the script being run in argv[1], with user parameters after that.
2073
+ *
2074
+ * Examples:
2075
+ *
2076
+ * program.parseAsync(process.argv);
2077
+ * program.parseAsync(); // implicitly use process.argv and auto-detect node vs electron conventions
2078
+ * program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
2079
+ *
2080
+ * @param {string[]} [argv]
2081
+ * @param {Object} [parseOptions]
2082
+ * @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'
2083
+ * @return {Promise}
2084
+ */
2085
+
2086
+ parseAsync(argv, parseOptions) {
2087
+ this.parse(argv, parseOptions);
2088
+ return Promise.all(this._actionResults).then(() => this);
2089
+ };
2090
+
2091
+ /**
2092
+ * Execute a sub-command executable.
2093
+ *
2094
+ * @api private
2095
+ */
2096
+
2097
+ _executeSubCommand(subcommand, args) {
2098
+ args = args.slice();
2099
+ let launchWithNode = false; // Use node for source targets so do not need to get permissions correct, and on Windows.
2100
+ const sourceExt = ['.js', '.ts', '.tsx', '.mjs', '.cjs'];
2101
+
2102
+ // Not checking for help first. Unlikely to have mandatory and executable, and can't robustly test for help flags in external command.
2103
+ this._checkForMissingMandatoryOptions();
2104
+
2105
+ // Want the entry script as the reference for command name and directory for searching for other files.
2106
+ let scriptPath = this._scriptPath;
2107
+ // Fallback in case not set, due to how Command created or called.
2108
+ if (!scriptPath && require.main) {
2109
+ scriptPath = require.main.filename;
2110
+ }
2111
+
2112
+ let baseDir;
2113
+ try {
2114
+ const resolvedLink = fs.realpathSync(scriptPath);
2115
+ baseDir = path.dirname(resolvedLink);
2116
+ } catch (e) {
2117
+ baseDir = '.'; // dummy, probably not going to find executable!
2118
+ }
2119
+
2120
+ // name of the subcommand, like `pm-install`
2121
+ let bin = path.basename(scriptPath, path.extname(scriptPath)) + '-' + subcommand._name;
2122
+ if (subcommand._executableFile) {
2123
+ bin = subcommand._executableFile;
2124
+ }
2125
+
2126
+ const localBin = path.join(baseDir, bin);
2127
+ if (fs.existsSync(localBin)) {
2128
+ // prefer local `./<bin>` to bin in the $PATH
2129
+ bin = localBin;
2130
+ } else {
2131
+ // Look for source files.
2132
+ sourceExt.forEach((ext) => {
2133
+ if (fs.existsSync(`${localBin}${ext}`)) {
2134
+ bin = `${localBin}${ext}`;
1486
2135
  }
1487
- this.emit('option:' + option.name(), arg);
1488
- // bool
2136
+ });
2137
+ }
2138
+ launchWithNode = sourceExt.includes(path.extname(bin));
2139
+
2140
+ let proc;
2141
+ if (process.platform !== 'win32') {
2142
+ if (launchWithNode) {
2143
+ args.unshift(bin);
2144
+ // add executable arguments to spawn
2145
+ args = incrementNodeInspectorPort(process.execArgv).concat(args);
2146
+
2147
+ proc = childProcess.spawn(process.argv[0], args, { stdio: 'inherit' });
1489
2148
  } else {
1490
- this.emit('option:' + option.name());
2149
+ proc = childProcess.spawn(bin, args, { stdio: 'inherit' });
1491
2150
  }
1492
- continue;
2151
+ } else {
2152
+ args.unshift(bin);
2153
+ // add executable arguments to spawn
2154
+ args = incrementNodeInspectorPort(process.execArgv).concat(args);
2155
+ proc = childProcess.spawn(process.execPath, args, { stdio: 'inherit' });
1493
2156
  }
1494
2157
 
1495
- // looks like an option
1496
- if (arg.length > 1 && arg[0] === '-') {
1497
- unknownOptions.push(arg);
2158
+ const signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];
2159
+ signals.forEach((signal) => {
2160
+ // @ts-ignore
2161
+ process.on(signal, () => {
2162
+ if (proc.killed === false && proc.exitCode === null) {
2163
+ proc.kill(signal);
2164
+ }
2165
+ });
2166
+ });
1498
2167
 
1499
- // If the next argument looks like it might be
1500
- // an argument for this option, we pass it on.
1501
- // If it isn't, then it'll simply be ignored
1502
- if ((i + 1) < argv.length && argv[i + 1][0] !== '-') {
1503
- unknownOptions.push(argv[++i]);
2168
+ // By default terminate process when spawned process terminates.
2169
+ // Suppressing the exit if exitCallback defined is a bit messy and of limited use, but does allow process to stay running!
2170
+ const exitCallback = this._exitCallback;
2171
+ if (!exitCallback) {
2172
+ proc.on('close', process.exit.bind(process));
2173
+ } else {
2174
+ proc.on('close', () => {
2175
+ exitCallback(new CommanderError(process.exitCode || 0, 'commander.executeSubCommandAsync', '(close)'));
2176
+ });
2177
+ }
2178
+ proc.on('error', (err) => {
2179
+ // @ts-ignore
2180
+ if (err.code === 'ENOENT') {
2181
+ const executableMissing = `'${bin}' does not exist
2182
+ - if '${subcommand._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
2183
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name`;
2184
+ throw new Error(executableMissing);
2185
+ // @ts-ignore
2186
+ } else if (err.code === 'EACCES') {
2187
+ throw new Error(`'${bin}' not executable`);
2188
+ }
2189
+ if (!exitCallback) {
2190
+ process.exit(1);
2191
+ } else {
2192
+ const wrappedError = new CommanderError(1, 'commander.executeSubCommandAsync', '(error)');
2193
+ wrappedError.nestedError = err;
2194
+ exitCallback(wrappedError);
1504
2195
  }
1505
- continue;
2196
+ });
2197
+
2198
+ // Store the reference to the child process
2199
+ this.runningCommand = proc;
2200
+ };
2201
+
2202
+ /**
2203
+ * @api private
2204
+ */
2205
+ _dispatchSubcommand(commandName, operands, unknown) {
2206
+ const subCommand = this._findCommand(commandName);
2207
+ if (!subCommand) this.help({ error: true });
2208
+
2209
+ if (subCommand._executableHandler) {
2210
+ this._executeSubCommand(subCommand, operands.concat(unknown));
2211
+ } else {
2212
+ subCommand._parseCommand(operands, unknown);
1506
2213
  }
2214
+ };
1507
2215
 
1508
- // arg
1509
- args.push(arg);
1510
- }
2216
+ /**
2217
+ * Process arguments in context of this command.
2218
+ *
2219
+ * @api private
2220
+ */
1511
2221
 
1512
- return { args: args, unknown: unknownOptions };
1513
- };
2222
+ _parseCommand(operands, unknown) {
2223
+ const parsed = this.parseOptions(unknown);
2224
+ operands = operands.concat(parsed.operands);
2225
+ unknown = parsed.unknown;
2226
+ this.args = operands.concat(unknown);
2227
+
2228
+ if (operands && this._findCommand(operands[0])) {
2229
+ this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
2230
+ } else if (this._hasImplicitHelpCommand() && operands[0] === this._helpCommandName) {
2231
+ if (operands.length === 1) {
2232
+ this.help();
2233
+ } else {
2234
+ this._dispatchSubcommand(operands[1], [], [this._helpLongFlag]);
2235
+ }
2236
+ } else if (this._defaultCommandName) {
2237
+ outputHelpIfRequested(this, unknown); // Run the help for default command from parent rather than passing to default command
2238
+ this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
2239
+ } else {
2240
+ if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
2241
+ // probably missing subcommand and no handler, user needs help
2242
+ this.help({ error: true });
2243
+ }
1514
2244
 
1515
- /**
1516
- * Return an object containing options as key-value pairs
1517
- *
1518
- * @return {Object}
1519
- * @api public
1520
- */
1521
- Command.prototype.opts = function() {
1522
- var result = {},
1523
- len = this.options.length;
2245
+ outputHelpIfRequested(this, parsed.unknown);
2246
+ this._checkForMissingMandatoryOptions();
1524
2247
 
1525
- for (var i = 0; i < len; i++) {
1526
- var key = this.options[i].attributeName();
1527
- result[key] = key === this._versionOptionName ? this._version : this[key];
1528
- }
1529
- return result;
1530
- };
2248
+ // We do not always call this check to avoid masking a "better" error, like unknown command.
2249
+ const checkForUnknownOptions = () => {
2250
+ if (parsed.unknown.length > 0) {
2251
+ this.unknownOption(parsed.unknown[0]);
2252
+ }
2253
+ };
1531
2254
 
1532
- /**
1533
- * Argument `name` is missing.
1534
- *
1535
- * @param {String} name
1536
- * @api private
1537
- */
2255
+ const commandEvent = `command:${this.name()}`;
2256
+ if (this._actionHandler) {
2257
+ checkForUnknownOptions();
2258
+ // Check expected arguments and collect variadic together.
2259
+ const args = this.args.slice();
2260
+ this._args.forEach((arg, i) => {
2261
+ if (arg.required && args[i] == null) {
2262
+ this.missingArgument(arg.name);
2263
+ } else if (arg.variadic) {
2264
+ args[i] = args.splice(i);
2265
+ args.length = Math.min(i + 1, args.length);
2266
+ }
2267
+ });
2268
+ if (args.length > this._args.length) {
2269
+ this._excessArguments(args);
2270
+ }
1538
2271
 
1539
- Command.prototype.missingArgument = function(name) {
1540
- console.error();
1541
- console.error(" error: missing required argument `%s'", name);
1542
- console.error();
1543
- process.exit(1);
1544
- };
2272
+ this._actionHandler(args);
2273
+ if (this.parent) this.parent.emit(commandEvent, operands, unknown); // legacy
2274
+ } else if (this.parent && this.parent.listenerCount(commandEvent)) {
2275
+ checkForUnknownOptions();
2276
+ this.parent.emit(commandEvent, operands, unknown); // legacy
2277
+ } else if (operands.length) {
2278
+ if (this._findCommand('*')) { // legacy default command
2279
+ this._dispatchSubcommand('*', operands, unknown);
2280
+ } else if (this.listenerCount('command:*')) {
2281
+ // skip option check, emit event for possible misspelling suggestion
2282
+ this.emit('command:*', operands, unknown);
2283
+ } else if (this.commands.length) {
2284
+ this.unknownCommand();
2285
+ } else {
2286
+ checkForUnknownOptions();
2287
+ }
2288
+ } else if (this.commands.length) {
2289
+ // This command has subcommands and nothing hooked up at this level, so display help.
2290
+ this.help({ error: true });
2291
+ } else {
2292
+ checkForUnknownOptions();
2293
+ // fall through for caller to handle after calling .parse()
2294
+ }
2295
+ }
2296
+ };
1545
2297
 
1546
- /**
1547
- * `Option` is missing an argument, but received `flag` or nothing.
1548
- *
1549
- * @param {String} option
1550
- * @param {String} flag
1551
- * @api private
1552
- */
2298
+ /**
2299
+ * Find matching command.
2300
+ *
2301
+ * @api private
2302
+ */
2303
+ _findCommand(name) {
2304
+ if (!name) return undefined;
2305
+ return this.commands.find(cmd => cmd._name === name || cmd._aliases.includes(name));
2306
+ };
1553
2307
 
1554
- Command.prototype.optionMissingArgument = function(option, flag) {
1555
- console.error();
1556
- if (flag) {
1557
- console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag);
1558
- } else {
1559
- console.error(" error: option `%s' argument missing", option.flags);
2308
+ /**
2309
+ * Return an option matching `arg` if any.
2310
+ *
2311
+ * @param {string} arg
2312
+ * @return {Option}
2313
+ * @api private
2314
+ */
2315
+
2316
+ _findOption(arg) {
2317
+ return this.options.find(option => option.is(arg));
2318
+ };
2319
+
2320
+ /**
2321
+ * Display an error message if a mandatory option does not have a value.
2322
+ * Lazy calling after checking for help flags from leaf subcommand.
2323
+ *
2324
+ * @api private
2325
+ */
2326
+
2327
+ _checkForMissingMandatoryOptions() {
2328
+ // Walk up hierarchy so can call in subcommand after checking for displaying help.
2329
+ for (let cmd = this; cmd; cmd = cmd.parent) {
2330
+ cmd.options.forEach((anOption) => {
2331
+ if (anOption.mandatory && (cmd._getOptionValue(anOption.attributeName()) === undefined)) {
2332
+ cmd.missingMandatoryOptionValue(anOption);
2333
+ }
2334
+ });
2335
+ }
2336
+ };
2337
+
2338
+ /**
2339
+ * Parse options from `argv` removing known options,
2340
+ * and return argv split into operands and unknown arguments.
2341
+ *
2342
+ * Examples:
2343
+ *
2344
+ * argv => operands, unknown
2345
+ * --known kkk op => [op], []
2346
+ * op --known kkk => [op], []
2347
+ * sub --unknown uuu op => [sub], [--unknown uuu op]
2348
+ * sub -- --unknown uuu op => [sub --unknown uuu op], []
2349
+ *
2350
+ * @param {String[]} argv
2351
+ * @return {{operands: String[], unknown: String[]}}
2352
+ */
2353
+
2354
+ parseOptions(argv) {
2355
+ const operands = []; // operands, not options or values
2356
+ const unknown = []; // first unknown option and remaining unknown args
2357
+ let dest = operands;
2358
+ const args = argv.slice();
2359
+
2360
+ function maybeOption(arg) {
2361
+ return arg.length > 1 && arg[0] === '-';
2362
+ }
2363
+
2364
+ // parse options
2365
+ let activeVariadicOption = null;
2366
+ while (args.length) {
2367
+ const arg = args.shift();
2368
+
2369
+ // literal
2370
+ if (arg === '--') {
2371
+ if (dest === unknown) dest.push(arg);
2372
+ dest.push(...args);
2373
+ break;
2374
+ }
2375
+
2376
+ if (activeVariadicOption && !maybeOption(arg)) {
2377
+ this.emit(`option:${activeVariadicOption.name()}`, arg);
2378
+ continue;
2379
+ }
2380
+ activeVariadicOption = null;
2381
+
2382
+ if (maybeOption(arg)) {
2383
+ const option = this._findOption(arg);
2384
+ // recognised option, call listener to assign value with possible custom processing
2385
+ if (option) {
2386
+ if (option.required) {
2387
+ const value = args.shift();
2388
+ if (value === undefined) this.optionMissingArgument(option);
2389
+ this.emit(`option:${option.name()}`, value);
2390
+ } else if (option.optional) {
2391
+ let value = null;
2392
+ // historical behaviour is optional value is following arg unless an option
2393
+ if (args.length > 0 && !maybeOption(args[0])) {
2394
+ value = args.shift();
2395
+ }
2396
+ this.emit(`option:${option.name()}`, value);
2397
+ } else { // boolean flag
2398
+ this.emit(`option:${option.name()}`);
2399
+ }
2400
+ activeVariadicOption = option.variadic ? option : null;
2401
+ continue;
2402
+ }
2403
+ }
2404
+
2405
+ // Look for combo options following single dash, eat first one if known.
2406
+ if (arg.length > 2 && arg[0] === '-' && arg[1] !== '-') {
2407
+ const option = this._findOption(`-${arg[1]}`);
2408
+ if (option) {
2409
+ if (option.required || (option.optional && this._combineFlagAndOptionalValue)) {
2410
+ // option with value following in same argument
2411
+ this.emit(`option:${option.name()}`, arg.slice(2));
2412
+ } else {
2413
+ // boolean option, emit and put back remainder of arg for further processing
2414
+ this.emit(`option:${option.name()}`);
2415
+ args.unshift(`-${arg.slice(2)}`);
2416
+ }
2417
+ continue;
2418
+ }
2419
+ }
2420
+
2421
+ // Look for known long flag with value, like --foo=bar
2422
+ if (/^--[^=]+=/.test(arg)) {
2423
+ const index = arg.indexOf('=');
2424
+ const option = this._findOption(arg.slice(0, index));
2425
+ if (option && (option.required || option.optional)) {
2426
+ this.emit(`option:${option.name()}`, arg.slice(index + 1));
2427
+ continue;
2428
+ }
2429
+ }
2430
+
2431
+ // Not a recognised option by this command.
2432
+ // Might be a command-argument, or subcommand option, or unknown option, or help command or option.
2433
+
2434
+ // An unknown option means further arguments also classified as unknown so can be reprocessed by subcommands.
2435
+ if (maybeOption(arg)) {
2436
+ dest = unknown;
2437
+ }
2438
+
2439
+ // If using positionalOptions, stop processing our options at subcommand.
2440
+ if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
2441
+ if (this._findCommand(arg)) {
2442
+ operands.push(arg);
2443
+ if (args.length > 0) unknown.push(...args);
2444
+ break;
2445
+ } else if (arg === this._helpCommandName && this._hasImplicitHelpCommand()) {
2446
+ operands.push(arg);
2447
+ if (args.length > 0) operands.push(...args);
2448
+ break;
2449
+ } else if (this._defaultCommandName) {
2450
+ unknown.push(arg);
2451
+ if (args.length > 0) unknown.push(...args);
2452
+ break;
2453
+ }
2454
+ }
2455
+
2456
+ // If using passThroughOptions, stop processing options at first command-argument.
2457
+ if (this._passThroughOptions) {
2458
+ dest.push(arg);
2459
+ if (args.length > 0) dest.push(...args);
2460
+ break;
2461
+ }
2462
+
2463
+ // add arg
2464
+ dest.push(arg);
2465
+ }
2466
+
2467
+ return { operands, unknown };
2468
+ };
2469
+
2470
+ /**
2471
+ * Return an object containing options as key-value pairs
2472
+ *
2473
+ * @return {Object}
2474
+ */
2475
+ opts() {
2476
+ if (this._storeOptionsAsProperties) {
2477
+ // Preserve original behaviour so backwards compatible when still using properties
2478
+ const result = {};
2479
+ const len = this.options.length;
2480
+
2481
+ for (let i = 0; i < len; i++) {
2482
+ const key = this.options[i].attributeName();
2483
+ result[key] = key === this._versionOptionName ? this._version : this[key];
2484
+ }
2485
+ return result;
2486
+ }
2487
+
2488
+ return this._optionValues;
2489
+ };
2490
+
2491
+ /**
2492
+ * Internal bottleneck for handling of parsing errors.
2493
+ *
2494
+ * @api private
2495
+ */
2496
+ _displayError(exitCode, code, message) {
2497
+ this._outputConfiguration.outputError(`${message}\n`, this._outputConfiguration.writeErr);
2498
+ this._exit(exitCode, code, message);
1560
2499
  }
1561
- console.error();
1562
- process.exit(1);
1563
- };
1564
2500
 
1565
- /**
1566
- * Unknown option `flag`.
1567
- *
1568
- * @param {String} flag
1569
- * @api private
1570
- */
2501
+ /**
2502
+ * Argument `name` is missing.
2503
+ *
2504
+ * @param {string} name
2505
+ * @api private
2506
+ */
2507
+
2508
+ missingArgument(name) {
2509
+ const message = `error: missing required argument '${name}'`;
2510
+ this._displayError(1, 'commander.missingArgument', message);
2511
+ };
1571
2512
 
1572
- Command.prototype.unknownOption = function(flag) {
1573
- if (this._allowUnknownOption) return;
1574
- console.error();
1575
- console.error(" error: unknown option `%s'", flag);
1576
- console.error();
1577
- process.exit(1);
1578
- };
2513
+ /**
2514
+ * `Option` is missing an argument.
2515
+ *
2516
+ * @param {Option} option
2517
+ * @api private
2518
+ */
1579
2519
 
1580
- /**
1581
- * Variadic argument with `name` is not the last argument as required.
1582
- *
1583
- * @param {String} name
1584
- * @api private
1585
- */
2520
+ optionMissingArgument(option) {
2521
+ const message = `error: option '${option.flags}' argument missing`;
2522
+ this._displayError(1, 'commander.optionMissingArgument', message);
2523
+ };
1586
2524
 
1587
- Command.prototype.variadicArgNotLast = function(name) {
1588
- console.error();
1589
- console.error(" error: variadic arguments must be last `%s'", name);
1590
- console.error();
1591
- process.exit(1);
1592
- };
2525
+ /**
2526
+ * `Option` does not have a value, and is a mandatory option.
2527
+ *
2528
+ * @param {Option} option
2529
+ * @api private
2530
+ */
1593
2531
 
1594
- /**
1595
- * Set the program version to `str`.
1596
- *
1597
- * This method auto-registers the "-V, --version" flag
1598
- * which will print the version number when passed.
1599
- *
1600
- * @param {String} str
1601
- * @param {String} [flags]
1602
- * @return {Command} for chaining
1603
- * @api public
1604
- */
2532
+ missingMandatoryOptionValue(option) {
2533
+ const message = `error: required option '${option.flags}' not specified`;
2534
+ this._displayError(1, 'commander.missingMandatoryOptionValue', message);
2535
+ };
1605
2536
 
1606
- Command.prototype.version = function(str, flags) {
1607
- if (arguments.length === 0) return this._version;
1608
- this._version = str;
1609
- flags = flags || '-V, --version';
1610
- var versionOption = new Option(flags, 'output the version number');
1611
- this._versionOptionName = versionOption.long.substr(2) || 'version';
1612
- this.options.push(versionOption);
1613
- this.on('option:' + this._versionOptionName, function() {
1614
- process.stdout.write(str + '\n');
1615
- process.exit(0);
1616
- });
1617
- return this;
1618
- };
2537
+ /**
2538
+ * Unknown option `flag`.
2539
+ *
2540
+ * @param {string} flag
2541
+ * @api private
2542
+ */
1619
2543
 
1620
- /**
1621
- * Set the description to `str`.
1622
- *
1623
- * @param {String} str
1624
- * @param {Object} argsDescription
1625
- * @return {String|Command}
1626
- * @api public
1627
- */
2544
+ unknownOption(flag) {
2545
+ if (this._allowUnknownOption) return;
2546
+ const message = `error: unknown option '${flag}'`;
2547
+ this._displayError(1, 'commander.unknownOption', message);
2548
+ };
1628
2549
 
1629
- Command.prototype.description = function(str, argsDescription) {
1630
- if (arguments.length === 0) return this._description;
1631
- this._description = str;
1632
- this._argsDescription = argsDescription;
1633
- return this;
1634
- };
2550
+ /**
2551
+ * Excess arguments, more than expected.
2552
+ *
2553
+ * @param {string[]} receivedArgs
2554
+ * @api private
2555
+ */
1635
2556
 
1636
- /**
1637
- * Set an alias for the command
1638
- *
1639
- * @param {String} alias
1640
- * @return {String|Command}
1641
- * @api public
1642
- */
2557
+ _excessArguments(receivedArgs) {
2558
+ if (this._allowExcessArguments) return;
1643
2559
 
1644
- Command.prototype.alias = function(alias) {
1645
- var command = this;
1646
- if (this.commands.length !== 0) {
1647
- command = this.commands[this.commands.length - 1];
1648
- }
2560
+ const expected = this._args.length;
2561
+ const s = (expected === 1) ? '' : 's';
2562
+ const forSubcommand = this.parent ? ` for '${this.name()}'` : '';
2563
+ const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
2564
+ this._displayError(1, 'commander.excessArguments', message);
2565
+ };
1649
2566
 
1650
- if (arguments.length === 0) return command._alias;
2567
+ /**
2568
+ * Unknown command.
2569
+ *
2570
+ * @api private
2571
+ */
1651
2572
 
1652
- if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');
2573
+ unknownCommand() {
2574
+ const partCommands = [this.name()];
2575
+ for (let parentCmd = this.parent; parentCmd; parentCmd = parentCmd.parent) {
2576
+ partCommands.unshift(parentCmd.name());
2577
+ }
2578
+ const fullCommand = partCommands.join(' ');
2579
+ const message = `error: unknown command '${this.args[0]}'.` +
2580
+ (this._hasHelpOption ? ` See '${fullCommand} ${this._helpLongFlag}'.` : '');
2581
+ this._displayError(1, 'commander.unknownCommand', message);
2582
+ };
1653
2583
 
1654
- command._alias = alias;
1655
- return this;
1656
- };
2584
+ /**
2585
+ * Set the program version to `str`.
2586
+ *
2587
+ * This method auto-registers the "-V, --version" flag
2588
+ * which will print the version number when passed.
2589
+ *
2590
+ * You can optionally supply the flags and description to override the defaults.
2591
+ *
2592
+ * @param {string} str
2593
+ * @param {string} [flags]
2594
+ * @param {string} [description]
2595
+ * @return {this | string} `this` command for chaining, or version string if no arguments
2596
+ */
1657
2597
 
1658
- /**
1659
- * Set / get the command usage `str`.
1660
- *
1661
- * @param {String} str
1662
- * @return {String|Command}
1663
- * @api public
1664
- */
2598
+ version(str, flags, description) {
2599
+ if (str === undefined) return this._version;
2600
+ this._version = str;
2601
+ flags = flags || '-V, --version';
2602
+ description = description || 'output the version number';
2603
+ const versionOption = this.createOption(flags, description);
2604
+ this._versionOptionName = versionOption.attributeName();
2605
+ this.options.push(versionOption);
2606
+ this.on('option:' + versionOption.name(), () => {
2607
+ this._outputConfiguration.writeOut(`${str}\n`);
2608
+ this._exit(0, 'commander.version', str);
2609
+ });
2610
+ return this;
2611
+ };
1665
2612
 
1666
- Command.prototype.usage = function(str) {
1667
- var args = this._args.map(function(arg) {
1668
- return humanReadableArgName(arg);
1669
- });
2613
+ /**
2614
+ * Set the description to `str`.
2615
+ *
2616
+ * @param {string} [str]
2617
+ * @param {Object} [argsDescription]
2618
+ * @return {string|Command}
2619
+ */
2620
+ description(str, argsDescription) {
2621
+ if (str === undefined && argsDescription === undefined) return this._description;
2622
+ this._description = str;
2623
+ this._argsDescription = argsDescription;
2624
+ return this;
2625
+ };
1670
2626
 
1671
- var usage = '[options]' +
1672
- (this.commands.length ? ' [command]' : '') +
1673
- (this._args.length ? ' ' + args.join(' ') : '');
2627
+ /**
2628
+ * Set an alias for the command.
2629
+ *
2630
+ * You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.
2631
+ *
2632
+ * @param {string} [alias]
2633
+ * @return {string|Command}
2634
+ */
1674
2635
 
1675
- if (arguments.length === 0) return this._usage || usage;
1676
- this._usage = str;
2636
+ alias(alias) {
2637
+ if (alias === undefined) return this._aliases[0]; // just return first, for backwards compatibility
1677
2638
 
1678
- return this;
1679
- };
2639
+ let command = this;
2640
+ if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
2641
+ // assume adding alias for last added executable subcommand, rather than this
2642
+ command = this.commands[this.commands.length - 1];
2643
+ }
1680
2644
 
1681
- /**
1682
- * Get or set the name of the command
1683
- *
1684
- * @param {String} str
1685
- * @return {String|Command}
1686
- * @api public
1687
- */
2645
+ if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');
1688
2646
 
1689
- Command.prototype.name = function(str) {
1690
- if (arguments.length === 0) return this._name;
1691
- this._name = str;
1692
- return this;
1693
- };
2647
+ command._aliases.push(alias);
2648
+ return this;
2649
+ };
1694
2650
 
1695
- /**
1696
- * Return prepared commands.
1697
- *
1698
- * @return {Array}
1699
- * @api private
1700
- */
2651
+ /**
2652
+ * Set aliases for the command.
2653
+ *
2654
+ * Only the first alias is shown in the auto-generated help.
2655
+ *
2656
+ * @param {string[]} [aliases]
2657
+ * @return {string[]|Command}
2658
+ */
1701
2659
 
1702
- Command.prototype.prepareCommands = function() {
1703
- return this.commands.filter(function(cmd) {
1704
- return !cmd._noHelp;
1705
- }).map(function(cmd) {
1706
- var args = cmd._args.map(function(arg) {
1707
- return humanReadableArgName(arg);
1708
- }).join(' ');
1709
-
1710
- return [
1711
- cmd._name +
1712
- (cmd._alias ? '|' + cmd._alias : '') +
1713
- (cmd.options.length ? ' [options]' : '') +
1714
- (args ? ' ' + args : ''),
1715
- cmd._description
1716
- ];
1717
- });
1718
- };
2660
+ aliases(aliases) {
2661
+ // Getter for the array of aliases is the main reason for having aliases() in addition to alias().
2662
+ if (aliases === undefined) return this._aliases;
1719
2663
 
1720
- /**
1721
- * Return the largest command length.
1722
- *
1723
- * @return {Number}
1724
- * @api private
1725
- */
2664
+ aliases.forEach((alias) => this.alias(alias));
2665
+ return this;
2666
+ };
1726
2667
 
1727
- Command.prototype.largestCommandLength = function() {
1728
- var commands = this.prepareCommands();
1729
- return commands.reduce(function(max, command) {
1730
- return Math.max(max, command[0].length);
1731
- }, 0);
1732
- };
2668
+ /**
2669
+ * Set / get the command usage `str`.
2670
+ *
2671
+ * @param {string} [str]
2672
+ * @return {String|Command}
2673
+ */
1733
2674
 
1734
- /**
1735
- * Return the largest option length.
1736
- *
1737
- * @return {Number}
1738
- * @api private
1739
- */
2675
+ usage(str) {
2676
+ if (str === undefined) {
2677
+ if (this._usage) return this._usage;
1740
2678
 
1741
- Command.prototype.largestOptionLength = function() {
1742
- var options = [].slice.call(this.options);
1743
- options.push({
1744
- flags: '-h, --help'
1745
- });
1746
- return options.reduce(function(max, option) {
1747
- return Math.max(max, option.flags.length);
1748
- }, 0);
1749
- };
2679
+ const args = this._args.map((arg) => {
2680
+ return humanReadableArgName(arg);
2681
+ });
2682
+ return [].concat(
2683
+ (this.options.length || this._hasHelpOption ? '[options]' : []),
2684
+ (this.commands.length ? '[command]' : []),
2685
+ (this._args.length ? args : [])
2686
+ ).join(' ');
2687
+ }
1750
2688
 
1751
- /**
1752
- * Return the largest arg length.
1753
- *
1754
- * @return {Number}
1755
- * @api private
1756
- */
2689
+ this._usage = str;
2690
+ return this;
2691
+ };
1757
2692
 
1758
- Command.prototype.largestArgLength = function() {
1759
- return this._args.reduce(function(max, arg) {
1760
- return Math.max(max, arg.name.length);
1761
- }, 0);
1762
- };
2693
+ /**
2694
+ * Get or set the name of the command
2695
+ *
2696
+ * @param {string} [str]
2697
+ * @return {string|Command}
2698
+ */
1763
2699
 
1764
- /**
1765
- * Return the pad width.
1766
- *
1767
- * @return {Number}
1768
- * @api private
1769
- */
2700
+ name(str) {
2701
+ if (str === undefined) return this._name;
2702
+ this._name = str;
2703
+ return this;
2704
+ };
2705
+
2706
+ /**
2707
+ * Return program help documentation.
2708
+ *
2709
+ * @param {{ error: boolean }} [contextOptions] - pass {error:true} to wrap for stderr instead of stdout
2710
+ * @return {string}
2711
+ */
1770
2712
 
1771
- Command.prototype.padWidth = function() {
1772
- var width = this.largestOptionLength();
1773
- if (this._argsDescription && this._args.length) {
1774
- if (this.largestArgLength() > width) {
1775
- width = this.largestArgLength();
2713
+ helpInformation(contextOptions) {
2714
+ const helper = this.createHelp();
2715
+ if (helper.helpWidth === undefined) {
2716
+ helper.helpWidth = (contextOptions && contextOptions.error) ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
1776
2717
  }
1777
- }
2718
+ return helper.formatHelp(this, helper);
2719
+ };
1778
2720
 
1779
- if (this.commands && this.commands.length) {
1780
- if (this.largestCommandLength() > width) {
1781
- width = this.largestCommandLength();
2721
+ /**
2722
+ * @api private
2723
+ */
2724
+
2725
+ _getHelpContext(contextOptions) {
2726
+ contextOptions = contextOptions || {};
2727
+ const context = { error: !!contextOptions.error };
2728
+ let write;
2729
+ if (context.error) {
2730
+ write = (arg) => this._outputConfiguration.writeErr(arg);
2731
+ } else {
2732
+ write = (arg) => this._outputConfiguration.writeOut(arg);
1782
2733
  }
2734
+ context.write = contextOptions.write || write;
2735
+ context.command = this;
2736
+ return context;
1783
2737
  }
1784
2738
 
1785
- return width;
1786
- };
2739
+ /**
2740
+ * Output help information for this command.
2741
+ *
2742
+ * Outputs built-in help, and custom text added using `.addHelpText()`.
2743
+ *
2744
+ * @param {{ error: boolean } | Function} [contextOptions] - pass {error:true} to write to stderr instead of stdout
2745
+ */
1787
2746
 
1788
- /**
1789
- * Return help for options.
1790
- *
1791
- * @return {String}
1792
- * @api private
1793
- */
2747
+ outputHelp(contextOptions) {
2748
+ let deprecatedCallback;
2749
+ if (typeof contextOptions === 'function') {
2750
+ deprecatedCallback = contextOptions;
2751
+ contextOptions = undefined;
2752
+ }
2753
+ const context = this._getHelpContext(contextOptions);
1794
2754
 
1795
- Command.prototype.optionHelp = function() {
1796
- var width = this.padWidth();
2755
+ const groupListeners = [];
2756
+ let command = this;
2757
+ while (command) {
2758
+ groupListeners.push(command); // ordered from current command to root
2759
+ command = command.parent;
2760
+ }
1797
2761
 
1798
- // Append the help information
1799
- return this.options.map(function(option) {
1800
- return pad(option.flags, width) + ' ' + option.description +
1801
- ((option.bool && option.defaultValue !== undefined) ? ' (default: ' + option.defaultValue + ')' : '');
1802
- }).concat([pad('-h, --help', width) + ' ' + 'output usage information'])
1803
- .join('\n');
1804
- };
2762
+ groupListeners.slice().reverse().forEach(command => command.emit('beforeAllHelp', context));
2763
+ this.emit('beforeHelp', context);
1805
2764
 
1806
- /**
1807
- * Return command help documentation.
1808
- *
1809
- * @return {String}
1810
- * @api private
1811
- */
2765
+ let helpInformation = this.helpInformation(context);
2766
+ if (deprecatedCallback) {
2767
+ helpInformation = deprecatedCallback(helpInformation);
2768
+ if (typeof helpInformation !== 'string' && !Buffer.isBuffer(helpInformation)) {
2769
+ throw new Error('outputHelp callback must return a string or a Buffer');
2770
+ }
2771
+ }
2772
+ context.write(helpInformation);
1812
2773
 
1813
- Command.prototype.commandHelp = function() {
1814
- if (!this.commands.length) return '';
1815
-
1816
- var commands = this.prepareCommands();
1817
- var width = this.padWidth();
1818
-
1819
- return [
1820
- ' Commands:',
1821
- '',
1822
- commands.map(function(cmd) {
1823
- var desc = cmd[1] ? ' ' + cmd[1] : '';
1824
- return (desc ? pad(cmd[0], width) : cmd[0]) + desc;
1825
- }).join('\n').replace(/^/gm, ' '),
1826
- ''
1827
- ].join('\n');
1828
- };
2774
+ this.emit(this._helpLongFlag); // deprecated
2775
+ this.emit('afterHelp', context);
2776
+ groupListeners.forEach(command => command.emit('afterAllHelp', context));
2777
+ };
1829
2778
 
1830
- /**
1831
- * Return program help documentation.
1832
- *
1833
- * @return {String}
1834
- * @api private
1835
- */
2779
+ /**
2780
+ * You can pass in flags and a description to override the help
2781
+ * flags and help description for your command. Pass in false to
2782
+ * disable the built-in help option.
2783
+ *
2784
+ * @param {string | boolean} [flags]
2785
+ * @param {string} [description]
2786
+ * @return {Command} `this` command for chaining
2787
+ */
1836
2788
 
1837
- Command.prototype.helpInformation = function() {
1838
- var desc = [];
1839
- if (this._description) {
1840
- desc = [
1841
- ' ' + this._description,
1842
- ''
1843
- ];
1844
-
1845
- var argsDescription = this._argsDescription;
1846
- if (argsDescription && this._args.length) {
1847
- var width = this.padWidth();
1848
- desc.push(' Arguments:');
1849
- desc.push('');
1850
- this._args.forEach(function(arg) {
1851
- desc.push(' ' + pad(arg.name, width) + ' ' + argsDescription[arg.name]);
1852
- });
1853
- desc.push('');
2789
+ helpOption(flags, description) {
2790
+ if (typeof flags === 'boolean') {
2791
+ this._hasHelpOption = flags;
2792
+ return this;
1854
2793
  }
1855
- }
2794
+ this._helpFlags = flags || this._helpFlags;
2795
+ this._helpDescription = description || this._helpDescription;
1856
2796
 
1857
- var cmdName = this._name;
1858
- if (this._alias) {
1859
- cmdName = cmdName + '|' + this._alias;
1860
- }
1861
- var usage = [
1862
- '',
1863
- ' Usage: ' + cmdName + ' ' + this.usage(),
1864
- ''
1865
- ];
2797
+ const helpFlags = _parseOptionFlags(this._helpFlags);
2798
+ this._helpShortFlag = helpFlags.shortFlag;
2799
+ this._helpLongFlag = helpFlags.longFlag;
1866
2800
 
1867
- var cmds = [];
1868
- var commandHelp = this.commandHelp();
1869
- if (commandHelp) cmds = [commandHelp];
2801
+ return this;
2802
+ };
1870
2803
 
1871
- var options = [
1872
- ' Options:',
1873
- '',
1874
- '' + this.optionHelp().replace(/^/gm, ' '),
1875
- ''
1876
- ];
2804
+ /**
2805
+ * Output help information and exit.
2806
+ *
2807
+ * Outputs built-in help, and custom text added using `.addHelpText()`.
2808
+ *
2809
+ * @param {{ error: boolean }} [contextOptions] - pass {error:true} to write to stderr instead of stdout
2810
+ */
1877
2811
 
1878
- return usage
1879
- .concat(desc)
1880
- .concat(options)
1881
- .concat(cmds)
1882
- .join('\n');
1883
- };
2812
+ help(contextOptions) {
2813
+ this.outputHelp(contextOptions);
2814
+ let exitCode = process.exitCode || 0;
2815
+ if (exitCode === 0 && contextOptions && typeof contextOptions !== 'function' && contextOptions.error) {
2816
+ exitCode = 1;
2817
+ }
2818
+ // message: do not have all displayed text available so only passing placeholder.
2819
+ this._exit(exitCode, 'commander.help', '(outputHelp)');
2820
+ };
1884
2821
 
2822
+ /**
2823
+ * Add additional text to be displayed with the built-in help.
2824
+ *
2825
+ * Position is 'before' or 'after' to affect just this command,
2826
+ * and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
2827
+ *
2828
+ * @param {string} position - before or after built-in help
2829
+ * @param {string | Function} text - string to add, or a function returning a string
2830
+ * @return {Command} `this` command for chaining
2831
+ */
2832
+ addHelpText(position, text) {
2833
+ const allowedValues = ['beforeAll', 'before', 'after', 'afterAll'];
2834
+ if (!allowedValues.includes(position)) {
2835
+ throw new Error(`Unexpected value for position to addHelpText.
2836
+ Expecting one of '${allowedValues.join("', '")}'`);
2837
+ }
2838
+ const helpEvent = `${position}Help`;
2839
+ this.on(helpEvent, (context) => {
2840
+ let helpStr;
2841
+ if (typeof text === 'function') {
2842
+ helpStr = text({ error: context.error, command: context.command });
2843
+ } else {
2844
+ helpStr = text;
2845
+ }
2846
+ // Ignore falsy value when nothing to output.
2847
+ if (helpStr) {
2848
+ context.write(`${helpStr}\n`);
2849
+ }
2850
+ });
2851
+ return this;
2852
+ }
2853
+ }
1885
2854
  /**
1886
- * Output help information for this command
1887
- *
1888
- * @api public
2855
+ * Expose the root command.
1889
2856
  */
1890
2857
 
1891
- Command.prototype.outputHelp = function(cb) {
1892
- if (!cb) {
1893
- cb = function(passthru) {
1894
- return passthru;
1895
- };
1896
- }
1897
- process.stdout.write(cb(this.helpInformation()));
1898
- this.emit('--help');
1899
- };
2858
+ exports = module.exports = new Command();
2859
+ exports.program = exports; // More explicit access to global command.
1900
2860
 
1901
2861
  /**
1902
- * Output help information and exit.
1903
- *
1904
- * @api public
2862
+ * Expose classes
1905
2863
  */
1906
2864
 
1907
- Command.prototype.help = function(cb) {
1908
- this.outputHelp(cb);
1909
- process.exit();
1910
- };
2865
+ exports.Command = Command;
2866
+ exports.Option = Option;
2867
+ exports.CommanderError = CommanderError;
2868
+ exports.InvalidOptionArgumentError = InvalidOptionArgumentError;
2869
+ exports.Help = Help;
1911
2870
 
1912
2871
  /**
1913
2872
  * Camel-case the given `flag`
1914
2873
  *
1915
- * @param {String} flag
1916
- * @return {String}
2874
+ * @param {string} flag
2875
+ * @return {string}
1917
2876
  * @api private
1918
2877
  */
1919
2878
 
1920
2879
  function camelcase(flag) {
1921
- return flag.split('-').reduce(function(str, word) {
2880
+ return flag.split('-').reduce((str, word) => {
1922
2881
  return str + word[0].toUpperCase() + word.slice(1);
1923
2882
  });
1924
2883
  }
1925
2884
 
1926
2885
  /**
1927
- * Pad `str` to `width`.
2886
+ * Output help information if help flags specified
1928
2887
  *
1929
- * @param {String} str
1930
- * @param {Number} width
1931
- * @return {String}
2888
+ * @param {Command} cmd - command to output help for
2889
+ * @param {Array} args - array of options to search for help flags
1932
2890
  * @api private
1933
2891
  */
1934
2892
 
1935
- function pad(str, width) {
1936
- var len = Math.max(0, width - str.length);
1937
- return str + Array(len + 1).join(' ');
1938
- }
1939
-
1940
- /**
1941
- * Output help information if necessary
1942
- *
1943
- * @param {Command} command to output help for
1944
- * @param {Array} array of options to search for -h or --help
1945
- * @api private
1946
- */
1947
-
1948
- function outputHelpIfNecessary(cmd, options) {
1949
- options = options || [];
1950
- for (var i = 0; i < options.length; i++) {
1951
- if (options[i] === '--help' || options[i] === '-h') {
1952
- cmd.outputHelp();
1953
- process.exit(0);
1954
- }
2893
+ function outputHelpIfRequested(cmd, args) {
2894
+ const helpOption = cmd._hasHelpOption && args.find(arg => arg === cmd._helpLongFlag || arg === cmd._helpShortFlag);
2895
+ if (helpOption) {
2896
+ cmd.outputHelp();
2897
+ // (Do not have all displayed text available so only passing placeholder.)
2898
+ cmd._exit(0, 'commander.helpDisplayed', '(outputHelp)');
1955
2899
  }
1956
2900
  }
1957
2901
 
1958
2902
  /**
1959
- * Takes an argument an returns its human readable equivalent for help usage.
2903
+ * Takes an argument and returns its human readable equivalent for help usage.
1960
2904
  *
1961
2905
  * @param {Object} arg
1962
- * @return {String}
2906
+ * @return {string}
1963
2907
  * @api private
1964
2908
  */
1965
2909
 
1966
2910
  function humanReadableArgName(arg) {
1967
- var nameOutput = arg.name + (arg.variadic === true ? '...' : '');
2911
+ const nameOutput = arg.name + (arg.variadic === true ? '...' : '');
1968
2912
 
1969
2913
  return arg.required
1970
2914
  ? '<' + nameOutput + '>'
1971
2915
  : '[' + nameOutput + ']';
1972
2916
  }
1973
2917
 
1974
- // for versions before node v0.8 when there weren't `fs.existsSync`
1975
- function exists(file) {
1976
- try {
1977
- if (fs__default.statSync(file).isFile()) {
1978
- return true;
1979
- }
1980
- } catch (e) {
1981
- return false;
2918
+ /**
2919
+ * Parse the short and long flag out of something like '-m,--mixed <value>'
2920
+ *
2921
+ * @api private
2922
+ */
2923
+
2924
+ function _parseOptionFlags(flags) {
2925
+ let shortFlag;
2926
+ let longFlag;
2927
+ // Use original very loose parsing to maintain backwards compatibility for now,
2928
+ // which allowed for example unintended `-sw, --short-word` [sic].
2929
+ const flagParts = flags.split(/[ |,]+/);
2930
+ if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1])) shortFlag = flagParts.shift();
2931
+ longFlag = flagParts.shift();
2932
+ // Add support for lone short flag without significantly changing parsing!
2933
+ if (!shortFlag && /^-[^-]$/.test(longFlag)) {
2934
+ shortFlag = longFlag;
2935
+ longFlag = undefined;
1982
2936
  }
2937
+ return { shortFlag, longFlag };
1983
2938
  }
1984
- });
2939
+
2940
+ /**
2941
+ * Scan arguments and increment port number for inspect calls (to avoid conflicts when spawning new command).
2942
+ *
2943
+ * @param {string[]} args - array of arguments from node.execArgv
2944
+ * @returns {string[]}
2945
+ * @api private
2946
+ */
2947
+
2948
+ function incrementNodeInspectorPort(args) {
2949
+ // Testing for these options:
2950
+ // --inspect[=[host:]port]
2951
+ // --inspect-brk[=[host:]port]
2952
+ // --inspect-port=[host:]port
2953
+ return args.map((arg) => {
2954
+ if (!arg.startsWith('--inspect')) {
2955
+ return arg;
2956
+ }
2957
+ let debugOption;
2958
+ let debugHost = '127.0.0.1';
2959
+ let debugPort = '9229';
2960
+ let match;
2961
+ if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
2962
+ // e.g. --inspect
2963
+ debugOption = match[1];
2964
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
2965
+ debugOption = match[1];
2966
+ if (/^\d+$/.test(match[3])) {
2967
+ // e.g. --inspect=1234
2968
+ debugPort = match[3];
2969
+ } else {
2970
+ // e.g. --inspect=localhost
2971
+ debugHost = match[3];
2972
+ }
2973
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
2974
+ // e.g. --inspect=localhost:1234
2975
+ debugOption = match[1];
2976
+ debugHost = match[3];
2977
+ debugPort = match[4];
2978
+ }
2979
+
2980
+ if (debugOption && debugPort !== '0') {
2981
+ return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
2982
+ }
2983
+ return arg;
2984
+ });
2985
+ }
2986
+ }(commander, commander.exports));
1985
2987
 
1986
2988
  var domain; // The domain module is executed on demand
1987
2989
  var hasSetImmediate = typeof setImmediate === "function";
@@ -1995,8 +2997,8 @@ var hasSetImmediate = typeof setImmediate === "function";
1995
2997
  // soon as possible, but if you use `rawAsap` directly, you are responsible to
1996
2998
  // either ensure that no exceptions are thrown from your task, or to manually
1997
2999
  // call `rawAsap.requestFlush` if an exception is thrown.
1998
- var raw = rawAsap;
1999
- function rawAsap(task) {
3000
+ var raw = rawAsap$1;
3001
+ function rawAsap$1(task) {
2000
3002
  if (!queue.length) {
2001
3003
  requestFlush();
2002
3004
  flushing = true;
@@ -2051,7 +3053,7 @@ function flush() {
2051
3053
  flushing = false;
2052
3054
  }
2053
3055
 
2054
- rawAsap.requestFlush = requestFlush;
3056
+ rawAsap$1.requestFlush = requestFlush;
2055
3057
  function requestFlush() {
2056
3058
  // Ensure flushing is not bound to any domain.
2057
3059
  // It is not sufficient to exit the domain, because domains exist on a stack.
@@ -2061,7 +3063,7 @@ function requestFlush() {
2061
3063
  if (!domain) {
2062
3064
  // Lazy execute the domain module.
2063
3065
  // Only employed if the user elects to use domains.
2064
- domain = require$$0$1;
3066
+ domain = require$$0$3;
2065
3067
  }
2066
3068
  domain.active = process.domain = null;
2067
3069
  }
@@ -2083,6 +3085,8 @@ function requestFlush() {
2083
3085
  }
2084
3086
  }
2085
3087
 
3088
+ var asap$2 = raw;
3089
+
2086
3090
  function noop() {}
2087
3091
 
2088
3092
  // States:
@@ -2130,78 +3134,78 @@ function tryCallTwo(fn, a, b) {
2130
3134
  }
2131
3135
  }
2132
3136
 
2133
- var core = Promise$1;
3137
+ var core = Promise$7;
2134
3138
 
2135
- function Promise$1(fn) {
3139
+ function Promise$7(fn) {
2136
3140
  if (typeof this !== 'object') {
2137
3141
  throw new TypeError('Promises must be constructed via new');
2138
3142
  }
2139
3143
  if (typeof fn !== 'function') {
2140
3144
  throw new TypeError('Promise constructor\'s argument is not a function');
2141
3145
  }
2142
- this._75 = 0;
2143
- this._83 = 0;
2144
- this._18 = null;
2145
- this._38 = null;
3146
+ this._U = 0;
3147
+ this._V = 0;
3148
+ this._W = null;
3149
+ this._X = null;
2146
3150
  if (fn === noop) return;
2147
3151
  doResolve(fn, this);
2148
3152
  }
2149
- Promise$1._47 = null;
2150
- Promise$1._71 = null;
2151
- Promise$1._44 = noop;
3153
+ Promise$7._Y = null;
3154
+ Promise$7._Z = null;
3155
+ Promise$7._0 = noop;
2152
3156
 
2153
- Promise$1.prototype.then = function(onFulfilled, onRejected) {
2154
- if (this.constructor !== Promise$1) {
3157
+ Promise$7.prototype.then = function(onFulfilled, onRejected) {
3158
+ if (this.constructor !== Promise$7) {
2155
3159
  return safeThen(this, onFulfilled, onRejected);
2156
3160
  }
2157
- var res = new Promise$1(noop);
3161
+ var res = new Promise$7(noop);
2158
3162
  handle(this, new Handler(onFulfilled, onRejected, res));
2159
3163
  return res;
2160
3164
  };
2161
3165
 
2162
3166
  function safeThen(self, onFulfilled, onRejected) {
2163
3167
  return new self.constructor(function (resolve, reject) {
2164
- var res = new Promise$1(noop);
3168
+ var res = new Promise$7(noop);
2165
3169
  res.then(resolve, reject);
2166
3170
  handle(self, new Handler(onFulfilled, onRejected, res));
2167
3171
  });
2168
3172
  }
2169
3173
  function handle(self, deferred) {
2170
- while (self._83 === 3) {
2171
- self = self._18;
3174
+ while (self._V === 3) {
3175
+ self = self._W;
2172
3176
  }
2173
- if (Promise$1._47) {
2174
- Promise$1._47(self);
3177
+ if (Promise$7._Y) {
3178
+ Promise$7._Y(self);
2175
3179
  }
2176
- if (self._83 === 0) {
2177
- if (self._75 === 0) {
2178
- self._75 = 1;
2179
- self._38 = deferred;
3180
+ if (self._V === 0) {
3181
+ if (self._U === 0) {
3182
+ self._U = 1;
3183
+ self._X = deferred;
2180
3184
  return;
2181
3185
  }
2182
- if (self._75 === 1) {
2183
- self._75 = 2;
2184
- self._38 = [self._38, deferred];
3186
+ if (self._U === 1) {
3187
+ self._U = 2;
3188
+ self._X = [self._X, deferred];
2185
3189
  return;
2186
3190
  }
2187
- self._38.push(deferred);
3191
+ self._X.push(deferred);
2188
3192
  return;
2189
3193
  }
2190
3194
  handleResolved(self, deferred);
2191
3195
  }
2192
3196
 
2193
3197
  function handleResolved(self, deferred) {
2194
- raw(function() {
2195
- var cb = self._83 === 1 ? deferred.onFulfilled : deferred.onRejected;
3198
+ asap$2(function() {
3199
+ var cb = self._V === 1 ? deferred.onFulfilled : deferred.onRejected;
2196
3200
  if (cb === null) {
2197
- if (self._83 === 1) {
2198
- resolve(deferred.promise, self._18);
3201
+ if (self._V === 1) {
3202
+ resolve(deferred.promise, self._W);
2199
3203
  } else {
2200
- reject(deferred.promise, self._18);
3204
+ reject(deferred.promise, self._W);
2201
3205
  }
2202
3206
  return;
2203
3207
  }
2204
- var ret = tryCallOne(cb, self._18);
3208
+ var ret = tryCallOne(cb, self._W);
2205
3209
  if (ret === IS_ERROR) {
2206
3210
  reject(deferred.promise, LAST_ERROR);
2207
3211
  } else {
@@ -2227,10 +3231,10 @@ function resolve(self, newValue) {
2227
3231
  }
2228
3232
  if (
2229
3233
  then === self.then &&
2230
- newValue instanceof Promise$1
3234
+ newValue instanceof Promise$7
2231
3235
  ) {
2232
- self._83 = 3;
2233
- self._18 = newValue;
3236
+ self._V = 3;
3237
+ self._W = newValue;
2234
3238
  finale(self);
2235
3239
  return;
2236
3240
  } else if (typeof then === 'function') {
@@ -2238,29 +3242,29 @@ function resolve(self, newValue) {
2238
3242
  return;
2239
3243
  }
2240
3244
  }
2241
- self._83 = 1;
2242
- self._18 = newValue;
3245
+ self._V = 1;
3246
+ self._W = newValue;
2243
3247
  finale(self);
2244
3248
  }
2245
3249
 
2246
3250
  function reject(self, newValue) {
2247
- self._83 = 2;
2248
- self._18 = newValue;
2249
- if (Promise$1._71) {
2250
- Promise$1._71(self, newValue);
3251
+ self._V = 2;
3252
+ self._W = newValue;
3253
+ if (Promise$7._Z) {
3254
+ Promise$7._Z(self, newValue);
2251
3255
  }
2252
3256
  finale(self);
2253
3257
  }
2254
3258
  function finale(self) {
2255
- if (self._75 === 1) {
2256
- handle(self, self._38);
2257
- self._38 = null;
3259
+ if (self._U === 1) {
3260
+ handle(self, self._X);
3261
+ self._X = null;
2258
3262
  }
2259
- if (self._75 === 2) {
2260
- for (var i = 0; i < self._38.length; i++) {
2261
- handle(self, self._38[i]);
3263
+ if (self._U === 2) {
3264
+ for (var i = 0; i < self._X.length; i++) {
3265
+ handle(self, self._X[i]);
2262
3266
  }
2263
- self._38 = null;
3267
+ self._X = null;
2264
3268
  }
2265
3269
  }
2266
3270
 
@@ -2293,7 +3297,8 @@ function doResolve(fn, promise) {
2293
3297
  }
2294
3298
  }
2295
3299
 
2296
- core.prototype.done = function (onFulfilled, onRejected) {
3300
+ var Promise$6 = core;
3301
+ Promise$6.prototype.done = function (onFulfilled, onRejected) {
2297
3302
  var self = arguments.length ? this.then.apply(this, arguments) : this;
2298
3303
  self.then(null, function (err) {
2299
3304
  setTimeout(function () {
@@ -2302,18 +3307,23 @@ core.prototype.done = function (onFulfilled, onRejected) {
2302
3307
  });
2303
3308
  };
2304
3309
 
2305
- core.prototype['finally'] = function (f) {
3310
+ var Promise$5 = core;
3311
+ Promise$5.prototype.finally = function (f) {
2306
3312
  return this.then(function (value) {
2307
- return core.resolve(f()).then(function () {
3313
+ return Promise$5.resolve(f()).then(function () {
2308
3314
  return value;
2309
3315
  });
2310
3316
  }, function (err) {
2311
- return core.resolve(f()).then(function () {
3317
+ return Promise$5.resolve(f()).then(function () {
2312
3318
  throw err;
2313
3319
  });
2314
3320
  });
2315
3321
  };
2316
3322
 
3323
+ //This file contains the ES6 extensions to the core Promises/A+ API
3324
+
3325
+ var Promise$4 = core;
3326
+
2317
3327
  /* Static Functions */
2318
3328
 
2319
3329
  var TRUE = valuePromise(true);
@@ -2324,13 +3334,13 @@ var ZERO = valuePromise(0);
2324
3334
  var EMPTYSTRING = valuePromise('');
2325
3335
 
2326
3336
  function valuePromise(value) {
2327
- var p = new core(core._44);
2328
- p._83 = 1;
2329
- p._18 = value;
3337
+ var p = new Promise$4(Promise$4._0);
3338
+ p._V = 1;
3339
+ p._W = value;
2330
3340
  return p;
2331
3341
  }
2332
- core.resolve = function (value) {
2333
- if (value instanceof core) return value;
3342
+ Promise$4.resolve = function (value) {
3343
+ if (value instanceof Promise$4) return value;
2334
3344
 
2335
3345
  if (value === null) return NULL;
2336
3346
  if (value === undefined) return UNDEFINED;
@@ -2343,10 +3353,10 @@ core.resolve = function (value) {
2343
3353
  try {
2344
3354
  var then = value.then;
2345
3355
  if (typeof then === 'function') {
2346
- return new core(then.bind(value));
3356
+ return new Promise$4(then.bind(value));
2347
3357
  }
2348
3358
  } catch (ex) {
2349
- return new core(function (resolve, reject) {
3359
+ return new Promise$4(function (resolve, reject) {
2350
3360
  reject(ex);
2351
3361
  });
2352
3362
  }
@@ -2354,20 +3364,32 @@ core.resolve = function (value) {
2354
3364
  return valuePromise(value);
2355
3365
  };
2356
3366
 
2357
- core.all = function (arr) {
2358
- var args = Array.prototype.slice.call(arr);
3367
+ var iterableToArray = function (iterable) {
3368
+ if (typeof Array.from === 'function') {
3369
+ // ES2015+, iterables exist
3370
+ iterableToArray = Array.from;
3371
+ return Array.from(iterable);
3372
+ }
3373
+
3374
+ // ES5, only arrays and array-likes exist
3375
+ iterableToArray = function (x) { return Array.prototype.slice.call(x); };
3376
+ return Array.prototype.slice.call(iterable);
3377
+ };
3378
+
3379
+ Promise$4.all = function (arr) {
3380
+ var args = iterableToArray(arr);
2359
3381
 
2360
- return new core(function (resolve, reject) {
3382
+ return new Promise$4(function (resolve, reject) {
2361
3383
  if (args.length === 0) return resolve([]);
2362
3384
  var remaining = args.length;
2363
3385
  function res(i, val) {
2364
3386
  if (val && (typeof val === 'object' || typeof val === 'function')) {
2365
- if (val instanceof core && val.then === core.prototype.then) {
2366
- while (val._83 === 3) {
2367
- val = val._18;
3387
+ if (val instanceof Promise$4 && val.then === Promise$4.prototype.then) {
3388
+ while (val._V === 3) {
3389
+ val = val._W;
2368
3390
  }
2369
- if (val._83 === 1) return res(i, val._18);
2370
- if (val._83 === 2) reject(val._18);
3391
+ if (val._V === 1) return res(i, val._W);
3392
+ if (val._V === 2) reject(val._W);
2371
3393
  val.then(function (val) {
2372
3394
  res(i, val);
2373
3395
  }, reject);
@@ -2375,7 +3397,7 @@ core.all = function (arr) {
2375
3397
  } else {
2376
3398
  var then = val.then;
2377
3399
  if (typeof then === 'function') {
2378
- var p = new core(then.bind(val));
3400
+ var p = new Promise$4(then.bind(val));
2379
3401
  p.then(function (val) {
2380
3402
  res(i, val);
2381
3403
  }, reject);
@@ -2394,26 +3416,27 @@ core.all = function (arr) {
2394
3416
  });
2395
3417
  };
2396
3418
 
2397
- core.reject = function (value) {
2398
- return new core(function (resolve, reject) {
3419
+ Promise$4.reject = function (value) {
3420
+ return new Promise$4(function (resolve, reject) {
2399
3421
  reject(value);
2400
3422
  });
2401
3423
  };
2402
3424
 
2403
- core.race = function (values) {
2404
- return new core(function (resolve, reject) {
2405
- values.forEach(function(value){
2406
- core.resolve(value).then(resolve, reject);
3425
+ Promise$4.race = function (values) {
3426
+ return new Promise$4(function (resolve, reject) {
3427
+ iterableToArray(values).forEach(function(value){
3428
+ Promise$4.resolve(value).then(resolve, reject);
2407
3429
  });
2408
3430
  });
2409
3431
  };
2410
3432
 
2411
3433
  /* Prototype Methods */
2412
3434
 
2413
- core.prototype['catch'] = function (onRejected) {
3435
+ Promise$4.prototype['catch'] = function (onRejected) {
2414
3436
  return this.then(null, onRejected);
2415
3437
  };
2416
3438
 
3439
+ var rawAsap = raw;
2417
3440
  var freeTasks = [];
2418
3441
 
2419
3442
  /**
@@ -2426,8 +3449,8 @@ var freeTasks = [];
2426
3449
  * @param {{call}} task A callable object, typically a function that takes no
2427
3450
  * arguments.
2428
3451
  */
2429
- var asap_1 = asap;
2430
- function asap(task) {
3452
+ var asap_1 = asap$1;
3453
+ function asap$1(task) {
2431
3454
  var rawTask;
2432
3455
  if (freeTasks.length) {
2433
3456
  rawTask = freeTasks.pop();
@@ -2436,7 +3459,7 @@ function asap(task) {
2436
3459
  }
2437
3460
  rawTask.task = task;
2438
3461
  rawTask.domain = process.domain;
2439
- raw(rawTask);
3462
+ rawAsap(rawTask);
2440
3463
  }
2441
3464
 
2442
3465
  function RawTask() {
@@ -2466,7 +3489,7 @@ RawTask.prototype.call = function () {
2466
3489
  // Ensure that flushing continues if an uncaught exception is
2467
3490
  // suppressed listening process.on("uncaughtException") or
2468
3491
  // domain.on("error").
2469
- raw.requestFlush();
3492
+ rawAsap.requestFlush();
2470
3493
  }
2471
3494
  // If the task threw an error, we do not want to exit the domain here.
2472
3495
  // Exiting the domain would prevent the domain from catching the error.
@@ -2476,9 +3499,15 @@ RawTask.prototype.call = function () {
2476
3499
  }
2477
3500
  };
2478
3501
 
3502
+ // This file contains then/promise specific extensions that are only useful
3503
+ // for node.js interop
3504
+
3505
+ var Promise$3 = core;
3506
+ var asap = asap_1;
3507
+
2479
3508
  /* Static Functions */
2480
3509
 
2481
- core.denodeify = function (fn, argumentCount) {
3510
+ Promise$3.denodeify = function (fn, argumentCount) {
2482
3511
  if (
2483
3512
  typeof argumentCount === 'number' && argumentCount !== Infinity
2484
3513
  ) {
@@ -2512,7 +3541,7 @@ function denodeifyWithCount(fn, argumentCount) {
2512
3541
  '});',
2513
3542
  '};'
2514
3543
  ].join('');
2515
- return Function(['Promise', 'fn'], body)(core, fn);
3544
+ return Function(['Promise', 'fn'], body)(Promise$3, fn);
2516
3545
  }
2517
3546
  function denodeifyWithoutCount(fn) {
2518
3547
  var fnLength = Math.max(fn.length - 1, 3);
@@ -2558,10 +3587,10 @@ function denodeifyWithoutCount(fn) {
2558
3587
  return Function(
2559
3588
  ['Promise', 'fn'],
2560
3589
  body
2561
- )(core, fn);
3590
+ )(Promise$3, fn);
2562
3591
  }
2563
3592
 
2564
- core.nodeify = function (fn) {
3593
+ Promise$3.nodeify = function (fn) {
2565
3594
  return function () {
2566
3595
  var args = Array.prototype.slice.call(arguments);
2567
3596
  var callback =
@@ -2571,11 +3600,11 @@ core.nodeify = function (fn) {
2571
3600
  return fn.apply(this, arguments).nodeify(callback, ctx);
2572
3601
  } catch (ex) {
2573
3602
  if (callback === null || typeof callback == 'undefined') {
2574
- return new core(function (resolve, reject) {
3603
+ return new Promise$3(function (resolve, reject) {
2575
3604
  reject(ex);
2576
3605
  });
2577
3606
  } else {
2578
- asap_1(function () {
3607
+ asap(function () {
2579
3608
  callback.call(ctx, ex);
2580
3609
  });
2581
3610
  }
@@ -2583,76 +3612,77 @@ core.nodeify = function (fn) {
2583
3612
  }
2584
3613
  };
2585
3614
 
2586
- core.prototype.nodeify = function (callback, ctx) {
3615
+ Promise$3.prototype.nodeify = function (callback, ctx) {
2587
3616
  if (typeof callback != 'function') return this;
2588
3617
 
2589
3618
  this.then(function (value) {
2590
- asap_1(function () {
3619
+ asap(function () {
2591
3620
  callback.call(ctx, null, value);
2592
3621
  });
2593
3622
  }, function (err) {
2594
- asap_1(function () {
3623
+ asap(function () {
2595
3624
  callback.call(ctx, err);
2596
3625
  });
2597
3626
  });
2598
3627
  };
2599
3628
 
2600
- core.enableSynchronous = function () {
2601
- core.prototype.isPending = function() {
3629
+ var Promise$2 = core;
3630
+ Promise$2.enableSynchronous = function () {
3631
+ Promise$2.prototype.isPending = function() {
2602
3632
  return this.getState() == 0;
2603
3633
  };
2604
3634
 
2605
- core.prototype.isFulfilled = function() {
3635
+ Promise$2.prototype.isFulfilled = function() {
2606
3636
  return this.getState() == 1;
2607
3637
  };
2608
3638
 
2609
- core.prototype.isRejected = function() {
3639
+ Promise$2.prototype.isRejected = function() {
2610
3640
  return this.getState() == 2;
2611
3641
  };
2612
3642
 
2613
- core.prototype.getValue = function () {
2614
- if (this._83 === 3) {
2615
- return this._18.getValue();
3643
+ Promise$2.prototype.getValue = function () {
3644
+ if (this._V === 3) {
3645
+ return this._W.getValue();
2616
3646
  }
2617
3647
 
2618
3648
  if (!this.isFulfilled()) {
2619
3649
  throw new Error('Cannot get a value of an unfulfilled promise.');
2620
3650
  }
2621
3651
 
2622
- return this._18;
3652
+ return this._W;
2623
3653
  };
2624
3654
 
2625
- core.prototype.getReason = function () {
2626
- if (this._83 === 3) {
2627
- return this._18.getReason();
3655
+ Promise$2.prototype.getReason = function () {
3656
+ if (this._V === 3) {
3657
+ return this._W.getReason();
2628
3658
  }
2629
3659
 
2630
3660
  if (!this.isRejected()) {
2631
3661
  throw new Error('Cannot get a rejection reason of a non-rejected promise.');
2632
3662
  }
2633
3663
 
2634
- return this._18;
3664
+ return this._W;
2635
3665
  };
2636
3666
 
2637
- core.prototype.getState = function () {
2638
- if (this._83 === 3) {
2639
- return this._18.getState();
3667
+ Promise$2.prototype.getState = function () {
3668
+ if (this._V === 3) {
3669
+ return this._W.getState();
2640
3670
  }
2641
- if (this._83 === -1 || this._83 === -2) {
3671
+ if (this._V === -1 || this._V === -2) {
2642
3672
  return 0;
2643
3673
  }
2644
3674
 
2645
- return this._83;
3675
+ return this._V;
2646
3676
  };
2647
3677
  };
2648
3678
 
2649
- core.disableSynchronous = function() {
2650
- core.prototype.isPending = undefined;
2651
- core.prototype.isFulfilled = undefined;
2652
- core.prototype.isRejected = undefined;
2653
- core.prototype.getValue = undefined;
2654
- core.prototype.getReason = undefined;
2655
- core.prototype.getState = undefined;
3679
+ Promise$2.disableSynchronous = function() {
3680
+ Promise$2.prototype.isPending = undefined;
3681
+ Promise$2.prototype.isFulfilled = undefined;
3682
+ Promise$2.prototype.isRejected = undefined;
3683
+ Promise$2.prototype.getValue = undefined;
3684
+ Promise$2.prototype.getReason = undefined;
3685
+ Promise$2.prototype.getState = undefined;
2656
3686
  };
2657
3687
 
2658
3688
  var lib = core;
@@ -2676,17 +3706,13 @@ var promise = lib;
2676
3706
  * limitations under the license.
2677
3707
  */
2678
3708
 
2679
-
2680
-
2681
-
2682
-
2683
-
2684
-
2685
-
2686
-
2687
-
2688
-
2689
-
3709
+ const colors = safe.exports;
3710
+ const fs = fs__default;
3711
+ const http = http$1;
3712
+ const https = https$1;
3713
+ const program = commander.exports;
3714
+ const Promise$1 = promise;
3715
+ const vm = require$$10;
2690
3716
 
2691
3717
  const DEFAULT_USER_AGENT = 'amphtml-validator';
2692
3718
 
@@ -2716,8 +3742,8 @@ function isHttpOrHttpsUrl(url) {
2716
3742
  * @return {Promise<string>}
2717
3743
  */
2718
3744
  function readFromFile(name) {
2719
- return new promise(function(resolve, reject) {
2720
- fs__default.readFile(name, 'utf8', function(err, data) {
3745
+ return new Promise$1(function(resolve, reject) {
3746
+ fs.readFile(name, 'utf8', function(err, data) {
2721
3747
  if (err) {
2722
3748
  reject(err);
2723
3749
  } else {
@@ -2734,7 +3760,7 @@ function readFromFile(name) {
2734
3760
  * @return {Promise<string>}
2735
3761
  */
2736
3762
  function readFromReadable(name, readable) {
2737
- return new promise(function(resolve, reject) {
3763
+ return new Promise$1(function(resolve, reject) {
2738
3764
  const chunks = [];
2739
3765
  readable.setEncoding('utf8');
2740
3766
  readable.on('data', function(chunk) {
@@ -2771,7 +3797,7 @@ function readFromStdin() {
2771
3797
  * @return {Promise<string>}
2772
3798
  */
2773
3799
  function readFromUrl(url, userAgent) {
2774
- return new promise(function(resolve, reject) {
3800
+ return new Promise$1(function(resolve, reject) {
2775
3801
  const clientModule = hasPrefix(url, 'http://') ? http : https;
2776
3802
  const req = clientModule.request(url, function(response) {
2777
3803
  if (response.statusCode !== 200) {
@@ -2876,8 +3902,8 @@ function ValidationError() {
2876
3902
 
2877
3903
  /**
2878
3904
  * The validator instance is a proxy object to a precompiled
2879
- * validator.js script - in practice the script was either downloaded
2880
- * from 'https://cdn.ampproject.org/v0/validator.js' or read from a
3905
+ * validator_wasm.js script - in practice the script was either downloaded
3906
+ * from 'https://cdn.ampproject.org/v0/validator_wasm.js' or read from a
2881
3907
  * local file.
2882
3908
  * @param {string} scriptContents
2883
3909
  * @throws {!Error}
@@ -2898,10 +3924,23 @@ function Validator(scriptContents) {
2898
3924
  try {
2899
3925
  new vm.Script(scriptContents).runInContext(this.sandbox);
2900
3926
  } catch (error) {
2901
- throw new Error('Could not instantiate validator.js - ' + error.message);
3927
+ throw new Error('Could not instantiate validator_wasm.js - ' +
3928
+ error.message);
2902
3929
  }
2903
3930
  }
2904
3931
 
3932
+ /**
3933
+ * Initialize the validator.
3934
+ * @return {Promise<undefined>!}
3935
+ */
3936
+ Validator.prototype.init = function() {
3937
+ if (this.sandbox.amp.validator.init) {
3938
+ return this.sandbox.amp.validator.init();
3939
+ } else {
3940
+ return Promise$1.resolve(undefined);
3941
+ }
3942
+ };
3943
+
2905
3944
  /**
2906
3945
  * Validates the provided inputString; the htmlFormat can be 'AMP' or
2907
3946
  * 'AMP4ADS'; it defaults to 'AMP' if not specified.
@@ -2939,7 +3978,7 @@ Validator.prototype.validateString = function(inputString, htmlFormat) {
2939
3978
  const instanceByValidatorJs = {};
2940
3979
 
2941
3980
  /**
2942
- * Provided a URL or a filename from which to fetch the validator.js
3981
+ * Provided a URL or a filename from which to fetch the validator_wasm.js
2943
3982
  * file, fetches, instantiates, and caches the validator instance
2944
3983
  * asynchronously. If you prefer to implement your own fetching /
2945
3984
  * caching logic, you may want to consider newInstance() instead,
@@ -2952,10 +3991,10 @@ const instanceByValidatorJs = {};
2952
3991
  */
2953
3992
  function getInstance(opt_validatorJs, opt_userAgent) {
2954
3993
  const validatorJs =
2955
- opt_validatorJs || 'https://cdn.ampproject.org/v0/validator.js';
3994
+ opt_validatorJs || 'https://cdn.ampproject.org/v0/validator_wasm.js';
2956
3995
  const userAgent = opt_userAgent || DEFAULT_USER_AGENT;
2957
3996
  if (instanceByValidatorJs.hasOwnProperty(validatorJs)) {
2958
- return promise.resolve(instanceByValidatorJs[validatorJs]);
3997
+ return Promise$1.resolve(instanceByValidatorJs[validatorJs]);
2959
3998
  }
2960
3999
  const validatorJsPromise = isHttpOrHttpsUrl(validatorJs) ?
2961
4000
  readFromUrl(validatorJs, userAgent) :
@@ -2973,15 +4012,17 @@ function getInstance(opt_validatorJs, opt_userAgent) {
2973
4012
  }
2974
4013
  instanceByValidatorJs[validatorJs] = instance;
2975
4014
  return instance;
4015
+ }).then(function(instance) {
4016
+ return instance.init().then(() => instance);
2976
4017
  });
2977
4018
  }
2978
- var getInstance_1 = getInstance;
4019
+ amphtmlValidator.getInstance = getInstance;
2979
4020
 
2980
4021
  /**
2981
- * Provided the contents of the validator.js file, e.g. as downloaded from
2982
- * 'https://cdn.ampproject.org/v0/validator.js', returns a new validator
4022
+ * Provided the contents of the validator_wasm.js file, e.g. as downloaded from
4023
+ * 'https://cdn.ampproject.org/v0/validator_wasm.js', returns a new validator
2983
4024
  * instance. The tradeoff between this function and getInstance() is that this
2984
- * function is synchronous but requires the contents of the validator.js
4025
+ * function is synchronous but requires the contents of the validator_wasm.js
2985
4026
  * file as a parameter, while getInstance is asynchronous, fetches files
2986
4027
  * from disk or the web, and caches them.
2987
4028
  *
@@ -2992,7 +4033,7 @@ var getInstance_1 = getInstance;
2992
4033
  function newInstance(validatorJsContents) {
2993
4034
  return new Validator(validatorJsContents);
2994
4035
  }
2995
- var newInstance_1 = newInstance;
4036
+ amphtmlValidator.newInstance = newInstance;
2996
4037
 
2997
4038
  // A note on emitting output to the console and process exit status:
2998
4039
  // Node.js prior to 0.11.8 did not support process.exitCode
@@ -3014,13 +4055,13 @@ var newInstance_1 = newInstance;
3014
4055
  function logValidationResult(filename, validationResult, color) {
3015
4056
  if (validationResult.status === 'PASS') {
3016
4057
  process.stdout.write(
3017
- filename + ': ' + (color ? safe.green('PASS') : 'PASS') + '\n');
4058
+ filename + ': ' + (color ? colors.green('PASS') : 'PASS') + '\n');
3018
4059
  }
3019
4060
  for (let ii = 0; ii < validationResult.errors.length; ii++) {
3020
4061
  const error = validationResult.errors[ii];
3021
4062
  let msg = filename + ':' + error.line + ':' + error.col + ' ';
3022
4063
  if (color) {
3023
- msg += (error.severity === 'ERROR' ? safe.red : safe.magenta)(
4064
+ msg += (error.severity === 'ERROR' ? colors.red : colors.magenta)(
3024
4065
  error.message);
3025
4066
  } else {
3026
4067
  msg += error.message;
@@ -3037,7 +4078,7 @@ function logValidationResult(filename, validationResult, color) {
3037
4078
  * Main entry point into the command line tool.
3038
4079
  */
3039
4080
  function main() {
3040
- commander
4081
+ program
3041
4082
  .usage(
3042
4083
  '[options] <fileOrUrlOrMinus...>\n\n' +
3043
4084
  ' Validates the files or urls provided as arguments. If "-" is\n' +
@@ -3048,7 +4089,7 @@ function main() {
3048
4089
  ' Latest published version by default, or\n' +
3049
4090
  ' dist/validator_minified.js (built with build.py)\n' +
3050
4091
  ' for development.',
3051
- 'https://cdn.ampproject.org/v0/validator.js')
4092
+ 'https://cdn.ampproject.org/v0/validator_wasm.js')
3052
4093
  .option(
3053
4094
  '--user-agent <userAgent>', 'User agent string to use in requests.',
3054
4095
  DEFAULT_USER_AGENT)
@@ -3068,57 +4109,58 @@ function main() {
3068
4109
  ' message in validator.proto.',
3069
4110
  'color')
3070
4111
  .parse(process.argv);
3071
- if (commander.args.length === 0) {
3072
- commander.outputHelp();
4112
+ const opts = program.opts();
4113
+ if (opts.length === 0) {
4114
+ program.outputHelp();
3073
4115
  process.exit(1);
3074
4116
  }
3075
- if (commander.html_format !== 'AMP' && commander.html_format !== 'AMP4ADS' &&
3076
- commander.html_format !== 'AMP4EMAIL') {
4117
+ if (opts.html_format !== 'AMP' && opts.html_format !== 'AMP4ADS' &&
4118
+ opts.html_format !== 'AMP4EMAIL') {
3077
4119
  process.stderr.write(
3078
4120
  '--html_format must be set to "AMP", "AMP4ADS", or "AMP4EMAIL".\n',
3079
4121
  function() {
3080
4122
  process.exit(1);
3081
4123
  });
3082
4124
  }
3083
- if (commander.format !== 'color' && commander.format !== 'text' &&
3084
- commander.format !== 'json') {
4125
+ if (opts.format !== 'color' && opts.format !== 'text' &&
4126
+ opts.format !== 'json') {
3085
4127
  process.stderr.write(
3086
4128
  '--format must be set to "color", "text", or "json".\n', function() {
3087
4129
  process.exit(1);
3088
4130
  });
3089
4131
  }
3090
4132
  const inputs = [];
3091
- for (let ii = 0; ii < commander.args.length; ii++) {
3092
- const item = commander.args[ii];
4133
+ for (let ii = 0; ii < program.args.length; ii++) {
4134
+ const item = program.args[ii];
3093
4135
  if (item === '-') {
3094
4136
  inputs.push(readFromStdin());
3095
4137
  } else if (isHttpOrHttpsUrl(item)) {
3096
- inputs.push(readFromUrl(item, commander.userAgent));
4138
+ inputs.push(readFromUrl(item, opts.userAgent));
3097
4139
  } else {
3098
4140
  inputs.push(readFromFile(item));
3099
4141
  }
3100
4142
  }
3101
- getInstance(commander.validator_js, commander.userAgent)
4143
+ getInstance(opts.validator_js, opts.userAgent)
3102
4144
  .then(function(validator) {
3103
- promise.all(inputs)
4145
+ Promise$1.all(inputs)
3104
4146
  .then(function(resolvedInputs) {
3105
4147
  const jsonOut = {};
3106
4148
  let hasError = false;
3107
4149
  for (let ii = 0; ii < resolvedInputs.length; ii++) {
3108
4150
  const validationResult = validator.validateString(
3109
- resolvedInputs[ii], commander.html_format);
3110
- if (commander.format === 'json') {
3111
- jsonOut[commander.args[ii]] = validationResult;
4151
+ resolvedInputs[ii], opts.html_format);
4152
+ if (opts.format === 'json') {
4153
+ jsonOut[program.args[ii]] = validationResult;
3112
4154
  } else {
3113
4155
  logValidationResult(
3114
- commander.args[ii], validationResult,
3115
- commander.format === 'color' ? true : false);
4156
+ program.args[ii], validationResult,
4157
+ opts.format === 'color' ? true : false);
3116
4158
  }
3117
4159
  if (validationResult.status !== 'PASS') {
3118
4160
  hasError = true;
3119
4161
  }
3120
4162
  }
3121
- if (commander.format === 'json') {
4163
+ if (opts.format === 'json') {
3122
4164
  process.stdout.write(
3123
4165
  JSON.stringify(jsonOut) + '\n', function() {
3124
4166
  process.exit(hasError ? 1 : 0);
@@ -3135,7 +4177,7 @@ function main() {
3135
4177
  })
3136
4178
  .catch(function(error) {
3137
4179
  process.stderr.write(
3138
- (commander.format == 'color' ? safe.red(error.message) :
4180
+ (opts.format == 'color' ? colors.red(error.message) :
3139
4181
  error.message) +
3140
4182
  '\n',
3141
4183
  function() {
@@ -3145,7 +4187,7 @@ function main() {
3145
4187
  })
3146
4188
  .catch(function(error) {
3147
4189
  process.stderr.write(
3148
- (commander.format == 'color' ? safe.red(error.message) :
4190
+ (opts.format == 'color' ? colors.red(error.message) :
3149
4191
  error.message) +
3150
4192
  '\n',
3151
4193
  function() {
@@ -3154,13 +4196,7 @@ function main() {
3154
4196
  });
3155
4197
  }
3156
4198
 
3157
- var main_1 = main;
3158
-
3159
- var amphtmlValidator = {
3160
- getInstance: getInstance_1,
3161
- newInstance: newInstance_1,
3162
- main: main_1
3163
- };
4199
+ amphtmlValidator.main = main;
3164
4200
 
3165
4201
  /** @typedef {{ cwd?: string, port: number, host?: string, https: boolean, config: import('types/config').ValidatedConfig }} Options */
3166
4202
  /** @typedef {import('types/internal').SSRComponent} SSRComponent */
@@ -3246,14 +4282,17 @@ class Watcher extends EventEmitter {
3246
4282
  }
3247
4283
  };
3248
4284
 
3249
- /** @type {(req: import("http").IncomingMessage, res: import("http").ServerResponse) => void} */
3250
- let handler = (req, res) => {};
3251
-
3252
- this.server = await get_server(this.https, vite_config, (req, res) => handler(req, res));
3253
-
3254
4285
  // don't warn on overriding defaults
3255
4286
  const [modified_vite_config] = deep_merge(default_config, vite_config);
3256
4287
 
4288
+ const kit_plugin = await create_plugin(this.config, this.dir, this.cwd, () => {
4289
+ if (!this.manifest) {
4290
+ throw new Error('Manifest is not available');
4291
+ }
4292
+
4293
+ return this.manifest;
4294
+ });
4295
+
3257
4296
  /** @type {[any, string[]]} */
3258
4297
  const [merged_config, conflicts] = deep_merge(modified_vite_config, {
3259
4298
  configFile: false,
@@ -3278,14 +4317,13 @@ class Watcher extends EventEmitter {
3278
4317
  compilerOptions: {
3279
4318
  hydratable: !!this.config.kit.hydrate
3280
4319
  }
3281
- })
4320
+ }),
4321
+ kit_plugin
3282
4322
  ],
3283
4323
  publicDir: this.config.kit.files.assets,
3284
4324
  server: {
3285
- middlewareMode: true,
3286
- hmr: {
3287
- ...(this.https ? { server: this.server, port: this.port } : {})
3288
- }
4325
+ host: this.host,
4326
+ https: this.https
3289
4327
  },
3290
4328
  base: this.config.kit.paths.assets.startsWith('/') ? `${this.config.kit.paths.assets}/` : '/'
3291
4329
  });
@@ -3293,18 +4331,8 @@ class Watcher extends EventEmitter {
3293
4331
  print_config_conflicts(conflicts, 'kit.vite.');
3294
4332
 
3295
4333
  this.vite = await vite.createServer(merged_config);
3296
-
3297
- const get_manifest = () => {
3298
- if (!this.manifest) {
3299
- throw new Error('Manifest is not available');
3300
- }
3301
-
3302
- return this.manifest;
3303
- };
3304
-
3305
- handler = await create_handler(this.vite, this.config, this.dir, this.cwd, get_manifest);
3306
-
3307
- this.server.listen(this.port, this.host || '0.0.0.0');
4334
+ remove_html_middlewares(this.vite.middlewares);
4335
+ await this.vite.listen(this.port);
3308
4336
  }
3309
4337
 
3310
4338
  update() {
@@ -3351,7 +4379,7 @@ class Watcher extends EventEmitter {
3351
4379
  }
3352
4380
 
3353
4381
  close() {
3354
- if (!this.vite || !this.server || !this.cheapwatch) {
4382
+ if (!this.vite || !this.cheapwatch) {
3355
4383
  throw new Error('Cannot close server before it is initialized');
3356
4384
  }
3357
4385
 
@@ -3359,7 +4387,6 @@ class Watcher extends EventEmitter {
3359
4387
  this.closed = true;
3360
4388
 
3361
4389
  this.vite.close();
3362
- this.server.close();
3363
4390
  this.cheapwatch.close();
3364
4391
  }
3365
4392
  }
@@ -3370,15 +4397,31 @@ function get_params(array) {
3370
4397
  // src/routes/[x]/[y]/[z]/svelte, create a function
3371
4398
  // that turns a RegExpExecArray into ({ x, y, z })
3372
4399
 
4400
+ // input has already been decoded by decodeURI
4401
+ // now handle the rest that decodeURIComponent would do
4402
+ const d = /** @param {string} s */ (s) =>
4403
+ s
4404
+ .replace(/%23/g, '#')
4405
+ .replace(/%3[Bb]/g, ';')
4406
+ .replace(/%2[Cc]/g, ',')
4407
+ .replace(/%2[Ff]/g, '/')
4408
+ .replace(/%3[Ff]/g, '?')
4409
+ .replace(/%3[Aa]/g, ':')
4410
+ .replace(/%40/g, '@')
4411
+ .replace(/%26/g, '&')
4412
+ .replace(/%3[Dd]/g, '=')
4413
+ .replace(/%2[Bb]/g, '+')
4414
+ .replace(/%24/g, '$');
4415
+
3373
4416
  /** @param {RegExpExecArray} match */
3374
4417
  const fn = (match) => {
3375
4418
  /** @type {Record<string, string>} */
3376
4419
  const params = {};
3377
4420
  array.forEach((key, i) => {
3378
4421
  if (key.startsWith('...')) {
3379
- params[key.slice(3)] = decodeURIComponent(match[i + 1] || '');
4422
+ params[key.slice(3)] = d(match[i + 1] || '');
3380
4423
  } else {
3381
- params[key] = decodeURIComponent(match[i + 1]);
4424
+ params[key] = d(match[i + 1]);
3382
4425
  }
3383
4426
  });
3384
4427
  return params;
@@ -3388,13 +4431,12 @@ function get_params(array) {
3388
4431
  }
3389
4432
 
3390
4433
  /**
3391
- * @param {vite.ViteDevServer} vite
3392
4434
  * @param {import('types/config').ValidatedConfig} config
3393
4435
  * @param {string} dir
3394
4436
  * @param {string} cwd
3395
4437
  * @param {() => import('types/internal').SSRManifest} get_manifest
3396
4438
  */
3397
- async function create_handler(vite, config, dir, cwd, get_manifest) {
4439
+ async function create_plugin(config, dir, cwd, get_manifest) {
3398
4440
  /**
3399
4441
  * @type {amp_validator.Validator?}
3400
4442
  */
@@ -3414,11 +4456,14 @@ async function create_handler(vite, config, dir, cwd, get_manifest) {
3414
4456
  };
3415
4457
 
3416
4458
  /**
3417
- * @param {import('http').IncomingMessage} req
3418
- * @param {import('http').ServerResponse} res
4459
+ * @param {vite.ViteDevServer} vite
3419
4460
  */
3420
- return (req, res) => {
3421
- vite.middlewares(req, res, async () => {
4461
+ function create_kit_middleware(vite) {
4462
+ /**
4463
+ * Use a named function for debugging
4464
+ * @type {import('connect').NextHandleFunction}
4465
+ */
4466
+ return async function svelteKitMiddleware(req, res) {
3422
4467
  try {
3423
4468
  if (!req.url || !req.method) throw new Error('Incomplete request');
3424
4469
  if (req.url === '/favicon.ico') return not_found(res);
@@ -3479,8 +4524,9 @@ async function create_handler(vite, config, dir, cwd, get_manifest) {
3479
4524
  return res.end(err.reason || 'Invalid request body');
3480
4525
  }
3481
4526
 
3482
- const host = /** @type {string} */ (config.kit.host ||
3483
- req.headers[config.kit.hostHeader || 'host']);
4527
+ const host = /** @type {string} */ (
4528
+ config.kit.host || req.headers[config.kit.hostHeader || 'host']
4529
+ );
3484
4530
 
3485
4531
  const rendered = await respond(
3486
4532
  {
@@ -3631,7 +4677,19 @@ async function create_handler(vite, config, dir, cwd, get_manifest) {
3631
4677
  res.statusCode = 500;
3632
4678
  res.end(error.stack);
3633
4679
  }
3634
- });
4680
+ };
4681
+ }
4682
+
4683
+ return {
4684
+ name: 'vite-plugin-svelte-kit',
4685
+ /**
4686
+ * @param {import('vite').ViteDevServer} vite
4687
+ */
4688
+ configureServer(vite) {
4689
+ return () => {
4690
+ vite.middlewares.use(create_kit_middleware(vite));
4691
+ };
4692
+ }
3635
4693
  };
3636
4694
  }
3637
4695
 
@@ -3641,4 +4699,21 @@ function not_found(res) {
3641
4699
  res.end('Not found');
3642
4700
  }
3643
4701
 
4702
+ /**
4703
+ * @param {import('connect').Server} server
4704
+ */
4705
+ function remove_html_middlewares(server) {
4706
+ const html_middlewares = [
4707
+ 'viteIndexHtmlMiddleware',
4708
+ 'vite404Middleware',
4709
+ 'viteSpaFallbackMiddleware'
4710
+ ];
4711
+ for (let i = server.stack.length - 1; i > 0; i--) {
4712
+ // @ts-expect-error using internals until https://github.com/vitejs/vite/pull/4640 is merged
4713
+ if (html_middlewares.includes(server.stack[i].handle.name)) {
4714
+ server.stack.splice(i, 1);
4715
+ }
4716
+ }
4717
+ }
4718
+
3644
4719
  export { dev };