@optique/core 0.10.7-dev.485 → 1.0.0-dev.1109
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 +4 -6
- package/dist/annotations.cjs +209 -1
- package/dist/annotations.d.cts +78 -1
- package/dist/annotations.d.ts +78 -1
- package/dist/annotations.js +201 -1
- package/dist/completion.cjs +186 -50
- package/dist/completion.js +186 -50
- package/dist/constructs.cjs +310 -78
- package/dist/constructs.d.cts +525 -644
- package/dist/constructs.d.ts +525 -644
- package/dist/constructs.js +311 -79
- package/dist/context.cjs +43 -3
- package/dist/context.d.cts +113 -5
- package/dist/context.d.ts +113 -5
- package/dist/context.js +41 -3
- package/dist/dependency.cjs +172 -66
- package/dist/dependency.d.cts +22 -2
- package/dist/dependency.d.ts +22 -2
- package/dist/dependency.js +172 -66
- package/dist/doc.cjs +46 -1
- package/dist/doc.d.cts +24 -0
- package/dist/doc.d.ts +24 -0
- package/dist/doc.js +46 -1
- package/dist/facade.cjs +702 -322
- package/dist/facade.d.cts +124 -190
- package/dist/facade.d.ts +124 -190
- package/dist/facade.js +703 -323
- package/dist/index.cjs +5 -0
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/message.cjs +7 -4
- package/dist/message.js +7 -4
- package/dist/mode-dispatch.cjs +23 -1
- package/dist/mode-dispatch.d.cts +55 -0
- package/dist/mode-dispatch.d.ts +55 -0
- package/dist/mode-dispatch.js +21 -1
- package/dist/modifiers.cjs +210 -55
- package/dist/modifiers.js +211 -56
- package/dist/parser.cjs +80 -47
- package/dist/parser.d.cts +18 -3
- package/dist/parser.d.ts +18 -3
- package/dist/parser.js +82 -50
- package/dist/primitives.cjs +102 -37
- package/dist/primitives.d.cts +81 -24
- package/dist/primitives.d.ts +81 -24
- package/dist/primitives.js +103 -39
- package/dist/usage.cjs +88 -6
- package/dist/usage.d.cts +51 -13
- package/dist/usage.d.ts +51 -13
- package/dist/usage.js +85 -7
- package/dist/valueparser.cjs +371 -99
- package/dist/valueparser.d.cts +56 -7
- package/dist/valueparser.d.ts +56 -7
- package/dist/valueparser.js +371 -99
- package/package.json +10 -1
package/dist/parser.cjs
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
const require_annotations = require('./annotations.cjs');
|
|
2
2
|
const require_message = require('./message.cjs');
|
|
3
|
+
const require_mode_dispatch = require('./mode-dispatch.cjs');
|
|
3
4
|
const require_usage = require('./usage.cjs');
|
|
4
5
|
const require_constructs = require('./constructs.cjs');
|
|
5
6
|
const require_modifiers = require('./modifiers.cjs');
|
|
6
7
|
const require_primitives = require('./primitives.cjs');
|
|
7
8
|
|
|
8
9
|
//#region src/parser.ts
|
|
10
|
+
function injectAnnotationsIntoState(state, options) {
|
|
11
|
+
const annotations = options?.annotations;
|
|
12
|
+
if (annotations == null) return state;
|
|
13
|
+
return require_annotations.injectAnnotations(state, annotations);
|
|
14
|
+
}
|
|
9
15
|
/**
|
|
10
16
|
* Parses an array of command-line arguments using the provided combined parser.
|
|
11
17
|
* This function processes the input arguments, applying the parser to each
|
|
@@ -29,11 +35,8 @@ const require_primitives = require('./primitives.cjs');
|
|
|
29
35
|
* @since 0.10.0 Added optional `options` parameter for annotations support.
|
|
30
36
|
*/
|
|
31
37
|
function parseSync(parser, args, options) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
...typeof initialState === "object" ? initialState : {},
|
|
35
|
-
[require_annotations.annotationKey]: options.annotations
|
|
36
|
-
};
|
|
38
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
39
|
+
const shouldUnwrapAnnotatedValue = options?.annotations != null || require_annotations.isInjectedAnnotationWrapper(parser.initialState);
|
|
37
40
|
let context = {
|
|
38
41
|
buffer: args,
|
|
39
42
|
optionsTerminated: false,
|
|
@@ -56,7 +59,7 @@ function parseSync(parser, args, options) {
|
|
|
56
59
|
const endResult = parser.complete(context.state);
|
|
57
60
|
return endResult.success ? {
|
|
58
61
|
success: true,
|
|
59
|
-
value: endResult.value
|
|
62
|
+
value: shouldUnwrapAnnotatedValue ? require_annotations.unwrapInjectedAnnotationWrapper(endResult.value) : endResult.value
|
|
60
63
|
} : {
|
|
61
64
|
success: false,
|
|
62
65
|
error: endResult.error
|
|
@@ -82,11 +85,8 @@ function parseSync(parser, args, options) {
|
|
|
82
85
|
* @since 0.10.0 Added optional `options` parameter for annotations support.
|
|
83
86
|
*/
|
|
84
87
|
async function parseAsync(parser, args, options) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
...typeof initialState === "object" ? initialState : {},
|
|
88
|
-
[require_annotations.annotationKey]: options.annotations
|
|
89
|
-
};
|
|
88
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
89
|
+
const shouldUnwrapAnnotatedValue = options?.annotations != null || require_annotations.isInjectedAnnotationWrapper(parser.initialState);
|
|
90
90
|
let context = {
|
|
91
91
|
buffer: args,
|
|
92
92
|
optionsTerminated: false,
|
|
@@ -109,7 +109,7 @@ async function parseAsync(parser, args, options) {
|
|
|
109
109
|
const endResult = await parser.complete(context.state);
|
|
110
110
|
return endResult.success ? {
|
|
111
111
|
success: true,
|
|
112
|
-
value: endResult.value
|
|
112
|
+
value: shouldUnwrapAnnotatedValue ? require_annotations.unwrapInjectedAnnotationWrapper(endResult.value) : endResult.value
|
|
113
113
|
} : {
|
|
114
114
|
success: false,
|
|
115
115
|
error: endResult.error
|
|
@@ -138,8 +138,7 @@ async function parseAsync(parser, args, options) {
|
|
|
138
138
|
* @since 0.10.0 Added optional `options` parameter for annotations support.
|
|
139
139
|
*/
|
|
140
140
|
function parse(parser, args, options) {
|
|
141
|
-
|
|
142
|
-
return parseSync(parser, args, options);
|
|
141
|
+
return require_mode_dispatch.dispatchByMode(parser.$mode, () => parseSync(parser, args, options), () => parseAsync(parser, args, options));
|
|
143
142
|
}
|
|
144
143
|
/**
|
|
145
144
|
* Generates command-line suggestions based on current parsing state.
|
|
@@ -180,11 +179,7 @@ function parse(parser, args, options) {
|
|
|
180
179
|
function suggestSync(parser, args, options) {
|
|
181
180
|
const allButLast = args.slice(0, -1);
|
|
182
181
|
const prefix = args[args.length - 1];
|
|
183
|
-
|
|
184
|
-
if (options?.annotations && initialState != null) initialState = {
|
|
185
|
-
...typeof initialState === "object" ? initialState : {},
|
|
186
|
-
[require_annotations.annotationKey]: options.annotations
|
|
187
|
-
};
|
|
182
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
188
183
|
let context = {
|
|
189
184
|
buffer: allButLast,
|
|
190
185
|
optionsTerminated: false,
|
|
@@ -223,11 +218,7 @@ function suggestSync(parser, args, options) {
|
|
|
223
218
|
async function suggestAsync(parser, args, options) {
|
|
224
219
|
const allButLast = args.slice(0, -1);
|
|
225
220
|
const prefix = args[args.length - 1];
|
|
226
|
-
|
|
227
|
-
if (options?.annotations && initialState != null) initialState = {
|
|
228
|
-
...typeof initialState === "object" ? initialState : {},
|
|
229
|
-
[require_annotations.annotationKey]: options.annotations
|
|
230
|
-
};
|
|
221
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
231
222
|
let context = {
|
|
232
223
|
buffer: allButLast,
|
|
233
224
|
optionsTerminated: false,
|
|
@@ -273,8 +264,7 @@ async function suggestAsync(parser, args, options) {
|
|
|
273
264
|
* @since 0.10.0 Added optional `options` parameter for annotations support.
|
|
274
265
|
*/
|
|
275
266
|
function suggest(parser, args, options) {
|
|
276
|
-
|
|
277
|
-
return suggestSync(parser, args, options);
|
|
267
|
+
return require_mode_dispatch.dispatchByMode(parser.$mode, () => suggestSync(parser, args, options), () => suggestAsync(parser, args, options));
|
|
278
268
|
}
|
|
279
269
|
/**
|
|
280
270
|
* Recursively searches for a command within nested exclusive usage terms.
|
|
@@ -339,11 +329,7 @@ function getDocPage(parser, args = [], options) {
|
|
|
339
329
|
* Internal sync implementation of getDocPage.
|
|
340
330
|
*/
|
|
341
331
|
function getDocPageSyncImpl(parser, args, options) {
|
|
342
|
-
|
|
343
|
-
if (options?.annotations && initialState != null) initialState = {
|
|
344
|
-
...typeof initialState === "object" ? initialState : {},
|
|
345
|
-
[require_annotations.annotationKey]: options.annotations
|
|
346
|
-
};
|
|
332
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
347
333
|
let context = {
|
|
348
334
|
buffer: args,
|
|
349
335
|
optionsTerminated: false,
|
|
@@ -361,11 +347,7 @@ function getDocPageSyncImpl(parser, args, options) {
|
|
|
361
347
|
* Internal async implementation of getDocPage.
|
|
362
348
|
*/
|
|
363
349
|
async function getDocPageAsyncImpl(parser, args, options) {
|
|
364
|
-
|
|
365
|
-
if (options?.annotations && initialState != null) initialState = {
|
|
366
|
-
...typeof initialState === "object" ? initialState : {},
|
|
367
|
-
[require_annotations.annotationKey]: options.annotations
|
|
368
|
-
};
|
|
350
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
369
351
|
let context = {
|
|
370
352
|
buffer: args,
|
|
371
353
|
optionsTerminated: false,
|
|
@@ -384,29 +366,79 @@ async function getDocPageAsyncImpl(parser, args, options) {
|
|
|
384
366
|
* Shared by both sync and async implementations.
|
|
385
367
|
*/
|
|
386
368
|
function buildDocPage(parser, context, args) {
|
|
387
|
-
|
|
369
|
+
let effectiveArgs = args;
|
|
370
|
+
let { brief, description, fragments, footer } = parser.getDocFragments({
|
|
388
371
|
kind: "available",
|
|
389
372
|
state: context.state
|
|
390
373
|
}, void 0);
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
374
|
+
if (args.length === 0 && Reflect.get(parser, Symbol.for("@optique/core/commandParser")) === true && fragments.length === 1 && fragments[0].type === "entry" && fragments[0].term.type === "command") {
|
|
375
|
+
const cmdName = fragments[0].term.name;
|
|
376
|
+
const matched = parser.getDocFragments({
|
|
377
|
+
kind: "available",
|
|
378
|
+
state: ["matched", cmdName]
|
|
379
|
+
}, void 0);
|
|
380
|
+
({brief, description, fragments, footer} = matched);
|
|
381
|
+
effectiveArgs = [cmdName];
|
|
397
382
|
}
|
|
398
|
-
|
|
383
|
+
const buildingSections = [];
|
|
384
|
+
let untitledSection = null;
|
|
385
|
+
const titledSectionMap = /* @__PURE__ */ new Map();
|
|
386
|
+
for (const fragment of fragments) if (fragment.type === "entry") {
|
|
387
|
+
if (untitledSection == null) {
|
|
388
|
+
untitledSection = { entries: [] };
|
|
389
|
+
buildingSections.push(untitledSection);
|
|
390
|
+
}
|
|
391
|
+
untitledSection.entries.push(fragment);
|
|
392
|
+
} else if (fragment.type === "section") if (fragment.title == null) {
|
|
393
|
+
if (untitledSection == null) {
|
|
394
|
+
untitledSection = { entries: [] };
|
|
395
|
+
buildingSections.push(untitledSection);
|
|
396
|
+
}
|
|
397
|
+
untitledSection.entries.push(...fragment.entries);
|
|
398
|
+
} else {
|
|
399
|
+
let section = titledSectionMap.get(fragment.title);
|
|
400
|
+
if (section == null) {
|
|
401
|
+
section = {
|
|
402
|
+
title: fragment.title,
|
|
403
|
+
entries: []
|
|
404
|
+
};
|
|
405
|
+
titledSectionMap.set(fragment.title, section);
|
|
406
|
+
buildingSections.push(section);
|
|
407
|
+
}
|
|
408
|
+
section.entries.push(...fragment.entries);
|
|
409
|
+
}
|
|
410
|
+
const sections = buildingSections;
|
|
399
411
|
const usage = [...require_usage.normalizeUsage(parser.usage)];
|
|
412
|
+
const maybeApplyCommandUsageLine = (term, arg, isLastArg, usageIndex) => {
|
|
413
|
+
if (term?.type !== "command" || term.name !== arg || !isLastArg || term.usageLine == null) return;
|
|
414
|
+
const defaultUsageLine = usage.slice(usageIndex + 1);
|
|
415
|
+
const customUsageLine = typeof term.usageLine === "function" ? term.usageLine(defaultUsageLine) : term.usageLine;
|
|
416
|
+
const normalizedCustomUsageLine = require_usage.normalizeUsage(customUsageLine);
|
|
417
|
+
usage.splice(usageIndex + 1, usage.length - (usageIndex + 1), ...normalizedCustomUsageLine);
|
|
418
|
+
};
|
|
400
419
|
let i = 0;
|
|
401
|
-
for (
|
|
420
|
+
for (let argIndex = 0; argIndex < effectiveArgs.length; argIndex++) {
|
|
421
|
+
const arg = effectiveArgs[argIndex];
|
|
402
422
|
if (i >= usage.length) break;
|
|
403
|
-
|
|
423
|
+
let term = usage[i];
|
|
404
424
|
if (term.type === "exclusive") {
|
|
405
425
|
const found = findCommandInExclusive(term, arg);
|
|
406
|
-
if (found)
|
|
426
|
+
if (found) {
|
|
427
|
+
usage.splice(i, 1, ...found);
|
|
428
|
+
term = usage[i];
|
|
429
|
+
}
|
|
407
430
|
}
|
|
431
|
+
maybeApplyCommandUsageLine(term, arg, argIndex === effectiveArgs.length - 1, i);
|
|
408
432
|
i++;
|
|
409
433
|
}
|
|
434
|
+
if (effectiveArgs.length === 0 && usage.length > 0) {
|
|
435
|
+
const first = usage[0];
|
|
436
|
+
if (first.type === "command" && first.usageLine != null) {
|
|
437
|
+
const defaultUsageLine = usage.slice(1);
|
|
438
|
+
const customUsageLine = typeof first.usageLine === "function" ? first.usageLine(defaultUsageLine) : first.usageLine;
|
|
439
|
+
usage.splice(1, usage.length - 1, ...require_usage.normalizeUsage(customUsageLine));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
410
442
|
return {
|
|
411
443
|
usage,
|
|
412
444
|
sections,
|
|
@@ -424,6 +456,7 @@ exports.command = require_primitives.command;
|
|
|
424
456
|
exports.concat = require_constructs.concat;
|
|
425
457
|
exports.conditional = require_constructs.conditional;
|
|
426
458
|
exports.constant = require_primitives.constant;
|
|
459
|
+
exports.fail = require_primitives.fail;
|
|
427
460
|
exports.flag = require_primitives.flag;
|
|
428
461
|
exports.getDocPage = getDocPage;
|
|
429
462
|
exports.getDocPageAsync = getDocPageAsync;
|
package/dist/parser.d.cts
CHANGED
|
@@ -4,9 +4,9 @@ import { Usage } from "./usage.cjs";
|
|
|
4
4
|
import { DocFragments, DocPage } from "./doc.cjs";
|
|
5
5
|
import { DependencyRegistryLike } from "./registry-types.cjs";
|
|
6
6
|
import { ValueParserResult } from "./valueparser.cjs";
|
|
7
|
-
import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
|
|
7
|
+
import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
|
|
8
8
|
import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.cjs";
|
|
9
|
-
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, flag, option, passThrough } from "./primitives.cjs";
|
|
9
|
+
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, fail, flag, option, passThrough } from "./primitives.cjs";
|
|
10
10
|
|
|
11
11
|
//#region src/parser.d.ts
|
|
12
12
|
|
|
@@ -158,6 +158,21 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
158
158
|
* fragments for this parser.
|
|
159
159
|
*/
|
|
160
160
|
getDocFragments(state: DocState<TState>, defaultValue?: TValue): DocFragments;
|
|
161
|
+
/**
|
|
162
|
+
* Optional predicate that determines whether completion should be
|
|
163
|
+
* deferred for the given parser state.
|
|
164
|
+
*
|
|
165
|
+
* When present, combinator wrappers ({@link optional}, {@link withDefault},
|
|
166
|
+
* {@link group}) forward this field to the outer parser. This enables
|
|
167
|
+
* packages like *\@optique/inquirer* to detect when interactive prompting
|
|
168
|
+
* should be deferred until an outer context (like a configuration file
|
|
169
|
+
* source) has resolved.
|
|
170
|
+
*
|
|
171
|
+
* @param state The current parser state.
|
|
172
|
+
* @returns `true` if completion should be deferred.
|
|
173
|
+
* @since 1.0.0
|
|
174
|
+
*/
|
|
175
|
+
shouldDeferCompletion?(state: TState): boolean;
|
|
161
176
|
}
|
|
162
177
|
/**
|
|
163
178
|
* The context of the parser, which includes the input buffer and the state.
|
|
@@ -534,4 +549,4 @@ declare function getDocPage(parser: Parser<"sync", unknown, unknown>, args?: rea
|
|
|
534
549
|
declare function getDocPage(parser: Parser<"async", unknown, unknown>, args?: readonly string[], options?: ParseOptions): Promise<DocPage | undefined>;
|
|
535
550
|
declare function getDocPage<M extends Mode>(parser: Parser<M, unknown, unknown>, args?: readonly string[], options?: ParseOptions): ModeValue<M, DocPage | undefined>;
|
|
536
551
|
//#endregion
|
|
537
|
-
export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, FlagErrorOptions, FlagOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
|
|
552
|
+
export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, FlagErrorOptions, FlagOptions, GroupOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
|
package/dist/parser.d.ts
CHANGED
|
@@ -4,9 +4,9 @@ import { Usage } from "./usage.js";
|
|
|
4
4
|
import { DocFragments, DocPage } from "./doc.js";
|
|
5
5
|
import { DependencyRegistryLike } from "./registry-types.js";
|
|
6
6
|
import { ValueParserResult } from "./valueparser.js";
|
|
7
|
-
import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
7
|
+
import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
8
8
|
import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
|
|
9
|
-
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, flag, option, passThrough } from "./primitives.js";
|
|
9
|
+
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, fail, flag, option, passThrough } from "./primitives.js";
|
|
10
10
|
|
|
11
11
|
//#region src/parser.d.ts
|
|
12
12
|
|
|
@@ -158,6 +158,21 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
158
158
|
* fragments for this parser.
|
|
159
159
|
*/
|
|
160
160
|
getDocFragments(state: DocState<TState>, defaultValue?: TValue): DocFragments;
|
|
161
|
+
/**
|
|
162
|
+
* Optional predicate that determines whether completion should be
|
|
163
|
+
* deferred for the given parser state.
|
|
164
|
+
*
|
|
165
|
+
* When present, combinator wrappers ({@link optional}, {@link withDefault},
|
|
166
|
+
* {@link group}) forward this field to the outer parser. This enables
|
|
167
|
+
* packages like *\@optique/inquirer* to detect when interactive prompting
|
|
168
|
+
* should be deferred until an outer context (like a configuration file
|
|
169
|
+
* source) has resolved.
|
|
170
|
+
*
|
|
171
|
+
* @param state The current parser state.
|
|
172
|
+
* @returns `true` if completion should be deferred.
|
|
173
|
+
* @since 1.0.0
|
|
174
|
+
*/
|
|
175
|
+
shouldDeferCompletion?(state: TState): boolean;
|
|
161
176
|
}
|
|
162
177
|
/**
|
|
163
178
|
* The context of the parser, which includes the input buffer and the state.
|
|
@@ -534,4 +549,4 @@ declare function getDocPage(parser: Parser<"sync", unknown, unknown>, args?: rea
|
|
|
534
549
|
declare function getDocPage(parser: Parser<"async", unknown, unknown>, args?: readonly string[], options?: ParseOptions): Promise<DocPage | undefined>;
|
|
535
550
|
declare function getDocPage<M extends Mode>(parser: Parser<M, unknown, unknown>, args?: readonly string[], options?: ParseOptions): ModeValue<M, DocPage | undefined>;
|
|
536
551
|
//#endregion
|
|
537
|
-
export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, FlagErrorOptions, FlagOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
|
|
552
|
+
export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, FlagErrorOptions, FlagOptions, GroupOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
|
package/dist/parser.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
|
|
2
2
|
import { message } from "./message.js";
|
|
3
|
+
import { dispatchByMode } from "./mode-dispatch.js";
|
|
3
4
|
import { normalizeUsage } from "./usage.js";
|
|
4
5
|
import { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
5
6
|
import { WithDefaultError, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
|
|
6
|
-
import { argument, command, constant, flag, option, passThrough } from "./primitives.js";
|
|
7
|
+
import { argument, command, constant, fail, flag, option, passThrough } from "./primitives.js";
|
|
7
8
|
|
|
8
9
|
//#region src/parser.ts
|
|
10
|
+
function injectAnnotationsIntoState(state, options) {
|
|
11
|
+
const annotations = options?.annotations;
|
|
12
|
+
if (annotations == null) return state;
|
|
13
|
+
return injectAnnotations(state, annotations);
|
|
14
|
+
}
|
|
9
15
|
/**
|
|
10
16
|
* Parses an array of command-line arguments using the provided combined parser.
|
|
11
17
|
* This function processes the input arguments, applying the parser to each
|
|
@@ -29,11 +35,8 @@ import { argument, command, constant, flag, option, passThrough } from "./primit
|
|
|
29
35
|
* @since 0.10.0 Added optional `options` parameter for annotations support.
|
|
30
36
|
*/
|
|
31
37
|
function parseSync(parser, args, options) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
...typeof initialState === "object" ? initialState : {},
|
|
35
|
-
[annotationKey]: options.annotations
|
|
36
|
-
};
|
|
38
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
39
|
+
const shouldUnwrapAnnotatedValue = options?.annotations != null || isInjectedAnnotationWrapper(parser.initialState);
|
|
37
40
|
let context = {
|
|
38
41
|
buffer: args,
|
|
39
42
|
optionsTerminated: false,
|
|
@@ -56,7 +59,7 @@ function parseSync(parser, args, options) {
|
|
|
56
59
|
const endResult = parser.complete(context.state);
|
|
57
60
|
return endResult.success ? {
|
|
58
61
|
success: true,
|
|
59
|
-
value: endResult.value
|
|
62
|
+
value: shouldUnwrapAnnotatedValue ? unwrapInjectedAnnotationWrapper(endResult.value) : endResult.value
|
|
60
63
|
} : {
|
|
61
64
|
success: false,
|
|
62
65
|
error: endResult.error
|
|
@@ -82,11 +85,8 @@ function parseSync(parser, args, options) {
|
|
|
82
85
|
* @since 0.10.0 Added optional `options` parameter for annotations support.
|
|
83
86
|
*/
|
|
84
87
|
async function parseAsync(parser, args, options) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
...typeof initialState === "object" ? initialState : {},
|
|
88
|
-
[annotationKey]: options.annotations
|
|
89
|
-
};
|
|
88
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
89
|
+
const shouldUnwrapAnnotatedValue = options?.annotations != null || isInjectedAnnotationWrapper(parser.initialState);
|
|
90
90
|
let context = {
|
|
91
91
|
buffer: args,
|
|
92
92
|
optionsTerminated: false,
|
|
@@ -109,7 +109,7 @@ async function parseAsync(parser, args, options) {
|
|
|
109
109
|
const endResult = await parser.complete(context.state);
|
|
110
110
|
return endResult.success ? {
|
|
111
111
|
success: true,
|
|
112
|
-
value: endResult.value
|
|
112
|
+
value: shouldUnwrapAnnotatedValue ? unwrapInjectedAnnotationWrapper(endResult.value) : endResult.value
|
|
113
113
|
} : {
|
|
114
114
|
success: false,
|
|
115
115
|
error: endResult.error
|
|
@@ -138,8 +138,7 @@ async function parseAsync(parser, args, options) {
|
|
|
138
138
|
* @since 0.10.0 Added optional `options` parameter for annotations support.
|
|
139
139
|
*/
|
|
140
140
|
function parse(parser, args, options) {
|
|
141
|
-
|
|
142
|
-
return parseSync(parser, args, options);
|
|
141
|
+
return dispatchByMode(parser.$mode, () => parseSync(parser, args, options), () => parseAsync(parser, args, options));
|
|
143
142
|
}
|
|
144
143
|
/**
|
|
145
144
|
* Generates command-line suggestions based on current parsing state.
|
|
@@ -180,11 +179,7 @@ function parse(parser, args, options) {
|
|
|
180
179
|
function suggestSync(parser, args, options) {
|
|
181
180
|
const allButLast = args.slice(0, -1);
|
|
182
181
|
const prefix = args[args.length - 1];
|
|
183
|
-
|
|
184
|
-
if (options?.annotations && initialState != null) initialState = {
|
|
185
|
-
...typeof initialState === "object" ? initialState : {},
|
|
186
|
-
[annotationKey]: options.annotations
|
|
187
|
-
};
|
|
182
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
188
183
|
let context = {
|
|
189
184
|
buffer: allButLast,
|
|
190
185
|
optionsTerminated: false,
|
|
@@ -223,11 +218,7 @@ function suggestSync(parser, args, options) {
|
|
|
223
218
|
async function suggestAsync(parser, args, options) {
|
|
224
219
|
const allButLast = args.slice(0, -1);
|
|
225
220
|
const prefix = args[args.length - 1];
|
|
226
|
-
|
|
227
|
-
if (options?.annotations && initialState != null) initialState = {
|
|
228
|
-
...typeof initialState === "object" ? initialState : {},
|
|
229
|
-
[annotationKey]: options.annotations
|
|
230
|
-
};
|
|
221
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
231
222
|
let context = {
|
|
232
223
|
buffer: allButLast,
|
|
233
224
|
optionsTerminated: false,
|
|
@@ -273,8 +264,7 @@ async function suggestAsync(parser, args, options) {
|
|
|
273
264
|
* @since 0.10.0 Added optional `options` parameter for annotations support.
|
|
274
265
|
*/
|
|
275
266
|
function suggest(parser, args, options) {
|
|
276
|
-
|
|
277
|
-
return suggestSync(parser, args, options);
|
|
267
|
+
return dispatchByMode(parser.$mode, () => suggestSync(parser, args, options), () => suggestAsync(parser, args, options));
|
|
278
268
|
}
|
|
279
269
|
/**
|
|
280
270
|
* Recursively searches for a command within nested exclusive usage terms.
|
|
@@ -339,11 +329,7 @@ function getDocPage(parser, args = [], options) {
|
|
|
339
329
|
* Internal sync implementation of getDocPage.
|
|
340
330
|
*/
|
|
341
331
|
function getDocPageSyncImpl(parser, args, options) {
|
|
342
|
-
|
|
343
|
-
if (options?.annotations && initialState != null) initialState = {
|
|
344
|
-
...typeof initialState === "object" ? initialState : {},
|
|
345
|
-
[annotationKey]: options.annotations
|
|
346
|
-
};
|
|
332
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
347
333
|
let context = {
|
|
348
334
|
buffer: args,
|
|
349
335
|
optionsTerminated: false,
|
|
@@ -361,11 +347,7 @@ function getDocPageSyncImpl(parser, args, options) {
|
|
|
361
347
|
* Internal async implementation of getDocPage.
|
|
362
348
|
*/
|
|
363
349
|
async function getDocPageAsyncImpl(parser, args, options) {
|
|
364
|
-
|
|
365
|
-
if (options?.annotations && initialState != null) initialState = {
|
|
366
|
-
...typeof initialState === "object" ? initialState : {},
|
|
367
|
-
[annotationKey]: options.annotations
|
|
368
|
-
};
|
|
350
|
+
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
369
351
|
let context = {
|
|
370
352
|
buffer: args,
|
|
371
353
|
optionsTerminated: false,
|
|
@@ -384,29 +366,79 @@ async function getDocPageAsyncImpl(parser, args, options) {
|
|
|
384
366
|
* Shared by both sync and async implementations.
|
|
385
367
|
*/
|
|
386
368
|
function buildDocPage(parser, context, args) {
|
|
387
|
-
|
|
369
|
+
let effectiveArgs = args;
|
|
370
|
+
let { brief, description, fragments, footer } = parser.getDocFragments({
|
|
388
371
|
kind: "available",
|
|
389
372
|
state: context.state
|
|
390
373
|
}, void 0);
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
374
|
+
if (args.length === 0 && Reflect.get(parser, Symbol.for("@optique/core/commandParser")) === true && fragments.length === 1 && fragments[0].type === "entry" && fragments[0].term.type === "command") {
|
|
375
|
+
const cmdName = fragments[0].term.name;
|
|
376
|
+
const matched = parser.getDocFragments({
|
|
377
|
+
kind: "available",
|
|
378
|
+
state: ["matched", cmdName]
|
|
379
|
+
}, void 0);
|
|
380
|
+
({brief, description, fragments, footer} = matched);
|
|
381
|
+
effectiveArgs = [cmdName];
|
|
397
382
|
}
|
|
398
|
-
|
|
383
|
+
const buildingSections = [];
|
|
384
|
+
let untitledSection = null;
|
|
385
|
+
const titledSectionMap = /* @__PURE__ */ new Map();
|
|
386
|
+
for (const fragment of fragments) if (fragment.type === "entry") {
|
|
387
|
+
if (untitledSection == null) {
|
|
388
|
+
untitledSection = { entries: [] };
|
|
389
|
+
buildingSections.push(untitledSection);
|
|
390
|
+
}
|
|
391
|
+
untitledSection.entries.push(fragment);
|
|
392
|
+
} else if (fragment.type === "section") if (fragment.title == null) {
|
|
393
|
+
if (untitledSection == null) {
|
|
394
|
+
untitledSection = { entries: [] };
|
|
395
|
+
buildingSections.push(untitledSection);
|
|
396
|
+
}
|
|
397
|
+
untitledSection.entries.push(...fragment.entries);
|
|
398
|
+
} else {
|
|
399
|
+
let section = titledSectionMap.get(fragment.title);
|
|
400
|
+
if (section == null) {
|
|
401
|
+
section = {
|
|
402
|
+
title: fragment.title,
|
|
403
|
+
entries: []
|
|
404
|
+
};
|
|
405
|
+
titledSectionMap.set(fragment.title, section);
|
|
406
|
+
buildingSections.push(section);
|
|
407
|
+
}
|
|
408
|
+
section.entries.push(...fragment.entries);
|
|
409
|
+
}
|
|
410
|
+
const sections = buildingSections;
|
|
399
411
|
const usage = [...normalizeUsage(parser.usage)];
|
|
412
|
+
const maybeApplyCommandUsageLine = (term, arg, isLastArg, usageIndex) => {
|
|
413
|
+
if (term?.type !== "command" || term.name !== arg || !isLastArg || term.usageLine == null) return;
|
|
414
|
+
const defaultUsageLine = usage.slice(usageIndex + 1);
|
|
415
|
+
const customUsageLine = typeof term.usageLine === "function" ? term.usageLine(defaultUsageLine) : term.usageLine;
|
|
416
|
+
const normalizedCustomUsageLine = normalizeUsage(customUsageLine);
|
|
417
|
+
usage.splice(usageIndex + 1, usage.length - (usageIndex + 1), ...normalizedCustomUsageLine);
|
|
418
|
+
};
|
|
400
419
|
let i = 0;
|
|
401
|
-
for (
|
|
420
|
+
for (let argIndex = 0; argIndex < effectiveArgs.length; argIndex++) {
|
|
421
|
+
const arg = effectiveArgs[argIndex];
|
|
402
422
|
if (i >= usage.length) break;
|
|
403
|
-
|
|
423
|
+
let term = usage[i];
|
|
404
424
|
if (term.type === "exclusive") {
|
|
405
425
|
const found = findCommandInExclusive(term, arg);
|
|
406
|
-
if (found)
|
|
426
|
+
if (found) {
|
|
427
|
+
usage.splice(i, 1, ...found);
|
|
428
|
+
term = usage[i];
|
|
429
|
+
}
|
|
407
430
|
}
|
|
431
|
+
maybeApplyCommandUsageLine(term, arg, argIndex === effectiveArgs.length - 1, i);
|
|
408
432
|
i++;
|
|
409
433
|
}
|
|
434
|
+
if (effectiveArgs.length === 0 && usage.length > 0) {
|
|
435
|
+
const first = usage[0];
|
|
436
|
+
if (first.type === "command" && first.usageLine != null) {
|
|
437
|
+
const defaultUsageLine = usage.slice(1);
|
|
438
|
+
const customUsageLine = typeof first.usageLine === "function" ? first.usageLine(defaultUsageLine) : first.usageLine;
|
|
439
|
+
usage.splice(1, usage.length - 1, ...normalizeUsage(customUsageLine));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
410
442
|
return {
|
|
411
443
|
usage,
|
|
412
444
|
sections,
|
|
@@ -417,4 +449,4 @@ function buildDocPage(parser, context, args) {
|
|
|
417
449
|
}
|
|
418
450
|
|
|
419
451
|
//#endregion
|
|
420
|
-
export { DuplicateOptionError, WithDefaultError, argument, command, concat, conditional, constant, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
|
|
452
|
+
export { DuplicateOptionError, WithDefaultError, argument, command, concat, conditional, constant, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
|