cli-kiss 0.2.7 → 0.2.9
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 +8 -3
- package/dist/index.d.ts +200 -190
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.mts +1 -1
- package/docs/.vitepress/theme/Layout.vue +16 -0
- package/docs/.vitepress/theme/index.ts +5 -1
- package/docs/.vitepress/theme/style.css +5 -1
- package/docs/guide/01_getting_started.md +2 -2
- package/docs/guide/02_commands.md +3 -3
- package/docs/guide/03_options.md +11 -11
- package/docs/guide/04_positionals.md +9 -9
- package/docs/guide/05_input_types.md +17 -16
- package/docs/guide/06_run_as_cli.md +1 -1
- package/docs/index.md +2 -2
- package/docs/public/favicon.ico +0 -0
- package/docs/public/logo.png +0 -0
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/lib/Command.ts +51 -40
- package/src/lib/Operation.ts +41 -25
- package/src/lib/Option.ts +198 -127
- package/src/lib/Positional.ts +51 -25
- package/src/lib/Reader.ts +188 -226
- package/src/lib/Run.ts +20 -9
- package/src/lib/Suggest.ts +78 -0
- package/src/lib/Type.ts +178 -154
- package/src/lib/Typo.ts +58 -55
- package/src/lib/Usage.ts +12 -12
- package/tests/unit.Reader.commons.ts +86 -123
- package/tests/unit.Reader.parsings.ts +14 -26
- package/tests/unit.Reader.shortBig.ts +75 -101
- package/tests/unit.command.aliases.ts +88 -0
- package/tests/unit.command.execute.ts +6 -6
- package/tests/unit.command.usage.ts +19 -13
- package/tests/unit.fuzzed.alternatives.ts +35 -26
- package/tests/unit.runner.colors.ts +8 -33
- package/tests/unit.runner.cycle.ts +141 -156
- package/tests/unit.runner.errors.ts +25 -22
- package/docs/public/hero.png +0 -0
- package/src/lib/Similarity.ts +0 -41
- package/tests/unit.Reader.aliases.ts +0 -62
package/src/lib/Typo.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { typeBooleanValuesFalse } from "./Type";
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Color names for terminal styling, used by {@link TypoStyle}.
|
|
5
3
|
* `dark*` = standard ANSI (30–37); `bright*` = high-intensity (90–97).
|
|
@@ -125,14 +123,14 @@ export const typoStyleRegularWeaker: TypoStyle = {
|
|
|
125
123
|
*/
|
|
126
124
|
export class TypoString {
|
|
127
125
|
#value: string;
|
|
128
|
-
#
|
|
126
|
+
#style: TypoStyle | undefined;
|
|
129
127
|
/**
|
|
130
128
|
* @param value - Raw text content.
|
|
131
|
-
* @param
|
|
129
|
+
* @param style - Style to apply when rendering.
|
|
132
130
|
*/
|
|
133
|
-
constructor(value: string,
|
|
131
|
+
constructor(value: string, style?: TypoStyle) {
|
|
134
132
|
this.#value = value;
|
|
135
|
-
this.#
|
|
133
|
+
this.#style = style;
|
|
136
134
|
}
|
|
137
135
|
/**
|
|
138
136
|
* Returns the text styled by `typoSupport`.
|
|
@@ -140,51 +138,75 @@ export class TypoString {
|
|
|
140
138
|
* @param typoSupport - Rendering mode.
|
|
141
139
|
*/
|
|
142
140
|
computeStyledString(typoSupport: TypoSupport): string {
|
|
143
|
-
return typoSupport.computeStyledString(this.#value, this.#
|
|
141
|
+
return typoSupport.computeStyledString(this.#value, this.#style);
|
|
144
142
|
}
|
|
145
143
|
/**
|
|
146
144
|
* Returns the raw text.
|
|
147
145
|
*/
|
|
148
146
|
getRawString(): string {
|
|
147
|
+
// TODO - should there be a global config or smthg instead of passing support everywhere?
|
|
149
148
|
return this.#value;
|
|
150
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Predefined ellipsis segment with subtle styling.
|
|
152
|
+
*/
|
|
153
|
+
static elipsis = new TypoString("...", typoStyleRegularWeaker);
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
/**
|
|
154
157
|
* A segment of styled text, a string, or an array of segments.
|
|
155
158
|
*/
|
|
156
|
-
export type TypoSegment = TypoText | TypoString |
|
|
159
|
+
export type TypoSegment = TypoText | TypoString | Array<TypoSegment>;
|
|
157
160
|
|
|
158
161
|
/**
|
|
159
162
|
* Mutable sequence of {@link TypoString} segments.
|
|
160
163
|
*/
|
|
161
164
|
export class TypoText {
|
|
162
|
-
#
|
|
165
|
+
#strings: Array<TypoString>;
|
|
163
166
|
/**
|
|
164
167
|
* @param segments - Initial text segments
|
|
165
168
|
*/
|
|
166
|
-
constructor(...segments: TypoSegment
|
|
167
|
-
this.#
|
|
169
|
+
constructor(...segments: Array<TypoSegment>) {
|
|
170
|
+
this.#strings = [];
|
|
168
171
|
for (const segment of segments) {
|
|
169
172
|
this.push(segment);
|
|
170
173
|
}
|
|
171
174
|
}
|
|
172
175
|
/**
|
|
173
176
|
* Appends new text segment(s).
|
|
174
|
-
*
|
|
175
|
-
* @param segment - Text segment(s) to append.
|
|
176
177
|
*/
|
|
177
|
-
push(
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
this.push(
|
|
178
|
+
push(...segments: Array<TypoSegment>): void {
|
|
179
|
+
for (const segment of segments) {
|
|
180
|
+
if (typeof segment === "string") {
|
|
181
|
+
this.#strings.push(new TypoString(segment));
|
|
182
|
+
} else if (segment instanceof TypoString) {
|
|
183
|
+
this.#strings.push(segment);
|
|
184
|
+
} else if (segment instanceof TypoText) {
|
|
185
|
+
this.#strings.push(...segment.#strings);
|
|
186
|
+
} else if (Array.isArray(segment)) {
|
|
187
|
+
for (const part of segment) {
|
|
188
|
+
this.push(part);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Appends separated segments, optionally truncating with an ellipsis.
|
|
195
|
+
*/
|
|
196
|
+
pushJoined(
|
|
197
|
+
segments: Array<TypoSegment>,
|
|
198
|
+
separator: TypoSegment,
|
|
199
|
+
ellipsisLimit: number,
|
|
200
|
+
): void {
|
|
201
|
+
for (let index = 0; index < segments.length; index++) {
|
|
202
|
+
if (index > 0) {
|
|
203
|
+
this.push(separator);
|
|
204
|
+
}
|
|
205
|
+
if (ellipsisLimit !== undefined && index >= ellipsisLimit) {
|
|
206
|
+
this.push(TypoString.elipsis);
|
|
207
|
+
break;
|
|
185
208
|
}
|
|
186
|
-
|
|
187
|
-
this.#typoStrings.push(segment);
|
|
209
|
+
this.push(segments[index]!);
|
|
188
210
|
}
|
|
189
211
|
}
|
|
190
212
|
/**
|
|
@@ -194,7 +216,7 @@ export class TypoText {
|
|
|
194
216
|
* @returns Concatenated styled string.
|
|
195
217
|
*/
|
|
196
218
|
computeStyledString(typoSupport: TypoSupport): string {
|
|
197
|
-
return this.#
|
|
219
|
+
return this.#strings
|
|
198
220
|
.map((t) => t.computeStyledString(typoSupport))
|
|
199
221
|
.join("");
|
|
200
222
|
}
|
|
@@ -202,32 +224,18 @@ export class TypoText {
|
|
|
202
224
|
* Returns the concatenated raw text.
|
|
203
225
|
*/
|
|
204
226
|
computeRawString(): string {
|
|
205
|
-
return this.#
|
|
227
|
+
return this.#strings.map((t) => t.getRawString()).join("");
|
|
206
228
|
}
|
|
207
229
|
/**
|
|
208
230
|
* Returns the total raw character count.
|
|
209
231
|
*/
|
|
210
232
|
computeRawLength(): number {
|
|
211
233
|
let length = 0;
|
|
212
|
-
for (const typoString of this.#
|
|
234
|
+
for (const typoString of this.#strings) {
|
|
213
235
|
length += typoString.getRawString().length;
|
|
214
236
|
}
|
|
215
237
|
return length;
|
|
216
238
|
}
|
|
217
|
-
/**
|
|
218
|
-
* Joins multiple segments with a separator.
|
|
219
|
-
* @returns A new {@link TypoText} containing the joined segments.
|
|
220
|
-
*/
|
|
221
|
-
static join(segments: Array<TypoSegment>, separator: TypoSegment): TypoText {
|
|
222
|
-
const result = new TypoText();
|
|
223
|
-
for (let index = 0; index < segments.length; index++) {
|
|
224
|
-
if (index > 0) {
|
|
225
|
-
result.push(separator);
|
|
226
|
-
}
|
|
227
|
-
result.push(segments[index]!);
|
|
228
|
-
}
|
|
229
|
-
return result;
|
|
230
|
-
}
|
|
231
239
|
}
|
|
232
240
|
|
|
233
241
|
/**
|
|
@@ -377,15 +385,6 @@ export class TypoSupport {
|
|
|
377
385
|
* Auto-detects styling mode from the process environment on best-effort basis.
|
|
378
386
|
*/
|
|
379
387
|
static inferFromEnv(): TypoSupport {
|
|
380
|
-
/*
|
|
381
|
-
console.warn({
|
|
382
|
-
no: readEnvVar("NO_COLOR"),
|
|
383
|
-
force: readEnvVar("FORCE_COLOR"),
|
|
384
|
-
mock: readEnvVar("MOCK_COLOR"),
|
|
385
|
-
term: readEnvVar("TERM"),
|
|
386
|
-
tty: process.stdout.isTTY,
|
|
387
|
-
});
|
|
388
|
-
*/
|
|
389
388
|
if (!process || !process.env || !process.stdout) {
|
|
390
389
|
return TypoSupport.none();
|
|
391
390
|
}
|
|
@@ -396,13 +395,17 @@ export class TypoSupport {
|
|
|
396
395
|
if (envForceColor === "0") {
|
|
397
396
|
return TypoSupport.none();
|
|
398
397
|
}
|
|
399
|
-
if (envForceColor
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
398
|
+
if (envForceColor === "1") {
|
|
399
|
+
return TypoSupport.tty();
|
|
400
|
+
}
|
|
401
|
+
if (envForceColor === "2") {
|
|
402
|
+
return TypoSupport.tty();
|
|
403
|
+
}
|
|
404
|
+
if (envForceColor === "3") {
|
|
405
|
+
return TypoSupport.tty();
|
|
403
406
|
}
|
|
404
|
-
if (
|
|
405
|
-
return TypoSupport.
|
|
407
|
+
if (envForceColor) {
|
|
408
|
+
return TypoSupport.tty();
|
|
406
409
|
}
|
|
407
410
|
if (!process.stdout.isTTY) {
|
|
408
411
|
return TypoSupport.none();
|
package/src/lib/Usage.ts
CHANGED
|
@@ -93,7 +93,7 @@ export type UsageOption = {
|
|
|
93
93
|
/**
|
|
94
94
|
* Extra annotation appended to the option label in help.
|
|
95
95
|
*/
|
|
96
|
-
annotation?: string | undefined;
|
|
96
|
+
annotation?: string | undefined; // TODO - maybe prefix/postfix would be more useful
|
|
97
97
|
/**
|
|
98
98
|
* Help text.
|
|
99
99
|
*/
|
|
@@ -175,7 +175,7 @@ export function usageToStyledLines(params: {
|
|
|
175
175
|
lines.push("");
|
|
176
176
|
const introText = new TypoText();
|
|
177
177
|
introText.push(textUsageText(usage.information.description));
|
|
178
|
-
if (usage.information.hint) {
|
|
178
|
+
if (usage.information.hint !== undefined) {
|
|
179
179
|
introText.push(textDelimiter(" "));
|
|
180
180
|
introText.push(textSubtleInfo(`(${usage.information.hint})`));
|
|
181
181
|
}
|
|
@@ -221,7 +221,7 @@ export function usageToStyledLines(params: {
|
|
|
221
221
|
for (const optionUsage of usage.options) {
|
|
222
222
|
const typoGridRow = new Array<TypoText>();
|
|
223
223
|
typoGridRow.push(new TypoText(textDelimiter(" ")));
|
|
224
|
-
if (optionUsage.short) {
|
|
224
|
+
if (optionUsage.short !== undefined) {
|
|
225
225
|
typoGridRow.push(
|
|
226
226
|
new TypoText(
|
|
227
227
|
textConstants(`-${optionUsage.short}`),
|
|
@@ -234,11 +234,11 @@ export function usageToStyledLines(params: {
|
|
|
234
234
|
const longOptionText = new TypoText(
|
|
235
235
|
textConstants(`--${optionUsage.long}`),
|
|
236
236
|
);
|
|
237
|
-
if (optionUsage.label) {
|
|
237
|
+
if (optionUsage.label !== undefined) {
|
|
238
238
|
longOptionText.push(textDelimiter(" "));
|
|
239
239
|
longOptionText.push(textUserInput(optionUsage.label));
|
|
240
240
|
}
|
|
241
|
-
if (optionUsage.annotation) {
|
|
241
|
+
if (optionUsage.annotation !== undefined) {
|
|
242
242
|
longOptionText.push(textSubtleInfo(optionUsage.annotation));
|
|
243
243
|
}
|
|
244
244
|
typoGridRow.push(longOptionText);
|
|
@@ -248,14 +248,14 @@ export function usageToStyledLines(params: {
|
|
|
248
248
|
lines.push(...typoGrid.computeStyledLines(typoSupport));
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
if (usage.information.examples) {
|
|
251
|
+
if (usage.information.examples !== undefined) {
|
|
252
252
|
lines.push("");
|
|
253
253
|
lines.push(textBlockTitle("Examples:").computeStyledString(typoSupport));
|
|
254
254
|
for (const example of usage.information.examples) {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
lines.push(
|
|
255
|
+
const explanationText = new TypoText();
|
|
256
|
+
explanationText.push(textDelimiter(" "));
|
|
257
|
+
explanationText.push(textSubtleInfo(`# ${example.explanation}`));
|
|
258
|
+
lines.push(explanationText.computeStyledString(typoSupport));
|
|
259
259
|
const commandLineText = new TypoText();
|
|
260
260
|
commandLineText.push(textDelimiter(" "));
|
|
261
261
|
commandLineText.push(textConstants(cliName));
|
|
@@ -299,11 +299,11 @@ function createInformationals(usage: {
|
|
|
299
299
|
hint?: string | undefined;
|
|
300
300
|
}): Array<TypoText> {
|
|
301
301
|
const informationals = [];
|
|
302
|
-
if (usage.description) {
|
|
302
|
+
if (usage.description !== undefined) {
|
|
303
303
|
informationals.push(textDelimiter(" "));
|
|
304
304
|
informationals.push(textUsefulInfo(usage.description));
|
|
305
305
|
}
|
|
306
|
-
if (usage.hint) {
|
|
306
|
+
if (usage.hint !== undefined) {
|
|
307
307
|
informationals.push(textDelimiter(" "));
|
|
308
308
|
informationals.push(textSubtleInfo(`(${usage.hint})`));
|
|
309
309
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { expect, it } from "@jest/globals";
|
|
2
|
-
import { ReaderArgs,
|
|
2
|
+
import { ReaderArgs, ReaderOptionNextGuard } from "../src";
|
|
3
3
|
|
|
4
4
|
it("run", async function () {
|
|
5
5
|
const stream = new ReaderArgs([
|
|
@@ -36,105 +36,97 @@ it("run", async function () {
|
|
|
36
36
|
|
|
37
37
|
expect(stream.consumePositional()).toStrictEqual("positional-0");
|
|
38
38
|
|
|
39
|
-
const kFlagUnset = stream.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
parsing: optionFlagParsing,
|
|
39
|
+
const kFlagUnset = stream.registerOptionLong({
|
|
40
|
+
key: "flag-unset",
|
|
41
|
+
nextGuard: optionFlagNextGuard,
|
|
43
42
|
});
|
|
44
|
-
const kFlagNo = stream.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
parsing: optionFlagParsing,
|
|
43
|
+
const kFlagNo = stream.registerOptionLong({
|
|
44
|
+
key: "no-flag-no",
|
|
45
|
+
nextGuard: optionFlagNextGuard,
|
|
48
46
|
});
|
|
49
|
-
const kFlagNormal = stream.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
parsing: optionFlagParsing,
|
|
47
|
+
const kFlagNormal = stream.registerOptionLong({
|
|
48
|
+
key: "flag-normal",
|
|
49
|
+
nextGuard: optionFlagNextGuard,
|
|
53
50
|
});
|
|
54
|
-
const kFlagPositive = stream.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
parsing: optionFlagParsing,
|
|
51
|
+
const kFlagPositive = stream.registerOptionLong({
|
|
52
|
+
key: "flag-positive",
|
|
53
|
+
nextGuard: optionFlagNextGuard,
|
|
58
54
|
});
|
|
59
|
-
const kFlagNegative = stream.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
parsing: optionFlagParsing,
|
|
55
|
+
const kFlagNegative = stream.registerOptionLong({
|
|
56
|
+
key: "flag-negative",
|
|
57
|
+
nextGuard: optionFlagNextGuard,
|
|
63
58
|
});
|
|
64
59
|
|
|
65
60
|
expect(stream.consumePositional()).toStrictEqual("positional-1");
|
|
66
61
|
|
|
67
|
-
const kOptionUnset = stream.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
parsing: optionValueFixedUniqueParsing,
|
|
62
|
+
const kOptionUnset = stream.registerOptionLong({
|
|
63
|
+
key: "option-unset",
|
|
64
|
+
nextGuard: optionValuedNextGuard,
|
|
71
65
|
});
|
|
72
|
-
const kOptionSplit = stream.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
parsing: optionValueFixedUniqueParsing,
|
|
66
|
+
const kOptionSplit = stream.registerOptionLong({
|
|
67
|
+
key: "option-split",
|
|
68
|
+
nextGuard: optionValuedNextGuard,
|
|
76
69
|
});
|
|
77
|
-
const kOptionJoin = stream.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
parsing: optionValueFixedUniqueParsing,
|
|
70
|
+
const kOptionJoin = stream.registerOptionLong({
|
|
71
|
+
key: "option-join",
|
|
72
|
+
nextGuard: optionValuedNextGuard,
|
|
81
73
|
});
|
|
82
74
|
|
|
83
|
-
const kA = stream.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
const kA = stream.registerOptionShort({
|
|
76
|
+
key: "a",
|
|
77
|
+
nextGuard: optionFlagNextGuard,
|
|
78
|
+
consumeGroupRestAsValue: false,
|
|
87
79
|
});
|
|
88
|
-
const kB = stream.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
80
|
+
const kB = stream.registerOptionShort({
|
|
81
|
+
key: "b",
|
|
82
|
+
nextGuard: optionValuedNextGuard,
|
|
83
|
+
consumeGroupRestAsValue: true,
|
|
92
84
|
});
|
|
93
85
|
|
|
94
|
-
const kC = stream.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
const kC = stream.registerOptionShort({
|
|
87
|
+
key: "c",
|
|
88
|
+
nextGuard: optionFlagNextGuard,
|
|
89
|
+
consumeGroupRestAsValue: false,
|
|
98
90
|
});
|
|
99
|
-
const kD = stream.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
91
|
+
const kD = stream.registerOptionShort({
|
|
92
|
+
key: "d",
|
|
93
|
+
nextGuard: optionValuedNextGuard,
|
|
94
|
+
consumeGroupRestAsValue: true,
|
|
103
95
|
});
|
|
104
96
|
|
|
105
|
-
const kE = stream.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
const kE = stream.registerOptionShort({
|
|
98
|
+
key: "e",
|
|
99
|
+
nextGuard: optionFlagNextGuard,
|
|
100
|
+
consumeGroupRestAsValue: false,
|
|
109
101
|
});
|
|
110
|
-
const kF = stream.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
102
|
+
const kF = stream.registerOptionShort({
|
|
103
|
+
key: "f",
|
|
104
|
+
nextGuard: optionValuedNextGuard,
|
|
105
|
+
consumeGroupRestAsValue: true,
|
|
114
106
|
});
|
|
115
107
|
|
|
116
108
|
expect(stream.consumePositional()).toStrictEqual("positional-2");
|
|
117
109
|
|
|
118
|
-
const kG = stream.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
110
|
+
const kG = stream.registerOptionShort({
|
|
111
|
+
key: "g",
|
|
112
|
+
nextGuard: optionFlagNextGuard,
|
|
113
|
+
consumeGroupRestAsValue: false,
|
|
122
114
|
});
|
|
123
|
-
const kH = stream.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
115
|
+
const kH = stream.registerOptionShort({
|
|
116
|
+
key: "h",
|
|
117
|
+
nextGuard: optionValuedNextGuard,
|
|
118
|
+
consumeGroupRestAsValue: true,
|
|
127
119
|
});
|
|
128
120
|
|
|
129
|
-
const kI = stream.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
121
|
+
const kI = stream.registerOptionShort({
|
|
122
|
+
key: "i",
|
|
123
|
+
nextGuard: optionFlagNextGuard,
|
|
124
|
+
consumeGroupRestAsValue: false,
|
|
133
125
|
});
|
|
134
|
-
const kJ = stream.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
126
|
+
const kJ = stream.registerOptionShort({
|
|
127
|
+
key: "j",
|
|
128
|
+
nextGuard: optionValuedNextGuard,
|
|
129
|
+
consumeGroupRestAsValue: true,
|
|
138
130
|
});
|
|
139
131
|
|
|
140
132
|
expect(stream.consumePositional()).toStrictEqual("positional-3");
|
|
@@ -145,76 +137,47 @@ it("run", async function () {
|
|
|
145
137
|
expect(stream.consumePositional()).toStrictEqual("positional-4");
|
|
146
138
|
expect(stream.consumePositional()).toStrictEqual(undefined);
|
|
147
139
|
|
|
148
|
-
expect(
|
|
149
|
-
expect(
|
|
150
|
-
|
|
151
|
-
]);
|
|
152
|
-
expect(
|
|
153
|
-
{ inlined: null, separated: [] },
|
|
154
|
-
]);
|
|
155
|
-
expect(stream.getOptionValues(kFlagPositive)).toStrictEqual([
|
|
156
|
-
{ inlined: "true", separated: [] },
|
|
157
|
-
]);
|
|
158
|
-
expect(stream.getOptionValues(kFlagNegative)).toStrictEqual([
|
|
159
|
-
{ inlined: "false", separated: [] },
|
|
160
|
-
]);
|
|
140
|
+
expect(kFlagUnset()).toStrictEqual([]);
|
|
141
|
+
expect(kFlagNo()).toStrictEqual([{ inlined: null, separated: [] }]);
|
|
142
|
+
expect(kFlagNormal()).toStrictEqual([{ inlined: null, separated: [] }]);
|
|
143
|
+
expect(kFlagPositive()).toStrictEqual([{ inlined: "true", separated: [] }]);
|
|
144
|
+
expect(kFlagNegative()).toStrictEqual([{ inlined: "false", separated: [] }]);
|
|
161
145
|
|
|
162
|
-
expect(
|
|
163
|
-
expect(
|
|
146
|
+
expect(kOptionUnset()).toStrictEqual([]);
|
|
147
|
+
expect(kOptionSplit()).toStrictEqual([
|
|
164
148
|
{ inlined: null, separated: ["1.1"] },
|
|
165
149
|
{ inlined: null, separated: ["1.2"] },
|
|
166
150
|
]);
|
|
167
|
-
expect(
|
|
151
|
+
expect(kOptionJoin()).toStrictEqual([
|
|
168
152
|
{ inlined: "2.1", separated: [] },
|
|
169
153
|
{ inlined: "2.2", separated: [] },
|
|
170
154
|
]);
|
|
171
155
|
|
|
172
|
-
expect(
|
|
173
|
-
|
|
174
|
-
]);
|
|
175
|
-
expect(stream.getOptionValues(kB)).toStrictEqual([
|
|
156
|
+
expect(kA()).toStrictEqual([{ inlined: null, separated: [] }]);
|
|
157
|
+
expect(kB()).toStrictEqual([
|
|
176
158
|
{ inlined: null, separated: ["3.1"] },
|
|
177
159
|
{ inlined: null, separated: ["3.2"] },
|
|
178
160
|
]);
|
|
179
161
|
|
|
180
|
-
expect(
|
|
181
|
-
|
|
182
|
-
]);
|
|
183
|
-
expect(stream.getOptionValues(kD)).toStrictEqual([
|
|
162
|
+
expect(kC()).toStrictEqual([{ inlined: null, separated: [] }]);
|
|
163
|
+
expect(kD()).toStrictEqual([
|
|
184
164
|
{ inlined: "4.1", separated: [] },
|
|
185
165
|
{ inlined: "4.2", separated: [] },
|
|
186
166
|
]);
|
|
187
167
|
|
|
188
|
-
expect(
|
|
189
|
-
|
|
190
|
-
]);
|
|
191
|
-
expect(stream.getOptionValues(kF)).toStrictEqual([
|
|
168
|
+
expect(kE()).toStrictEqual([{ inlined: null, separated: [] }]);
|
|
169
|
+
expect(kF()).toStrictEqual([
|
|
192
170
|
{ inlined: "5.1", separated: [] },
|
|
193
171
|
{ inlined: "5.2", separated: [] },
|
|
194
172
|
]);
|
|
195
173
|
|
|
196
|
-
expect(
|
|
197
|
-
|
|
198
|
-
]);
|
|
199
|
-
expect(stream.getOptionValues(kH)).toStrictEqual([
|
|
200
|
-
{ inlined: "FALSE", separated: [] },
|
|
201
|
-
]);
|
|
174
|
+
expect(kG()).toStrictEqual([{ inlined: null, separated: [] }]);
|
|
175
|
+
expect(kH()).toStrictEqual([{ inlined: "FALSE", separated: [] }]);
|
|
202
176
|
|
|
203
|
-
expect(
|
|
204
|
-
|
|
205
|
-
]);
|
|
206
|
-
expect(stream.getOptionValues(kJ)).toStrictEqual([
|
|
207
|
-
{ inlined: "TRUE", separated: [] },
|
|
208
|
-
]);
|
|
177
|
+
expect(kI()).toStrictEqual([{ inlined: null, separated: [] }]);
|
|
178
|
+
expect(kJ()).toStrictEqual([{ inlined: "TRUE", separated: [] }]);
|
|
209
179
|
});
|
|
210
180
|
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
const optionValueFixedUniqueParsing: ReaderOptionParsing = {
|
|
217
|
-
consumeShortGroup: true,
|
|
218
|
-
consumeNextArg: (inlined, separated) =>
|
|
219
|
-
inlined === null && separated.length === 0,
|
|
220
|
-
};
|
|
181
|
+
const optionFlagNextGuard: ReaderOptionNextGuard = () => false;
|
|
182
|
+
const optionValuedNextGuard: ReaderOptionNextGuard = (value) =>
|
|
183
|
+
value.inlined === null && value.separated.length === 0;
|
|
@@ -3,47 +3,35 @@ import { ReaderArgs } from "../src";
|
|
|
3
3
|
|
|
4
4
|
it("run", async function () {
|
|
5
5
|
const readerArgs1 = new ReaderArgs(["--val=1", "A", "B", "STOP", "C"]);
|
|
6
|
-
const kOptionVariadicStop = readerArgs1.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
consumeNextArg: (_inlined, separated, nextArg) =>
|
|
12
|
-
nextArg !== undefined && separated[separated.length - 1] !== "STOP",
|
|
13
|
-
},
|
|
6
|
+
const kOptionVariadicStop = readerArgs1.registerOptionLong({
|
|
7
|
+
key: "val",
|
|
8
|
+
nextGuard: (value, nextArg) =>
|
|
9
|
+
nextArg !== undefined &&
|
|
10
|
+
value.separated[value.separated.length - 1] !== "STOP",
|
|
14
11
|
});
|
|
15
12
|
expect(readerArgs1.consumePositional()).toStrictEqual("C");
|
|
16
13
|
expect(readerArgs1.consumePositional()).toStrictEqual(undefined);
|
|
17
|
-
expect(
|
|
14
|
+
expect(kOptionVariadicStop()).toStrictEqual([
|
|
18
15
|
{ inlined: "1", separated: ["A", "B", "STOP"] },
|
|
19
16
|
]);
|
|
20
17
|
|
|
21
18
|
const readerArgs2 = new ReaderArgs(["--val=1", "A", "B", "C"]);
|
|
22
|
-
const kOptionVariadicFull = readerArgs2.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
parsing: {
|
|
26
|
-
consumeShortGroup: true,
|
|
27
|
-
consumeNextArg: (_inlined, _separated, nextArg) => nextArg !== undefined,
|
|
28
|
-
},
|
|
19
|
+
const kOptionVariadicFull = readerArgs2.registerOptionLong({
|
|
20
|
+
key: "val",
|
|
21
|
+
nextGuard: (_value, nextArg) => nextArg !== undefined,
|
|
29
22
|
});
|
|
30
23
|
expect(readerArgs2.consumePositional()).toStrictEqual(undefined);
|
|
31
|
-
expect(
|
|
24
|
+
expect(kOptionVariadicFull()).toStrictEqual([
|
|
32
25
|
{ inlined: "1", separated: ["A", "B", "C"] },
|
|
33
26
|
]);
|
|
34
27
|
|
|
35
28
|
const readerArgs3 = new ReaderArgs(["--val=2", "A", "B", "--val=1", "C"]);
|
|
36
|
-
const kOptionVariadicKeyed = readerArgs3.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
parsing: {
|
|
40
|
-
consumeShortGroup: true,
|
|
41
|
-
consumeNextArg: (inlined, separated) =>
|
|
42
|
-
separated.length < Number(inlined ?? "0"),
|
|
43
|
-
},
|
|
29
|
+
const kOptionVariadicKeyed = readerArgs3.registerOptionLong({
|
|
30
|
+
key: "val",
|
|
31
|
+
nextGuard: (value) => value.separated.length < Number(value.inlined ?? "0"),
|
|
44
32
|
});
|
|
45
33
|
expect(readerArgs3.consumePositional()).toStrictEqual(undefined);
|
|
46
|
-
expect(
|
|
34
|
+
expect(kOptionVariadicKeyed()).toStrictEqual([
|
|
47
35
|
{ inlined: "2", separated: ["A", "B"] },
|
|
48
36
|
{ inlined: "1", separated: ["C"] },
|
|
49
37
|
]);
|