@optique/core 1.1.8 → 1.1.10
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 +260 -40
- package/dist/constructs.js +260 -40
- package/dist/displaywidth.cjs +13 -1
- package/dist/displaywidth.d.cts +10 -1
- package/dist/displaywidth.d.ts +10 -1
- package/dist/displaywidth.js +12 -1
- package/dist/doc.cjs +8 -4
- package/dist/doc.js +8 -4
- package/dist/extension.cjs +17 -0
- package/dist/extension.d.cts +13 -1
- package/dist/extension.d.ts +13 -1
- package/dist/extension.js +17 -1
- package/dist/internal/passthrough.cjs +230 -0
- package/dist/internal/passthrough.js +213 -0
- package/dist/message.cjs +32 -6
- package/dist/message.js +33 -7
- package/dist/modifiers.cjs +22 -0
- package/dist/modifiers.js +22 -0
- package/dist/primitives.cjs +47 -10
- package/dist/primitives.js +47 -10
- package/dist/suggestion.cjs +3 -1
- package/dist/suggestion.js +3 -1
- package/package.json +2 -2
package/dist/displaywidth.cjs
CHANGED
|
@@ -16,6 +16,17 @@ function getDisplayWidth(text) {
|
|
|
16
16
|
for (const { segment } of segmenter.segment(stripped)) width += graphemeWidth(segment);
|
|
17
17
|
return width;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Removes ANSI escape sequences (CSI and OSC) from a string, leaving only
|
|
21
|
+
* the text a terminal would print.
|
|
22
|
+
*
|
|
23
|
+
* @param text The string to strip.
|
|
24
|
+
* @returns The string without ANSI escape sequences.
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
function stripAnsi(text) {
|
|
28
|
+
return text.replace(ansiRegex, "");
|
|
29
|
+
}
|
|
19
30
|
const zeroWidthRegex = /^[\p{Cf}\p{Mn}\p{Me}]+$/u;
|
|
20
31
|
const emojiPresentationRegex = /\p{Emoji_Presentation}/u;
|
|
21
32
|
const emojiWithVS16Regex = /\p{Emoji}\uFE0F/u;
|
|
@@ -41,4 +52,5 @@ function isEastAsianWide(cp) {
|
|
|
41
52
|
}
|
|
42
53
|
|
|
43
54
|
//#endregion
|
|
44
|
-
exports.getDisplayWidth = getDisplayWidth;
|
|
55
|
+
exports.getDisplayWidth = getDisplayWidth;
|
|
56
|
+
exports.stripAnsi = stripAnsi;
|
package/dist/displaywidth.d.cts
CHANGED
|
@@ -8,5 +8,14 @@
|
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
10
|
declare function getDisplayWidth(text: string): number;
|
|
11
|
+
/**
|
|
12
|
+
* Removes ANSI escape sequences (CSI and OSC) from a string, leaving only
|
|
13
|
+
* the text a terminal would print.
|
|
14
|
+
*
|
|
15
|
+
* @param text The string to strip.
|
|
16
|
+
* @returns The string without ANSI escape sequences.
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
declare function stripAnsi(text: string): string;
|
|
11
20
|
//#endregion
|
|
12
|
-
export { getDisplayWidth };
|
|
21
|
+
export { getDisplayWidth, stripAnsi };
|
package/dist/displaywidth.d.ts
CHANGED
|
@@ -8,5 +8,14 @@
|
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
10
|
declare function getDisplayWidth(text: string): number;
|
|
11
|
+
/**
|
|
12
|
+
* Removes ANSI escape sequences (CSI and OSC) from a string, leaving only
|
|
13
|
+
* the text a terminal would print.
|
|
14
|
+
*
|
|
15
|
+
* @param text The string to strip.
|
|
16
|
+
* @returns The string without ANSI escape sequences.
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
declare function stripAnsi(text: string): string;
|
|
11
20
|
//#endregion
|
|
12
|
-
export { getDisplayWidth };
|
|
21
|
+
export { getDisplayWidth, stripAnsi };
|
package/dist/displaywidth.js
CHANGED
|
@@ -15,6 +15,17 @@ function getDisplayWidth(text) {
|
|
|
15
15
|
for (const { segment } of segmenter.segment(stripped)) width += graphemeWidth(segment);
|
|
16
16
|
return width;
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Removes ANSI escape sequences (CSI and OSC) from a string, leaving only
|
|
20
|
+
* the text a terminal would print.
|
|
21
|
+
*
|
|
22
|
+
* @param text The string to strip.
|
|
23
|
+
* @returns The string without ANSI escape sequences.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
function stripAnsi(text) {
|
|
27
|
+
return text.replace(ansiRegex, "");
|
|
28
|
+
}
|
|
18
29
|
const zeroWidthRegex = /^[\p{Cf}\p{Mn}\p{Me}]+$/u;
|
|
19
30
|
const emojiPresentationRegex = /\p{Emoji_Presentation}/u;
|
|
20
31
|
const emojiWithVS16Regex = /\p{Emoji}\uFE0F/u;
|
|
@@ -40,4 +51,4 @@ function isEastAsianWide(cp) {
|
|
|
40
51
|
}
|
|
41
52
|
|
|
42
53
|
//#endregion
|
|
43
|
-
export { getDisplayWidth };
|
|
54
|
+
export { getDisplayWidth, stripAnsi };
|
package/dist/doc.cjs
CHANGED
|
@@ -341,13 +341,15 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
341
341
|
const suffix = typeof options.showDefault === "object" ? options.showDefault.suffix ?? "]" : "]";
|
|
342
342
|
const prefixWidth = require_displaywidth.getDisplayWidth(prefix);
|
|
343
343
|
const suffixWidth = require_displaywidth.getDisplayWidth(suffix);
|
|
344
|
+
let defaultPrefix = prefix;
|
|
344
345
|
let defaultStartWidth;
|
|
345
346
|
if (descColumnWidth != null) {
|
|
346
347
|
const lastW = lastLineVisibleLength(description);
|
|
347
348
|
const effectiveLastW = lastW + currentExtraOffset();
|
|
348
349
|
if (effectiveLastW + prefixWidth >= descColumnWidth) {
|
|
349
350
|
description += "\n";
|
|
350
|
-
|
|
351
|
+
defaultPrefix = prefix.trimStart();
|
|
352
|
+
defaultStartWidth = require_displaywidth.getDisplayWidth(defaultPrefix);
|
|
351
353
|
} else defaultStartWidth = effectiveLastW + prefixWidth;
|
|
352
354
|
}
|
|
353
355
|
const defaultFormatOptions = {
|
|
@@ -357,7 +359,7 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
357
359
|
startWidth: defaultStartWidth
|
|
358
360
|
};
|
|
359
361
|
const defaultContent = require_message.formatMessage(entry.default, defaultFormatOptions);
|
|
360
|
-
const defaultText = `${
|
|
362
|
+
const defaultText = `${defaultPrefix}${defaultContent}${suffix}`;
|
|
361
363
|
const formattedDefault = options.colors ? `\x1b[2m${defaultText}\x1b[0m` : defaultText;
|
|
362
364
|
description += formattedDefault;
|
|
363
365
|
}
|
|
@@ -385,6 +387,7 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
385
387
|
const choicesPrefixWidth = require_displaywidth.getDisplayWidth(prefix);
|
|
386
388
|
const choicesSuffixWidth = require_displaywidth.getDisplayWidth(suffix);
|
|
387
389
|
const choicesLabelWidth = require_displaywidth.getDisplayWidth(label);
|
|
390
|
+
let choicesHeading = `${prefix}${label}`;
|
|
388
391
|
let choicesStartWidth;
|
|
389
392
|
if (descColumnWidth != null) {
|
|
390
393
|
const lastW = lastLineVisibleLength(description);
|
|
@@ -392,7 +395,8 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
392
395
|
const prefixLabelLen = choicesPrefixWidth + choicesLabelWidth;
|
|
393
396
|
if (effectiveLastW + prefixLabelLen >= descColumnWidth) {
|
|
394
397
|
description += "\n";
|
|
395
|
-
|
|
398
|
+
choicesHeading = choicesHeading.trimStart();
|
|
399
|
+
choicesStartWidth = require_displaywidth.getDisplayWidth(choicesHeading);
|
|
396
400
|
} else choicesStartWidth = effectiveLastW + prefixLabelLen;
|
|
397
401
|
}
|
|
398
402
|
const choicesFormatOptions = {
|
|
@@ -402,7 +406,7 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
402
406
|
startWidth: choicesStartWidth
|
|
403
407
|
};
|
|
404
408
|
const choicesDisplay = require_message.formatMessage(truncatedTerms, choicesFormatOptions);
|
|
405
|
-
const choicesText = `${
|
|
409
|
+
const choicesText = `${choicesHeading}${choicesDisplay}${suffix}`;
|
|
406
410
|
const formattedChoices = options.colors ? `\x1b[2m${choicesText}\x1b[0m` : choicesText;
|
|
407
411
|
description += formattedChoices;
|
|
408
412
|
}
|
package/dist/doc.js
CHANGED
|
@@ -341,13 +341,15 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
341
341
|
const suffix = typeof options.showDefault === "object" ? options.showDefault.suffix ?? "]" : "]";
|
|
342
342
|
const prefixWidth = getDisplayWidth(prefix);
|
|
343
343
|
const suffixWidth = getDisplayWidth(suffix);
|
|
344
|
+
let defaultPrefix = prefix;
|
|
344
345
|
let defaultStartWidth;
|
|
345
346
|
if (descColumnWidth != null) {
|
|
346
347
|
const lastW = lastLineVisibleLength(description);
|
|
347
348
|
const effectiveLastW = lastW + currentExtraOffset();
|
|
348
349
|
if (effectiveLastW + prefixWidth >= descColumnWidth) {
|
|
349
350
|
description += "\n";
|
|
350
|
-
|
|
351
|
+
defaultPrefix = prefix.trimStart();
|
|
352
|
+
defaultStartWidth = getDisplayWidth(defaultPrefix);
|
|
351
353
|
} else defaultStartWidth = effectiveLastW + prefixWidth;
|
|
352
354
|
}
|
|
353
355
|
const defaultFormatOptions = {
|
|
@@ -357,7 +359,7 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
357
359
|
startWidth: defaultStartWidth
|
|
358
360
|
};
|
|
359
361
|
const defaultContent = formatMessage(entry.default, defaultFormatOptions);
|
|
360
|
-
const defaultText = `${
|
|
362
|
+
const defaultText = `${defaultPrefix}${defaultContent}${suffix}`;
|
|
361
363
|
const formattedDefault = options.colors ? `\x1b[2m${defaultText}\x1b[0m` : defaultText;
|
|
362
364
|
description += formattedDefault;
|
|
363
365
|
}
|
|
@@ -385,6 +387,7 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
385
387
|
const choicesPrefixWidth = getDisplayWidth(prefix);
|
|
386
388
|
const choicesSuffixWidth = getDisplayWidth(suffix);
|
|
387
389
|
const choicesLabelWidth = getDisplayWidth(label);
|
|
390
|
+
let choicesHeading = `${prefix}${label}`;
|
|
388
391
|
let choicesStartWidth;
|
|
389
392
|
if (descColumnWidth != null) {
|
|
390
393
|
const lastW = lastLineVisibleLength(description);
|
|
@@ -392,7 +395,8 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
392
395
|
const prefixLabelLen = choicesPrefixWidth + choicesLabelWidth;
|
|
393
396
|
if (effectiveLastW + prefixLabelLen >= descColumnWidth) {
|
|
394
397
|
description += "\n";
|
|
395
|
-
|
|
398
|
+
choicesHeading = choicesHeading.trimStart();
|
|
399
|
+
choicesStartWidth = getDisplayWidth(choicesHeading);
|
|
396
400
|
} else choicesStartWidth = effectiveLastW + prefixLabelLen;
|
|
397
401
|
}
|
|
398
402
|
const choicesFormatOptions = {
|
|
@@ -402,7 +406,7 @@ function formatDocPage(programName, page, options = {}) {
|
|
|
402
406
|
startWidth: choicesStartWidth
|
|
403
407
|
};
|
|
404
408
|
const choicesDisplay = formatMessage(truncatedTerms, choicesFormatOptions);
|
|
405
|
-
const choicesText = `${
|
|
409
|
+
const choicesText = `${choicesHeading}${choicesDisplay}${suffix}`;
|
|
406
410
|
const formattedChoices = options.colors ? `\x1b[2m${choicesText}\x1b[0m` : choicesText;
|
|
407
411
|
description += formattedChoices;
|
|
408
412
|
}
|
package/dist/extension.cjs
CHANGED
|
@@ -2,6 +2,7 @@ const require_internal_annotations = require('./internal/annotations.cjs');
|
|
|
2
2
|
const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
|
|
3
3
|
const require_internal_parser = require('./internal/parser.cjs');
|
|
4
4
|
const require_annotation_state = require('./annotation-state.cjs');
|
|
5
|
+
const require_passthrough = require('./internal/passthrough.cjs');
|
|
5
6
|
|
|
6
7
|
//#region src/extension.ts
|
|
7
8
|
const emptyTraits = Object.freeze({});
|
|
@@ -71,9 +72,25 @@ function delegateSuggestNodes(innerParser, outerParser, state, path, innerState,
|
|
|
71
72
|
function mapSourceMetadata(parser, mapSource) {
|
|
72
73
|
return require_internal_parser.composeWrappedSourceMetadata(parser.dependencyMetadata, mapSource);
|
|
73
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Delegates CLI option matching and capture priority through a parser wrapper.
|
|
77
|
+
* Use the same child-state projection as the wrapper's parse method. This
|
|
78
|
+
* preserves selected command options without changing public leading names.
|
|
79
|
+
*
|
|
80
|
+
* @param wrapper The parser being constructed.
|
|
81
|
+
* @param inner Its wrapped CLI parser.
|
|
82
|
+
* @param getInnerState Projects the wrapper state to the CLI parser state.
|
|
83
|
+
* @throws {TypeError} If metadata cannot be defined on the wrapper.
|
|
84
|
+
* @since 1.0.11
|
|
85
|
+
*/
|
|
86
|
+
function delegateOptionParsing(wrapper, inner, getInnerState) {
|
|
87
|
+
require_passthrough.defineOptionMatch(wrapper, (state, token) => require_passthrough.getOptionMatch(inner, getInnerState(state), token));
|
|
88
|
+
require_passthrough.definePassThroughPriority(wrapper, [inner], (state, token) => require_passthrough.getPassThroughPriority(inner, getInnerState(state), token));
|
|
89
|
+
}
|
|
74
90
|
|
|
75
91
|
//#endregion
|
|
76
92
|
exports.defineTraits = defineTraits;
|
|
93
|
+
exports.delegateOptionParsing = delegateOptionParsing;
|
|
77
94
|
exports.delegateSuggestNodes = delegateSuggestNodes;
|
|
78
95
|
exports.dispatchByMode = require_mode_dispatch.dispatchByMode;
|
|
79
96
|
exports.getTraits = getTraits;
|
package/dist/extension.d.cts
CHANGED
|
@@ -93,5 +93,17 @@ declare function delegateSuggestNodes<TInnerState>(innerParser: Parser<Mode, unk
|
|
|
93
93
|
* @since 1.0.0
|
|
94
94
|
*/
|
|
95
95
|
declare function mapSourceMetadata<M extends Mode, TValue, TState>(parser: Pick<Parser<M, TValue, TState>, "dependencyMetadata">, mapSource: (source: ParserSourceMetadata<M, TValue, TState>) => ParserSourceMetadata<M, TValue, TState>): Parser<M, TValue, TState>["dependencyMetadata"] | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* Delegates CLI option matching and capture priority through a parser wrapper.
|
|
98
|
+
* Use the same child-state projection as the wrapper's parse method. This
|
|
99
|
+
* preserves selected command options without changing public leading names.
|
|
100
|
+
*
|
|
101
|
+
* @param wrapper The parser being constructed.
|
|
102
|
+
* @param inner Its wrapped CLI parser.
|
|
103
|
+
* @param getInnerState Projects the wrapper state to the CLI parser state.
|
|
104
|
+
* @throws {TypeError} If metadata cannot be defined on the wrapper.
|
|
105
|
+
* @since 1.0.11
|
|
106
|
+
*/
|
|
107
|
+
declare function delegateOptionParsing<TOuterState, TInnerState>(wrapper: Parser<Mode, unknown, TOuterState>, inner: Parser<Mode, unknown, TInnerState>, getInnerState: (state: TOuterState) => TInnerState): void;
|
|
96
108
|
//#endregion
|
|
97
|
-
export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateSuggestNodes, dispatchByMode, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
|
|
109
|
+
export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateOptionParsing, delegateSuggestNodes, dispatchByMode, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
|
package/dist/extension.d.ts
CHANGED
|
@@ -93,5 +93,17 @@ declare function delegateSuggestNodes<TInnerState>(innerParser: Parser<Mode, unk
|
|
|
93
93
|
* @since 1.0.0
|
|
94
94
|
*/
|
|
95
95
|
declare function mapSourceMetadata<M extends Mode, TValue, TState>(parser: Pick<Parser<M, TValue, TState>, "dependencyMetadata">, mapSource: (source: ParserSourceMetadata<M, TValue, TState>) => ParserSourceMetadata<M, TValue, TState>): Parser<M, TValue, TState>["dependencyMetadata"] | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* Delegates CLI option matching and capture priority through a parser wrapper.
|
|
98
|
+
* Use the same child-state projection as the wrapper's parse method. This
|
|
99
|
+
* preserves selected command options without changing public leading names.
|
|
100
|
+
*
|
|
101
|
+
* @param wrapper The parser being constructed.
|
|
102
|
+
* @param inner Its wrapped CLI parser.
|
|
103
|
+
* @param getInnerState Projects the wrapper state to the CLI parser state.
|
|
104
|
+
* @throws {TypeError} If metadata cannot be defined on the wrapper.
|
|
105
|
+
* @since 1.0.11
|
|
106
|
+
*/
|
|
107
|
+
declare function delegateOptionParsing<TOuterState, TInnerState>(wrapper: Parser<Mode, unknown, TOuterState>, inner: Parser<Mode, unknown, TInnerState>, getInnerState: (state: TOuterState) => TInnerState): void;
|
|
96
108
|
//#endregion
|
|
97
|
-
export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateSuggestNodes, dispatchByMode, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
|
|
109
|
+
export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateOptionParsing, delegateSuggestNodes, dispatchByMode, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
|
package/dist/extension.js
CHANGED
|
@@ -2,6 +2,7 @@ import { inheritAnnotations, injectAnnotations, isInjectedAnnotationState, unwra
|
|
|
2
2
|
import { dispatchByMode, mapModeValue, wrapForMode } from "./internal/mode-dispatch.js";
|
|
3
3
|
import { annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, defineInheritedAnnotationParser, getDelegatingSuggestRuntimeNodes, inheritParentAnnotationsKey, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
|
|
4
4
|
import { withAnnotationView } from "./annotation-state.js";
|
|
5
|
+
import { defineOptionMatch, definePassThroughPriority, getOptionMatch, getPassThroughPriority } from "./internal/passthrough.js";
|
|
5
6
|
|
|
6
7
|
//#region src/extension.ts
|
|
7
8
|
const emptyTraits = Object.freeze({});
|
|
@@ -71,6 +72,21 @@ function delegateSuggestNodes(innerParser, outerParser, state, path, innerState,
|
|
|
71
72
|
function mapSourceMetadata(parser, mapSource) {
|
|
72
73
|
return composeWrappedSourceMetadata(parser.dependencyMetadata, mapSource);
|
|
73
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Delegates CLI option matching and capture priority through a parser wrapper.
|
|
77
|
+
* Use the same child-state projection as the wrapper's parse method. This
|
|
78
|
+
* preserves selected command options without changing public leading names.
|
|
79
|
+
*
|
|
80
|
+
* @param wrapper The parser being constructed.
|
|
81
|
+
* @param inner Its wrapped CLI parser.
|
|
82
|
+
* @param getInnerState Projects the wrapper state to the CLI parser state.
|
|
83
|
+
* @throws {TypeError} If metadata cannot be defined on the wrapper.
|
|
84
|
+
* @since 1.0.11
|
|
85
|
+
*/
|
|
86
|
+
function delegateOptionParsing(wrapper, inner, getInnerState) {
|
|
87
|
+
defineOptionMatch(wrapper, (state, token) => getOptionMatch(inner, getInnerState(state), token));
|
|
88
|
+
definePassThroughPriority(wrapper, [inner], (state, token) => getPassThroughPriority(inner, getInnerState(state), token));
|
|
89
|
+
}
|
|
74
90
|
|
|
75
91
|
//#endregion
|
|
76
|
-
export { defineTraits, delegateSuggestNodes, dispatchByMode, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
|
|
92
|
+
export { defineTraits, delegateOptionParsing, delegateSuggestNodes, dispatchByMode, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/internal/passthrough.ts
|
|
3
|
+
/** Retains the deepest diagnostic and highest matching lane priority. @internal */
|
|
4
|
+
function retainConsumingFailure(current, failure, priority) {
|
|
5
|
+
return {
|
|
6
|
+
failure: current != null && current.failure.consumed >= failure.consumed ? current.failure : failure,
|
|
7
|
+
priority: Math.max(current?.priority ?? -Infinity, priority)
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
const passThroughFailure = Symbol("passThroughFailure");
|
|
11
|
+
/**
|
|
12
|
+
* Gets the sibling failure that prevents pass-through capture at this cursor.
|
|
13
|
+
* Stale hints inherited through a successful child do not block later input.
|
|
14
|
+
* @param context The pass-through parser's context.
|
|
15
|
+
* @returns The failure at this cursor, or undefined if capture is allowed.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
function getPassThroughFailure(context, capturePriority$1 = -Infinity) {
|
|
19
|
+
const hinted = context;
|
|
20
|
+
const hint = hinted[passThroughFailure];
|
|
21
|
+
return hint?.buffer === context.buffer && hint.optionsTerminated === context.optionsTerminated && hint.failure.priority >= capturePriority$1 ? hint.failure : void 0;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Carries a sibling's consuming failure into a child parse call. Only
|
|
25
|
+
* passThrough consults the hint; ordinary alternatives may still recover.
|
|
26
|
+
* @param context The child context, without modifying the parent's context.
|
|
27
|
+
* @param failure The deepest matching consuming failure at this input position.
|
|
28
|
+
* @returns A context with a hint for active option-like input, or the original.
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
function withPassThroughFailure(context, failure, capturePriority$1 = -Infinity) {
|
|
32
|
+
const token = context.buffer[0];
|
|
33
|
+
const existing = getPassThroughFailure(context);
|
|
34
|
+
if (existing != null && existing.priority < capturePriority$1) {
|
|
35
|
+
const hinted$1 = context;
|
|
36
|
+
const { [passThroughFailure]: _discarded,...rest } = hinted$1;
|
|
37
|
+
context = rest;
|
|
38
|
+
}
|
|
39
|
+
if (failure == null || failure.failure.consumed < 1 || failure.priority < capturePriority$1 || context.optionsTerminated || token == null || token === "--" || !/^[-/+]/.test(token)) return context;
|
|
40
|
+
const retained = getPassThroughFailure(context);
|
|
41
|
+
const combined = retainConsumingFailure(retained, failure.failure, failure.priority);
|
|
42
|
+
const hinted = {
|
|
43
|
+
...context,
|
|
44
|
+
[passThroughFailure]: {
|
|
45
|
+
buffer: context.buffer,
|
|
46
|
+
optionsTerminated: context.optionsTerminated,
|
|
47
|
+
failure: combined
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
return hinted;
|
|
51
|
+
}
|
|
52
|
+
/** Retains a child's rejected option failure only at the parent's cursor. @internal */
|
|
53
|
+
function retainConsumingFailureHint(current, context, next) {
|
|
54
|
+
if (next.buffer !== context.buffer || next.optionsTerminated !== context.optionsTerminated) return current;
|
|
55
|
+
const hint = getPassThroughFailure(next);
|
|
56
|
+
return hint == null ? current : retainConsumingFailure(current, hint.failure, hint.priority);
|
|
57
|
+
}
|
|
58
|
+
const capturePriority = Symbol("capturePriority");
|
|
59
|
+
/** Checks for capture through usage-preserving wrappers. @internal */
|
|
60
|
+
function hasPassThroughUsage(usage) {
|
|
61
|
+
return usage.some((term) => term.type === "passthrough" || (term.type === "optional" || term.type === "multiple") && hasPassThroughUsage(term.terms) || term.type === "exclusive" && term.terms.some(hasPassThroughUsage));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Gets the priority of reachable capture, respecting an explicit override.
|
|
65
|
+
* @param parser The parser whose capture priority is needed.
|
|
66
|
+
* @param state The current parser state.
|
|
67
|
+
* @param token The current token, omitted for an unfiltered priority lookup.
|
|
68
|
+
* @returns The capture priority, or undefined when capture is absent.
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
function getPassThroughPriority(parser, state = parser.initialState, token) {
|
|
72
|
+
if (!hasPassThroughUsage(parser.usage)) return void 0;
|
|
73
|
+
const annotated = parser;
|
|
74
|
+
const hint = annotated[capturePriority];
|
|
75
|
+
if (hint == null) return parser.priority;
|
|
76
|
+
const priority = hint.getPriority == null ? hint.priority : hint.getPriority(state, token);
|
|
77
|
+
return priority == null ? void 0 : hint.ownerPriority === parser.priority ? priority : parser.priority;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Records capture priority separately from unrelated children's priorities.
|
|
81
|
+
* @param parser The newly constructed parser.
|
|
82
|
+
* @param children Its transparent children.
|
|
83
|
+
* @param getPriority Optional state-aware capture priority lookup.
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
function definePassThroughPriority(parser, children, getPriority) {
|
|
87
|
+
const priorities = children.filter((child) => hasPassThroughUsage(child.usage)).map((child) => getPassThroughPriority(child) ?? child.priority);
|
|
88
|
+
if (priorities.length === 0) return;
|
|
89
|
+
Object.defineProperty(parser, capturePriority, {
|
|
90
|
+
value: {
|
|
91
|
+
ownerPriority: parser.priority,
|
|
92
|
+
priority: Math.max(...priorities),
|
|
93
|
+
getPriority
|
|
94
|
+
},
|
|
95
|
+
enumerable: true
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Copies only a cursor-valid hint when rebuilding a child context.
|
|
100
|
+
* @param context The successful child's context.
|
|
101
|
+
* @returns Private hint properties, or an empty object for stale hints.
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
function getPassThroughFailureHint(context) {
|
|
105
|
+
const hinted = context;
|
|
106
|
+
const hint = hinted[passThroughFailure];
|
|
107
|
+
return hint != null && getPassThroughFailure(context) != null ? { [passThroughFailure]: hint } : {};
|
|
108
|
+
}
|
|
109
|
+
/** Finds a Boolean option through usage-preserving wrappers. */
|
|
110
|
+
function hasFlagUsage(usage, name) {
|
|
111
|
+
return usage.some((term) => term.type === "option" && term.metavar == null && term.names.some((optionName) => optionName === name) || (term.type === "optional" || term.type === "multiple") && hasFlagUsage(term.terms, name) || term.type === "exclusive" && term.terms.some((terms) => hasFlagUsage(terms, name)));
|
|
112
|
+
}
|
|
113
|
+
/** Matches exact options, attached values, and leading bundled flags. */
|
|
114
|
+
function matchesOptionToken(parser, token) {
|
|
115
|
+
if (token == null || token === "--" || !/^[-/+]/.test(token)) return false;
|
|
116
|
+
if (parser.leadingNames.has(token)) return true;
|
|
117
|
+
const slashOption = token.startsWith("/");
|
|
118
|
+
const separator = slashOption ? token.indexOf(":") : token.startsWith("-") ? token.indexOf("=") : -1;
|
|
119
|
+
if (separator > (slashOption ? 0 : 2) && parser.leadingNames.has(token.slice(0, separator))) return true;
|
|
120
|
+
const shortName = token.slice(0, 2);
|
|
121
|
+
return token.length > 2 && /^-[^-]$/.test(shortName) && parser.leadingNames.has(shortName) && hasFlagUsage(parser.usage, shortName);
|
|
122
|
+
}
|
|
123
|
+
const optionMatchKey = Symbol("optionMatch");
|
|
124
|
+
/**
|
|
125
|
+
* Records state-aware option matching without changing public leading names.
|
|
126
|
+
* @param parser The newly constructed transparent parser.
|
|
127
|
+
* @param match Finds a reachable known-option lane.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
function defineOptionMatch(parser, match) {
|
|
131
|
+
Object.defineProperty(parser, optionMatchKey, {
|
|
132
|
+
value: {
|
|
133
|
+
ownerPriority: parser.priority,
|
|
134
|
+
match
|
|
135
|
+
},
|
|
136
|
+
enumerable: true
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Finds a matching option's actual priority, including selected command children.
|
|
141
|
+
* @param parser The parser to inspect.
|
|
142
|
+
* @param state Its current state.
|
|
143
|
+
* @param token The current token.
|
|
144
|
+
* @returns A reachable option match, or undefined.
|
|
145
|
+
* @internal
|
|
146
|
+
*/
|
|
147
|
+
function getOptionMatch(parser, state, token) {
|
|
148
|
+
if (token == null || token === "--" || !/^[-/+]/.test(token)) return void 0;
|
|
149
|
+
const annotated = parser;
|
|
150
|
+
const matcher = annotated[optionMatchKey];
|
|
151
|
+
if (matcher != null) {
|
|
152
|
+
const match = matcher.match(state, token);
|
|
153
|
+
return match == null || matcher.ownerPriority === parser.priority ? match : {
|
|
154
|
+
...match,
|
|
155
|
+
priority: parser.priority
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return matchesOptionToken(parser, token) ? {
|
|
159
|
+
priority: parser.priority,
|
|
160
|
+
continuesCommand: false
|
|
161
|
+
} : void 0;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Combines option matches while retaining active command continuation.
|
|
165
|
+
* @param matches Matches from transparent children.
|
|
166
|
+
* @returns Their highest priority and whether any matching command continues.
|
|
167
|
+
* @internal
|
|
168
|
+
*/
|
|
169
|
+
function combineOptionMatches(matches) {
|
|
170
|
+
const found = matches.filter((match) => match != null);
|
|
171
|
+
return found.length === 0 ? void 0 : {
|
|
172
|
+
priority: Math.max(...found.map((match) => match.priority)),
|
|
173
|
+
continuesCommand: found.some((match) => match.continuesCommand)
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const knownCompletionKey = Symbol("knownCompletion");
|
|
177
|
+
/** Marks a completion value that can be inspected without running user code. @internal */
|
|
178
|
+
function defineKnownCompletion(parser, value) {
|
|
179
|
+
defineKnownCompletionLookup(parser, (state) => ({ value: value(state) }));
|
|
180
|
+
}
|
|
181
|
+
/** Registers a known-value lookup that may decline unknown completion. @internal */
|
|
182
|
+
function defineKnownCompletionLookup(parser, value) {
|
|
183
|
+
Object.defineProperty(parser, knownCompletionKey, {
|
|
184
|
+
value: {
|
|
185
|
+
complete: parser.complete,
|
|
186
|
+
value
|
|
187
|
+
},
|
|
188
|
+
enumerable: true
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/** Looks up a known value only while the original completion is intact. @internal */
|
|
192
|
+
function getKnownCompletion(parser, state) {
|
|
193
|
+
const annotated = parser;
|
|
194
|
+
const hint = annotated[knownCompletionKey];
|
|
195
|
+
return hint != null && hint.complete === parser.complete ? hint.value(state) : void 0;
|
|
196
|
+
}
|
|
197
|
+
/** Combines the priorities of currently reachable capture lanes. @internal */
|
|
198
|
+
function combinePassThroughPriorities(priorities) {
|
|
199
|
+
const found = priorities.filter((priority) => priority != null);
|
|
200
|
+
return found.length === 0 ? void 0 : Math.max(...found);
|
|
201
|
+
}
|
|
202
|
+
/** Forwards known completion through a state-preserving wrapper. @internal */
|
|
203
|
+
function delegateKnownCompletion(wrapper, inner) {
|
|
204
|
+
Object.defineProperty(wrapper, knownCompletionKey, {
|
|
205
|
+
value: {
|
|
206
|
+
complete: wrapper.complete,
|
|
207
|
+
value: (state) => getKnownCompletion(inner, state)
|
|
208
|
+
},
|
|
209
|
+
enumerable: true
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
//#endregion
|
|
214
|
+
exports.combineOptionMatches = combineOptionMatches;
|
|
215
|
+
exports.combinePassThroughPriorities = combinePassThroughPriorities;
|
|
216
|
+
exports.defineKnownCompletion = defineKnownCompletion;
|
|
217
|
+
exports.defineKnownCompletionLookup = defineKnownCompletionLookup;
|
|
218
|
+
exports.defineOptionMatch = defineOptionMatch;
|
|
219
|
+
exports.definePassThroughPriority = definePassThroughPriority;
|
|
220
|
+
exports.delegateKnownCompletion = delegateKnownCompletion;
|
|
221
|
+
exports.getKnownCompletion = getKnownCompletion;
|
|
222
|
+
exports.getOptionMatch = getOptionMatch;
|
|
223
|
+
exports.getPassThroughFailure = getPassThroughFailure;
|
|
224
|
+
exports.getPassThroughFailureHint = getPassThroughFailureHint;
|
|
225
|
+
exports.getPassThroughPriority = getPassThroughPriority;
|
|
226
|
+
exports.hasPassThroughUsage = hasPassThroughUsage;
|
|
227
|
+
exports.matchesOptionToken = matchesOptionToken;
|
|
228
|
+
exports.retainConsumingFailure = retainConsumingFailure;
|
|
229
|
+
exports.retainConsumingFailureHint = retainConsumingFailureHint;
|
|
230
|
+
exports.withPassThroughFailure = withPassThroughFailure;
|