@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.
- package/assets/runtime/internal/start.js +6 -5
- package/dist/chunks/cert.js +2494 -2338
- package/dist/chunks/index.js +2348 -1273
- package/dist/chunks/index2.js +44 -23
- package/dist/chunks/index3.js +604 -23
- package/dist/chunks/index4.js +303 -522
- package/dist/chunks/index5.js +328 -303
- package/dist/chunks/index6.js +19408 -296
- package/dist/cli.js +6 -6
- package/dist/ssr.js +41 -34
- package/package.json +17 -17
- package/types/internal.d.ts +1 -3
- package/dist/chunks/_commonjsHelpers.js +0 -8
- package/dist/chunks/index7.js +0 -19368
package/dist/chunks/index.js
CHANGED
|
@@ -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
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
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$
|
|
11
|
+
import require$$0$3 from 'domain';
|
|
13
12
|
import 'querystring';
|
|
14
|
-
import
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
750
|
-
});
|
|
770
|
+
var commander = {exports: {}};
|
|
751
771
|
|
|
752
772
|
/**
|
|
753
773
|
* Module dependencies.
|
|
754
774
|
*/
|
|
755
775
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
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
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
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
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
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
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
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
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
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
|
-
|
|
822
|
-
|
|
823
|
-
*
|
|
824
|
-
* @return {String}
|
|
825
|
-
* @api private
|
|
826
|
-
*/
|
|
892
|
+
optionTerm(option) {
|
|
893
|
+
return option.flags;
|
|
894
|
+
}
|
|
827
895
|
|
|
828
|
-
|
|
829
|
-
|
|
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
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
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
|
-
|
|
841
|
-
|
|
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
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
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
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
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
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
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
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
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
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
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
|
-
|
|
952
|
-
|
|
953
|
-
|
|
958
|
+
/**
|
|
959
|
+
* Get the description for the command.
|
|
960
|
+
*
|
|
961
|
+
* @param {Command} cmd
|
|
962
|
+
* @returns {string}
|
|
963
|
+
*/
|
|
954
964
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
* @api private
|
|
960
|
-
*/
|
|
965
|
+
commandDescription(cmd) {
|
|
966
|
+
// @ts-ignore: overloaded return type
|
|
967
|
+
return cmd.description();
|
|
968
|
+
}
|
|
961
969
|
|
|
962
|
-
|
|
963
|
-
|
|
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
|
-
|
|
968
|
-
|
|
969
|
-
|
|
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
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
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
|
-
|
|
987
|
-
|
|
988
|
-
|
|
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 (
|
|
997
|
-
|
|
998
|
-
|
|
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 (
|
|
1001
|
-
|
|
999
|
+
if (option.defaultValue !== undefined) {
|
|
1000
|
+
extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
|
|
1002
1001
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
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
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1132
|
-
|
|
1133
|
-
if (
|
|
1134
|
-
|
|
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
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
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
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
if (
|
|
1164
|
-
|
|
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
|
-
//
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
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
|
-
|
|
1184
|
-
}
|
|
1064
|
+
return output.join('\n');
|
|
1065
|
+
}
|
|
1185
1066
|
|
|
1186
|
-
/**
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
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
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
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
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
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
|
-
|
|
1211
|
-
|
|
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
|
-
|
|
1214
|
-
|
|
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
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
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
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
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
|
-
|
|
1157
|
+
default(value, description) {
|
|
1158
|
+
this.defaultValue = value;
|
|
1159
|
+
this.defaultValueDescription = description;
|
|
1160
|
+
return this;
|
|
1161
|
+
};
|
|
1227
1162
|
|
|
1228
|
-
|
|
1229
|
-
|
|
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
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
return command.alias() === name;
|
|
1236
|
-
})[0];
|
|
1237
|
-
}
|
|
1170
|
+
argParser(fn) {
|
|
1171
|
+
this.parseArg = fn;
|
|
1172
|
+
return this;
|
|
1173
|
+
};
|
|
1238
1174
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
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
|
-
|
|
1252
|
-
|
|
1182
|
+
makeOptionMandatory(mandatory = true) {
|
|
1183
|
+
this.mandatory = !!mandatory;
|
|
1184
|
+
return this;
|
|
1185
|
+
};
|
|
1253
1186
|
|
|
1254
|
-
/**
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
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
|
-
|
|
1264
|
-
|
|
1199
|
+
/**
|
|
1200
|
+
* @api private
|
|
1201
|
+
*/
|
|
1265
1202
|
|
|
1266
|
-
|
|
1267
|
-
|
|
1203
|
+
_concatValue(value, previous) {
|
|
1204
|
+
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
1205
|
+
return [value];
|
|
1206
|
+
}
|
|
1268
1207
|
|
|
1269
|
-
|
|
1270
|
-
if (args[0] === 'help') {
|
|
1271
|
-
args[0] = args[1];
|
|
1272
|
-
args[1] = '--help';
|
|
1208
|
+
return previous.concat(value);
|
|
1273
1209
|
}
|
|
1274
1210
|
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1211
|
+
/**
|
|
1212
|
+
* Only allow option value to be one of choices.
|
|
1213
|
+
*
|
|
1214
|
+
* @param {string[]} values
|
|
1215
|
+
* @return {Option}
|
|
1216
|
+
*/
|
|
1279
1217
|
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
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
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1232
|
+
/**
|
|
1233
|
+
* Return option name.
|
|
1234
|
+
*
|
|
1235
|
+
* @return {string}
|
|
1236
|
+
*/
|
|
1290
1237
|
|
|
1291
|
-
|
|
1292
|
-
|
|
1238
|
+
name() {
|
|
1239
|
+
if (this.long) {
|
|
1240
|
+
return this.long.replace(/^--/, '');
|
|
1241
|
+
}
|
|
1242
|
+
return this.short.replace(/^-/, '');
|
|
1243
|
+
};
|
|
1293
1244
|
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
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
|
-
|
|
1253
|
+
attributeName() {
|
|
1254
|
+
return camelcase(this.name().replace(/^no-/, ''));
|
|
1255
|
+
};
|
|
1304
1256
|
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
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
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
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
|
-
|
|
1317
|
-
args.
|
|
1318
|
-
|
|
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
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
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
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
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
|
-
|
|
1337
|
-
}
|
|
1642
|
+
return this;
|
|
1643
|
+
};
|
|
1338
1644
|
|
|
1339
|
-
|
|
1340
|
-
|
|
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
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
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
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
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
|
-
|
|
1804
|
+
option.default(fn);
|
|
1379
1805
|
}
|
|
1806
|
+
|
|
1807
|
+
return this.addOption(option);
|
|
1380
1808
|
}
|
|
1381
1809
|
|
|
1382
|
-
|
|
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
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
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
|
-
|
|
1398
|
-
|
|
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
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
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
|
-
|
|
1408
|
-
|
|
1946
|
+
return this;
|
|
1947
|
+
};
|
|
1409
1948
|
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
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
|
-
|
|
1418
|
-
|
|
1965
|
+
/**
|
|
1966
|
+
* Store option value
|
|
1967
|
+
*
|
|
1968
|
+
* @param {string} key
|
|
1969
|
+
* @param {Object} value
|
|
1970
|
+
* @api private
|
|
1971
|
+
*/
|
|
1419
1972
|
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
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
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
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
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
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
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1488
|
-
|
|
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
|
-
|
|
2149
|
+
proc = childProcess.spawn(bin, args, { stdio: 'inherit' });
|
|
1491
2150
|
}
|
|
1492
|
-
|
|
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
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
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
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
2216
|
+
/**
|
|
2217
|
+
* Process arguments in context of this command.
|
|
2218
|
+
*
|
|
2219
|
+
* @api private
|
|
2220
|
+
*/
|
|
1511
2221
|
|
|
1512
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
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
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
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
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
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
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
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
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
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
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
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
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
};
|
|
2513
|
+
/**
|
|
2514
|
+
* `Option` is missing an argument.
|
|
2515
|
+
*
|
|
2516
|
+
* @param {Option} option
|
|
2517
|
+
* @api private
|
|
2518
|
+
*/
|
|
1579
2519
|
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
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
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
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
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
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
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
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
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
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
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
2550
|
+
/**
|
|
2551
|
+
* Excess arguments, more than expected.
|
|
2552
|
+
*
|
|
2553
|
+
* @param {string[]} receivedArgs
|
|
2554
|
+
* @api private
|
|
2555
|
+
*/
|
|
1635
2556
|
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
*
|
|
1639
|
-
* @param {String} alias
|
|
1640
|
-
* @return {String|Command}
|
|
1641
|
-
* @api public
|
|
1642
|
-
*/
|
|
2557
|
+
_excessArguments(receivedArgs) {
|
|
2558
|
+
if (this._allowExcessArguments) return;
|
|
1643
2559
|
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
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
|
-
|
|
2567
|
+
/**
|
|
2568
|
+
* Unknown command.
|
|
2569
|
+
*
|
|
2570
|
+
* @api private
|
|
2571
|
+
*/
|
|
1651
2572
|
|
|
1652
|
-
|
|
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
|
-
|
|
1655
|
-
|
|
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
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
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
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
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
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
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
|
-
|
|
1676
|
-
|
|
2636
|
+
alias(alias) {
|
|
2637
|
+
if (alias === undefined) return this._aliases[0]; // just return first, for backwards compatibility
|
|
1677
2638
|
|
|
1678
|
-
|
|
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
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
return this;
|
|
1693
|
-
};
|
|
2647
|
+
command._aliases.push(alias);
|
|
2648
|
+
return this;
|
|
2649
|
+
};
|
|
1694
2650
|
|
|
1695
|
-
/**
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
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
|
-
|
|
1703
|
-
|
|
1704
|
-
return
|
|
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
|
-
|
|
1722
|
-
|
|
1723
|
-
* @return {Number}
|
|
1724
|
-
* @api private
|
|
1725
|
-
*/
|
|
2664
|
+
aliases.forEach((alias) => this.alias(alias));
|
|
2665
|
+
return this;
|
|
2666
|
+
};
|
|
1726
2667
|
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
2668
|
+
/**
|
|
2669
|
+
* Set / get the command usage `str`.
|
|
2670
|
+
*
|
|
2671
|
+
* @param {string} [str]
|
|
2672
|
+
* @return {String|Command}
|
|
2673
|
+
*/
|
|
1733
2674
|
|
|
1734
|
-
|
|
1735
|
-
|
|
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
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
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
|
-
|
|
1753
|
-
|
|
1754
|
-
* @return {Number}
|
|
1755
|
-
* @api private
|
|
1756
|
-
*/
|
|
2689
|
+
this._usage = str;
|
|
2690
|
+
return this;
|
|
2691
|
+
};
|
|
1757
2692
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
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
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
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
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
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
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
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
|
-
|
|
1796
|
-
|
|
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
|
-
|
|
1799
|
-
|
|
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
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
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
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
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
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
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
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
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
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
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
|
-
|
|
1868
|
-
|
|
1869
|
-
if (commandHelp) cmds = [commandHelp];
|
|
2801
|
+
return this;
|
|
2802
|
+
};
|
|
1870
2803
|
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
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
|
-
|
|
1879
|
-
.
|
|
1880
|
-
.
|
|
1881
|
-
.
|
|
1882
|
-
|
|
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
|
-
*
|
|
1887
|
-
*
|
|
1888
|
-
* @api public
|
|
2855
|
+
* Expose the root command.
|
|
1889
2856
|
*/
|
|
1890
2857
|
|
|
1891
|
-
|
|
1892
|
-
|
|
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
|
-
*
|
|
1903
|
-
*
|
|
1904
|
-
* @api public
|
|
2862
|
+
* Expose classes
|
|
1905
2863
|
*/
|
|
1906
2864
|
|
|
1907
|
-
Command
|
|
1908
|
-
|
|
1909
|
-
|
|
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 {
|
|
1916
|
-
* @return {
|
|
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(
|
|
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
|
-
*
|
|
2886
|
+
* Output help information if help flags specified
|
|
1928
2887
|
*
|
|
1929
|
-
* @param {
|
|
1930
|
-
* @param {
|
|
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
|
|
1936
|
-
|
|
1937
|
-
|
|
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
|
|
2903
|
+
* Takes an argument and returns its human readable equivalent for help usage.
|
|
1960
2904
|
*
|
|
1961
2905
|
* @param {Object} arg
|
|
1962
|
-
* @return {
|
|
2906
|
+
* @return {string}
|
|
1963
2907
|
* @api private
|
|
1964
2908
|
*/
|
|
1965
2909
|
|
|
1966
2910
|
function humanReadableArgName(arg) {
|
|
1967
|
-
|
|
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
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
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$
|
|
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$
|
|
3137
|
+
var core = Promise$7;
|
|
2134
3138
|
|
|
2135
|
-
function Promise$
|
|
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.
|
|
2143
|
-
this.
|
|
2144
|
-
this.
|
|
2145
|
-
this.
|
|
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$
|
|
2150
|
-
Promise$
|
|
2151
|
-
Promise$
|
|
3153
|
+
Promise$7._Y = null;
|
|
3154
|
+
Promise$7._Z = null;
|
|
3155
|
+
Promise$7._0 = noop;
|
|
2152
3156
|
|
|
2153
|
-
Promise$
|
|
2154
|
-
if (this.constructor !== Promise$
|
|
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$
|
|
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$
|
|
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.
|
|
2171
|
-
self = self.
|
|
3174
|
+
while (self._V === 3) {
|
|
3175
|
+
self = self._W;
|
|
2172
3176
|
}
|
|
2173
|
-
if (Promise$
|
|
2174
|
-
Promise$
|
|
3177
|
+
if (Promise$7._Y) {
|
|
3178
|
+
Promise$7._Y(self);
|
|
2175
3179
|
}
|
|
2176
|
-
if (self.
|
|
2177
|
-
if (self.
|
|
2178
|
-
self.
|
|
2179
|
-
self.
|
|
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.
|
|
2183
|
-
self.
|
|
2184
|
-
self.
|
|
3186
|
+
if (self._U === 1) {
|
|
3187
|
+
self._U = 2;
|
|
3188
|
+
self._X = [self._X, deferred];
|
|
2185
3189
|
return;
|
|
2186
3190
|
}
|
|
2187
|
-
self.
|
|
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
|
-
|
|
2195
|
-
var cb = self.
|
|
3198
|
+
asap$2(function() {
|
|
3199
|
+
var cb = self._V === 1 ? deferred.onFulfilled : deferred.onRejected;
|
|
2196
3200
|
if (cb === null) {
|
|
2197
|
-
if (self.
|
|
2198
|
-
resolve(deferred.promise, self.
|
|
3201
|
+
if (self._V === 1) {
|
|
3202
|
+
resolve(deferred.promise, self._W);
|
|
2199
3203
|
} else {
|
|
2200
|
-
reject(deferred.promise, self.
|
|
3204
|
+
reject(deferred.promise, self._W);
|
|
2201
3205
|
}
|
|
2202
3206
|
return;
|
|
2203
3207
|
}
|
|
2204
|
-
var ret = tryCallOne(cb, self.
|
|
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$
|
|
3234
|
+
newValue instanceof Promise$7
|
|
2231
3235
|
) {
|
|
2232
|
-
self.
|
|
2233
|
-
self.
|
|
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.
|
|
2242
|
-
self.
|
|
3245
|
+
self._V = 1;
|
|
3246
|
+
self._W = newValue;
|
|
2243
3247
|
finale(self);
|
|
2244
3248
|
}
|
|
2245
3249
|
|
|
2246
3250
|
function reject(self, newValue) {
|
|
2247
|
-
self.
|
|
2248
|
-
self.
|
|
2249
|
-
if (Promise$
|
|
2250
|
-
Promise$
|
|
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.
|
|
2256
|
-
handle(self, self.
|
|
2257
|
-
self.
|
|
3259
|
+
if (self._U === 1) {
|
|
3260
|
+
handle(self, self._X);
|
|
3261
|
+
self._X = null;
|
|
2258
3262
|
}
|
|
2259
|
-
if (self.
|
|
2260
|
-
for (var i = 0; i < self.
|
|
2261
|
-
handle(self, self.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
3310
|
+
var Promise$5 = core;
|
|
3311
|
+
Promise$5.prototype.finally = function (f) {
|
|
2306
3312
|
return this.then(function (value) {
|
|
2307
|
-
return
|
|
3313
|
+
return Promise$5.resolve(f()).then(function () {
|
|
2308
3314
|
return value;
|
|
2309
3315
|
});
|
|
2310
3316
|
}, function (err) {
|
|
2311
|
-
return
|
|
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
|
|
2328
|
-
p.
|
|
2329
|
-
p.
|
|
3337
|
+
var p = new Promise$4(Promise$4._0);
|
|
3338
|
+
p._V = 1;
|
|
3339
|
+
p._W = value;
|
|
2330
3340
|
return p;
|
|
2331
3341
|
}
|
|
2332
|
-
|
|
2333
|
-
if (value instanceof
|
|
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
|
|
3356
|
+
return new Promise$4(then.bind(value));
|
|
2347
3357
|
}
|
|
2348
3358
|
} catch (ex) {
|
|
2349
|
-
return new
|
|
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
|
-
|
|
2358
|
-
|
|
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
|
|
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
|
|
2366
|
-
while (val.
|
|
2367
|
-
val = val.
|
|
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.
|
|
2370
|
-
if (val.
|
|
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
|
|
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
|
-
|
|
2398
|
-
return new
|
|
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
|
-
|
|
2404
|
-
return new
|
|
2405
|
-
values.forEach(function(value){
|
|
2406
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)(
|
|
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
|
-
)(
|
|
3590
|
+
)(Promise$3, fn);
|
|
2562
3591
|
}
|
|
2563
3592
|
|
|
2564
|
-
|
|
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
|
|
3603
|
+
return new Promise$3(function (resolve, reject) {
|
|
2575
3604
|
reject(ex);
|
|
2576
3605
|
});
|
|
2577
3606
|
} else {
|
|
2578
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3619
|
+
asap(function () {
|
|
2591
3620
|
callback.call(ctx, null, value);
|
|
2592
3621
|
});
|
|
2593
3622
|
}, function (err) {
|
|
2594
|
-
|
|
3623
|
+
asap(function () {
|
|
2595
3624
|
callback.call(ctx, err);
|
|
2596
3625
|
});
|
|
2597
3626
|
});
|
|
2598
3627
|
};
|
|
2599
3628
|
|
|
2600
|
-
|
|
2601
|
-
|
|
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
|
-
|
|
3635
|
+
Promise$2.prototype.isFulfilled = function() {
|
|
2606
3636
|
return this.getState() == 1;
|
|
2607
3637
|
};
|
|
2608
3638
|
|
|
2609
|
-
|
|
3639
|
+
Promise$2.prototype.isRejected = function() {
|
|
2610
3640
|
return this.getState() == 2;
|
|
2611
3641
|
};
|
|
2612
3642
|
|
|
2613
|
-
|
|
2614
|
-
if (this.
|
|
2615
|
-
return this.
|
|
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.
|
|
3652
|
+
return this._W;
|
|
2623
3653
|
};
|
|
2624
3654
|
|
|
2625
|
-
|
|
2626
|
-
if (this.
|
|
2627
|
-
return this.
|
|
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.
|
|
3664
|
+
return this._W;
|
|
2635
3665
|
};
|
|
2636
3666
|
|
|
2637
|
-
|
|
2638
|
-
if (this.
|
|
2639
|
-
return this.
|
|
3667
|
+
Promise$2.prototype.getState = function () {
|
|
3668
|
+
if (this._V === 3) {
|
|
3669
|
+
return this._W.getState();
|
|
2640
3670
|
}
|
|
2641
|
-
if (this.
|
|
3671
|
+
if (this._V === -1 || this._V === -2) {
|
|
2642
3672
|
return 0;
|
|
2643
3673
|
}
|
|
2644
3674
|
|
|
2645
|
-
return this.
|
|
3675
|
+
return this._V;
|
|
2646
3676
|
};
|
|
2647
3677
|
};
|
|
2648
3678
|
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
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
|
|
2720
|
-
|
|
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
|
|
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
|
|
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
|
-
*
|
|
2880
|
-
* from 'https://cdn.ampproject.org/v0/
|
|
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
|
|
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
|
|
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/
|
|
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
|
|
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
|
-
|
|
4019
|
+
amphtmlValidator.getInstance = getInstance;
|
|
2979
4020
|
|
|
2980
4021
|
/**
|
|
2981
|
-
* Provided the contents of the
|
|
2982
|
-
* 'https://cdn.ampproject.org/v0/
|
|
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
|
|
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
|
-
|
|
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 ?
|
|
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' ?
|
|
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
|
-
|
|
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/
|
|
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
|
-
|
|
3072
|
-
|
|
4112
|
+
const opts = program.opts();
|
|
4113
|
+
if (opts.length === 0) {
|
|
4114
|
+
program.outputHelp();
|
|
3073
4115
|
process.exit(1);
|
|
3074
4116
|
}
|
|
3075
|
-
if (
|
|
3076
|
-
|
|
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 (
|
|
3084
|
-
|
|
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 <
|
|
3092
|
-
const item =
|
|
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,
|
|
4138
|
+
inputs.push(readFromUrl(item, opts.userAgent));
|
|
3097
4139
|
} else {
|
|
3098
4140
|
inputs.push(readFromFile(item));
|
|
3099
4141
|
}
|
|
3100
4142
|
}
|
|
3101
|
-
getInstance(
|
|
4143
|
+
getInstance(opts.validator_js, opts.userAgent)
|
|
3102
4144
|
.then(function(validator) {
|
|
3103
|
-
|
|
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],
|
|
3110
|
-
if (
|
|
3111
|
-
jsonOut[
|
|
4151
|
+
resolvedInputs[ii], opts.html_format);
|
|
4152
|
+
if (opts.format === 'json') {
|
|
4153
|
+
jsonOut[program.args[ii]] = validationResult;
|
|
3112
4154
|
} else {
|
|
3113
4155
|
logValidationResult(
|
|
3114
|
-
|
|
3115
|
-
|
|
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 (
|
|
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
|
-
(
|
|
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
|
-
(
|
|
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
|
-
|
|
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
|
-
|
|
3286
|
-
|
|
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
|
-
|
|
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.
|
|
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)] =
|
|
4422
|
+
params[key.slice(3)] = d(match[i + 1] || '');
|
|
3380
4423
|
} else {
|
|
3381
|
-
params[key] =
|
|
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
|
|
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 {
|
|
3418
|
-
* @param {import('http').ServerResponse} res
|
|
4459
|
+
* @param {vite.ViteDevServer} vite
|
|
3419
4460
|
*/
|
|
3420
|
-
|
|
3421
|
-
|
|
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} */ (
|
|
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 };
|