cli-kiss 0.2.3 → 0.2.4
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/README.md +1 -1
- package/dist/index.d.ts +643 -667
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.mts +1 -3
- package/docs/.vitepress/theme/index.ts +4 -0
- package/docs/.vitepress/theme/style.css +4 -0
- package/docs/guide/02_commands.md +67 -31
- package/docs/guide/03_options.md +11 -10
- package/docs/guide/05_types.md +1 -1
- package/docs/guide/06_run.md +1 -1
- package/docs/index.md +8 -3
- package/docs/public/hero.png +0 -0
- package/package.json +1 -1
- package/src/lib/Command.ts +36 -93
- package/src/lib/Operation.ts +12 -30
- package/src/lib/Option.ts +120 -96
- package/src/lib/Positional.ts +9 -34
- package/src/lib/Reader.ts +122 -98
- package/src/lib/Run.ts +30 -17
- package/src/lib/Type.ts +26 -22
- package/src/lib/Typo.ts +62 -83
- package/src/lib/Usage.ts +174 -78
- package/tests/unit.Reader.aliases.ts +31 -15
- package/tests/unit.Reader.commons.ts +99 -43
- package/tests/unit.Reader.shortBig.ts +75 -31
- package/tests/unit.command.execute.ts +76 -33
- package/tests/unit.command.usage.ts +35 -35
- package/tests/unit.runner.cycle.ts +13 -13
- package/tests/unit.runner.errors.ts +19 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { expect, it } from "@jest/globals";
|
|
2
|
-
import { ReaderArgs } from "../src";
|
|
2
|
+
import { ReaderArgs, ReaderOptionParsing } from "../src";
|
|
3
3
|
|
|
4
|
-
it("run", async ()
|
|
4
|
+
it("run", async function () {
|
|
5
5
|
const stream = new ReaderArgs([
|
|
6
6
|
"positional-0",
|
|
7
7
|
"-aasof-normal",
|
|
@@ -12,47 +12,48 @@ it("run", async () => {
|
|
|
12
12
|
"1.1",
|
|
13
13
|
"-eesov-split",
|
|
14
14
|
"1.2",
|
|
15
|
-
"-ffsov-join=2",
|
|
15
|
+
"-ffsov-join=2.1",
|
|
16
|
+
"-ggsov-join=2.2",
|
|
16
17
|
"positional-2",
|
|
17
18
|
]);
|
|
18
19
|
|
|
19
20
|
expect(stream.consumePositional()).toStrictEqual("positional-0");
|
|
20
21
|
|
|
22
|
+
const kSofUnset = stream.registerOption({
|
|
23
|
+
longs: [],
|
|
24
|
+
shorts: ["sof-unset"],
|
|
25
|
+
parsing: optionFlagParsing,
|
|
26
|
+
});
|
|
21
27
|
const kSofNormal = stream.registerOption({
|
|
22
28
|
shorts: ["sof-normal"],
|
|
23
29
|
longs: [],
|
|
24
|
-
|
|
30
|
+
parsing: optionFlagParsing,
|
|
25
31
|
});
|
|
26
32
|
const kSofPositive = stream.registerOption({
|
|
27
33
|
longs: [],
|
|
28
34
|
shorts: ["sof-positive"],
|
|
29
|
-
|
|
35
|
+
parsing: optionFlagParsing,
|
|
30
36
|
});
|
|
31
37
|
const kSofNegative = stream.registerOption({
|
|
32
38
|
longs: [],
|
|
33
39
|
shorts: ["sof-negative"],
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
const kSofUnset = stream.registerOption({
|
|
37
|
-
longs: [],
|
|
38
|
-
shorts: ["sof-unset"],
|
|
39
|
-
valued: false,
|
|
40
|
+
parsing: optionFlagParsing,
|
|
40
41
|
});
|
|
41
42
|
|
|
42
43
|
const kAa = stream.registerOption({
|
|
43
44
|
longs: [],
|
|
44
45
|
shorts: ["aa"],
|
|
45
|
-
|
|
46
|
+
parsing: optionFlagParsing,
|
|
46
47
|
});
|
|
47
48
|
const kBb = stream.registerOption({
|
|
48
49
|
longs: [],
|
|
49
50
|
shorts: ["bb"],
|
|
50
|
-
|
|
51
|
+
parsing: optionFlagParsing,
|
|
51
52
|
});
|
|
52
53
|
const kCc = stream.registerOption({
|
|
53
54
|
longs: [],
|
|
54
55
|
shorts: ["cc"],
|
|
55
|
-
|
|
56
|
+
parsing: optionFlagParsing,
|
|
56
57
|
});
|
|
57
58
|
|
|
58
59
|
expect(stream.consumePositional()).toStrictEqual("positional-1");
|
|
@@ -60,51 +61,94 @@ it("run", async () => {
|
|
|
60
61
|
const kSovSplit = stream.registerOption({
|
|
61
62
|
longs: [],
|
|
62
63
|
shorts: ["sov-split"],
|
|
63
|
-
|
|
64
|
+
parsing: optionValueFixedUniqueParsing,
|
|
64
65
|
});
|
|
65
66
|
const kSovJoin = stream.registerOption({
|
|
66
67
|
longs: [],
|
|
67
68
|
shorts: ["sov-join"],
|
|
68
|
-
|
|
69
|
+
parsing: optionValueFixedUniqueParsing,
|
|
69
70
|
});
|
|
70
71
|
const kSovUnset = stream.registerOption({
|
|
71
72
|
longs: [],
|
|
72
73
|
shorts: ["sov-unset"],
|
|
73
|
-
|
|
74
|
+
parsing: optionValueFixedUniqueParsing,
|
|
74
75
|
});
|
|
75
76
|
|
|
76
77
|
const kDd = stream.registerOption({
|
|
77
78
|
longs: [],
|
|
78
79
|
shorts: ["dd"],
|
|
79
|
-
|
|
80
|
+
parsing: optionFlagParsing,
|
|
80
81
|
});
|
|
81
82
|
const kEe = stream.registerOption({
|
|
82
83
|
longs: [],
|
|
83
84
|
shorts: ["ee"],
|
|
84
|
-
|
|
85
|
+
parsing: optionFlagParsing,
|
|
85
86
|
});
|
|
86
87
|
const kFf = stream.registerOption({
|
|
87
88
|
longs: [],
|
|
88
89
|
shorts: ["ff"],
|
|
89
|
-
|
|
90
|
+
parsing: optionFlagParsing,
|
|
91
|
+
});
|
|
92
|
+
const kGg = stream.registerOption({
|
|
93
|
+
longs: [],
|
|
94
|
+
shorts: ["gg"],
|
|
95
|
+
parsing: optionFlagParsing,
|
|
90
96
|
});
|
|
91
97
|
|
|
92
98
|
expect(stream.consumePositional()).toStrictEqual("positional-2");
|
|
93
99
|
|
|
94
|
-
expect(stream.getOptionValues(kSofNormal)).toStrictEqual(["true"]);
|
|
95
|
-
expect(stream.getOptionValues(kSofPositive)).toStrictEqual(["true"]);
|
|
96
|
-
expect(stream.getOptionValues(kSofNegative)).toStrictEqual(["false"]);
|
|
97
100
|
expect(stream.getOptionValues(kSofUnset)).toStrictEqual([]);
|
|
101
|
+
expect(stream.getOptionValues(kSofNormal)).toStrictEqual([
|
|
102
|
+
{ inlined: null, separated: [] },
|
|
103
|
+
]);
|
|
104
|
+
expect(stream.getOptionValues(kSofPositive)).toStrictEqual([
|
|
105
|
+
{ inlined: "true", separated: [] },
|
|
106
|
+
]);
|
|
107
|
+
expect(stream.getOptionValues(kSofNegative)).toStrictEqual([
|
|
108
|
+
{ inlined: "false", separated: [] },
|
|
109
|
+
]);
|
|
98
110
|
|
|
99
|
-
expect(stream.getOptionValues(kAa)).toStrictEqual([
|
|
100
|
-
|
|
101
|
-
|
|
111
|
+
expect(stream.getOptionValues(kAa)).toStrictEqual([
|
|
112
|
+
{ inlined: null, separated: [] },
|
|
113
|
+
]);
|
|
114
|
+
expect(stream.getOptionValues(kBb)).toStrictEqual([
|
|
115
|
+
{ inlined: null, separated: [] },
|
|
116
|
+
]);
|
|
117
|
+
expect(stream.getOptionValues(kCc)).toStrictEqual([
|
|
118
|
+
{ inlined: null, separated: [] },
|
|
119
|
+
]);
|
|
102
120
|
|
|
103
121
|
expect(stream.getOptionValues(kSovUnset)).toStrictEqual([]);
|
|
104
|
-
expect(stream.getOptionValues(kSovSplit)).toStrictEqual([
|
|
105
|
-
|
|
122
|
+
expect(stream.getOptionValues(kSovSplit)).toStrictEqual([
|
|
123
|
+
{ inlined: null, separated: ["1.1"] },
|
|
124
|
+
{ inlined: null, separated: ["1.2"] },
|
|
125
|
+
]);
|
|
126
|
+
expect(stream.getOptionValues(kSovJoin)).toStrictEqual([
|
|
127
|
+
{ inlined: "2.1", separated: [] },
|
|
128
|
+
{ inlined: "2.2", separated: [] },
|
|
129
|
+
]);
|
|
106
130
|
|
|
107
|
-
expect(stream.getOptionValues(kDd)).toStrictEqual([
|
|
108
|
-
|
|
109
|
-
|
|
131
|
+
expect(stream.getOptionValues(kDd)).toStrictEqual([
|
|
132
|
+
{ inlined: null, separated: [] },
|
|
133
|
+
]);
|
|
134
|
+
expect(stream.getOptionValues(kEe)).toStrictEqual([
|
|
135
|
+
{ inlined: null, separated: [] },
|
|
136
|
+
]);
|
|
137
|
+
expect(stream.getOptionValues(kFf)).toStrictEqual([
|
|
138
|
+
{ inlined: null, separated: [] },
|
|
139
|
+
]);
|
|
140
|
+
expect(stream.getOptionValues(kGg)).toStrictEqual([
|
|
141
|
+
{ inlined: null, separated: [] },
|
|
142
|
+
]);
|
|
110
143
|
});
|
|
144
|
+
|
|
145
|
+
const optionFlagParsing: ReaderOptionParsing = {
|
|
146
|
+
consumeShortGroup: false,
|
|
147
|
+
consumeNextArg: () => false,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const optionValueFixedUniqueParsing: ReaderOptionParsing = {
|
|
151
|
+
consumeShortGroup: true,
|
|
152
|
+
consumeNextArg: (inlined, separated) =>
|
|
153
|
+
inlined === null && separated.length === 0,
|
|
154
|
+
};
|
|
@@ -21,10 +21,21 @@ const rootCommand = commandChained(
|
|
|
21
21
|
{ description: "?" },
|
|
22
22
|
operation(
|
|
23
23
|
{
|
|
24
|
-
options: {
|
|
24
|
+
options: {
|
|
25
|
+
flagPositive: optionFlag({
|
|
26
|
+
short: "fp",
|
|
27
|
+
long: "flag-positive",
|
|
28
|
+
default: true,
|
|
29
|
+
}),
|
|
30
|
+
flagNegative: optionFlag({
|
|
31
|
+
short: "fn",
|
|
32
|
+
long: "flag-negative",
|
|
33
|
+
default: false,
|
|
34
|
+
}),
|
|
35
|
+
},
|
|
25
36
|
positionals: [positionalRequired({ label: "POS-1", type: typeNumber })],
|
|
26
37
|
},
|
|
27
|
-
async (context, inputs)
|
|
38
|
+
async function (context, inputs) {
|
|
28
39
|
return { at: "root", context, inputs };
|
|
29
40
|
},
|
|
30
41
|
),
|
|
@@ -45,7 +56,7 @@ const rootCommand = commandChained(
|
|
|
45
56
|
},
|
|
46
57
|
positionals: [positionalRequired({ type: typeNumber })],
|
|
47
58
|
},
|
|
48
|
-
async (context, inputs)
|
|
59
|
+
async function (context, inputs) {
|
|
49
60
|
return { at: "mid", context, inputs };
|
|
50
61
|
},
|
|
51
62
|
),
|
|
@@ -57,7 +68,7 @@ const rootCommand = commandChained(
|
|
|
57
68
|
options: {},
|
|
58
69
|
positionals: [positionalRequired({ type: typeString })],
|
|
59
70
|
},
|
|
60
|
-
async (context, inputs)
|
|
71
|
+
async function (context, inputs) {
|
|
61
72
|
return { at: "sub1", context, inputs };
|
|
62
73
|
},
|
|
63
74
|
),
|
|
@@ -73,7 +84,7 @@ const rootCommand = commandChained(
|
|
|
73
84
|
positionalVariadics({ type: typeString }),
|
|
74
85
|
],
|
|
75
86
|
},
|
|
76
|
-
async (context, inputs)
|
|
87
|
+
async function (context, inputs) {
|
|
77
88
|
return { at: "sub2", context, inputs };
|
|
78
89
|
},
|
|
79
90
|
),
|
|
@@ -82,13 +93,14 @@ const rootCommand = commandChained(
|
|
|
82
93
|
),
|
|
83
94
|
);
|
|
84
95
|
|
|
85
|
-
it("run", async ()
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
it("run", async function () {
|
|
97
|
+
expect(
|
|
98
|
+
await executeInterpreted(
|
|
99
|
+
["-fn=true", "-fp", "50", "51", "sub1", "final"],
|
|
100
|
+
"Run Context Input",
|
|
101
|
+
rootCommand,
|
|
102
|
+
),
|
|
103
|
+
).toStrictEqual({
|
|
92
104
|
at: "sub1",
|
|
93
105
|
context: {
|
|
94
106
|
at: "mid",
|
|
@@ -96,7 +108,7 @@ it("run", async () => {
|
|
|
96
108
|
at: "root",
|
|
97
109
|
context: "Run Context Input",
|
|
98
110
|
inputs: {
|
|
99
|
-
options: {
|
|
111
|
+
options: { flagPositive: true, flagNegative: true },
|
|
100
112
|
positionals: [50],
|
|
101
113
|
},
|
|
102
114
|
},
|
|
@@ -111,25 +123,56 @@ it("run", async () => {
|
|
|
111
123
|
},
|
|
112
124
|
});
|
|
113
125
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
126
|
+
expect(
|
|
127
|
+
await executeInterpreted(
|
|
128
|
+
["50", "51", "sub2", "9999.99"],
|
|
129
|
+
"Run Context Input",
|
|
130
|
+
rootCommand,
|
|
131
|
+
),
|
|
132
|
+
).toStrictEqual({
|
|
133
|
+
at: "sub2",
|
|
134
|
+
context: {
|
|
135
|
+
at: "mid",
|
|
136
|
+
context: {
|
|
137
|
+
at: "root",
|
|
138
|
+
context: "Run Context Input",
|
|
139
|
+
inputs: {
|
|
140
|
+
options: { flagPositive: true, flagNegative: false },
|
|
141
|
+
positionals: [50],
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
inputs: {
|
|
145
|
+
options: { string: undefined, number: [] },
|
|
146
|
+
positionals: [51],
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
inputs: {
|
|
150
|
+
options: {},
|
|
151
|
+
positionals: [9999.99, "42", []],
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
expect(
|
|
156
|
+
await executeInterpreted(
|
|
157
|
+
[
|
|
158
|
+
"40",
|
|
159
|
+
"41",
|
|
160
|
+
"sub2",
|
|
161
|
+
"--string-option=hello",
|
|
162
|
+
"--number-option",
|
|
163
|
+
"123.1,123.2",
|
|
164
|
+
"--number-option",
|
|
165
|
+
"123.3",
|
|
166
|
+
"88.88",
|
|
167
|
+
"a,b",
|
|
168
|
+
"final",
|
|
169
|
+
"--no-flag-positive",
|
|
170
|
+
"--no-flag-negative",
|
|
171
|
+
],
|
|
172
|
+
"Run Context Input",
|
|
173
|
+
rootCommand,
|
|
174
|
+
),
|
|
175
|
+
).toStrictEqual({
|
|
133
176
|
at: "sub2",
|
|
134
177
|
context: {
|
|
135
178
|
at: "mid",
|
|
@@ -137,7 +180,7 @@ it("run", async () => {
|
|
|
137
180
|
at: "root",
|
|
138
181
|
context: "Run Context Input",
|
|
139
182
|
inputs: {
|
|
140
|
-
options: {
|
|
183
|
+
options: { flagPositive: false, flagNegative: false },
|
|
141
184
|
positionals: [40],
|
|
142
185
|
},
|
|
143
186
|
},
|
|
@@ -48,7 +48,7 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
48
48
|
}),
|
|
49
49
|
],
|
|
50
50
|
},
|
|
51
|
-
async (context, inputs)
|
|
51
|
+
async function (context, inputs) {
|
|
52
52
|
return { at: "root", context, inputs };
|
|
53
53
|
},
|
|
54
54
|
),
|
|
@@ -92,7 +92,7 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
92
92
|
}),
|
|
93
93
|
],
|
|
94
94
|
},
|
|
95
|
-
async (context, inputs)
|
|
95
|
+
async function (context, inputs) {
|
|
96
96
|
return { at: "root", context, inputs };
|
|
97
97
|
},
|
|
98
98
|
),
|
|
@@ -128,7 +128,7 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
128
128
|
}),
|
|
129
129
|
],
|
|
130
130
|
},
|
|
131
|
-
async (context, inputs)
|
|
131
|
+
async function (context, inputs) {
|
|
132
132
|
return { at: "sub1", context, inputs };
|
|
133
133
|
},
|
|
134
134
|
),
|
|
@@ -185,7 +185,7 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
185
185
|
}),
|
|
186
186
|
],
|
|
187
187
|
},
|
|
188
|
-
async (context, inputs)
|
|
188
|
+
async function (context, inputs) {
|
|
189
189
|
return { at: "sub2", context, inputs };
|
|
190
190
|
},
|
|
191
191
|
),
|
|
@@ -194,7 +194,7 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
194
194
|
),
|
|
195
195
|
);
|
|
196
196
|
|
|
197
|
-
it("run", async ()
|
|
197
|
+
it("run", async function () {
|
|
198
198
|
const usage1 = await getUsage([], rootCommand);
|
|
199
199
|
const usage2 = await getUsage(["50"], rootCommand);
|
|
200
200
|
const usage3 = await getUsage(["50", "51"], rootCommand);
|
|
@@ -209,16 +209,6 @@ it("run", async () => {
|
|
|
209
209
|
rootCommand,
|
|
210
210
|
);
|
|
211
211
|
|
|
212
|
-
console.log(usage1.join("\n"));
|
|
213
|
-
console.log(usage2.join("\n"));
|
|
214
|
-
console.log(usage3.join("\n"));
|
|
215
|
-
console.log(usage4.join("\n"));
|
|
216
|
-
console.log(usage5.join("\n"));
|
|
217
|
-
console.log(usage6.join("\n"));
|
|
218
|
-
console.log(usage7.join("\n"));
|
|
219
|
-
/*
|
|
220
|
-
*/
|
|
221
|
-
|
|
222
212
|
const usageRoot = [
|
|
223
213
|
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<POS-1>}@darkBlue}+ {{[REST]...}@darkBlue}+",
|
|
224
214
|
"",
|
|
@@ -233,8 +223,8 @@ it("run", async () => {
|
|
|
233
223
|
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}* boolean-flag description",
|
|
234
224
|
"",
|
|
235
225
|
"{{Examples:}@darkGreen}+",
|
|
236
|
-
"
|
|
237
|
-
"
|
|
226
|
+
" {{# Example usage of the root command}-}*",
|
|
227
|
+
" {{my-cli}@darkCyan}+ {{42}@darkBlue}+ {{-b}@darkCyan}+",
|
|
238
228
|
"",
|
|
239
229
|
];
|
|
240
230
|
const usageMid = [
|
|
@@ -253,13 +243,13 @@ it("run", async () => {
|
|
|
253
243
|
" {{sub2}@darkCyan}+ Subcommand 2 description {{(Subcommand 2 hint)}-}*",
|
|
254
244
|
"",
|
|
255
245
|
"{{Options:}@darkGreen}+",
|
|
256
|
-
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}*
|
|
257
|
-
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<COOL-STUFF>}@darkBlue}+
|
|
258
|
-
" {{--complex-option}@darkCyan}+ {{<NUMBER,STRING[,STRING]...>}@darkBlue}+ complex-option description",
|
|
246
|
+
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}* boolean-flag description",
|
|
247
|
+
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<COOL-STUFF>}@darkBlue}+ string-option description",
|
|
248
|
+
" {{--complex-option}@darkCyan}+ {{<NUMBER,STRING[,STRING]...>}@darkBlue}+{{ [*]}-}* complex-option description",
|
|
259
249
|
"",
|
|
260
250
|
"{{Examples:}@darkGreen}+",
|
|
261
|
-
"
|
|
262
|
-
"
|
|
251
|
+
" {{# Example usage of the mid command}-}*",
|
|
252
|
+
" {{my-cli}@darkCyan}+ {{42}@darkBlue}+ {{-b}@darkCyan}+ {{43}@darkBlue}+",
|
|
263
253
|
"",
|
|
264
254
|
];
|
|
265
255
|
const usageSub1 = [
|
|
@@ -275,13 +265,13 @@ it("run", async () => {
|
|
|
275
265
|
" {{<POS-STRING>}@darkBlue}+ Required positional string",
|
|
276
266
|
"",
|
|
277
267
|
"{{Options:}@darkGreen}+",
|
|
278
|
-
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}*
|
|
279
|
-
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<COOL-STUFF>}@darkBlue}+
|
|
280
|
-
" {{--complex-option}@darkCyan}+ {{<NUMBER,STRING[,STRING]...>}@darkBlue}+ complex-option description",
|
|
268
|
+
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}* boolean-flag description",
|
|
269
|
+
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<COOL-STUFF>}@darkBlue}+ string-option description",
|
|
270
|
+
" {{--complex-option}@darkCyan}+ {{<NUMBER,STRING[,STRING]...>}@darkBlue}+{{ [*]}-}* complex-option description",
|
|
281
271
|
"",
|
|
282
272
|
"{{Examples:}@darkGreen}+",
|
|
283
|
-
"
|
|
284
|
-
"
|
|
273
|
+
" {{# Example usage of subcommand 1}-}*",
|
|
274
|
+
" {{my-cli}@darkCyan}+ {{-b}@darkCyan}+ {{42}@darkBlue}+ {{43}@darkBlue}+ {{sub1}@darkCyan}+ {{valid}@darkBlue}+",
|
|
285
275
|
"",
|
|
286
276
|
];
|
|
287
277
|
const usageSub2 = [
|
|
@@ -299,17 +289,27 @@ it("run", async () => {
|
|
|
299
289
|
" {{[VARIADIC]...}@darkBlue}+ Variadic positionals strings",
|
|
300
290
|
"",
|
|
301
291
|
"{{Options:}@darkGreen}+",
|
|
302
|
-
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}*
|
|
303
|
-
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<COOL-STUFF>}@darkBlue}+
|
|
304
|
-
" {{--complex-option}@darkCyan}+ {{<NUMBER,STRING[,STRING]...>}@darkBlue}+ complex-option description",
|
|
305
|
-
" {{--dudu}@darkCyan}+ {{<STRING>}@darkBlue}+
|
|
292
|
+
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}* boolean-flag description",
|
|
293
|
+
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<COOL-STUFF>}@darkBlue}+ string-option description",
|
|
294
|
+
" {{--complex-option}@darkCyan}+ {{<NUMBER,STRING[,STRING]...>}@darkBlue}+{{ [*]}-}* complex-option description",
|
|
295
|
+
" {{--dudu}@darkCyan}+ {{<STRING>}@darkBlue}+ Dudu option description {{(Dudu option hint)}-}*",
|
|
306
296
|
"",
|
|
307
297
|
"{{Examples:}@darkGreen}+",
|
|
308
|
-
"
|
|
309
|
-
"
|
|
298
|
+
" {{# Example usage of subcommand 2}-}*",
|
|
299
|
+
" {{my-cli}@darkCyan}+ {{40}@darkBlue}+ {{41}@darkBlue}+ {{sub2}@darkCyan}+ {{--dudu}@darkCyan}+{{=}-}*{{hello}@darkBlue}+ {{50}@darkBlue}+",
|
|
310
300
|
"",
|
|
311
301
|
];
|
|
312
302
|
|
|
303
|
+
/*
|
|
304
|
+
console.log(usage1.join("\n"));
|
|
305
|
+
console.log(usage2.join("\n"));
|
|
306
|
+
console.log(usage3.join("\n"));
|
|
307
|
+
console.log(usage4.join("\n"));
|
|
308
|
+
console.log(usage5.join("\n"));
|
|
309
|
+
console.log(usage6.join("\n"));
|
|
310
|
+
console.log(usage7.join("\n"));
|
|
311
|
+
*/
|
|
312
|
+
|
|
313
313
|
expect(usage1).toStrictEqual(usageRoot);
|
|
314
314
|
expect(usage2).toStrictEqual(usageMid);
|
|
315
315
|
expect(usage3).toStrictEqual(usageMid);
|
|
@@ -338,7 +338,7 @@ async function getUsage<Context, Result>(
|
|
|
338
338
|
*/
|
|
339
339
|
return usageToStyledLines({
|
|
340
340
|
cliName: "my-cli",
|
|
341
|
-
|
|
342
|
-
typoSupport: TypoSupport.
|
|
341
|
+
usage: commandDecoder.generateUsage(),
|
|
342
|
+
typoSupport: TypoSupport.mock(),
|
|
343
343
|
});
|
|
344
344
|
}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
typeUrl,
|
|
17
17
|
} from "../src";
|
|
18
18
|
|
|
19
|
-
it("run", async ()
|
|
19
|
+
it("run", async function () {
|
|
20
20
|
const rootUsage = [
|
|
21
21
|
"Usage: my-cli <REQUIRED1> <SUBCOMMAND>",
|
|
22
22
|
"",
|
|
@@ -30,7 +30,7 @@ it("run", async () => {
|
|
|
30
30
|
"",
|
|
31
31
|
"Options:",
|
|
32
32
|
" --flag[=no] Option flag description",
|
|
33
|
-
" --repeatable <STRING>
|
|
33
|
+
" --repeatable <STRING> [*] Option repeatable description",
|
|
34
34
|
" --single-value <NUMBER-ENUM> Option single value description",
|
|
35
35
|
"",
|
|
36
36
|
].join("\n");
|
|
@@ -47,9 +47,9 @@ it("run", async () => {
|
|
|
47
47
|
"",
|
|
48
48
|
"Options:",
|
|
49
49
|
" --flag[=no] Option flag description",
|
|
50
|
-
" --repeatable <STRING>
|
|
50
|
+
" --repeatable <STRING> [*] Option repeatable description",
|
|
51
51
|
" --single-value <NUMBER-ENUM> Option single value description",
|
|
52
|
-
" --url <URL>
|
|
52
|
+
" --url <URL> [*] Option url description",
|
|
53
53
|
"",
|
|
54
54
|
].join("\n");
|
|
55
55
|
|
|
@@ -101,7 +101,7 @@ it("run", async () => {
|
|
|
101
101
|
await testCase(
|
|
102
102
|
["--invalid1", "--invalid2", "required1", "--invalid3"],
|
|
103
103
|
[],
|
|
104
|
-
[rootUsage, "Error:
|
|
104
|
+
[rootUsage, "Error: Unexpected unknown option: --invalid1"],
|
|
105
105
|
1,
|
|
106
106
|
);
|
|
107
107
|
await testCase(
|
|
@@ -135,13 +135,13 @@ it("run", async () => {
|
|
|
135
135
|
await testCase(
|
|
136
136
|
["--url", "https://example.com"],
|
|
137
137
|
[],
|
|
138
|
-
[rootUsage, "Error:
|
|
138
|
+
[rootUsage, "Error: Unexpected unknown option: --url"],
|
|
139
139
|
1,
|
|
140
140
|
);
|
|
141
141
|
await testCase(
|
|
142
142
|
["required1", "--url", "https://example.com"],
|
|
143
143
|
[],
|
|
144
|
-
[rootUsage, "Error:
|
|
144
|
+
[rootUsage, "Error: Unexpected unknown option: --url"],
|
|
145
145
|
1,
|
|
146
146
|
);
|
|
147
147
|
await testCase(
|
|
@@ -187,13 +187,13 @@ it("run", async () => {
|
|
|
187
187
|
await testCase(
|
|
188
188
|
["--invalid", "required1", "subcommand", "required2"],
|
|
189
189
|
[],
|
|
190
|
-
[rootUsage, "Error:
|
|
190
|
+
[rootUsage, "Error: Unexpected unknown option: --invalid"],
|
|
191
191
|
1,
|
|
192
192
|
);
|
|
193
193
|
await testCase(
|
|
194
194
|
["required1", "subcommand", "required2", "--nope"],
|
|
195
195
|
[],
|
|
196
|
-
[subcommandUsage, "Error:
|
|
196
|
+
[subcommandUsage, "Error: Unexpected unknown option: --nope"],
|
|
197
197
|
1,
|
|
198
198
|
);
|
|
199
199
|
await testCase(
|
|
@@ -283,7 +283,7 @@ it("run", async () => {
|
|
|
283
283
|
await testCase(
|
|
284
284
|
["--url", "not-a-url", "required1", "subcommand", "required2"],
|
|
285
285
|
[],
|
|
286
|
-
[rootUsage, "Error:
|
|
286
|
+
[rootUsage, "Error: Unexpected unknown option: --url"],
|
|
287
287
|
1,
|
|
288
288
|
);
|
|
289
289
|
await testCase(
|
|
@@ -372,7 +372,7 @@ async function testCase(
|
|
|
372
372
|
}),
|
|
373
373
|
],
|
|
374
374
|
},
|
|
375
|
-
async ()
|
|
375
|
+
async function () {
|
|
376
376
|
console.log("Has executed root command");
|
|
377
377
|
},
|
|
378
378
|
),
|
|
@@ -407,7 +407,7 @@ async function testCase(
|
|
|
407
407
|
}),
|
|
408
408
|
],
|
|
409
409
|
},
|
|
410
|
-
async ()
|
|
410
|
+
async function () {
|
|
411
411
|
console.log("Has executed subcommand");
|
|
412
412
|
},
|
|
413
413
|
),
|
|
@@ -435,7 +435,7 @@ function makeMocked<P, R>(returns: Array<R>) {
|
|
|
435
435
|
const history = new Array<P>();
|
|
436
436
|
return {
|
|
437
437
|
history,
|
|
438
|
-
call
|
|
438
|
+
call(p: P) {
|
|
439
439
|
history.push(p);
|
|
440
440
|
if (history.length > returns.length) {
|
|
441
441
|
throw new Error(
|
|
@@ -10,15 +10,31 @@ import {
|
|
|
10
10
|
typeUrl,
|
|
11
11
|
} from "../src";
|
|
12
12
|
|
|
13
|
-
it("run", async ()
|
|
13
|
+
it("run", async function () {
|
|
14
14
|
await testCase(
|
|
15
15
|
["hello"],
|
|
16
16
|
'{{Error:}@darkRed}+ Unexpected argument: {{"hello"}@darkYellow}+',
|
|
17
17
|
);
|
|
18
|
+
await testCase(
|
|
19
|
+
["--nope"],
|
|
20
|
+
"{{Error:}@darkRed}+ Unexpected unknown option: {{--nope}@darkYellow}+",
|
|
21
|
+
);
|
|
18
22
|
await testCase(
|
|
19
23
|
["--flag", "--flag"],
|
|
20
24
|
"{{Error:}@darkRed}+ {{--flag}@darkCyan}+: Must not be set multiple times",
|
|
21
25
|
);
|
|
26
|
+
await testCase(
|
|
27
|
+
["--flag", "--no-flag"],
|
|
28
|
+
"{{Error:}@darkRed}+ {{--flag}@darkCyan}+: Must not be set in combination with: {{--no-flag}@darkCyan}+",
|
|
29
|
+
);
|
|
30
|
+
await testCase(
|
|
31
|
+
["--no-flag", "--no-flag"],
|
|
32
|
+
"{{Error:}@darkRed}+ {{--no-flag}@darkCyan}+: Must not be set multiple times",
|
|
33
|
+
);
|
|
34
|
+
await testCase(
|
|
35
|
+
["--single-value=a", "--single-value=b"],
|
|
36
|
+
"{{Error:}@darkRed}+ {{--single-value}@darkCyan}+: Requires a single value, but got multiple",
|
|
37
|
+
);
|
|
22
38
|
await testCase(
|
|
23
39
|
["--flag=invalid"],
|
|
24
40
|
'{{Error:}@darkRed}+ {{--flag}@darkCyan}+: {{<BOOLEAN>}@darkBlue}+: {{Boolean}@darkMagenta}+: Invalid value: {{"invalid"}@darkYellow}+',
|
|
@@ -59,7 +75,7 @@ async function testCase(args: Array<string>, error: string) {
|
|
|
59
75
|
},
|
|
60
76
|
positionals: [],
|
|
61
77
|
},
|
|
62
|
-
async ()
|
|
78
|
+
async function () {},
|
|
63
79
|
),
|
|
64
80
|
);
|
|
65
81
|
console.log = onLogStdOut.call;
|
|
@@ -79,7 +95,7 @@ function makeMocked<P, R>(returns: Array<R>) {
|
|
|
79
95
|
const history = new Array<P>();
|
|
80
96
|
return {
|
|
81
97
|
history,
|
|
82
|
-
call
|
|
98
|
+
call(p: P) {
|
|
83
99
|
history.push(p);
|
|
84
100
|
if (history.length > returns.length) {
|
|
85
101
|
throw new Error(
|