sv 0.6.11 → 0.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +546 -180
- package/dist/index.js +1 -1
- package/dist/{install-Bj_yXcZX.js → install-DJcXCdFP.js} +0 -53
- package/dist/templates/demo/files.types=checkjs.json +2 -6
- package/dist/templates/demo/files.types=none.json +2 -6
- package/dist/templates/demo/files.types=typescript.json +2 -6
- package/dist/templates/demo/package.json +1 -1
- package/dist/templates/library/package.json +4 -5
- package/dist/templates/minimal/package.json +1 -1
- package/package.json +4 -4
package/dist/bin.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { g as getDefaultExportFromCjs$2, a as commonjsGlobal,
|
|
2
|
+
import { g as getDefaultExportFromCjs$2, a as commonjsGlobal, t as templates, c as create$1 } from './main-UNazaUHM.js';
|
|
3
3
|
import require$$0 from 'node:events';
|
|
4
|
-
import require$$1, { execSync } from 'node:child_process';
|
|
4
|
+
import require$$1, { exec, execSync } from 'node:child_process';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import process$1 from 'node:process';
|
|
8
|
-
import { u as up$1, d as dedent, p as parseJson, a as parseScript, b as imports, c as common, e as exports$1, o as object$1, v as variables, _ as _function, f as parseSvelte, g as array$1, w as walk$1, k as kit, h as addFromString, E as Element, j as index, l as parseHtml, m as parseHtml$1, A as AtRule, n as parseCss, q as pc, r as intro, s as outro, t as log$1, x as cancel, y as box, z as multiselect, B as isCancel, C as confirm, D as createWorkspace, F as setupAddons, G as note, H as select, I as text, J as packageManagerPrompt, K as applyAddons, L as installDependencies, M as formatFiles, N as spinner, O as getHighlighter, P as detectSync, Q as getUserAgent, R as resolveCommand, S as group, T as from } from './install-
|
|
8
|
+
import { u as up$1, d as dedent, p as parseJson, a as parseScript, b as imports, c as common, e as exports$1, o as object$1, v as variables, _ as _function, f as parseSvelte, g as array$1, w as walk$1, k as kit, h as addFromString, E as Element, j as index, l as parseHtml, m as parseHtml$1, A as AtRule, n as parseCss, q as pc, r as intro, s as outro, t as log$1, x as cancel, y as box, z as multiselect, B as isCancel, C as confirm, D as createWorkspace, F as setupAddons, G as note, H as select, I as text, J as packageManagerPrompt, K as applyAddons, L as installDependencies, M as formatFiles, N as spinner, O as getHighlighter, P as detectSync, Q as getUserAgent, R as resolveCommand, S as group, T as from } from './install-DJcXCdFP.js';
|
|
9
9
|
import 'node:readline';
|
|
10
10
|
import 'node:tty';
|
|
11
11
|
import { createGunzip } from 'node:zlib';
|
|
@@ -14,6 +14,7 @@ import { pipeline } from 'node:stream/promises';
|
|
|
14
14
|
import require$$5 from 'events';
|
|
15
15
|
import require$$1$1 from 'fs';
|
|
16
16
|
import require$$1$1$1 from 'path';
|
|
17
|
+
import { promisify } from 'node:util';
|
|
17
18
|
import 'node:module';
|
|
18
19
|
import 'child_process';
|
|
19
20
|
import 'process';
|
|
@@ -24,7 +25,7 @@ import 'url';
|
|
|
24
25
|
import 'node:fs/promises';
|
|
25
26
|
|
|
26
27
|
var name = "sv";
|
|
27
|
-
var version = "0.6.
|
|
28
|
+
var version = "0.6.13";
|
|
28
29
|
var type = "module";
|
|
29
30
|
var description = "A CLI for creating and updating SvelteKit projects";
|
|
30
31
|
var license = "MIT";
|
|
@@ -61,7 +62,7 @@ var devDependencies = {
|
|
|
61
62
|
"@types/degit": "^2.8.6",
|
|
62
63
|
"@types/ps-tree": "^1.1.6",
|
|
63
64
|
"@types/tar-fs": "^2.0.4",
|
|
64
|
-
commander: "^
|
|
65
|
+
commander: "^13.0.0",
|
|
65
66
|
degit: "^2.8.4",
|
|
66
67
|
empathic: "^1.0.0",
|
|
67
68
|
"package-manager-detector": "^0.2.7",
|
|
@@ -331,11 +332,24 @@ function requireHelp () {
|
|
|
331
332
|
class Help {
|
|
332
333
|
constructor() {
|
|
333
334
|
this.helpWidth = undefined;
|
|
335
|
+
this.minWidthToWrap = 40;
|
|
334
336
|
this.sortSubcommands = false;
|
|
335
337
|
this.sortOptions = false;
|
|
336
338
|
this.showGlobalOptions = false;
|
|
337
339
|
}
|
|
338
340
|
|
|
341
|
+
/**
|
|
342
|
+
* prepareContext is called by Commander after applying overrides from `Command.configureHelp()`
|
|
343
|
+
* and just before calling `formatHelp()`.
|
|
344
|
+
*
|
|
345
|
+
* Commander just uses the helpWidth and the rest is provided for optional use by more complex subclasses.
|
|
346
|
+
*
|
|
347
|
+
* @param {{ error?: boolean, helpWidth?: number, outputHasColors?: boolean }} contextOptions
|
|
348
|
+
*/
|
|
349
|
+
prepareContext(contextOptions) {
|
|
350
|
+
this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
|
|
351
|
+
}
|
|
352
|
+
|
|
339
353
|
/**
|
|
340
354
|
* Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
|
|
341
355
|
*
|
|
@@ -510,7 +524,12 @@ function requireHelp () {
|
|
|
510
524
|
|
|
511
525
|
longestSubcommandTermLength(cmd, helper) {
|
|
512
526
|
return helper.visibleCommands(cmd).reduce((max, command) => {
|
|
513
|
-
return Math.max(
|
|
527
|
+
return Math.max(
|
|
528
|
+
max,
|
|
529
|
+
this.displayWidth(
|
|
530
|
+
helper.styleSubcommandTerm(helper.subcommandTerm(command)),
|
|
531
|
+
),
|
|
532
|
+
);
|
|
514
533
|
}, 0);
|
|
515
534
|
}
|
|
516
535
|
|
|
@@ -524,7 +543,10 @@ function requireHelp () {
|
|
|
524
543
|
|
|
525
544
|
longestOptionTermLength(cmd, helper) {
|
|
526
545
|
return helper.visibleOptions(cmd).reduce((max, option) => {
|
|
527
|
-
return Math.max(
|
|
546
|
+
return Math.max(
|
|
547
|
+
max,
|
|
548
|
+
this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))),
|
|
549
|
+
);
|
|
528
550
|
}, 0);
|
|
529
551
|
}
|
|
530
552
|
|
|
@@ -538,7 +560,10 @@ function requireHelp () {
|
|
|
538
560
|
|
|
539
561
|
longestGlobalOptionTermLength(cmd, helper) {
|
|
540
562
|
return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
|
|
541
|
-
return Math.max(
|
|
563
|
+
return Math.max(
|
|
564
|
+
max,
|
|
565
|
+
this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))),
|
|
566
|
+
);
|
|
542
567
|
}, 0);
|
|
543
568
|
}
|
|
544
569
|
|
|
@@ -552,7 +577,12 @@ function requireHelp () {
|
|
|
552
577
|
|
|
553
578
|
longestArgumentTermLength(cmd, helper) {
|
|
554
579
|
return helper.visibleArguments(cmd).reduce((max, argument) => {
|
|
555
|
-
return Math.max(
|
|
580
|
+
return Math.max(
|
|
581
|
+
max,
|
|
582
|
+
this.displayWidth(
|
|
583
|
+
helper.styleArgumentTerm(helper.argumentTerm(argument)),
|
|
584
|
+
),
|
|
585
|
+
);
|
|
556
586
|
}, 0);
|
|
557
587
|
}
|
|
558
588
|
|
|
@@ -669,11 +699,11 @@ function requireHelp () {
|
|
|
669
699
|
);
|
|
670
700
|
}
|
|
671
701
|
if (extraInfo.length > 0) {
|
|
672
|
-
const
|
|
702
|
+
const extraDescription = `(${extraInfo.join(', ')})`;
|
|
673
703
|
if (argument.description) {
|
|
674
|
-
return `${argument.description} ${
|
|
704
|
+
return `${argument.description} ${extraDescription}`;
|
|
675
705
|
}
|
|
676
|
-
return
|
|
706
|
+
return extraDescription;
|
|
677
707
|
}
|
|
678
708
|
return argument.description;
|
|
679
709
|
}
|
|
@@ -688,71 +718,73 @@ function requireHelp () {
|
|
|
688
718
|
|
|
689
719
|
formatHelp(cmd, helper) {
|
|
690
720
|
const termWidth = helper.padWidth(cmd, helper);
|
|
691
|
-
const helpWidth = helper.helpWidth
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
if (description) {
|
|
696
|
-
const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
|
|
697
|
-
return helper.wrap(
|
|
698
|
-
fullText,
|
|
699
|
-
helpWidth - itemIndentWidth,
|
|
700
|
-
termWidth + itemSeparatorWidth,
|
|
701
|
-
);
|
|
702
|
-
}
|
|
703
|
-
return term;
|
|
704
|
-
}
|
|
705
|
-
function formatList(textArray) {
|
|
706
|
-
return textArray.join('\n').replace(/^/gm, ' '.repeat(itemIndentWidth));
|
|
721
|
+
const helpWidth = helper.helpWidth ?? 80; // in case prepareContext() was not called
|
|
722
|
+
|
|
723
|
+
function callFormatItem(term, description) {
|
|
724
|
+
return helper.formatItem(term, termWidth, description, helper);
|
|
707
725
|
}
|
|
708
726
|
|
|
709
727
|
// Usage
|
|
710
|
-
let output = [
|
|
728
|
+
let output = [
|
|
729
|
+
`${helper.styleTitle('Usage:')} ${helper.styleUsage(helper.commandUsage(cmd))}`,
|
|
730
|
+
'',
|
|
731
|
+
];
|
|
711
732
|
|
|
712
733
|
// Description
|
|
713
734
|
const commandDescription = helper.commandDescription(cmd);
|
|
714
735
|
if (commandDescription.length > 0) {
|
|
715
736
|
output = output.concat([
|
|
716
|
-
helper.
|
|
737
|
+
helper.boxWrap(
|
|
738
|
+
helper.styleCommandDescription(commandDescription),
|
|
739
|
+
helpWidth,
|
|
740
|
+
),
|
|
717
741
|
'',
|
|
718
742
|
]);
|
|
719
743
|
}
|
|
720
744
|
|
|
721
745
|
// Arguments
|
|
722
746
|
const argumentList = helper.visibleArguments(cmd).map((argument) => {
|
|
723
|
-
return
|
|
724
|
-
helper.argumentTerm(argument),
|
|
725
|
-
helper.argumentDescription(argument),
|
|
747
|
+
return callFormatItem(
|
|
748
|
+
helper.styleArgumentTerm(helper.argumentTerm(argument)),
|
|
749
|
+
helper.styleArgumentDescription(helper.argumentDescription(argument)),
|
|
726
750
|
);
|
|
727
751
|
});
|
|
728
752
|
if (argumentList.length > 0) {
|
|
729
|
-
output = output.concat([
|
|
753
|
+
output = output.concat([
|
|
754
|
+
helper.styleTitle('Arguments:'),
|
|
755
|
+
...argumentList,
|
|
756
|
+
'',
|
|
757
|
+
]);
|
|
730
758
|
}
|
|
731
759
|
|
|
732
760
|
// Options
|
|
733
761
|
const optionList = helper.visibleOptions(cmd).map((option) => {
|
|
734
|
-
return
|
|
735
|
-
helper.optionTerm(option),
|
|
736
|
-
helper.optionDescription(option),
|
|
762
|
+
return callFormatItem(
|
|
763
|
+
helper.styleOptionTerm(helper.optionTerm(option)),
|
|
764
|
+
helper.styleOptionDescription(helper.optionDescription(option)),
|
|
737
765
|
);
|
|
738
766
|
});
|
|
739
767
|
if (optionList.length > 0) {
|
|
740
|
-
output = output.concat([
|
|
768
|
+
output = output.concat([
|
|
769
|
+
helper.styleTitle('Options:'),
|
|
770
|
+
...optionList,
|
|
771
|
+
'',
|
|
772
|
+
]);
|
|
741
773
|
}
|
|
742
774
|
|
|
743
|
-
if (
|
|
775
|
+
if (helper.showGlobalOptions) {
|
|
744
776
|
const globalOptionList = helper
|
|
745
777
|
.visibleGlobalOptions(cmd)
|
|
746
778
|
.map((option) => {
|
|
747
|
-
return
|
|
748
|
-
helper.optionTerm(option),
|
|
749
|
-
helper.optionDescription(option),
|
|
779
|
+
return callFormatItem(
|
|
780
|
+
helper.styleOptionTerm(helper.optionTerm(option)),
|
|
781
|
+
helper.styleOptionDescription(helper.optionDescription(option)),
|
|
750
782
|
);
|
|
751
783
|
});
|
|
752
784
|
if (globalOptionList.length > 0) {
|
|
753
785
|
output = output.concat([
|
|
754
|
-
'Global Options:',
|
|
755
|
-
|
|
786
|
+
helper.styleTitle('Global Options:'),
|
|
787
|
+
...globalOptionList,
|
|
756
788
|
'',
|
|
757
789
|
]);
|
|
758
790
|
}
|
|
@@ -760,18 +792,103 @@ function requireHelp () {
|
|
|
760
792
|
|
|
761
793
|
// Commands
|
|
762
794
|
const commandList = helper.visibleCommands(cmd).map((cmd) => {
|
|
763
|
-
return
|
|
764
|
-
helper.subcommandTerm(cmd),
|
|
765
|
-
helper.subcommandDescription(cmd),
|
|
795
|
+
return callFormatItem(
|
|
796
|
+
helper.styleSubcommandTerm(helper.subcommandTerm(cmd)),
|
|
797
|
+
helper.styleSubcommandDescription(helper.subcommandDescription(cmd)),
|
|
766
798
|
);
|
|
767
799
|
});
|
|
768
800
|
if (commandList.length > 0) {
|
|
769
|
-
output = output.concat([
|
|
801
|
+
output = output.concat([
|
|
802
|
+
helper.styleTitle('Commands:'),
|
|
803
|
+
...commandList,
|
|
804
|
+
'',
|
|
805
|
+
]);
|
|
770
806
|
}
|
|
771
807
|
|
|
772
808
|
return output.join('\n');
|
|
773
809
|
}
|
|
774
810
|
|
|
811
|
+
/**
|
|
812
|
+
* Return display width of string, ignoring ANSI escape sequences. Used in padding and wrapping calculations.
|
|
813
|
+
*
|
|
814
|
+
* @param {string} str
|
|
815
|
+
* @returns {number}
|
|
816
|
+
*/
|
|
817
|
+
displayWidth(str) {
|
|
818
|
+
return stripColor(str).length;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Style the title for displaying in the help. Called with 'Usage:', 'Options:', etc.
|
|
823
|
+
*
|
|
824
|
+
* @param {string} str
|
|
825
|
+
* @returns {string}
|
|
826
|
+
*/
|
|
827
|
+
styleTitle(str) {
|
|
828
|
+
return str;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
styleUsage(str) {
|
|
832
|
+
// Usage has lots of parts the user might like to color separately! Assume default usage string which is formed like:
|
|
833
|
+
// command subcommand [options] [command] <foo> [bar]
|
|
834
|
+
return str
|
|
835
|
+
.split(' ')
|
|
836
|
+
.map((word) => {
|
|
837
|
+
if (word === '[options]') return this.styleOptionText(word);
|
|
838
|
+
if (word === '[command]') return this.styleSubcommandText(word);
|
|
839
|
+
if (word[0] === '[' || word[0] === '<')
|
|
840
|
+
return this.styleArgumentText(word);
|
|
841
|
+
return this.styleCommandText(word); // Restrict to initial words?
|
|
842
|
+
})
|
|
843
|
+
.join(' ');
|
|
844
|
+
}
|
|
845
|
+
styleCommandDescription(str) {
|
|
846
|
+
return this.styleDescriptionText(str);
|
|
847
|
+
}
|
|
848
|
+
styleOptionDescription(str) {
|
|
849
|
+
return this.styleDescriptionText(str);
|
|
850
|
+
}
|
|
851
|
+
styleSubcommandDescription(str) {
|
|
852
|
+
return this.styleDescriptionText(str);
|
|
853
|
+
}
|
|
854
|
+
styleArgumentDescription(str) {
|
|
855
|
+
return this.styleDescriptionText(str);
|
|
856
|
+
}
|
|
857
|
+
styleDescriptionText(str) {
|
|
858
|
+
return str;
|
|
859
|
+
}
|
|
860
|
+
styleOptionTerm(str) {
|
|
861
|
+
return this.styleOptionText(str);
|
|
862
|
+
}
|
|
863
|
+
styleSubcommandTerm(str) {
|
|
864
|
+
// This is very like usage with lots of parts! Assume default string which is formed like:
|
|
865
|
+
// subcommand [options] <foo> [bar]
|
|
866
|
+
return str
|
|
867
|
+
.split(' ')
|
|
868
|
+
.map((word) => {
|
|
869
|
+
if (word === '[options]') return this.styleOptionText(word);
|
|
870
|
+
if (word[0] === '[' || word[0] === '<')
|
|
871
|
+
return this.styleArgumentText(word);
|
|
872
|
+
return this.styleSubcommandText(word); // Restrict to initial words?
|
|
873
|
+
})
|
|
874
|
+
.join(' ');
|
|
875
|
+
}
|
|
876
|
+
styleArgumentTerm(str) {
|
|
877
|
+
return this.styleArgumentText(str);
|
|
878
|
+
}
|
|
879
|
+
styleOptionText(str) {
|
|
880
|
+
return str;
|
|
881
|
+
}
|
|
882
|
+
styleArgumentText(str) {
|
|
883
|
+
return str;
|
|
884
|
+
}
|
|
885
|
+
styleSubcommandText(str) {
|
|
886
|
+
return str;
|
|
887
|
+
}
|
|
888
|
+
styleCommandText(str) {
|
|
889
|
+
return str;
|
|
890
|
+
}
|
|
891
|
+
|
|
775
892
|
/**
|
|
776
893
|
* Calculate the pad width from the maximum term length.
|
|
777
894
|
*
|
|
@@ -790,53 +907,126 @@ function requireHelp () {
|
|
|
790
907
|
}
|
|
791
908
|
|
|
792
909
|
/**
|
|
793
|
-
*
|
|
794
|
-
* Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
|
|
910
|
+
* Detect manually wrapped and indented strings by checking for line break followed by whitespace.
|
|
795
911
|
*
|
|
796
912
|
* @param {string} str
|
|
797
|
-
* @
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
913
|
+
* @returns {boolean}
|
|
914
|
+
*/
|
|
915
|
+
preformatted(str) {
|
|
916
|
+
return /\n[^\S\r\n]/.test(str);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Format the "item", which consists of a term and description. Pad the term and wrap the description, indenting the following lines.
|
|
801
921
|
*
|
|
922
|
+
* So "TTT", 5, "DDD DDDD DD DDD" might be formatted for this.helpWidth=17 like so:
|
|
923
|
+
* TTT DDD DDDD
|
|
924
|
+
* DD DDD
|
|
925
|
+
*
|
|
926
|
+
* @param {string} term
|
|
927
|
+
* @param {number} termWidth
|
|
928
|
+
* @param {string} description
|
|
929
|
+
* @param {Help} helper
|
|
930
|
+
* @returns {string}
|
|
802
931
|
*/
|
|
932
|
+
formatItem(term, termWidth, description, helper) {
|
|
933
|
+
const itemIndent = 2;
|
|
934
|
+
const itemIndentStr = ' '.repeat(itemIndent);
|
|
935
|
+
if (!description) return itemIndentStr + term;
|
|
803
936
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
' \\f\\t\\v\u00a0\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff';
|
|
808
|
-
// Detect manually wrapped and indented strings by searching for line break followed by spaces.
|
|
809
|
-
const manualIndent = new RegExp(`[\\n][${indents}]+`);
|
|
810
|
-
if (str.match(manualIndent)) return str;
|
|
811
|
-
// Do not wrap if not enough room for a wrapped column of text (as could end up with a word per line).
|
|
812
|
-
const columnWidth = width - indent;
|
|
813
|
-
if (columnWidth < minColumnWidth) return str;
|
|
814
|
-
|
|
815
|
-
const leadingStr = str.slice(0, indent);
|
|
816
|
-
const columnText = str.slice(indent).replace('\r\n', '\n');
|
|
817
|
-
const indentString = ' '.repeat(indent);
|
|
818
|
-
const zeroWidthSpace = '\u200B';
|
|
819
|
-
const breaks = `\\s${zeroWidthSpace}`;
|
|
820
|
-
// Match line end (so empty lines don't collapse),
|
|
821
|
-
// or as much text as will fit in column, or excess text up to first break.
|
|
822
|
-
const regex = new RegExp(
|
|
823
|
-
`\n|.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`,
|
|
824
|
-
'g',
|
|
937
|
+
// Pad the term out to a consistent width, so descriptions are aligned.
|
|
938
|
+
const paddedTerm = term.padEnd(
|
|
939
|
+
termWidth + term.length - helper.displayWidth(term),
|
|
825
940
|
);
|
|
826
|
-
|
|
941
|
+
|
|
942
|
+
// Format the description.
|
|
943
|
+
const spacerWidth = 2; // between term and description
|
|
944
|
+
const helpWidth = this.helpWidth ?? 80; // in case prepareContext() was not called
|
|
945
|
+
const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
|
|
946
|
+
let formattedDescription;
|
|
947
|
+
if (
|
|
948
|
+
remainingWidth < this.minWidthToWrap ||
|
|
949
|
+
helper.preformatted(description)
|
|
950
|
+
) {
|
|
951
|
+
formattedDescription = description;
|
|
952
|
+
} else {
|
|
953
|
+
const wrappedDescription = helper.boxWrap(description, remainingWidth);
|
|
954
|
+
formattedDescription = wrappedDescription.replace(
|
|
955
|
+
/\n/g,
|
|
956
|
+
'\n' + ' '.repeat(termWidth + spacerWidth),
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
// Construct and overall indent.
|
|
827
961
|
return (
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
return (i > 0 ? indentString : '') + line.trimEnd();
|
|
833
|
-
})
|
|
834
|
-
.join('\n')
|
|
962
|
+
itemIndentStr +
|
|
963
|
+
paddedTerm +
|
|
964
|
+
' '.repeat(spacerWidth) +
|
|
965
|
+
formattedDescription.replace(/\n/g, `\n${itemIndentStr}`)
|
|
835
966
|
);
|
|
836
967
|
}
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* Wrap a string at whitespace, preserving existing line breaks.
|
|
971
|
+
* Wrapping is skipped if the width is less than `minWidthToWrap`.
|
|
972
|
+
*
|
|
973
|
+
* @param {string} str
|
|
974
|
+
* @param {number} width
|
|
975
|
+
* @returns {string}
|
|
976
|
+
*/
|
|
977
|
+
boxWrap(str, width) {
|
|
978
|
+
if (width < this.minWidthToWrap) return str;
|
|
979
|
+
|
|
980
|
+
const rawLines = str.split(/\r\n|\n/);
|
|
981
|
+
// split up text by whitespace
|
|
982
|
+
const chunkPattern = /[\s]*[^\s]+/g;
|
|
983
|
+
const wrappedLines = [];
|
|
984
|
+
rawLines.forEach((line) => {
|
|
985
|
+
const chunks = line.match(chunkPattern);
|
|
986
|
+
if (chunks === null) {
|
|
987
|
+
wrappedLines.push('');
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
let sumChunks = [chunks.shift()];
|
|
992
|
+
let sumWidth = this.displayWidth(sumChunks[0]);
|
|
993
|
+
chunks.forEach((chunk) => {
|
|
994
|
+
const visibleWidth = this.displayWidth(chunk);
|
|
995
|
+
// Accumulate chunks while they fit into width.
|
|
996
|
+
if (sumWidth + visibleWidth <= width) {
|
|
997
|
+
sumChunks.push(chunk);
|
|
998
|
+
sumWidth += visibleWidth;
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
wrappedLines.push(sumChunks.join(''));
|
|
1002
|
+
|
|
1003
|
+
const nextChunk = chunk.trimStart(); // trim space at line break
|
|
1004
|
+
sumChunks = [nextChunk];
|
|
1005
|
+
sumWidth = this.displayWidth(nextChunk);
|
|
1006
|
+
});
|
|
1007
|
+
wrappedLines.push(sumChunks.join(''));
|
|
1008
|
+
});
|
|
1009
|
+
|
|
1010
|
+
return wrappedLines.join('\n');
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Strip style ANSI escape sequences from the string. In particular, SGR (Select Graphic Rendition) codes.
|
|
1016
|
+
*
|
|
1017
|
+
* @param {string} str
|
|
1018
|
+
* @returns {string}
|
|
1019
|
+
* @package
|
|
1020
|
+
*/
|
|
1021
|
+
|
|
1022
|
+
function stripColor(str) {
|
|
1023
|
+
// eslint-disable-next-line no-control-regex
|
|
1024
|
+
const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
|
|
1025
|
+
return str.replace(sgrPattern, '');
|
|
837
1026
|
}
|
|
838
1027
|
|
|
839
1028
|
help.Help = Help;
|
|
1029
|
+
help.stripColor = stripColor;
|
|
840
1030
|
return help;
|
|
841
1031
|
}
|
|
842
1032
|
|
|
@@ -1056,13 +1246,16 @@ function requireOption () {
|
|
|
1056
1246
|
|
|
1057
1247
|
/**
|
|
1058
1248
|
* Return option name, in a camelcase format that can be used
|
|
1059
|
-
* as
|
|
1249
|
+
* as an object attribute key.
|
|
1060
1250
|
*
|
|
1061
1251
|
* @return {string}
|
|
1062
1252
|
*/
|
|
1063
1253
|
|
|
1064
1254
|
attributeName() {
|
|
1065
|
-
|
|
1255
|
+
if (this.negate) {
|
|
1256
|
+
return camelcase(this.name().replace(/^no-/, ''));
|
|
1257
|
+
}
|
|
1258
|
+
return camelcase(this.name());
|
|
1066
1259
|
}
|
|
1067
1260
|
|
|
1068
1261
|
/**
|
|
@@ -1161,17 +1354,32 @@ function requireOption () {
|
|
|
1161
1354
|
function splitOptionFlags(flags) {
|
|
1162
1355
|
let shortFlag;
|
|
1163
1356
|
let longFlag;
|
|
1164
|
-
//
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
if (
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1357
|
+
// short flag, single dash and single character
|
|
1358
|
+
const shortFlagExp = /^-[^-]$/;
|
|
1359
|
+
// long flag, double dash and at least one character
|
|
1360
|
+
const longFlagExp = /^--[^-]/;
|
|
1361
|
+
|
|
1362
|
+
const flagParts = flags.split(/[ |,]+/).concat('guard');
|
|
1363
|
+
if (shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();
|
|
1364
|
+
if (longFlagExp.test(flagParts[0])) longFlag = flagParts.shift();
|
|
1365
|
+
|
|
1366
|
+
// Check for some unsupported flags that people try.
|
|
1367
|
+
if (/^-[^-][^-]/.test(flagParts[0]))
|
|
1368
|
+
throw new Error(
|
|
1369
|
+
`invalid Option flags, short option is dash and single character: '${flags}'`,
|
|
1370
|
+
);
|
|
1371
|
+
if (shortFlag && shortFlagExp.test(flagParts[0]))
|
|
1372
|
+
throw new Error(
|
|
1373
|
+
`invalid Option flags, more than one short flag: '${flags}'`,
|
|
1374
|
+
);
|
|
1375
|
+
if (longFlag && longFlagExp.test(flagParts[0]))
|
|
1376
|
+
throw new Error(
|
|
1377
|
+
`invalid Option flags, more than one long flag: '${flags}'`,
|
|
1378
|
+
);
|
|
1379
|
+
// Generic error if failed to find a flag or an unexpected flag left over.
|
|
1380
|
+
if (!(shortFlag || longFlag) || flagParts[0].startsWith('-'))
|
|
1381
|
+
throw new Error(`invalid Option flags: '${flags}'`);
|
|
1382
|
+
|
|
1175
1383
|
return { shortFlag, longFlag };
|
|
1176
1384
|
}
|
|
1177
1385
|
|
|
@@ -1304,7 +1512,7 @@ function requireCommand () {
|
|
|
1304
1512
|
|
|
1305
1513
|
const { Argument, humanReadableArgName } = requireArgument();
|
|
1306
1514
|
const { CommanderError } = requireError();
|
|
1307
|
-
const { Help } = requireHelp();
|
|
1515
|
+
const { Help, stripColor } = requireHelp();
|
|
1308
1516
|
const { Option, DualOptions } = requireOption();
|
|
1309
1517
|
const { suggestSimilar } = requireSuggestSimilar();
|
|
1310
1518
|
|
|
@@ -1323,7 +1531,7 @@ function requireCommand () {
|
|
|
1323
1531
|
this.options = [];
|
|
1324
1532
|
this.parent = null;
|
|
1325
1533
|
this._allowUnknownOption = false;
|
|
1326
|
-
this._allowExcessArguments =
|
|
1534
|
+
this._allowExcessArguments = false;
|
|
1327
1535
|
/** @type {Argument[]} */
|
|
1328
1536
|
this.registeredArguments = [];
|
|
1329
1537
|
this._args = this.registeredArguments; // deprecated old name
|
|
@@ -1353,16 +1561,22 @@ function requireCommand () {
|
|
|
1353
1561
|
/** @type {(boolean | string)} */
|
|
1354
1562
|
this._showHelpAfterError = false;
|
|
1355
1563
|
this._showSuggestionAfterError = true;
|
|
1564
|
+
this._savedState = null; // used in save/restoreStateBeforeParse
|
|
1356
1565
|
|
|
1357
|
-
// see
|
|
1566
|
+
// see configureOutput() for docs
|
|
1358
1567
|
this._outputConfiguration = {
|
|
1359
1568
|
writeOut: (str) => process.stdout.write(str),
|
|
1360
1569
|
writeErr: (str) => process.stderr.write(str),
|
|
1570
|
+
outputError: (str, write) => write(str),
|
|
1361
1571
|
getOutHelpWidth: () =>
|
|
1362
1572
|
process.stdout.isTTY ? process.stdout.columns : undefined,
|
|
1363
1573
|
getErrHelpWidth: () =>
|
|
1364
1574
|
process.stderr.isTTY ? process.stderr.columns : undefined,
|
|
1365
|
-
|
|
1575
|
+
getOutHasColors: () =>
|
|
1576
|
+
useColor() ?? (process.stdout.isTTY && process.stdout.hasColors?.()),
|
|
1577
|
+
getErrHasColors: () =>
|
|
1578
|
+
useColor() ?? (process.stderr.isTTY && process.stderr.hasColors?.()),
|
|
1579
|
+
stripColor: (str) => stripColor(str),
|
|
1366
1580
|
};
|
|
1367
1581
|
|
|
1368
1582
|
this._hidden = false;
|
|
@@ -1511,14 +1725,18 @@ function requireCommand () {
|
|
|
1511
1725
|
*
|
|
1512
1726
|
* The configuration properties are all functions:
|
|
1513
1727
|
*
|
|
1514
|
-
* //
|
|
1728
|
+
* // change how output being written, defaults to stdout and stderr
|
|
1515
1729
|
* writeOut(str)
|
|
1516
1730
|
* writeErr(str)
|
|
1517
|
-
* //
|
|
1731
|
+
* // change how output being written for errors, defaults to writeErr
|
|
1732
|
+
* outputError(str, write) // used for displaying errors and not used for displaying help
|
|
1733
|
+
* // specify width for wrapping help
|
|
1518
1734
|
* getOutHelpWidth()
|
|
1519
1735
|
* getErrHelpWidth()
|
|
1520
|
-
* //
|
|
1521
|
-
*
|
|
1736
|
+
* // color support, currently only used with Help
|
|
1737
|
+
* getOutHasColors()
|
|
1738
|
+
* getErrHasColors()
|
|
1739
|
+
* stripColor() // used to remove ANSI escape codes if output does not have colors
|
|
1522
1740
|
*
|
|
1523
1741
|
* @param {object} [configuration] - configuration options
|
|
1524
1742
|
* @return {(Command | object)} `this` command for chaining, or stored configuration
|
|
@@ -2356,6 +2574,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2356
2574
|
*/
|
|
2357
2575
|
|
|
2358
2576
|
parse(argv, parseOptions) {
|
|
2577
|
+
this._prepareForParse();
|
|
2359
2578
|
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
|
2360
2579
|
this._parseCommand([], userArgs);
|
|
2361
2580
|
|
|
@@ -2384,12 +2603,82 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2384
2603
|
*/
|
|
2385
2604
|
|
|
2386
2605
|
async parseAsync(argv, parseOptions) {
|
|
2606
|
+
this._prepareForParse();
|
|
2387
2607
|
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
|
2388
2608
|
await this._parseCommand([], userArgs);
|
|
2389
2609
|
|
|
2390
2610
|
return this;
|
|
2391
2611
|
}
|
|
2392
2612
|
|
|
2613
|
+
_prepareForParse() {
|
|
2614
|
+
if (this._savedState === null) {
|
|
2615
|
+
this.saveStateBeforeParse();
|
|
2616
|
+
} else {
|
|
2617
|
+
this.restoreStateBeforeParse();
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
/**
|
|
2622
|
+
* Called the first time parse is called to save state and allow a restore before subsequent calls to parse.
|
|
2623
|
+
* Not usually called directly, but available for subclasses to save their custom state.
|
|
2624
|
+
*
|
|
2625
|
+
* This is called in a lazy way. Only commands used in parsing chain will have state saved.
|
|
2626
|
+
*/
|
|
2627
|
+
saveStateBeforeParse() {
|
|
2628
|
+
this._savedState = {
|
|
2629
|
+
// name is stable if supplied by author, but may be unspecified for root command and deduced during parsing
|
|
2630
|
+
_name: this._name,
|
|
2631
|
+
// option values before parse have default values (including false for negated options)
|
|
2632
|
+
// shallow clones
|
|
2633
|
+
_optionValues: { ...this._optionValues },
|
|
2634
|
+
_optionValueSources: { ...this._optionValueSources },
|
|
2635
|
+
};
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
/**
|
|
2639
|
+
* Restore state before parse for calls after the first.
|
|
2640
|
+
* Not usually called directly, but available for subclasses to save their custom state.
|
|
2641
|
+
*
|
|
2642
|
+
* This is called in a lazy way. Only commands used in parsing chain will have state restored.
|
|
2643
|
+
*/
|
|
2644
|
+
restoreStateBeforeParse() {
|
|
2645
|
+
if (this._storeOptionsAsProperties)
|
|
2646
|
+
throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
|
|
2647
|
+
- either make a new Command for each call to parse, or stop storing options as properties`);
|
|
2648
|
+
|
|
2649
|
+
// clear state from _prepareUserArgs
|
|
2650
|
+
this._name = this._savedState._name;
|
|
2651
|
+
this._scriptPath = null;
|
|
2652
|
+
this.rawArgs = [];
|
|
2653
|
+
// clear state from setOptionValueWithSource
|
|
2654
|
+
this._optionValues = { ...this._savedState._optionValues };
|
|
2655
|
+
this._optionValueSources = { ...this._savedState._optionValueSources };
|
|
2656
|
+
// clear state from _parseCommand
|
|
2657
|
+
this.args = [];
|
|
2658
|
+
// clear state from _processArguments
|
|
2659
|
+
this.processedArgs = [];
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
/**
|
|
2663
|
+
* Throw if expected executable is missing. Add lots of help for author.
|
|
2664
|
+
*
|
|
2665
|
+
* @param {string} executableFile
|
|
2666
|
+
* @param {string} executableDir
|
|
2667
|
+
* @param {string} subcommandName
|
|
2668
|
+
*/
|
|
2669
|
+
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
|
2670
|
+
if (fs$1.existsSync(executableFile)) return;
|
|
2671
|
+
|
|
2672
|
+
const executableDirMessage = executableDir
|
|
2673
|
+
? `searched for local subcommand relative to directory '${executableDir}'`
|
|
2674
|
+
: 'no directory for search for local subcommand, use .executableDir() to supply a custom directory';
|
|
2675
|
+
const executableMissing = `'${executableFile}' does not exist
|
|
2676
|
+
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
2677
|
+
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path
|
|
2678
|
+
- ${executableDirMessage}`;
|
|
2679
|
+
throw new Error(executableMissing);
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2393
2682
|
/**
|
|
2394
2683
|
* Execute a sub-command executable.
|
|
2395
2684
|
*
|
|
@@ -2430,7 +2719,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2430
2719
|
let resolvedScriptPath; // resolve possible symlink for installed npm binary
|
|
2431
2720
|
try {
|
|
2432
2721
|
resolvedScriptPath = fs$1.realpathSync(this._scriptPath);
|
|
2433
|
-
} catch
|
|
2722
|
+
} catch {
|
|
2434
2723
|
resolvedScriptPath = this._scriptPath;
|
|
2435
2724
|
}
|
|
2436
2725
|
executableDir = path$1.resolve(
|
|
@@ -2473,6 +2762,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2473
2762
|
proc = childProcess.spawn(executableFile, args, { stdio: 'inherit' });
|
|
2474
2763
|
}
|
|
2475
2764
|
} else {
|
|
2765
|
+
this._checkForMissingExecutable(
|
|
2766
|
+
executableFile,
|
|
2767
|
+
executableDir,
|
|
2768
|
+
subcommand._name,
|
|
2769
|
+
);
|
|
2476
2770
|
args.unshift(executableFile);
|
|
2477
2771
|
// add executable arguments to spawn
|
|
2478
2772
|
args = incrementNodeInspectorPort(process.execArgv).concat(args);
|
|
@@ -2511,14 +2805,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2511
2805
|
proc.on('error', (err) => {
|
|
2512
2806
|
// @ts-ignore: because err.code is an unknown property
|
|
2513
2807
|
if (err.code === 'ENOENT') {
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path
|
|
2520
|
-
- ${executableDirMessage}`;
|
|
2521
|
-
throw new Error(executableMissing);
|
|
2808
|
+
this._checkForMissingExecutable(
|
|
2809
|
+
executableFile,
|
|
2810
|
+
executableDir,
|
|
2811
|
+
subcommand._name,
|
|
2812
|
+
);
|
|
2522
2813
|
// @ts-ignore: because err.code is an unknown property
|
|
2523
2814
|
} else if (err.code === 'EACCES') {
|
|
2524
2815
|
throw new Error(`'${executableFile}' not executable`);
|
|
@@ -2548,6 +2839,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2548
2839
|
const subCommand = this._findCommand(commandName);
|
|
2549
2840
|
if (!subCommand) this.help({ error: true });
|
|
2550
2841
|
|
|
2842
|
+
subCommand._prepareForParse();
|
|
2551
2843
|
let promiseChain;
|
|
2552
2844
|
promiseChain = this._chainOrCallSubCommandHook(
|
|
2553
2845
|
promiseChain,
|
|
@@ -2925,6 +3217,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2925
3217
|
* Parse options from `argv` removing known options,
|
|
2926
3218
|
* and return argv split into operands and unknown arguments.
|
|
2927
3219
|
*
|
|
3220
|
+
* Side effects: modifies command by storing options. Does not reset state if called again.
|
|
3221
|
+
*
|
|
2928
3222
|
* Examples:
|
|
2929
3223
|
*
|
|
2930
3224
|
* argv => operands, unknown
|
|
@@ -3550,31 +3844,49 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3550
3844
|
|
|
3551
3845
|
helpInformation(contextOptions) {
|
|
3552
3846
|
const helper = this.createHelp();
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
}
|
|
3559
|
-
|
|
3847
|
+
const context = this._getOutputContext(contextOptions);
|
|
3848
|
+
helper.prepareContext({
|
|
3849
|
+
error: context.error,
|
|
3850
|
+
helpWidth: context.helpWidth,
|
|
3851
|
+
outputHasColors: context.hasColors,
|
|
3852
|
+
});
|
|
3853
|
+
const text = helper.formatHelp(this, helper);
|
|
3854
|
+
if (context.hasColors) return text;
|
|
3855
|
+
return this._outputConfiguration.stripColor(text);
|
|
3560
3856
|
}
|
|
3561
3857
|
|
|
3562
3858
|
/**
|
|
3859
|
+
* @typedef HelpContext
|
|
3860
|
+
* @type {object}
|
|
3861
|
+
* @property {boolean} error
|
|
3862
|
+
* @property {number} helpWidth
|
|
3863
|
+
* @property {boolean} hasColors
|
|
3864
|
+
* @property {function} write - includes stripColor if needed
|
|
3865
|
+
*
|
|
3866
|
+
* @returns {HelpContext}
|
|
3563
3867
|
* @private
|
|
3564
3868
|
*/
|
|
3565
3869
|
|
|
3566
|
-
|
|
3870
|
+
_getOutputContext(contextOptions) {
|
|
3567
3871
|
contextOptions = contextOptions || {};
|
|
3568
|
-
const
|
|
3569
|
-
let
|
|
3570
|
-
|
|
3571
|
-
|
|
3872
|
+
const error = !!contextOptions.error;
|
|
3873
|
+
let baseWrite;
|
|
3874
|
+
let hasColors;
|
|
3875
|
+
let helpWidth;
|
|
3876
|
+
if (error) {
|
|
3877
|
+
baseWrite = (str) => this._outputConfiguration.writeErr(str);
|
|
3878
|
+
hasColors = this._outputConfiguration.getErrHasColors();
|
|
3879
|
+
helpWidth = this._outputConfiguration.getErrHelpWidth();
|
|
3572
3880
|
} else {
|
|
3573
|
-
|
|
3881
|
+
baseWrite = (str) => this._outputConfiguration.writeOut(str);
|
|
3882
|
+
hasColors = this._outputConfiguration.getOutHasColors();
|
|
3883
|
+
helpWidth = this._outputConfiguration.getOutHelpWidth();
|
|
3574
3884
|
}
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3885
|
+
const write = (str) => {
|
|
3886
|
+
if (!hasColors) str = this._outputConfiguration.stripColor(str);
|
|
3887
|
+
return baseWrite(str);
|
|
3888
|
+
};
|
|
3889
|
+
return { error, write, hasColors, helpWidth };
|
|
3578
3890
|
}
|
|
3579
3891
|
|
|
3580
3892
|
/**
|
|
@@ -3591,14 +3903,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3591
3903
|
deprecatedCallback = contextOptions;
|
|
3592
3904
|
contextOptions = undefined;
|
|
3593
3905
|
}
|
|
3594
|
-
|
|
3906
|
+
|
|
3907
|
+
const outputContext = this._getOutputContext(contextOptions);
|
|
3908
|
+
/** @type {HelpTextEventContext} */
|
|
3909
|
+
const eventContext = {
|
|
3910
|
+
error: outputContext.error,
|
|
3911
|
+
write: outputContext.write,
|
|
3912
|
+
command: this,
|
|
3913
|
+
};
|
|
3595
3914
|
|
|
3596
3915
|
this._getCommandAndAncestors()
|
|
3597
3916
|
.reverse()
|
|
3598
|
-
.forEach((command) => command.emit('beforeAllHelp',
|
|
3599
|
-
this.emit('beforeHelp',
|
|
3917
|
+
.forEach((command) => command.emit('beforeAllHelp', eventContext));
|
|
3918
|
+
this.emit('beforeHelp', eventContext);
|
|
3600
3919
|
|
|
3601
|
-
let helpInformation = this.helpInformation(
|
|
3920
|
+
let helpInformation = this.helpInformation({ error: outputContext.error });
|
|
3602
3921
|
if (deprecatedCallback) {
|
|
3603
3922
|
helpInformation = deprecatedCallback(helpInformation);
|
|
3604
3923
|
if (
|
|
@@ -3608,14 +3927,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3608
3927
|
throw new Error('outputHelp callback must return a string or a Buffer');
|
|
3609
3928
|
}
|
|
3610
3929
|
}
|
|
3611
|
-
|
|
3930
|
+
outputContext.write(helpInformation);
|
|
3612
3931
|
|
|
3613
3932
|
if (this._getHelpOption()?.long) {
|
|
3614
3933
|
this.emit(this._getHelpOption().long); // deprecated
|
|
3615
3934
|
}
|
|
3616
|
-
this.emit('afterHelp',
|
|
3935
|
+
this.emit('afterHelp', eventContext);
|
|
3617
3936
|
this._getCommandAndAncestors().forEach((command) =>
|
|
3618
|
-
command.emit('afterAllHelp',
|
|
3937
|
+
command.emit('afterAllHelp', eventContext),
|
|
3619
3938
|
);
|
|
3620
3939
|
}
|
|
3621
3940
|
|
|
@@ -3635,6 +3954,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3635
3954
|
helpOption(flags, description) {
|
|
3636
3955
|
// Support disabling built-in help option.
|
|
3637
3956
|
if (typeof flags === 'boolean') {
|
|
3957
|
+
// true is not an expected value. Do something sensible but no unit-test.
|
|
3958
|
+
// istanbul ignore if
|
|
3638
3959
|
if (flags) {
|
|
3639
3960
|
this._helpOption = this._helpOption ?? undefined; // preserve existing option
|
|
3640
3961
|
} else {
|
|
@@ -3688,7 +4009,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3688
4009
|
|
|
3689
4010
|
help(contextOptions) {
|
|
3690
4011
|
this.outputHelp(contextOptions);
|
|
3691
|
-
let exitCode = process.exitCode
|
|
4012
|
+
let exitCode = Number(process.exitCode ?? 0); // process.exitCode does allow a string or an integer, but we prefer just a number
|
|
3692
4013
|
if (
|
|
3693
4014
|
exitCode === 0 &&
|
|
3694
4015
|
contextOptions &&
|
|
@@ -3701,6 +4022,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3701
4022
|
this._exit(exitCode, 'commander.help', '(outputHelp)');
|
|
3702
4023
|
}
|
|
3703
4024
|
|
|
4025
|
+
/**
|
|
4026
|
+
* // Do a little typing to coordinate emit and listener for the help text events.
|
|
4027
|
+
* @typedef HelpTextEventContext
|
|
4028
|
+
* @type {object}
|
|
4029
|
+
* @property {boolean} error
|
|
4030
|
+
* @property {Command} command
|
|
4031
|
+
* @property {function} write
|
|
4032
|
+
*/
|
|
4033
|
+
|
|
3704
4034
|
/**
|
|
3705
4035
|
* Add additional text to be displayed with the built-in help.
|
|
3706
4036
|
*
|
|
@@ -3711,14 +4041,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3711
4041
|
* @param {(string | Function)} text - string to add, or a function returning a string
|
|
3712
4042
|
* @return {Command} `this` command for chaining
|
|
3713
4043
|
*/
|
|
4044
|
+
|
|
3714
4045
|
addHelpText(position, text) {
|
|
3715
4046
|
const allowedValues = ['beforeAll', 'before', 'after', 'afterAll'];
|
|
3716
4047
|
if (!allowedValues.includes(position)) {
|
|
3717
4048
|
throw new Error(`Unexpected value for position to addHelpText.
|
|
3718
4049
|
Expecting one of '${allowedValues.join("', '")}'`);
|
|
3719
4050
|
}
|
|
4051
|
+
|
|
3720
4052
|
const helpEvent = `${position}Help`;
|
|
3721
|
-
this.on(helpEvent, (context) => {
|
|
4053
|
+
this.on(helpEvent, (/** @type {HelpTextEventContext} */ context) => {
|
|
3722
4054
|
let helpStr;
|
|
3723
4055
|
if (typeof text === 'function') {
|
|
3724
4056
|
helpStr = text({ error: context.error, command: context.command });
|
|
@@ -3802,7 +4134,36 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3802
4134
|
});
|
|
3803
4135
|
}
|
|
3804
4136
|
|
|
4137
|
+
/**
|
|
4138
|
+
* @returns {boolean | undefined}
|
|
4139
|
+
* @package
|
|
4140
|
+
*/
|
|
4141
|
+
function useColor() {
|
|
4142
|
+
// Test for common conventions.
|
|
4143
|
+
// NB: the observed behaviour is in combination with how author adds color! For example:
|
|
4144
|
+
// - we do not test NODE_DISABLE_COLORS, but util:styletext does
|
|
4145
|
+
// - we do test NO_COLOR, but Chalk does not
|
|
4146
|
+
//
|
|
4147
|
+
// References:
|
|
4148
|
+
// https://no-color.org
|
|
4149
|
+
// https://bixense.com/clicolors/
|
|
4150
|
+
// https://github.com/nodejs/node/blob/0a00217a5f67ef4a22384cfc80eb6dd9a917fdc1/lib/internal/tty.js#L109
|
|
4151
|
+
// https://github.com/chalk/supports-color/blob/c214314a14bcb174b12b3014b2b0a8de375029ae/index.js#L33
|
|
4152
|
+
// (https://force-color.org recent web page from 2023, does not match major javascript implementations)
|
|
4153
|
+
|
|
4154
|
+
if (
|
|
4155
|
+
process.env.NO_COLOR ||
|
|
4156
|
+
process.env.FORCE_COLOR === '0' ||
|
|
4157
|
+
process.env.FORCE_COLOR === 'false'
|
|
4158
|
+
)
|
|
4159
|
+
return false;
|
|
4160
|
+
if (process.env.FORCE_COLOR || process.env.CLICOLOR_FORCE !== undefined)
|
|
4161
|
+
return true;
|
|
4162
|
+
return undefined;
|
|
4163
|
+
}
|
|
4164
|
+
|
|
3805
4165
|
command.Command = Command;
|
|
4166
|
+
command.useColor = useColor; // exporting for tests
|
|
3806
4167
|
return command;
|
|
3807
4168
|
}
|
|
3808
4169
|
|
|
@@ -4948,18 +5309,18 @@ var drizzle = defineAddon({
|
|
|
4948
5309
|
},
|
|
4949
5310
|
run: ({ sv, typescript, options: options2, kit }) => {
|
|
4950
5311
|
const ext = typescript ? "ts" : "js";
|
|
4951
|
-
sv.dependency("drizzle-orm", "^0.
|
|
4952
|
-
sv.devDependency("drizzle-kit", "^0.
|
|
4953
|
-
if (options2.mysql === "mysql2") sv.dependency("mysql2", "^3.
|
|
4954
|
-
if (options2.mysql === "planetscale") sv.dependency("@planetscale/database", "^1.
|
|
4955
|
-
if (options2.postgresql === "neon") sv.dependency("@neondatabase/serverless", "^0.
|
|
4956
|
-
if (options2.postgresql === "postgres.js") sv.dependency("postgres", "^3.4.
|
|
5312
|
+
sv.dependency("drizzle-orm", "^0.38.4");
|
|
5313
|
+
sv.devDependency("drizzle-kit", "^0.30.2");
|
|
5314
|
+
if (options2.mysql === "mysql2") sv.dependency("mysql2", "^3.12.0");
|
|
5315
|
+
if (options2.mysql === "planetscale") sv.dependency("@planetscale/database", "^1.19.0");
|
|
5316
|
+
if (options2.postgresql === "neon") sv.dependency("@neondatabase/serverless", "^0.10.4");
|
|
5317
|
+
if (options2.postgresql === "postgres.js") sv.dependency("postgres", "^3.4.5");
|
|
4957
5318
|
if (options2.sqlite === "better-sqlite3") {
|
|
4958
|
-
sv.dependency("better-sqlite3", "^11.
|
|
4959
|
-
sv.devDependency("@types/better-sqlite3", "^7.6.
|
|
5319
|
+
sv.dependency("better-sqlite3", "^11.8.0");
|
|
5320
|
+
sv.devDependency("@types/better-sqlite3", "^7.6.12");
|
|
4960
5321
|
}
|
|
4961
5322
|
if (options2.sqlite === "libsql" || options2.sqlite === "turso")
|
|
4962
|
-
sv.dependency("@libsql/client", "^0.
|
|
5323
|
+
sv.dependency("@libsql/client", "^0.14.0");
|
|
4963
5324
|
sv.file(".env", (content) => generateEnvFileContent(content, options2));
|
|
4964
5325
|
sv.file(".env.example", (content) => generateEnvFileContent(content, options2));
|
|
4965
5326
|
if (options2.docker && (options2.mysql === "mysql2" || options2.postgresql === "postgres.js")) {
|
|
@@ -5027,7 +5388,6 @@ var drizzle = defineAddon({
|
|
|
5027
5388
|
if (exportDefault.type !== "CallExpression") return content;
|
|
5028
5389
|
const objExpression = exportDefault.arguments?.[0];
|
|
5029
5390
|
if (!objExpression || objExpression.type !== "ObjectExpression") return content;
|
|
5030
|
-
const driver = options2.sqlite === "turso" ? common.createLiteral("turso") : void 0;
|
|
5031
5391
|
const authToken = options2.sqlite === "turso" ? common.expressionFromString("process.env.DATABASE_AUTH_TOKEN") : void 0;
|
|
5032
5392
|
object$1.properties(objExpression, {
|
|
5033
5393
|
schema: common.createLiteral(`./src/lib/server/db/schema.${typescript ? "ts" : "js"}`),
|
|
@@ -5036,11 +5396,11 @@ var drizzle = defineAddon({
|
|
|
5036
5396
|
authToken
|
|
5037
5397
|
}),
|
|
5038
5398
|
verbose: { type: "BooleanLiteral", value: true },
|
|
5039
|
-
strict: { type: "BooleanLiteral", value: true }
|
|
5040
|
-
driver
|
|
5399
|
+
strict: { type: "BooleanLiteral", value: true }
|
|
5041
5400
|
});
|
|
5401
|
+
const dialect = options2.sqlite === "turso" ? "turso" : options2.database;
|
|
5042
5402
|
object$1.overrideProperties(objExpression, {
|
|
5043
|
-
dialect: common.createLiteral(
|
|
5403
|
+
dialect: common.createLiteral(dialect)
|
|
5044
5404
|
});
|
|
5045
5405
|
if (options2.database !== "sqlite") object$1.removeProperty(objExpression, "driver");
|
|
5046
5406
|
return generateCode();
|
|
@@ -5271,13 +5631,13 @@ var eslint = defineAddon({
|
|
|
5271
5631
|
options: {},
|
|
5272
5632
|
run: ({ sv, typescript, dependencyVersion }) => {
|
|
5273
5633
|
const prettierInstalled = Boolean(dependencyVersion("prettier"));
|
|
5274
|
-
sv.devDependency("eslint", "^9.
|
|
5275
|
-
sv.devDependency("@eslint/compat", "^1.2.
|
|
5276
|
-
sv.devDependency("globals", "^15.
|
|
5277
|
-
sv.devDependency("eslint-plugin-svelte", "^2.
|
|
5278
|
-
sv.devDependency("@eslint/js", "^9.
|
|
5279
|
-
if (typescript) sv.devDependency("typescript-eslint", "^8.
|
|
5280
|
-
if (prettierInstalled) sv.devDependency("eslint-config-prettier", "^
|
|
5634
|
+
sv.devDependency("eslint", "^9.18.0");
|
|
5635
|
+
sv.devDependency("@eslint/compat", "^1.2.5");
|
|
5636
|
+
sv.devDependency("globals", "^15.14.0");
|
|
5637
|
+
sv.devDependency("eslint-plugin-svelte", "^2.46.1");
|
|
5638
|
+
sv.devDependency("@eslint/js", "^9.18.0");
|
|
5639
|
+
if (typescript) sv.devDependency("typescript-eslint", "^8.20.0");
|
|
5640
|
+
if (prettierInstalled) sv.devDependency("eslint-config-prettier", "^10.0.1");
|
|
5281
5641
|
sv.file("package.json", (content) => {
|
|
5282
5642
|
const { data, generateCode } = parseJson(content);
|
|
5283
5643
|
data.scripts ?? (data.scripts = {});
|
|
@@ -5368,11 +5728,11 @@ var eslint = defineAddon({
|
|
|
5368
5728
|
});
|
|
5369
5729
|
|
|
5370
5730
|
const adapters = [
|
|
5371
|
-
{ id: "node", package: "@sveltejs/adapter-node", version: "^5.2.
|
|
5372
|
-
{ id: "static", package: "@sveltejs/adapter-static", version: "^3.0.
|
|
5373
|
-
{ id: "vercel", package: "@sveltejs/adapter-vercel", version: "^5.5.
|
|
5374
|
-
{ id: "cloudflare-pages", package: "@sveltejs/adapter-cloudflare", version: "^
|
|
5375
|
-
{ id: "cloudflare-workers", package: "@sveltejs/adapter-cloudflare-workers", version: "^2.
|
|
5731
|
+
{ id: "node", package: "@sveltejs/adapter-node", version: "^5.2.11" },
|
|
5732
|
+
{ id: "static", package: "@sveltejs/adapter-static", version: "^3.0.8" },
|
|
5733
|
+
{ id: "vercel", package: "@sveltejs/adapter-vercel", version: "^5.5.2" },
|
|
5734
|
+
{ id: "cloudflare-pages", package: "@sveltejs/adapter-cloudflare", version: "^5.0.1" },
|
|
5735
|
+
{ id: "cloudflare-workers", package: "@sveltejs/adapter-cloudflare-workers", version: "^2.7.0" },
|
|
5376
5736
|
{ id: "netlify", package: "@sveltejs/adapter-netlify", version: "^4.4.0" }
|
|
5377
5737
|
];
|
|
5378
5738
|
const options$4 = defineAddonOptions({
|
|
@@ -6820,7 +7180,7 @@ var lucia = defineAddon({
|
|
|
6820
7180
|
sv.dependency("@oslojs/crypto", "^1.0.1");
|
|
6821
7181
|
sv.dependency("@oslojs/encoding", "^1.1.0");
|
|
6822
7182
|
if (options2.demo) {
|
|
6823
|
-
sv.dependency("@node-rs/argon2", "^
|
|
7183
|
+
sv.dependency("@node-rs/argon2", "^2.0.2");
|
|
6824
7184
|
}
|
|
6825
7185
|
sv.file(`drizzle.config.${ext}`, (content) => {
|
|
6826
7186
|
const { ast, generateCode } = parseScript(content);
|
|
@@ -7375,7 +7735,7 @@ var mdsvex = defineAddon({
|
|
|
7375
7735
|
homepage: "https://mdsvex.pngwn.io",
|
|
7376
7736
|
options: {},
|
|
7377
7737
|
run: ({ sv }) => {
|
|
7378
|
-
sv.devDependency("mdsvex", "^0.
|
|
7738
|
+
sv.devDependency("mdsvex", "^0.12.3");
|
|
7379
7739
|
sv.file("svelte.config.js", (content) => {
|
|
7380
7740
|
const { ast, generateCode } = parseScript(content);
|
|
7381
7741
|
imports.addNamed(ast, "mdsvex", { mdsvex: "mdsvex" });
|
|
@@ -7476,7 +7836,7 @@ var paraglide = defineAddon({
|
|
|
7476
7836
|
const ext = typescript ? "ts" : "js";
|
|
7477
7837
|
if (!kit$1) throw new Error("SvelteKit is required");
|
|
7478
7838
|
const paraglideOutDir = "src/lib/paraglide";
|
|
7479
|
-
sv.dependency("@inlang/paraglide-sveltekit", "^0.
|
|
7839
|
+
sv.dependency("@inlang/paraglide-sveltekit", "^0.15.5");
|
|
7480
7840
|
sv.file("project.inlang/settings.json", (content) => {
|
|
7481
7841
|
if (content) return content;
|
|
7482
7842
|
const { data, generateCode } = parseJson(content);
|
|
@@ -7678,7 +8038,7 @@ var playwright = defineAddon({
|
|
|
7678
8038
|
options: {},
|
|
7679
8039
|
run: ({ sv, typescript }) => {
|
|
7680
8040
|
const ext = typescript ? "ts" : "js";
|
|
7681
|
-
sv.devDependency("@playwright/test", "^1.
|
|
8041
|
+
sv.devDependency("@playwright/test", "^1.49.1");
|
|
7682
8042
|
sv.file("package.json", (content) => {
|
|
7683
8043
|
const { data, generateCode } = parseJson(content);
|
|
7684
8044
|
data.scripts ?? (data.scripts = {});
|
|
@@ -7736,8 +8096,8 @@ var prettier = defineAddon({
|
|
|
7736
8096
|
homepage: "https://prettier.io",
|
|
7737
8097
|
options: {},
|
|
7738
8098
|
run: ({ sv, dependencyVersion }) => {
|
|
7739
|
-
sv.devDependency("prettier", "^3.
|
|
7740
|
-
sv.devDependency("prettier-plugin-svelte", "^3.
|
|
8099
|
+
sv.devDependency("prettier", "^3.4.2");
|
|
8100
|
+
sv.devDependency("prettier-plugin-svelte", "^3.3.3");
|
|
7741
8101
|
sv.file(".prettierignore", (content) => {
|
|
7742
8102
|
if (content) return content;
|
|
7743
8103
|
return dedent`
|
|
@@ -7792,7 +8152,7 @@ var prettier = defineAddon({
|
|
|
7792
8152
|
);
|
|
7793
8153
|
}
|
|
7794
8154
|
if (eslintInstalled) {
|
|
7795
|
-
sv.devDependency("eslint-config-prettier", "^
|
|
8155
|
+
sv.devDependency("eslint-config-prettier", "^10.0.1");
|
|
7796
8156
|
sv.file("eslint.config.js", addEslintConfigPrettier);
|
|
7797
8157
|
}
|
|
7798
8158
|
}
|
|
@@ -7831,13 +8191,13 @@ const plugins = [
|
|
|
7831
8191
|
{
|
|
7832
8192
|
id: "typography",
|
|
7833
8193
|
package: "@tailwindcss/typography",
|
|
7834
|
-
version: "^0.5.
|
|
8194
|
+
version: "^0.5.16",
|
|
7835
8195
|
identifier: "typography"
|
|
7836
8196
|
},
|
|
7837
8197
|
{
|
|
7838
8198
|
id: "forms",
|
|
7839
8199
|
package: "@tailwindcss/forms",
|
|
7840
|
-
version: "^0.5.
|
|
8200
|
+
version: "^0.5.10",
|
|
7841
8201
|
identifier: "forms"
|
|
7842
8202
|
},
|
|
7843
8203
|
{
|
|
@@ -7864,12 +8224,12 @@ var tailwindcss = defineAddon({
|
|
|
7864
8224
|
run: ({ sv, options: options2, typescript, kit, dependencyVersion }) => {
|
|
7865
8225
|
const ext = typescript ? "ts" : "js";
|
|
7866
8226
|
const prettierInstalled = Boolean(dependencyVersion("prettier"));
|
|
7867
|
-
sv.devDependency("tailwindcss", "^3.4.
|
|
8227
|
+
sv.devDependency("tailwindcss", "^3.4.17");
|
|
7868
8228
|
sv.devDependency("autoprefixer", "^10.4.20");
|
|
7869
|
-
if (prettierInstalled) sv.devDependency("prettier-plugin-tailwindcss", "^0.6.
|
|
8229
|
+
if (prettierInstalled) sv.devDependency("prettier-plugin-tailwindcss", "^0.6.10");
|
|
7870
8230
|
for (const plugin of plugins) {
|
|
7871
8231
|
if (!options2.plugins.includes(plugin.id)) continue;
|
|
7872
|
-
sv.
|
|
8232
|
+
sv.devDependency(plugin.package, plugin.version);
|
|
7873
8233
|
}
|
|
7874
8234
|
sv.file(`tailwind.config.${ext}`, (content) => {
|
|
7875
8235
|
const { ast, generateCode } = parseScript(content);
|
|
@@ -7969,7 +8329,7 @@ var vitest = defineAddon({
|
|
|
7969
8329
|
options: {},
|
|
7970
8330
|
run: ({ sv, typescript }) => {
|
|
7971
8331
|
const ext = typescript ? "ts" : "js";
|
|
7972
|
-
sv.devDependency("vitest", "^2.
|
|
8332
|
+
sv.devDependency("vitest", "^2.1.8");
|
|
7973
8333
|
sv.file("package.json", (content) => {
|
|
7974
8334
|
const { data, generateCode } = parseJson(content);
|
|
7975
8335
|
data.scripts ?? (data.scripts = {});
|
|
@@ -8114,7 +8474,13 @@ const helpConfig = {
|
|
|
8114
8474
|
return `--[no-]${longFlag.slice(2)}`;
|
|
8115
8475
|
}
|
|
8116
8476
|
return option.flags;
|
|
8117
|
-
}
|
|
8477
|
+
},
|
|
8478
|
+
styleTitle: (str) => pc.underline(str),
|
|
8479
|
+
styleCommandText: (str) => pc.red(str),
|
|
8480
|
+
styleDescriptionText: (str) => pc.gray(str),
|
|
8481
|
+
styleOptionText: (str) => pc.white(str),
|
|
8482
|
+
styleArgumentText: (str) => pc.white(str),
|
|
8483
|
+
styleSubcommandText: (str) => pc.red(str)
|
|
8118
8484
|
};
|
|
8119
8485
|
function formatDescription(arg) {
|
|
8120
8486
|
let output = arg.description;
|
|
@@ -11727,9 +12093,9 @@ function getGlobalPreconditions(cwd, addons, addonSetupResult) {
|
|
|
11727
12093
|
name: "clean working directory",
|
|
11728
12094
|
run: async () => {
|
|
11729
12095
|
try {
|
|
11730
|
-
const
|
|
11731
|
-
|
|
11732
|
-
|
|
12096
|
+
const asyncExec = promisify(exec);
|
|
12097
|
+
const { stdout } = await asyncExec("git status --short", {
|
|
12098
|
+
cwd
|
|
11733
12099
|
});
|
|
11734
12100
|
if (stdout) {
|
|
11735
12101
|
return { success: false, message: "Found modified files" };
|