@optique/core 0.9.0-dev.224 → 0.9.0-dev.227
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/constructs.cjs +1332 -602
- package/dist/constructs.d.cts +182 -62
- package/dist/constructs.d.ts +182 -62
- package/dist/constructs.js +1332 -602
- package/dist/facade.cjs +188 -144
- package/dist/facade.d.cts +41 -3
- package/dist/facade.d.ts +41 -3
- package/dist/facade.js +187 -145
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/modifiers.cjs +228 -79
- package/dist/modifiers.d.cts +11 -6
- package/dist/modifiers.d.ts +11 -6
- package/dist/modifiers.js +228 -79
- package/dist/parser.cjs +217 -33
- package/dist/parser.d.cts +202 -18
- package/dist/parser.d.ts +202 -18
- package/dist/parser.js +212 -34
- package/dist/primitives.cjs +242 -97
- package/dist/primitives.d.cts +14 -10
- package/dist/primitives.d.ts +14 -10
- package/dist/primitives.js +242 -97
- package/dist/valueparser.cjs +10 -1
- package/dist/valueparser.d.cts +29 -16
- package/dist/valueparser.d.ts +29 -16
- package/dist/valueparser.js +10 -1
- package/package.json +1 -1
package/dist/primitives.cjs
CHANGED
|
@@ -13,6 +13,7 @@ function constant(value) {
|
|
|
13
13
|
return {
|
|
14
14
|
$valueType: [],
|
|
15
15
|
$stateType: [],
|
|
16
|
+
$mode: "sync",
|
|
16
17
|
priority: 0,
|
|
17
18
|
usage: [],
|
|
18
19
|
initialState: value,
|
|
@@ -37,6 +38,112 @@ function constant(value) {
|
|
|
37
38
|
}
|
|
38
39
|
};
|
|
39
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Internal sync helper for option suggest functionality.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix) {
|
|
46
|
+
if (hidden) return;
|
|
47
|
+
const equalsIndex = prefix.indexOf("=");
|
|
48
|
+
if (equalsIndex >= 0) {
|
|
49
|
+
const optionPart = prefix.slice(0, equalsIndex);
|
|
50
|
+
const valuePart = prefix.slice(equalsIndex + 1);
|
|
51
|
+
if (optionNames$1.includes(optionPart)) {
|
|
52
|
+
if (valueParser && valueParser.suggest) {
|
|
53
|
+
const valueSuggestions = valueParser.suggest(valuePart);
|
|
54
|
+
for (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
|
|
55
|
+
kind: "literal",
|
|
56
|
+
text: `${optionPart}=${suggestion.text}`,
|
|
57
|
+
description: suggestion.description
|
|
58
|
+
};
|
|
59
|
+
else yield {
|
|
60
|
+
kind: "literal",
|
|
61
|
+
text: `${optionPart}=${suggestion.pattern || ""}`,
|
|
62
|
+
description: suggestion.description
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
|
|
68
|
+
for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
|
|
69
|
+
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
70
|
+
yield {
|
|
71
|
+
kind: "literal",
|
|
72
|
+
text: optionName$1
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (valueParser && valueParser.suggest) {
|
|
77
|
+
let shouldSuggestValues = false;
|
|
78
|
+
if (context.buffer.length > 0) {
|
|
79
|
+
const lastToken = context.buffer[context.buffer.length - 1];
|
|
80
|
+
if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
|
|
81
|
+
} else if (context.state === void 0 && context.buffer.length === 0) shouldSuggestValues = true;
|
|
82
|
+
if (shouldSuggestValues) yield* valueParser.suggest(prefix);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Internal async helper for option suggest functionality.
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context, prefix) {
|
|
91
|
+
if (hidden) return;
|
|
92
|
+
const equalsIndex = prefix.indexOf("=");
|
|
93
|
+
if (equalsIndex >= 0) {
|
|
94
|
+
const optionPart = prefix.slice(0, equalsIndex);
|
|
95
|
+
const valuePart = prefix.slice(equalsIndex + 1);
|
|
96
|
+
if (optionNames$1.includes(optionPart)) {
|
|
97
|
+
if (valueParser && valueParser.suggest) {
|
|
98
|
+
const valueSuggestions = valueParser.suggest(valuePart);
|
|
99
|
+
for await (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
|
|
100
|
+
kind: "literal",
|
|
101
|
+
text: `${optionPart}=${suggestion.text}`,
|
|
102
|
+
description: suggestion.description
|
|
103
|
+
};
|
|
104
|
+
else yield {
|
|
105
|
+
kind: "literal",
|
|
106
|
+
text: `${optionPart}=${suggestion.pattern || ""}`,
|
|
107
|
+
description: suggestion.description
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
|
|
113
|
+
for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
|
|
114
|
+
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
115
|
+
yield {
|
|
116
|
+
kind: "literal",
|
|
117
|
+
text: optionName$1
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (valueParser && valueParser.suggest) {
|
|
122
|
+
let shouldSuggestValues = false;
|
|
123
|
+
if (context.buffer.length > 0) {
|
|
124
|
+
const lastToken = context.buffer[context.buffer.length - 1];
|
|
125
|
+
if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
|
|
126
|
+
} else if (context.state === void 0 && context.buffer.length === 0) shouldSuggestValues = true;
|
|
127
|
+
if (shouldSuggestValues) for await (const suggestion of valueParser.suggest(prefix)) yield suggestion;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Internal sync helper for argument suggest functionality.
|
|
133
|
+
* @internal
|
|
134
|
+
*/
|
|
135
|
+
function* suggestArgumentSync(valueParser, hidden, prefix) {
|
|
136
|
+
if (hidden) return;
|
|
137
|
+
if (valueParser.suggest) yield* valueParser.suggest(prefix);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Internal async helper for argument suggest functionality.
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
async function* suggestArgumentAsync(valueParser, hidden, prefix) {
|
|
144
|
+
if (hidden) return;
|
|
145
|
+
if (valueParser.suggest) for await (const suggestion of valueParser.suggest(prefix)) yield suggestion;
|
|
146
|
+
}
|
|
40
147
|
function option(...args) {
|
|
41
148
|
const lastArg = args.at(-1);
|
|
42
149
|
const secondLastArg = args.at(-2);
|
|
@@ -59,7 +166,10 @@ function option(...args) {
|
|
|
59
166
|
optionNames$1 = args;
|
|
60
167
|
valueParser = void 0;
|
|
61
168
|
}
|
|
62
|
-
|
|
169
|
+
const mode = valueParser?.$mode ?? "sync";
|
|
170
|
+
const isAsync = mode === "async";
|
|
171
|
+
const result = {
|
|
172
|
+
$mode: mode,
|
|
63
173
|
$valueType: [],
|
|
64
174
|
$stateType: [],
|
|
65
175
|
priority: 10,
|
|
@@ -105,7 +215,7 @@ function option(...args) {
|
|
|
105
215
|
consumed: context.buffer.slice(0, 1)
|
|
106
216
|
};
|
|
107
217
|
if (optionNames$1.includes(context.buffer[0])) {
|
|
108
|
-
if (context.state
|
|
218
|
+
if (context.state?.success && (valueParser != null || context.state.value)) return {
|
|
109
219
|
success: false,
|
|
110
220
|
consumed: 1,
|
|
111
221
|
error: options.errors?.duplicate ? typeof options.errors.duplicate === "function" ? options.errors.duplicate(context.buffer[0]) : options.errors.duplicate : require_message.message`${require_message.optionName(context.buffer[0])} cannot be used multiple times.`
|
|
@@ -127,12 +237,21 @@ function option(...args) {
|
|
|
127
237
|
consumed: 1,
|
|
128
238
|
error: require_message.message`Option ${require_message.optionName(context.buffer[0])} requires a value, but got no value.`
|
|
129
239
|
};
|
|
130
|
-
const
|
|
240
|
+
const parseResultOrPromise = valueParser.parse(context.buffer[1]);
|
|
241
|
+
if (isAsync) return parseResultOrPromise.then((parseResult) => ({
|
|
242
|
+
success: true,
|
|
243
|
+
next: {
|
|
244
|
+
...context,
|
|
245
|
+
state: parseResult,
|
|
246
|
+
buffer: context.buffer.slice(2)
|
|
247
|
+
},
|
|
248
|
+
consumed: context.buffer.slice(0, 2)
|
|
249
|
+
}));
|
|
131
250
|
return {
|
|
132
251
|
success: true,
|
|
133
252
|
next: {
|
|
134
253
|
...context,
|
|
135
|
-
state:
|
|
254
|
+
state: parseResultOrPromise,
|
|
136
255
|
buffer: context.buffer.slice(2)
|
|
137
256
|
},
|
|
138
257
|
consumed: context.buffer.slice(0, 2)
|
|
@@ -141,7 +260,7 @@ function option(...args) {
|
|
|
141
260
|
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/")).map((name) => name.startsWith("/") ? `${name}:` : `${name}=`);
|
|
142
261
|
for (const prefix of prefixes) {
|
|
143
262
|
if (!context.buffer[0].startsWith(prefix)) continue;
|
|
144
|
-
if (context.state
|
|
263
|
+
if (context.state?.success && (valueParser != null || context.state.value)) return {
|
|
145
264
|
success: false,
|
|
146
265
|
consumed: 1,
|
|
147
266
|
error: options.errors?.duplicate ? typeof options.errors.duplicate === "function" ? options.errors.duplicate(prefix) : options.errors.duplicate : require_message.message`${require_message.optionName(prefix)} cannot be used multiple times.`
|
|
@@ -152,12 +271,21 @@ function option(...args) {
|
|
|
152
271
|
consumed: 1,
|
|
153
272
|
error: options.errors?.unexpectedValue ? typeof options.errors.unexpectedValue === "function" ? options.errors.unexpectedValue(value) : options.errors.unexpectedValue : require_message.message`Option ${require_message.optionName(prefix)} is a Boolean flag, but got a value: ${value}.`
|
|
154
273
|
};
|
|
155
|
-
const
|
|
274
|
+
const parseResultOrPromise = valueParser.parse(value);
|
|
275
|
+
if (isAsync) return parseResultOrPromise.then((parseResult) => ({
|
|
276
|
+
success: true,
|
|
277
|
+
next: {
|
|
278
|
+
...context,
|
|
279
|
+
state: parseResult,
|
|
280
|
+
buffer: context.buffer.slice(1)
|
|
281
|
+
},
|
|
282
|
+
consumed: context.buffer.slice(0, 1)
|
|
283
|
+
}));
|
|
156
284
|
return {
|
|
157
285
|
success: true,
|
|
158
286
|
next: {
|
|
159
287
|
...context,
|
|
160
|
-
state:
|
|
288
|
+
state: parseResultOrPromise,
|
|
161
289
|
buffer: context.buffer.slice(1)
|
|
162
290
|
},
|
|
163
291
|
consumed: context.buffer.slice(0, 1)
|
|
@@ -167,7 +295,7 @@ function option(...args) {
|
|
|
167
295
|
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
168
296
|
for (const shortOption of shortOptions) {
|
|
169
297
|
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
170
|
-
if (context.state
|
|
298
|
+
if (context.state?.success && (valueParser != null || context.state.value)) return {
|
|
171
299
|
success: false,
|
|
172
300
|
consumed: 1,
|
|
173
301
|
error: options.errors?.duplicate ? typeof options.errors.duplicate === "function" ? options.errors.duplicate(shortOption) : options.errors.duplicate : require_message.message`${require_message.optionName(shortOption)} cannot be used multiple times.`
|
|
@@ -220,50 +348,8 @@ function option(...args) {
|
|
|
220
348
|
};
|
|
221
349
|
},
|
|
222
350
|
suggest(context, prefix) {
|
|
223
|
-
if (options.hidden
|
|
224
|
-
|
|
225
|
-
const equalsIndex = prefix.indexOf("=");
|
|
226
|
-
if (equalsIndex >= 0) {
|
|
227
|
-
const optionPart = prefix.slice(0, equalsIndex);
|
|
228
|
-
const valuePart = prefix.slice(equalsIndex + 1);
|
|
229
|
-
if (optionNames$1.includes(optionPart)) {
|
|
230
|
-
if (valueParser && valueParser.suggest) {
|
|
231
|
-
const valueSuggestions = valueParser.suggest(valuePart);
|
|
232
|
-
for (const suggestion of valueSuggestions) if (suggestion.kind === "literal") suggestions.push({
|
|
233
|
-
kind: "literal",
|
|
234
|
-
text: `${optionPart}=${suggestion.text}`,
|
|
235
|
-
description: suggestion.description
|
|
236
|
-
});
|
|
237
|
-
else suggestions.push({
|
|
238
|
-
kind: "literal",
|
|
239
|
-
text: `${optionPart}=${suggestion.pattern || ""}`,
|
|
240
|
-
description: suggestion.description
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
} else {
|
|
245
|
-
if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
|
|
246
|
-
for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
|
|
247
|
-
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
248
|
-
suggestions.push({
|
|
249
|
-
kind: "literal",
|
|
250
|
-
text: optionName$1
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
if (valueParser && valueParser.suggest) {
|
|
255
|
-
let shouldSuggestValues = false;
|
|
256
|
-
if (context.buffer.length > 0) {
|
|
257
|
-
const lastToken = context.buffer[context.buffer.length - 1];
|
|
258
|
-
if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
|
|
259
|
-
} else if (context.state === void 0 && context.buffer.length === 0) shouldSuggestValues = true;
|
|
260
|
-
if (shouldSuggestValues) {
|
|
261
|
-
const valueSuggestions = valueParser.suggest(prefix);
|
|
262
|
-
suggestions.push(...valueSuggestions);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
return suggestions;
|
|
351
|
+
if (isAsync) return suggestOptionAsync(optionNames$1, valueParser, options.hidden ?? false, context, prefix);
|
|
352
|
+
return suggestOptionSync(optionNames$1, valueParser, options.hidden ?? false, context, prefix);
|
|
267
353
|
},
|
|
268
354
|
getDocFragments(_state, defaultValue) {
|
|
269
355
|
if (options.hidden) return {
|
|
@@ -289,6 +375,7 @@ function option(...args) {
|
|
|
289
375
|
return `option(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
|
|
290
376
|
}
|
|
291
377
|
};
|
|
378
|
+
return result;
|
|
292
379
|
}
|
|
293
380
|
/**
|
|
294
381
|
* Creates a parser for command-line flags that must be explicitly provided.
|
|
@@ -332,6 +419,7 @@ function flag(...args) {
|
|
|
332
419
|
return {
|
|
333
420
|
$valueType: [],
|
|
334
421
|
$stateType: [],
|
|
422
|
+
$mode: "sync",
|
|
335
423
|
priority: 10,
|
|
336
424
|
usage: [{
|
|
337
425
|
type: "option",
|
|
@@ -483,6 +571,7 @@ function flag(...args) {
|
|
|
483
571
|
* Creates a parser that expects a single argument value.
|
|
484
572
|
* This parser is typically used for positional arguments
|
|
485
573
|
* that are not options or flags.
|
|
574
|
+
* @template M The execution mode of the parser.
|
|
486
575
|
* @template T The type of the value produced by the parser.
|
|
487
576
|
* @param valueParser The {@link ValueParser} that defines how to parse
|
|
488
577
|
* the argument value.
|
|
@@ -492,13 +581,15 @@ function flag(...args) {
|
|
|
492
581
|
* the parsed value of type {@link T}.
|
|
493
582
|
*/
|
|
494
583
|
function argument(valueParser, options = {}) {
|
|
584
|
+
const isAsync = valueParser.$mode === "async";
|
|
495
585
|
const optionPattern = /^--?[a-z0-9-]+$/i;
|
|
496
586
|
const term = {
|
|
497
587
|
type: "argument",
|
|
498
588
|
metavar: valueParser.metavar,
|
|
499
589
|
...options.hidden && { hidden: true }
|
|
500
590
|
};
|
|
501
|
-
|
|
591
|
+
const result = {
|
|
592
|
+
$mode: valueParser.$mode,
|
|
502
593
|
$valueType: [],
|
|
503
594
|
$stateType: [],
|
|
504
595
|
priority: 5,
|
|
@@ -532,13 +623,23 @@ function argument(valueParser, options = {}) {
|
|
|
532
623
|
consumed: i,
|
|
533
624
|
error: options.errors?.multiple ? typeof options.errors.multiple === "function" ? options.errors.multiple(valueParser.metavar) : options.errors.multiple : require_message.message`The argument ${require_message.metavar(valueParser.metavar)} cannot be used multiple times.`
|
|
534
625
|
};
|
|
535
|
-
const
|
|
626
|
+
const parseResultOrPromise = valueParser.parse(context.buffer[i]);
|
|
627
|
+
if (isAsync) return parseResultOrPromise.then((parseResult) => ({
|
|
628
|
+
success: true,
|
|
629
|
+
next: {
|
|
630
|
+
...context,
|
|
631
|
+
buffer: context.buffer.slice(i + 1),
|
|
632
|
+
state: parseResult,
|
|
633
|
+
optionsTerminated
|
|
634
|
+
},
|
|
635
|
+
consumed: context.buffer.slice(0, i + 1)
|
|
636
|
+
}));
|
|
536
637
|
return {
|
|
537
638
|
success: true,
|
|
538
639
|
next: {
|
|
539
640
|
...context,
|
|
540
641
|
buffer: context.buffer.slice(i + 1),
|
|
541
|
-
state:
|
|
642
|
+
state: parseResultOrPromise,
|
|
542
643
|
optionsTerminated
|
|
543
644
|
},
|
|
544
645
|
consumed: context.buffer.slice(0, i + 1)
|
|
@@ -556,13 +657,8 @@ function argument(valueParser, options = {}) {
|
|
|
556
657
|
};
|
|
557
658
|
},
|
|
558
659
|
suggest(_context, prefix) {
|
|
559
|
-
if (options.hidden
|
|
560
|
-
|
|
561
|
-
if (valueParser.suggest) {
|
|
562
|
-
const valueSuggestions = valueParser.suggest(prefix);
|
|
563
|
-
suggestions.push(...valueSuggestions);
|
|
564
|
-
}
|
|
565
|
-
return suggestions;
|
|
660
|
+
if (isAsync) return suggestArgumentAsync(valueParser, options.hidden ?? false, prefix);
|
|
661
|
+
return suggestArgumentSync(valueParser, options.hidden ?? false, prefix);
|
|
566
662
|
},
|
|
567
663
|
getDocFragments(_state, defaultValue) {
|
|
568
664
|
if (options.hidden) return {
|
|
@@ -584,11 +680,52 @@ function argument(valueParser, options = {}) {
|
|
|
584
680
|
return `argument()`;
|
|
585
681
|
}
|
|
586
682
|
};
|
|
683
|
+
return result;
|
|
684
|
+
}
|
|
685
|
+
function* suggestCommandSync(context, prefix, name, parser, options) {
|
|
686
|
+
if (options.hidden) return;
|
|
687
|
+
if (context.state === void 0) {
|
|
688
|
+
if (name.startsWith(prefix)) yield {
|
|
689
|
+
kind: "literal",
|
|
690
|
+
text: name,
|
|
691
|
+
...options.description && { description: options.description }
|
|
692
|
+
};
|
|
693
|
+
} else if (context.state[0] === "matched") yield* parser.suggest({
|
|
694
|
+
...context,
|
|
695
|
+
state: parser.initialState
|
|
696
|
+
}, prefix);
|
|
697
|
+
else if (context.state[0] === "parsing") yield* parser.suggest({
|
|
698
|
+
...context,
|
|
699
|
+
state: context.state[1]
|
|
700
|
+
}, prefix);
|
|
701
|
+
}
|
|
702
|
+
async function* suggestCommandAsync(context, prefix, name, parser, options) {
|
|
703
|
+
if (options.hidden) return;
|
|
704
|
+
if (context.state === void 0) {
|
|
705
|
+
if (name.startsWith(prefix)) yield {
|
|
706
|
+
kind: "literal",
|
|
707
|
+
text: name,
|
|
708
|
+
...options.description && { description: options.description }
|
|
709
|
+
};
|
|
710
|
+
} else if (context.state[0] === "matched") {
|
|
711
|
+
const suggestions = parser.suggest({
|
|
712
|
+
...context,
|
|
713
|
+
state: parser.initialState
|
|
714
|
+
}, prefix);
|
|
715
|
+
for await (const s of suggestions) yield s;
|
|
716
|
+
} else if (context.state[0] === "parsing") {
|
|
717
|
+
const suggestions = parser.suggest({
|
|
718
|
+
...context,
|
|
719
|
+
state: context.state[1]
|
|
720
|
+
}, prefix);
|
|
721
|
+
for await (const s of suggestions) yield s;
|
|
722
|
+
}
|
|
587
723
|
}
|
|
588
724
|
/**
|
|
589
725
|
* Creates a parser that matches a specific subcommand name and then applies
|
|
590
726
|
* an inner parser to the remaining arguments.
|
|
591
727
|
* This is useful for building CLI tools with subcommands like git, npm, etc.
|
|
728
|
+
* @template M The execution mode of the parser.
|
|
592
729
|
* @template T The type of the value returned by the inner parser.
|
|
593
730
|
* @template TState The type of the state used by the inner parser.
|
|
594
731
|
* @param name The subcommand name to match (e.g., `"show"`, `"edit"`).
|
|
@@ -599,7 +736,9 @@ function argument(valueParser, options = {}) {
|
|
|
599
736
|
* to the inner parser for the remaining arguments.
|
|
600
737
|
*/
|
|
601
738
|
function command(name, parser, options = {}) {
|
|
602
|
-
|
|
739
|
+
const isAsync = parser.$mode === "async";
|
|
740
|
+
const result = {
|
|
741
|
+
$mode: parser.$mode,
|
|
603
742
|
$valueType: [],
|
|
604
743
|
$stateType: [],
|
|
605
744
|
priority: 15,
|
|
@@ -646,33 +785,57 @@ function command(name, parser, options = {}) {
|
|
|
646
785
|
consumed: context.buffer.slice(0, 1)
|
|
647
786
|
};
|
|
648
787
|
} else if (context.state[0] === "matched") {
|
|
649
|
-
const
|
|
788
|
+
const parseResultOrPromise = parser.parse({
|
|
650
789
|
...context,
|
|
651
790
|
state: parser.initialState
|
|
652
791
|
});
|
|
653
|
-
if (
|
|
792
|
+
if (isAsync) return parseResultOrPromise.then((parseResult$1) => {
|
|
793
|
+
if (parseResult$1.success) return {
|
|
794
|
+
success: true,
|
|
795
|
+
next: {
|
|
796
|
+
...parseResult$1.next,
|
|
797
|
+
state: ["parsing", parseResult$1.next.state]
|
|
798
|
+
},
|
|
799
|
+
consumed: parseResult$1.consumed
|
|
800
|
+
};
|
|
801
|
+
return parseResult$1;
|
|
802
|
+
});
|
|
803
|
+
const parseResult = parseResultOrPromise;
|
|
804
|
+
if (parseResult.success) return {
|
|
654
805
|
success: true,
|
|
655
806
|
next: {
|
|
656
|
-
...
|
|
657
|
-
state: ["parsing",
|
|
807
|
+
...parseResult.next,
|
|
808
|
+
state: ["parsing", parseResult.next.state]
|
|
658
809
|
},
|
|
659
|
-
consumed:
|
|
810
|
+
consumed: parseResult.consumed
|
|
660
811
|
};
|
|
661
|
-
return
|
|
812
|
+
return parseResult;
|
|
662
813
|
} else if (context.state[0] === "parsing") {
|
|
663
|
-
const
|
|
814
|
+
const parseResultOrPromise = parser.parse({
|
|
664
815
|
...context,
|
|
665
816
|
state: context.state[1]
|
|
666
817
|
});
|
|
667
|
-
if (
|
|
818
|
+
if (isAsync) return parseResultOrPromise.then((parseResult$1) => {
|
|
819
|
+
if (parseResult$1.success) return {
|
|
820
|
+
success: true,
|
|
821
|
+
next: {
|
|
822
|
+
...parseResult$1.next,
|
|
823
|
+
state: ["parsing", parseResult$1.next.state]
|
|
824
|
+
},
|
|
825
|
+
consumed: parseResult$1.consumed
|
|
826
|
+
};
|
|
827
|
+
return parseResult$1;
|
|
828
|
+
});
|
|
829
|
+
const parseResult = parseResultOrPromise;
|
|
830
|
+
if (parseResult.success) return {
|
|
668
831
|
success: true,
|
|
669
832
|
next: {
|
|
670
|
-
...
|
|
671
|
-
state: ["parsing",
|
|
833
|
+
...parseResult.next,
|
|
834
|
+
state: ["parsing", parseResult.next.state]
|
|
672
835
|
},
|
|
673
|
-
consumed:
|
|
836
|
+
consumed: parseResult.consumed
|
|
674
837
|
};
|
|
675
|
-
return
|
|
838
|
+
return parseResult;
|
|
676
839
|
}
|
|
677
840
|
return {
|
|
678
841
|
success: false,
|
|
@@ -693,28 +856,8 @@ function command(name, parser, options = {}) {
|
|
|
693
856
|
};
|
|
694
857
|
},
|
|
695
858
|
suggest(context, prefix) {
|
|
696
|
-
if (
|
|
697
|
-
|
|
698
|
-
if (context.state === void 0) {
|
|
699
|
-
if (name.startsWith(prefix)) suggestions.push({
|
|
700
|
-
kind: "literal",
|
|
701
|
-
text: name,
|
|
702
|
-
...options.description && { description: options.description }
|
|
703
|
-
});
|
|
704
|
-
} else if (context.state[0] === "matched") {
|
|
705
|
-
const innerSuggestions = parser.suggest({
|
|
706
|
-
...context,
|
|
707
|
-
state: parser.initialState
|
|
708
|
-
}, prefix);
|
|
709
|
-
suggestions.push(...innerSuggestions);
|
|
710
|
-
} else if (context.state[0] === "parsing") {
|
|
711
|
-
const innerSuggestions = parser.suggest({
|
|
712
|
-
...context,
|
|
713
|
-
state: context.state[1]
|
|
714
|
-
}, prefix);
|
|
715
|
-
suggestions.push(...innerSuggestions);
|
|
716
|
-
}
|
|
717
|
-
return suggestions;
|
|
859
|
+
if (isAsync) return suggestCommandAsync(context, prefix, name, parser, options);
|
|
860
|
+
return suggestCommandSync(context, prefix, name, parser, options);
|
|
718
861
|
},
|
|
719
862
|
getDocFragments(state, defaultValue) {
|
|
720
863
|
if (options.hidden) return {
|
|
@@ -750,6 +893,7 @@ function command(name, parser, options = {}) {
|
|
|
750
893
|
return `command(${JSON.stringify(name)})`;
|
|
751
894
|
}
|
|
752
895
|
};
|
|
896
|
+
return result;
|
|
753
897
|
}
|
|
754
898
|
/**
|
|
755
899
|
* Creates a parser that collects unrecognized options and passes them through.
|
|
@@ -804,6 +948,7 @@ function passThrough(options = {}) {
|
|
|
804
948
|
return {
|
|
805
949
|
$valueType: [],
|
|
806
950
|
$stateType: [],
|
|
951
|
+
$mode: "sync",
|
|
807
952
|
priority: -10,
|
|
808
953
|
usage: [{
|
|
809
954
|
type: "passthrough",
|
package/dist/primitives.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Message } from "./message.cjs";
|
|
2
2
|
import { OptionName } from "./usage.cjs";
|
|
3
3
|
import { ValueParser, ValueParserResult } from "./valueparser.cjs";
|
|
4
|
-
import { Parser } from "./parser.cjs";
|
|
4
|
+
import { Mode, Parser } from "./parser.cjs";
|
|
5
5
|
|
|
6
6
|
//#region src/primitives.d.ts
|
|
7
7
|
|
|
@@ -10,7 +10,7 @@ import { Parser } from "./parser.cjs";
|
|
|
10
10
|
* produces a constant value of the type {@link T}.
|
|
11
11
|
* @template T The type of the constant value produced by the parser.
|
|
12
12
|
*/
|
|
13
|
-
declare function constant<const T>(value: T): Parser<T, T>;
|
|
13
|
+
declare function constant<const T>(value: T): Parser<"sync", T, T>;
|
|
14
14
|
/**
|
|
15
15
|
* Options for the {@link option} parser.
|
|
16
16
|
*/
|
|
@@ -78,6 +78,7 @@ interface OptionErrorOptions {
|
|
|
78
78
|
/**
|
|
79
79
|
* Creates a parser for various styles of command-line options that take an
|
|
80
80
|
* argument value, such as `--option=value`, `-o value`, or `/option:value`.
|
|
81
|
+
* @template M The execution mode of the parser.
|
|
81
82
|
* @template T The type of value this parser produces.
|
|
82
83
|
* @param args The {@link OptionName}s to parse, followed by
|
|
83
84
|
* a {@link ValueParser} that defines how to parse the value of
|
|
@@ -86,10 +87,11 @@ interface OptionErrorOptions {
|
|
|
86
87
|
* @returns A {@link Parser} that can parse the specified options and their
|
|
87
88
|
* values.
|
|
88
89
|
*/
|
|
89
|
-
declare function option<T>(...args: readonly [...readonly OptionName[], ValueParser<T>]): Parser<T, ValueParserResult<T> | undefined>;
|
|
90
|
+
declare function option<M extends Mode, T>(...args: readonly [...readonly OptionName[], ValueParser<M, T>]): Parser<M, T, ValueParserResult<T> | undefined>;
|
|
90
91
|
/**
|
|
91
92
|
* Creates a parser for various styles of command-line options that take an
|
|
92
93
|
* argument value, such as `--option=value`, `-o value`, or `/option:value`.
|
|
94
|
+
* @template M The execution mode of the parser.
|
|
93
95
|
* @template T The type of value this parser produces.
|
|
94
96
|
* @param args The {@link OptionName}s to parse, followed by
|
|
95
97
|
* a {@link ValueParser} that defines how to parse the value of
|
|
@@ -98,7 +100,7 @@ declare function option<T>(...args: readonly [...readonly OptionName[], ValuePar
|
|
|
98
100
|
* @returns A {@link Parser} that can parse the specified options and their
|
|
99
101
|
* values.
|
|
100
102
|
*/
|
|
101
|
-
declare function option<T>(...args: readonly [...readonly OptionName[], ValueParser<T>, OptionOptions]): Parser<T, ValueParserResult<T> | undefined>;
|
|
103
|
+
declare function option<M extends Mode, T>(...args: readonly [...readonly OptionName[], ValueParser<M, T>, OptionOptions]): Parser<M, T, ValueParserResult<T> | undefined>;
|
|
102
104
|
/**
|
|
103
105
|
* Creates a parser for various styles of command-line options that do not
|
|
104
106
|
* take an argument value, such as `--option`, `-o`, or `/option`.
|
|
@@ -106,7 +108,7 @@ declare function option<T>(...args: readonly [...readonly OptionName[], ValuePar
|
|
|
106
108
|
* @return A {@link Parser} that can parse the specified options as Boolean
|
|
107
109
|
* flags, producing `true` if the option is present.
|
|
108
110
|
*/
|
|
109
|
-
declare function option(...optionNames: readonly OptionName[]): Parser<boolean, ValueParserResult<boolean> | undefined>;
|
|
111
|
+
declare function option(...optionNames: readonly OptionName[]): Parser<"sync", boolean, ValueParserResult<boolean> | undefined>;
|
|
110
112
|
/**
|
|
111
113
|
* Creates a parser for various styles of command-line options that take an
|
|
112
114
|
* argument value, such as `--option=value`, `-o value`, or `/option:value`.
|
|
@@ -116,7 +118,7 @@ declare function option(...optionNames: readonly OptionName[]): Parser<boolean,
|
|
|
116
118
|
* @returns A {@link Parser} that can parse the specified options and their
|
|
117
119
|
* values.
|
|
118
120
|
*/
|
|
119
|
-
declare function option(...args: readonly [...readonly OptionName[], OptionOptions]): Parser<boolean, ValueParserResult<boolean> | undefined>;
|
|
121
|
+
declare function option(...args: readonly [...readonly OptionName[], OptionOptions]): Parser<"sync", boolean, ValueParserResult<boolean> | undefined>;
|
|
120
122
|
/**
|
|
121
123
|
* Options for the {@link flag} parser.
|
|
122
124
|
*/
|
|
@@ -202,7 +204,7 @@ interface FlagErrorOptions {
|
|
|
202
204
|
* });
|
|
203
205
|
* ```
|
|
204
206
|
*/
|
|
205
|
-
declare function flag(...args: readonly [...readonly OptionName[], FlagOptions] | readonly OptionName[]): Parser<true, ValueParserResult<true> | undefined>;
|
|
207
|
+
declare function flag(...args: readonly [...readonly OptionName[], FlagOptions] | readonly OptionName[]): Parser<"sync", true, ValueParserResult<true> | undefined>;
|
|
206
208
|
/**
|
|
207
209
|
* Options for the {@link argument} parser.
|
|
208
210
|
*/
|
|
@@ -248,6 +250,7 @@ interface ArgumentErrorOptions {
|
|
|
248
250
|
* Creates a parser that expects a single argument value.
|
|
249
251
|
* This parser is typically used for positional arguments
|
|
250
252
|
* that are not options or flags.
|
|
253
|
+
* @template M The execution mode of the parser.
|
|
251
254
|
* @template T The type of the value produced by the parser.
|
|
252
255
|
* @param valueParser The {@link ValueParser} that defines how to parse
|
|
253
256
|
* the argument value.
|
|
@@ -256,7 +259,7 @@ interface ArgumentErrorOptions {
|
|
|
256
259
|
* @returns A {@link Parser} that expects a single argument value and produces
|
|
257
260
|
* the parsed value of type {@link T}.
|
|
258
261
|
*/
|
|
259
|
-
declare function argument<T>(valueParser: ValueParser<T>, options?: ArgumentOptions): Parser<T, ValueParserResult<T> | undefined>;
|
|
262
|
+
declare function argument<M extends Mode, T>(valueParser: ValueParser<M, T>, options?: ArgumentOptions): Parser<M, T, ValueParserResult<T> | undefined>;
|
|
260
263
|
/**
|
|
261
264
|
* Options for the {@link command} parser.
|
|
262
265
|
* @since 0.5.0
|
|
@@ -325,6 +328,7 @@ type CommandState<TState> = undefined | ["matched", string] | ["parsing", TState
|
|
|
325
328
|
* Creates a parser that matches a specific subcommand name and then applies
|
|
326
329
|
* an inner parser to the remaining arguments.
|
|
327
330
|
* This is useful for building CLI tools with subcommands like git, npm, etc.
|
|
331
|
+
* @template M The execution mode of the parser.
|
|
328
332
|
* @template T The type of the value returned by the inner parser.
|
|
329
333
|
* @template TState The type of the state used by the inner parser.
|
|
330
334
|
* @param name The subcommand name to match (e.g., `"show"`, `"edit"`).
|
|
@@ -334,7 +338,7 @@ type CommandState<TState> = undefined | ["matched", string] | ["parsing", TState
|
|
|
334
338
|
* @returns A {@link Parser} that matches the command name and delegates
|
|
335
339
|
* to the inner parser for the remaining arguments.
|
|
336
340
|
*/
|
|
337
|
-
declare function command<T, TState>(name: string, parser: Parser<T, TState>, options?: CommandOptions): Parser<T, CommandState<TState>>;
|
|
341
|
+
declare function command<M extends Mode, T, TState>(name: string, parser: Parser<M, T, TState>, options?: CommandOptions): Parser<M, T, CommandState<TState>>;
|
|
338
342
|
/**
|
|
339
343
|
* Format options for how {@link passThrough} captures options.
|
|
340
344
|
* @since 0.8.0
|
|
@@ -417,6 +421,6 @@ interface PassThroughOptions {
|
|
|
417
421
|
*
|
|
418
422
|
* @since 0.8.0
|
|
419
423
|
*/
|
|
420
|
-
declare function passThrough(options?: PassThroughOptions): Parser<readonly string[], readonly string[]>;
|
|
424
|
+
declare function passThrough(options?: PassThroughOptions): Parser<"sync", readonly string[], readonly string[]>;
|
|
421
425
|
//#endregion
|
|
422
426
|
export { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, PassThroughFormat, PassThroughOptions, argument, command, constant, flag, option, passThrough };
|