@optique/core 1.0.0-dev.664 → 1.0.0-dev.667
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/annotations.cjs +8 -0
- package/dist/annotations.d.cts +8 -1
- package/dist/annotations.d.ts +8 -1
- package/dist/annotations.js +8 -1
- package/dist/constructs.cjs +45 -8
- package/dist/constructs.js +45 -8
- package/dist/facade.cjs +200 -15
- package/dist/facade.js +200 -15
- package/package.json +1 -1
package/dist/annotations.cjs
CHANGED
|
@@ -16,6 +16,13 @@
|
|
|
16
16
|
*/
|
|
17
17
|
const annotationKey = Symbol.for("@optique/core/parser/annotation");
|
|
18
18
|
/**
|
|
19
|
+
* Internal marker attached during the first pass of `runWith()` so wrappers
|
|
20
|
+
* with side effects can defer work until dynamic contexts have resolved.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
const firstPassAnnotationKey = Symbol.for("@optique/core/parser/firstPass");
|
|
25
|
+
/**
|
|
19
26
|
* Internal key for preserving primitive parser state values when annotations
|
|
20
27
|
* are injected into non-object states.
|
|
21
28
|
* @internal
|
|
@@ -234,6 +241,7 @@ exports.annotateFreshArray = annotateFreshArray;
|
|
|
234
241
|
exports.annotationKey = annotationKey;
|
|
235
242
|
exports.annotationStateValueKey = annotationStateValueKey;
|
|
236
243
|
exports.annotationWrapperKey = annotationWrapperKey;
|
|
244
|
+
exports.firstPassAnnotationKey = firstPassAnnotationKey;
|
|
237
245
|
exports.getAnnotations = getAnnotations;
|
|
238
246
|
exports.inheritAnnotations = inheritAnnotations;
|
|
239
247
|
exports.injectAnnotations = injectAnnotations;
|
package/dist/annotations.d.cts
CHANGED
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
* @since 0.10.0
|
|
15
15
|
*/
|
|
16
16
|
declare const annotationKey: unique symbol;
|
|
17
|
+
/**
|
|
18
|
+
* Internal marker attached during the first pass of `runWith()` so wrappers
|
|
19
|
+
* with side effects can defer work until dynamic contexts have resolved.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
declare const firstPassAnnotationKey: unique symbol;
|
|
17
24
|
/**
|
|
18
25
|
* Internal key for preserving primitive parser state values when annotations
|
|
19
26
|
* are injected into non-object states.
|
|
@@ -127,4 +134,4 @@ declare function unwrapInjectedAnnotationWrapper<T>(value: T): T;
|
|
|
127
134
|
*/
|
|
128
135
|
declare function isInjectedAnnotationWrapper(value: unknown): boolean;
|
|
129
136
|
//#endregion
|
|
130
|
-
export { Annotations, ParseOptions, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
|
137
|
+
export { Annotations, ParseOptions, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
package/dist/annotations.d.ts
CHANGED
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
* @since 0.10.0
|
|
15
15
|
*/
|
|
16
16
|
declare const annotationKey: unique symbol;
|
|
17
|
+
/**
|
|
18
|
+
* Internal marker attached during the first pass of `runWith()` so wrappers
|
|
19
|
+
* with side effects can defer work until dynamic contexts have resolved.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
declare const firstPassAnnotationKey: unique symbol;
|
|
17
24
|
/**
|
|
18
25
|
* Internal key for preserving primitive parser state values when annotations
|
|
19
26
|
* are injected into non-object states.
|
|
@@ -127,4 +134,4 @@ declare function unwrapInjectedAnnotationWrapper<T>(value: T): T;
|
|
|
127
134
|
*/
|
|
128
135
|
declare function isInjectedAnnotationWrapper(value: unknown): boolean;
|
|
129
136
|
//#endregion
|
|
130
|
-
export { Annotations, ParseOptions, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
|
137
|
+
export { Annotations, ParseOptions, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
package/dist/annotations.js
CHANGED
|
@@ -15,6 +15,13 @@
|
|
|
15
15
|
*/
|
|
16
16
|
const annotationKey = Symbol.for("@optique/core/parser/annotation");
|
|
17
17
|
/**
|
|
18
|
+
* Internal marker attached during the first pass of `runWith()` so wrappers
|
|
19
|
+
* with side effects can defer work until dynamic contexts have resolved.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
const firstPassAnnotationKey = Symbol.for("@optique/core/parser/firstPass");
|
|
24
|
+
/**
|
|
18
25
|
* Internal key for preserving primitive parser state values when annotations
|
|
19
26
|
* are injected into non-object states.
|
|
20
27
|
* @internal
|
|
@@ -229,4 +236,4 @@ function isInjectedAnnotationWrapper(value) {
|
|
|
229
236
|
}
|
|
230
237
|
|
|
231
238
|
//#endregion
|
|
232
|
-
export { annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
|
239
|
+
export { annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
package/dist/constructs.cjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const require_annotations = require('./annotations.cjs');
|
|
1
2
|
const require_message = require('./message.cjs');
|
|
2
3
|
const require_dependency = require('./dependency.cjs');
|
|
3
4
|
const require_mode_dispatch = require('./mode-dispatch.cjs');
|
|
@@ -6,6 +7,7 @@ const require_suggestion = require('./suggestion.cjs');
|
|
|
6
7
|
const require_usage_internals = require('./usage-internals.cjs');
|
|
7
8
|
|
|
8
9
|
//#region src/constructs.ts
|
|
10
|
+
const inheritParentAnnotationsKey = Symbol.for("@optique/core/inheritParentAnnotations");
|
|
9
11
|
function createUnexpectedInputErrorWithScopedSuggestions(baseError, invalidInput, parsers, customFormatter) {
|
|
10
12
|
const options = /* @__PURE__ */ new Set();
|
|
11
13
|
const commands = /* @__PURE__ */ new Set();
|
|
@@ -842,6 +844,31 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
842
844
|
for (const key of parserKeys) state[key] = parsers[key].initialState;
|
|
843
845
|
return state;
|
|
844
846
|
};
|
|
847
|
+
const inheritedFieldStateCache = /* @__PURE__ */ new WeakMap();
|
|
848
|
+
const createFieldStateGetter = (parentState) => {
|
|
849
|
+
return (field, parser) => {
|
|
850
|
+
const fieldKey = field;
|
|
851
|
+
const cache = parentState != null && typeof parentState === "object" ? inheritedFieldStateCache.get(parentState) ?? (() => {
|
|
852
|
+
const stateCache = /* @__PURE__ */ new Map();
|
|
853
|
+
inheritedFieldStateCache.set(parentState, stateCache);
|
|
854
|
+
return stateCache;
|
|
855
|
+
})() : void 0;
|
|
856
|
+
if (cache?.has(fieldKey)) return cache.get(fieldKey);
|
|
857
|
+
const sourceState = parentState != null && typeof parentState === "object" && fieldKey in parentState ? parentState[fieldKey] : parser.initialState;
|
|
858
|
+
if (sourceState == null || typeof sourceState !== "object") {
|
|
859
|
+
cache?.set(fieldKey, sourceState);
|
|
860
|
+
return sourceState;
|
|
861
|
+
}
|
|
862
|
+
const annotations = require_annotations.getAnnotations(parentState);
|
|
863
|
+
if (annotations === void 0 || require_annotations.getAnnotations(sourceState) === annotations) {
|
|
864
|
+
cache?.set(fieldKey, sourceState);
|
|
865
|
+
return sourceState;
|
|
866
|
+
}
|
|
867
|
+
const inheritedState = Reflect.get(parser, inheritParentAnnotationsKey) === true ? require_annotations.injectAnnotations(sourceState, annotations) : require_annotations.inheritAnnotations(parentState, sourceState);
|
|
868
|
+
cache?.set(fieldKey, inheritedState);
|
|
869
|
+
return inheritedState;
|
|
870
|
+
};
|
|
871
|
+
};
|
|
845
872
|
if (!options.allowDuplicates) checkDuplicateOptionNames(parserPairs.map(([field, parser]) => [field, parser.usage]));
|
|
846
873
|
const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
|
|
847
874
|
const combinedMode = parserKeys.some((k) => parsers[k].$mode === "async") ? "async" : "sync";
|
|
@@ -866,10 +893,11 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
866
893
|
let madeProgress = true;
|
|
867
894
|
while (madeProgress && currentContext.buffer.length > 0) {
|
|
868
895
|
madeProgress = false;
|
|
896
|
+
const getFieldState = createFieldStateGetter(currentContext.state);
|
|
869
897
|
for (const [field, parser] of parserPairs) {
|
|
870
898
|
const result = parser.parse({
|
|
871
899
|
...currentContext,
|
|
872
|
-
state:
|
|
900
|
+
state: getFieldState(field, parser)
|
|
873
901
|
});
|
|
874
902
|
if (result.success && result.consumed.length > 0) {
|
|
875
903
|
currentContext = {
|
|
@@ -895,8 +923,9 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
895
923
|
};
|
|
896
924
|
if (context.buffer.length === 0) {
|
|
897
925
|
let allCanComplete = true;
|
|
926
|
+
const getFieldState = createFieldStateGetter(context.state);
|
|
898
927
|
for (const [field, parser] of parserPairs) {
|
|
899
|
-
const fieldState =
|
|
928
|
+
const fieldState = getFieldState(field, parser);
|
|
900
929
|
const completeResult = parser.complete(fieldState);
|
|
901
930
|
if (!completeResult.success) {
|
|
902
931
|
allCanComplete = false;
|
|
@@ -922,10 +951,11 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
922
951
|
let madeProgress = true;
|
|
923
952
|
while (madeProgress && currentContext.buffer.length > 0) {
|
|
924
953
|
madeProgress = false;
|
|
954
|
+
const getFieldState = createFieldStateGetter(currentContext.state);
|
|
925
955
|
for (const [field, parser] of parserPairs) {
|
|
926
956
|
const resultOrPromise = parser.parse({
|
|
927
957
|
...currentContext,
|
|
928
|
-
state:
|
|
958
|
+
state: getFieldState(field, parser)
|
|
929
959
|
});
|
|
930
960
|
const result = await resultOrPromise;
|
|
931
961
|
if (result.success && result.consumed.length > 0) {
|
|
@@ -952,8 +982,9 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
952
982
|
};
|
|
953
983
|
if (context.buffer.length === 0) {
|
|
954
984
|
let allCanComplete = true;
|
|
985
|
+
const getFieldState = createFieldStateGetter(context.state);
|
|
955
986
|
for (const [field, parser] of parserPairs) {
|
|
956
|
-
const fieldState =
|
|
987
|
+
const fieldState = getFieldState(field, parser);
|
|
957
988
|
const completeResult = await parser.complete(fieldState);
|
|
958
989
|
if (!completeResult.success) {
|
|
959
990
|
allCanComplete = false;
|
|
@@ -987,6 +1018,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
987
1018
|
return require_mode_dispatch.dispatchByMode(combinedMode, () => {
|
|
988
1019
|
const preCompletedState = {};
|
|
989
1020
|
const preCompletedKeys = /* @__PURE__ */ new Set();
|
|
1021
|
+
const getFieldState = createFieldStateGetter(state);
|
|
990
1022
|
for (const field of parserKeys) {
|
|
991
1023
|
const fieldKey = field;
|
|
992
1024
|
const fieldState = state[fieldKey];
|
|
@@ -1006,10 +1038,11 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1006
1038
|
preCompletedState[fieldKey] = completed;
|
|
1007
1039
|
preCompletedKeys.add(fieldKey);
|
|
1008
1040
|
} else preCompletedState[fieldKey] = fieldState;
|
|
1009
|
-
} else preCompletedState[fieldKey] =
|
|
1041
|
+
} else preCompletedState[fieldKey] = getFieldState(field, fieldParser);
|
|
1010
1042
|
}
|
|
1011
1043
|
const resolvedState = resolveDeferredParseStates(preCompletedState);
|
|
1012
1044
|
const result = {};
|
|
1045
|
+
const getCompletionFieldState = createFieldStateGetter(state);
|
|
1013
1046
|
for (const field of parserKeys) {
|
|
1014
1047
|
const fieldKey = field;
|
|
1015
1048
|
const fieldResolvedState = resolvedState[fieldKey];
|
|
@@ -1023,7 +1056,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1023
1056
|
};
|
|
1024
1057
|
continue;
|
|
1025
1058
|
}
|
|
1026
|
-
const
|
|
1059
|
+
const completionState = fieldResolvedState === void 0 ? getCompletionFieldState(field, fieldParser) : fieldResolvedState;
|
|
1060
|
+
const valueResult = fieldParser.complete(completionState);
|
|
1027
1061
|
if (valueResult.success) result[fieldKey] = valueResult.value;
|
|
1028
1062
|
else return {
|
|
1029
1063
|
success: false,
|
|
@@ -1037,6 +1071,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1037
1071
|
}, async () => {
|
|
1038
1072
|
const preCompletedState = {};
|
|
1039
1073
|
const preCompletedKeys = /* @__PURE__ */ new Set();
|
|
1074
|
+
const getFieldState = createFieldStateGetter(state);
|
|
1040
1075
|
for (const field of parserKeys) {
|
|
1041
1076
|
const fieldKey = field;
|
|
1042
1077
|
const fieldState = state[fieldKey];
|
|
@@ -1056,10 +1091,11 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1056
1091
|
preCompletedState[fieldKey] = completed;
|
|
1057
1092
|
preCompletedKeys.add(fieldKey);
|
|
1058
1093
|
} else preCompletedState[fieldKey] = fieldState;
|
|
1059
|
-
} else preCompletedState[fieldKey] =
|
|
1094
|
+
} else preCompletedState[fieldKey] = getFieldState(field, fieldParser);
|
|
1060
1095
|
}
|
|
1061
1096
|
const resolvedState = await resolveDeferredParseStatesAsync(preCompletedState);
|
|
1062
1097
|
const result = {};
|
|
1098
|
+
const getCompletionFieldState = createFieldStateGetter(state);
|
|
1063
1099
|
for (const field of parserKeys) {
|
|
1064
1100
|
const fieldKey = field;
|
|
1065
1101
|
const fieldResolvedState = resolvedState[fieldKey];
|
|
@@ -1073,7 +1109,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1073
1109
|
};
|
|
1074
1110
|
continue;
|
|
1075
1111
|
}
|
|
1076
|
-
const
|
|
1112
|
+
const completionState = fieldResolvedState === void 0 ? getCompletionFieldState(field, fieldParser) : fieldResolvedState;
|
|
1113
|
+
const valueResult = await fieldParser.complete(completionState);
|
|
1077
1114
|
if (valueResult.success) result[fieldKey] = valueResult.value;
|
|
1078
1115
|
else return {
|
|
1079
1116
|
success: false,
|
package/dist/constructs.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getAnnotations, inheritAnnotations, injectAnnotations } from "./annotations.js";
|
|
1
2
|
import { message, optionName, text, values } from "./message.js";
|
|
2
3
|
import { DependencyRegistry, dependencyId, isDeferredParseState, isDependencySourceState, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, wrappedDependencySourceMarker } from "./dependency.js";
|
|
3
4
|
import { dispatchByMode, dispatchIterableByMode } from "./mode-dispatch.js";
|
|
@@ -6,6 +7,7 @@ import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggest
|
|
|
6
7
|
import { collectLeadingCandidates } from "./usage-internals.js";
|
|
7
8
|
|
|
8
9
|
//#region src/constructs.ts
|
|
10
|
+
const inheritParentAnnotationsKey = Symbol.for("@optique/core/inheritParentAnnotations");
|
|
9
11
|
function createUnexpectedInputErrorWithScopedSuggestions(baseError, invalidInput, parsers, customFormatter) {
|
|
10
12
|
const options = /* @__PURE__ */ new Set();
|
|
11
13
|
const commands = /* @__PURE__ */ new Set();
|
|
@@ -842,6 +844,31 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
842
844
|
for (const key of parserKeys) state[key] = parsers[key].initialState;
|
|
843
845
|
return state;
|
|
844
846
|
};
|
|
847
|
+
const inheritedFieldStateCache = /* @__PURE__ */ new WeakMap();
|
|
848
|
+
const createFieldStateGetter = (parentState) => {
|
|
849
|
+
return (field, parser) => {
|
|
850
|
+
const fieldKey = field;
|
|
851
|
+
const cache = parentState != null && typeof parentState === "object" ? inheritedFieldStateCache.get(parentState) ?? (() => {
|
|
852
|
+
const stateCache = /* @__PURE__ */ new Map();
|
|
853
|
+
inheritedFieldStateCache.set(parentState, stateCache);
|
|
854
|
+
return stateCache;
|
|
855
|
+
})() : void 0;
|
|
856
|
+
if (cache?.has(fieldKey)) return cache.get(fieldKey);
|
|
857
|
+
const sourceState = parentState != null && typeof parentState === "object" && fieldKey in parentState ? parentState[fieldKey] : parser.initialState;
|
|
858
|
+
if (sourceState == null || typeof sourceState !== "object") {
|
|
859
|
+
cache?.set(fieldKey, sourceState);
|
|
860
|
+
return sourceState;
|
|
861
|
+
}
|
|
862
|
+
const annotations = getAnnotations(parentState);
|
|
863
|
+
if (annotations === void 0 || getAnnotations(sourceState) === annotations) {
|
|
864
|
+
cache?.set(fieldKey, sourceState);
|
|
865
|
+
return sourceState;
|
|
866
|
+
}
|
|
867
|
+
const inheritedState = Reflect.get(parser, inheritParentAnnotationsKey) === true ? injectAnnotations(sourceState, annotations) : inheritAnnotations(parentState, sourceState);
|
|
868
|
+
cache?.set(fieldKey, inheritedState);
|
|
869
|
+
return inheritedState;
|
|
870
|
+
};
|
|
871
|
+
};
|
|
845
872
|
if (!options.allowDuplicates) checkDuplicateOptionNames(parserPairs.map(([field, parser]) => [field, parser.usage]));
|
|
846
873
|
const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
|
|
847
874
|
const combinedMode = parserKeys.some((k) => parsers[k].$mode === "async") ? "async" : "sync";
|
|
@@ -866,10 +893,11 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
866
893
|
let madeProgress = true;
|
|
867
894
|
while (madeProgress && currentContext.buffer.length > 0) {
|
|
868
895
|
madeProgress = false;
|
|
896
|
+
const getFieldState = createFieldStateGetter(currentContext.state);
|
|
869
897
|
for (const [field, parser] of parserPairs) {
|
|
870
898
|
const result = parser.parse({
|
|
871
899
|
...currentContext,
|
|
872
|
-
state:
|
|
900
|
+
state: getFieldState(field, parser)
|
|
873
901
|
});
|
|
874
902
|
if (result.success && result.consumed.length > 0) {
|
|
875
903
|
currentContext = {
|
|
@@ -895,8 +923,9 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
895
923
|
};
|
|
896
924
|
if (context.buffer.length === 0) {
|
|
897
925
|
let allCanComplete = true;
|
|
926
|
+
const getFieldState = createFieldStateGetter(context.state);
|
|
898
927
|
for (const [field, parser] of parserPairs) {
|
|
899
|
-
const fieldState =
|
|
928
|
+
const fieldState = getFieldState(field, parser);
|
|
900
929
|
const completeResult = parser.complete(fieldState);
|
|
901
930
|
if (!completeResult.success) {
|
|
902
931
|
allCanComplete = false;
|
|
@@ -922,10 +951,11 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
922
951
|
let madeProgress = true;
|
|
923
952
|
while (madeProgress && currentContext.buffer.length > 0) {
|
|
924
953
|
madeProgress = false;
|
|
954
|
+
const getFieldState = createFieldStateGetter(currentContext.state);
|
|
925
955
|
for (const [field, parser] of parserPairs) {
|
|
926
956
|
const resultOrPromise = parser.parse({
|
|
927
957
|
...currentContext,
|
|
928
|
-
state:
|
|
958
|
+
state: getFieldState(field, parser)
|
|
929
959
|
});
|
|
930
960
|
const result = await resultOrPromise;
|
|
931
961
|
if (result.success && result.consumed.length > 0) {
|
|
@@ -952,8 +982,9 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
952
982
|
};
|
|
953
983
|
if (context.buffer.length === 0) {
|
|
954
984
|
let allCanComplete = true;
|
|
985
|
+
const getFieldState = createFieldStateGetter(context.state);
|
|
955
986
|
for (const [field, parser] of parserPairs) {
|
|
956
|
-
const fieldState =
|
|
987
|
+
const fieldState = getFieldState(field, parser);
|
|
957
988
|
const completeResult = await parser.complete(fieldState);
|
|
958
989
|
if (!completeResult.success) {
|
|
959
990
|
allCanComplete = false;
|
|
@@ -987,6 +1018,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
987
1018
|
return dispatchByMode(combinedMode, () => {
|
|
988
1019
|
const preCompletedState = {};
|
|
989
1020
|
const preCompletedKeys = /* @__PURE__ */ new Set();
|
|
1021
|
+
const getFieldState = createFieldStateGetter(state);
|
|
990
1022
|
for (const field of parserKeys) {
|
|
991
1023
|
const fieldKey = field;
|
|
992
1024
|
const fieldState = state[fieldKey];
|
|
@@ -1006,10 +1038,11 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1006
1038
|
preCompletedState[fieldKey] = completed;
|
|
1007
1039
|
preCompletedKeys.add(fieldKey);
|
|
1008
1040
|
} else preCompletedState[fieldKey] = fieldState;
|
|
1009
|
-
} else preCompletedState[fieldKey] =
|
|
1041
|
+
} else preCompletedState[fieldKey] = getFieldState(field, fieldParser);
|
|
1010
1042
|
}
|
|
1011
1043
|
const resolvedState = resolveDeferredParseStates(preCompletedState);
|
|
1012
1044
|
const result = {};
|
|
1045
|
+
const getCompletionFieldState = createFieldStateGetter(state);
|
|
1013
1046
|
for (const field of parserKeys) {
|
|
1014
1047
|
const fieldKey = field;
|
|
1015
1048
|
const fieldResolvedState = resolvedState[fieldKey];
|
|
@@ -1023,7 +1056,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1023
1056
|
};
|
|
1024
1057
|
continue;
|
|
1025
1058
|
}
|
|
1026
|
-
const
|
|
1059
|
+
const completionState = fieldResolvedState === void 0 ? getCompletionFieldState(field, fieldParser) : fieldResolvedState;
|
|
1060
|
+
const valueResult = fieldParser.complete(completionState);
|
|
1027
1061
|
if (valueResult.success) result[fieldKey] = valueResult.value;
|
|
1028
1062
|
else return {
|
|
1029
1063
|
success: false,
|
|
@@ -1037,6 +1071,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1037
1071
|
}, async () => {
|
|
1038
1072
|
const preCompletedState = {};
|
|
1039
1073
|
const preCompletedKeys = /* @__PURE__ */ new Set();
|
|
1074
|
+
const getFieldState = createFieldStateGetter(state);
|
|
1040
1075
|
for (const field of parserKeys) {
|
|
1041
1076
|
const fieldKey = field;
|
|
1042
1077
|
const fieldState = state[fieldKey];
|
|
@@ -1056,10 +1091,11 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1056
1091
|
preCompletedState[fieldKey] = completed;
|
|
1057
1092
|
preCompletedKeys.add(fieldKey);
|
|
1058
1093
|
} else preCompletedState[fieldKey] = fieldState;
|
|
1059
|
-
} else preCompletedState[fieldKey] =
|
|
1094
|
+
} else preCompletedState[fieldKey] = getFieldState(field, fieldParser);
|
|
1060
1095
|
}
|
|
1061
1096
|
const resolvedState = await resolveDeferredParseStatesAsync(preCompletedState);
|
|
1062
1097
|
const result = {};
|
|
1098
|
+
const getCompletionFieldState = createFieldStateGetter(state);
|
|
1063
1099
|
for (const field of parserKeys) {
|
|
1064
1100
|
const fieldKey = field;
|
|
1065
1101
|
const fieldResolvedState = resolvedState[fieldKey];
|
|
@@ -1073,7 +1109,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1073
1109
|
};
|
|
1074
1110
|
continue;
|
|
1075
1111
|
}
|
|
1076
|
-
const
|
|
1112
|
+
const completionState = fieldResolvedState === void 0 ? getCompletionFieldState(field, fieldParser) : fieldResolvedState;
|
|
1113
|
+
const valueResult = await fieldParser.complete(completionState);
|
|
1077
1114
|
if (valueResult.success) result[fieldKey] = valueResult.value;
|
|
1078
1115
|
else return {
|
|
1079
1116
|
success: false,
|
package/dist/facade.cjs
CHANGED
|
@@ -11,6 +11,159 @@ const require_primitives = require('./primitives.cjs');
|
|
|
11
11
|
const require_parser = require('./parser.cjs');
|
|
12
12
|
|
|
13
13
|
//#region src/facade.ts
|
|
14
|
+
const phase1ConfigAnnotationsKey = Symbol.for("@optique/config/phase1PromptAnnotations");
|
|
15
|
+
const phase2UndefinedParsedValueKey = Symbol.for("@optique/config/phase2UndefinedParsedValue");
|
|
16
|
+
const deferredPromptValueKey = Symbol.for("@optique/inquirer/deferredPromptValue");
|
|
17
|
+
function isDeferredPromptValue(value$1) {
|
|
18
|
+
return value$1 != null && typeof value$1 === "object" && deferredPromptValueKey in value$1;
|
|
19
|
+
}
|
|
20
|
+
function isPlainObject(value$1) {
|
|
21
|
+
const proto = Object.getPrototypeOf(value$1);
|
|
22
|
+
return proto === Object.prototype || proto === null;
|
|
23
|
+
}
|
|
24
|
+
function shouldSkipCollectionOwnKey(value$1, key) {
|
|
25
|
+
if (Array.isArray(value$1)) return key === "length" || typeof key === "string" && Number.isInteger(Number(key)) && String(Number(key)) === key;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
function containsDeferredPromptValuesInOwnProperties(value$1, seen) {
|
|
29
|
+
for (const key of Reflect.ownKeys(value$1)) {
|
|
30
|
+
if (shouldSkipCollectionOwnKey(value$1, key)) continue;
|
|
31
|
+
const descriptor = Object.getOwnPropertyDescriptor(value$1, key);
|
|
32
|
+
if (descriptor != null && "value" in descriptor && containsDeferredPromptValuesForContexts(descriptor.value, seen)) return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
function copySanitizedOwnProperties(source, target, seen) {
|
|
37
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
38
|
+
if (shouldSkipCollectionOwnKey(source, key)) continue;
|
|
39
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
40
|
+
if (descriptor == null) continue;
|
|
41
|
+
if ("value" in descriptor) descriptor.value = stripDeferredPromptValuesForContexts(descriptor.value, seen);
|
|
42
|
+
Object.defineProperty(target, key, descriptor);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function createArrayCloneLike(value$1) {
|
|
46
|
+
try {
|
|
47
|
+
const arrayCtor = value$1.constructor;
|
|
48
|
+
return Reflect.construct(Array, [value$1.length], arrayCtor);
|
|
49
|
+
} catch {
|
|
50
|
+
return new Array(value$1.length);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function createSetCloneLike(value$1) {
|
|
54
|
+
try {
|
|
55
|
+
const setCtor = value$1.constructor;
|
|
56
|
+
return Reflect.construct(Set, [], setCtor);
|
|
57
|
+
} catch {
|
|
58
|
+
return /* @__PURE__ */ new Set();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function createMapCloneLike(value$1) {
|
|
62
|
+
try {
|
|
63
|
+
const mapCtor = value$1.constructor;
|
|
64
|
+
return Reflect.construct(Map, [], mapCtor);
|
|
65
|
+
} catch {
|
|
66
|
+
return /* @__PURE__ */ new Map();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function containsDeferredPromptValuesForContexts(value$1, seen = /* @__PURE__ */ new WeakSet()) {
|
|
70
|
+
if (isDeferredPromptValue(value$1)) return true;
|
|
71
|
+
if (value$1 == null || typeof value$1 !== "object") return false;
|
|
72
|
+
if (seen.has(value$1)) return false;
|
|
73
|
+
seen.add(value$1);
|
|
74
|
+
if (Array.isArray(value$1)) {
|
|
75
|
+
if (value$1.some((item) => containsDeferredPromptValuesForContexts(item, seen))) return true;
|
|
76
|
+
return containsDeferredPromptValuesInOwnProperties(value$1, seen);
|
|
77
|
+
}
|
|
78
|
+
if (value$1 instanceof Set) {
|
|
79
|
+
for (const entryValue of value$1) if (containsDeferredPromptValuesForContexts(entryValue, seen)) return true;
|
|
80
|
+
return containsDeferredPromptValuesInOwnProperties(value$1, seen);
|
|
81
|
+
}
|
|
82
|
+
if (value$1 instanceof Map) {
|
|
83
|
+
for (const [key, entryValue] of value$1) if (containsDeferredPromptValuesForContexts(key, seen) || containsDeferredPromptValuesForContexts(entryValue, seen)) return true;
|
|
84
|
+
return containsDeferredPromptValuesInOwnProperties(value$1, seen);
|
|
85
|
+
}
|
|
86
|
+
return containsDeferredPromptValuesInOwnProperties(value$1, seen);
|
|
87
|
+
}
|
|
88
|
+
function stripDeferredPromptValuesForContexts(value$1, seen = /* @__PURE__ */ new WeakMap()) {
|
|
89
|
+
if (isDeferredPromptValue(value$1)) return void 0;
|
|
90
|
+
if (value$1 == null || typeof value$1 !== "object") return value$1;
|
|
91
|
+
const cached = seen.get(value$1);
|
|
92
|
+
if (cached !== void 0) return cached;
|
|
93
|
+
if (Array.isArray(value$1)) {
|
|
94
|
+
if (!containsDeferredPromptValuesForContexts(value$1)) return value$1;
|
|
95
|
+
const clone$1 = createArrayCloneLike(value$1);
|
|
96
|
+
seen.set(value$1, clone$1);
|
|
97
|
+
for (let i = 0; i < value$1.length; i++) clone$1[i] = stripDeferredPromptValuesForContexts(value$1[i], seen);
|
|
98
|
+
copySanitizedOwnProperties(value$1, clone$1, seen);
|
|
99
|
+
return clone$1;
|
|
100
|
+
}
|
|
101
|
+
if (value$1 instanceof Set) {
|
|
102
|
+
if (!containsDeferredPromptValuesForContexts(value$1)) return value$1;
|
|
103
|
+
const clone$1 = createSetCloneLike(value$1);
|
|
104
|
+
seen.set(value$1, clone$1);
|
|
105
|
+
for (const entryValue of value$1) clone$1.add(stripDeferredPromptValuesForContexts(entryValue, seen));
|
|
106
|
+
copySanitizedOwnProperties(value$1, clone$1, seen);
|
|
107
|
+
return clone$1;
|
|
108
|
+
}
|
|
109
|
+
if (value$1 instanceof Map) {
|
|
110
|
+
if (!containsDeferredPromptValuesForContexts(value$1)) return value$1;
|
|
111
|
+
const clone$1 = createMapCloneLike(value$1);
|
|
112
|
+
seen.set(value$1, clone$1);
|
|
113
|
+
for (const [key, entryValue] of value$1) clone$1.set(stripDeferredPromptValuesForContexts(key, seen), stripDeferredPromptValuesForContexts(entryValue, seen));
|
|
114
|
+
copySanitizedOwnProperties(value$1, clone$1, seen);
|
|
115
|
+
return clone$1;
|
|
116
|
+
}
|
|
117
|
+
if (!isPlainObject(value$1)) {
|
|
118
|
+
if (!containsDeferredPromptValuesForContexts(value$1)) return value$1;
|
|
119
|
+
return createSanitizedNonPlainContextView(value$1, seen);
|
|
120
|
+
}
|
|
121
|
+
const clone = Object.create(Object.getPrototypeOf(value$1));
|
|
122
|
+
seen.set(value$1, clone);
|
|
123
|
+
for (const key of Reflect.ownKeys(value$1)) {
|
|
124
|
+
const descriptor = Object.getOwnPropertyDescriptor(value$1, key);
|
|
125
|
+
if (descriptor == null) continue;
|
|
126
|
+
if ("value" in descriptor) descriptor.value = stripDeferredPromptValuesForContexts(descriptor.value, seen);
|
|
127
|
+
Object.defineProperty(clone, key, descriptor);
|
|
128
|
+
}
|
|
129
|
+
return clone;
|
|
130
|
+
}
|
|
131
|
+
function finalizeParsedForContext(context, parsed) {
|
|
132
|
+
if (parsed !== void 0 || !Reflect.has(context, phase1ConfigAnnotationsKey)) return parsed;
|
|
133
|
+
return { [phase2UndefinedParsedValueKey]: true };
|
|
134
|
+
}
|
|
135
|
+
function createSanitizedNonPlainContextView(value$1, seen) {
|
|
136
|
+
const proxy = new Proxy(value$1, {
|
|
137
|
+
get(target, key, receiver) {
|
|
138
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
139
|
+
if (descriptor != null && "value" in descriptor) return stripDeferredPromptValuesForContexts(descriptor.value, seen);
|
|
140
|
+
return Reflect.get(target, key, receiver);
|
|
141
|
+
},
|
|
142
|
+
getOwnPropertyDescriptor(target, key) {
|
|
143
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
144
|
+
if (descriptor == null || !("value" in descriptor)) return descriptor;
|
|
145
|
+
return {
|
|
146
|
+
...descriptor,
|
|
147
|
+
value: stripDeferredPromptValuesForContexts(descriptor.value, seen)
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
seen.set(value$1, proxy);
|
|
152
|
+
return proxy;
|
|
153
|
+
}
|
|
154
|
+
function prepareParsedForContexts(parsed) {
|
|
155
|
+
if (parsed == null || typeof parsed !== "object") return stripDeferredPromptValuesForContexts(parsed);
|
|
156
|
+
if (isDeferredPromptValue(parsed)) return void 0;
|
|
157
|
+
if (Array.isArray(parsed) || isPlainObject(parsed) || parsed instanceof Set || parsed instanceof Map) {
|
|
158
|
+
if (!containsDeferredPromptValuesForContexts(parsed)) return parsed;
|
|
159
|
+
return stripDeferredPromptValuesForContexts(parsed);
|
|
160
|
+
}
|
|
161
|
+
if (!containsDeferredPromptValuesForContexts(parsed)) return parsed;
|
|
162
|
+
return createSanitizedNonPlainContextView(parsed, /* @__PURE__ */ new WeakMap());
|
|
163
|
+
}
|
|
164
|
+
function withPreparedParsedForContext(context, preparedParsed, run) {
|
|
165
|
+
return run(finalizeParsedForContext(context, preparedParsed));
|
|
166
|
+
}
|
|
14
167
|
/**
|
|
15
168
|
* Creates help parsers based on the sub-config.
|
|
16
169
|
*/
|
|
@@ -850,10 +1003,14 @@ async function collectPhase1Annotations(contexts, options) {
|
|
|
850
1003
|
for (const context of contexts) {
|
|
851
1004
|
const result = context.getAnnotations(void 0, options);
|
|
852
1005
|
hasDynamic ||= needsTwoPhaseContext(context, result);
|
|
853
|
-
|
|
1006
|
+
const annotations = result instanceof Promise ? await result : result;
|
|
1007
|
+
const internalAnnotationsGetter = Reflect.get(context, phase1ConfigAnnotationsKey);
|
|
1008
|
+
const internalAnnotations = typeof internalAnnotationsGetter === "function" ? internalAnnotationsGetter.call(context, void 0, annotations) : void 0;
|
|
1009
|
+
annotationsList.push(internalAnnotations == null ? annotations : mergeAnnotations([annotations, internalAnnotations]));
|
|
854
1010
|
}
|
|
855
1011
|
return {
|
|
856
1012
|
annotations: mergeAnnotations(annotationsList),
|
|
1013
|
+
annotationsList,
|
|
857
1014
|
hasDynamic
|
|
858
1015
|
};
|
|
859
1016
|
}
|
|
@@ -867,11 +1024,21 @@ async function collectPhase1Annotations(contexts, options) {
|
|
|
867
1024
|
*/
|
|
868
1025
|
async function collectAnnotations(contexts, parsed, options) {
|
|
869
1026
|
const annotationsList = [];
|
|
1027
|
+
const preparedParsed = prepareParsedForContexts(parsed);
|
|
870
1028
|
for (const context of contexts) {
|
|
871
|
-
const
|
|
872
|
-
|
|
1029
|
+
const mergedAnnotations = await withPreparedParsedForContext(context, preparedParsed, async (contextParsed) => {
|
|
1030
|
+
const result = context.getAnnotations(contextParsed, options);
|
|
1031
|
+
const annotations = result instanceof Promise ? await result : result;
|
|
1032
|
+
const internalAnnotationsGetter = Reflect.get(context, phase1ConfigAnnotationsKey);
|
|
1033
|
+
const internalAnnotations = typeof internalAnnotationsGetter === "function" ? internalAnnotationsGetter.call(context, contextParsed, annotations) : void 0;
|
|
1034
|
+
return internalAnnotations == null ? annotations : mergeAnnotations([annotations, internalAnnotations]);
|
|
1035
|
+
});
|
|
1036
|
+
annotationsList.push(mergedAnnotations);
|
|
873
1037
|
}
|
|
874
|
-
return
|
|
1038
|
+
return {
|
|
1039
|
+
annotations: mergeAnnotations(annotationsList),
|
|
1040
|
+
annotationsList
|
|
1041
|
+
};
|
|
875
1042
|
}
|
|
876
1043
|
/**
|
|
877
1044
|
* Collects phase 1 annotations from all contexts synchronously and determines
|
|
@@ -889,10 +1056,13 @@ function collectPhase1AnnotationsSync(contexts, options) {
|
|
|
889
1056
|
const result = context.getAnnotations(void 0, options);
|
|
890
1057
|
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
891
1058
|
hasDynamic ||= needsTwoPhaseContext(context, result);
|
|
892
|
-
|
|
1059
|
+
const internalAnnotationsGetter = Reflect.get(context, phase1ConfigAnnotationsKey);
|
|
1060
|
+
const internalAnnotations = typeof internalAnnotationsGetter === "function" ? internalAnnotationsGetter.call(context, void 0, result) : void 0;
|
|
1061
|
+
annotationsList.push(internalAnnotations == null ? result : mergeAnnotations([result, internalAnnotations]));
|
|
893
1062
|
}
|
|
894
1063
|
return {
|
|
895
1064
|
annotations: mergeAnnotations(annotationsList),
|
|
1065
|
+
annotationsList,
|
|
896
1066
|
hasDynamic
|
|
897
1067
|
};
|
|
898
1068
|
}
|
|
@@ -919,12 +1089,27 @@ function needsTwoPhaseContext(context, result) {
|
|
|
919
1089
|
*/
|
|
920
1090
|
function collectAnnotationsSync(contexts, parsed, options) {
|
|
921
1091
|
const annotationsList = [];
|
|
1092
|
+
const preparedParsed = prepareParsedForContexts(parsed);
|
|
922
1093
|
for (const context of contexts) {
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
1094
|
+
const mergedAnnotations = withPreparedParsedForContext(context, preparedParsed, (contextParsed) => {
|
|
1095
|
+
const result = context.getAnnotations(contextParsed, options);
|
|
1096
|
+
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
1097
|
+
const internalAnnotationsGetter = Reflect.get(context, phase1ConfigAnnotationsKey);
|
|
1098
|
+
const internalAnnotations = typeof internalAnnotationsGetter === "function" ? internalAnnotationsGetter.call(context, contextParsed, result) : void 0;
|
|
1099
|
+
return internalAnnotations == null ? result : mergeAnnotations([result, internalAnnotations]);
|
|
1100
|
+
});
|
|
1101
|
+
annotationsList.push(mergedAnnotations);
|
|
926
1102
|
}
|
|
927
|
-
return
|
|
1103
|
+
return {
|
|
1104
|
+
annotations: mergeAnnotations(annotationsList),
|
|
1105
|
+
annotationsList
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
function mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList) {
|
|
1109
|
+
const mergedPerContext = [];
|
|
1110
|
+
const length = Math.max(phase1AnnotationsList.length, phase2AnnotationsList.length);
|
|
1111
|
+
for (let i = 0; i < length; i++) mergedPerContext.push(mergeAnnotations([phase2AnnotationsList[i] ?? {}, phase1AnnotationsList[i] ?? {}]));
|
|
1112
|
+
return mergeAnnotations(mergedPerContext);
|
|
928
1113
|
}
|
|
929
1114
|
/**
|
|
930
1115
|
* Disposes all contexts that implement `AsyncDisposable` or `Disposable`.
|
|
@@ -1022,7 +1207,7 @@ async function runWith(parser, programName, contexts, options) {
|
|
|
1022
1207
|
return Promise.resolve(runParser(parser, programName, args, options));
|
|
1023
1208
|
}
|
|
1024
1209
|
try {
|
|
1025
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, options);
|
|
1210
|
+
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, options);
|
|
1026
1211
|
if (!needsTwoPhase) {
|
|
1027
1212
|
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1028
1213
|
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
@@ -1047,8 +1232,8 @@ async function runWith(parser, programName, contexts, options) {
|
|
|
1047
1232
|
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1048
1233
|
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1049
1234
|
}
|
|
1050
|
-
const
|
|
1051
|
-
const finalAnnotations =
|
|
1235
|
+
const { annotationsList: phase2AnnotationsList } = await collectAnnotations(contexts, firstPassResult, options);
|
|
1236
|
+
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1052
1237
|
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1053
1238
|
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1054
1239
|
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
@@ -1079,7 +1264,7 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1079
1264
|
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1080
1265
|
if (contexts.length === 0) return runParser(parser, programName, args, options);
|
|
1081
1266
|
try {
|
|
1082
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, options);
|
|
1267
|
+
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, options);
|
|
1083
1268
|
if (!needsTwoPhase) {
|
|
1084
1269
|
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1085
1270
|
return runParser(augmentedParser, programName, args, options);
|
|
@@ -1093,8 +1278,8 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1093
1278
|
} catch {
|
|
1094
1279
|
return runParser(augmentedParser1, programName, args, options);
|
|
1095
1280
|
}
|
|
1096
|
-
const
|
|
1097
|
-
const finalAnnotations =
|
|
1281
|
+
const { annotationsList: phase2AnnotationsList } = collectAnnotationsSync(contexts, firstPassResult, options);
|
|
1282
|
+
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1098
1283
|
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1099
1284
|
return runParser(augmentedParser2, programName, args, options);
|
|
1100
1285
|
} finally {
|
package/dist/facade.js
CHANGED
|
@@ -11,6 +11,159 @@ import { argument, command, constant, flag, option } from "./primitives.js";
|
|
|
11
11
|
import { getDocPage, parseAsync, parseSync, suggest, suggestAsync } from "./parser.js";
|
|
12
12
|
|
|
13
13
|
//#region src/facade.ts
|
|
14
|
+
const phase1ConfigAnnotationsKey = Symbol.for("@optique/config/phase1PromptAnnotations");
|
|
15
|
+
const phase2UndefinedParsedValueKey = Symbol.for("@optique/config/phase2UndefinedParsedValue");
|
|
16
|
+
const deferredPromptValueKey = Symbol.for("@optique/inquirer/deferredPromptValue");
|
|
17
|
+
function isDeferredPromptValue(value$1) {
|
|
18
|
+
return value$1 != null && typeof value$1 === "object" && deferredPromptValueKey in value$1;
|
|
19
|
+
}
|
|
20
|
+
function isPlainObject(value$1) {
|
|
21
|
+
const proto = Object.getPrototypeOf(value$1);
|
|
22
|
+
return proto === Object.prototype || proto === null;
|
|
23
|
+
}
|
|
24
|
+
function shouldSkipCollectionOwnKey(value$1, key) {
|
|
25
|
+
if (Array.isArray(value$1)) return key === "length" || typeof key === "string" && Number.isInteger(Number(key)) && String(Number(key)) === key;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
function containsDeferredPromptValuesInOwnProperties(value$1, seen) {
|
|
29
|
+
for (const key of Reflect.ownKeys(value$1)) {
|
|
30
|
+
if (shouldSkipCollectionOwnKey(value$1, key)) continue;
|
|
31
|
+
const descriptor = Object.getOwnPropertyDescriptor(value$1, key);
|
|
32
|
+
if (descriptor != null && "value" in descriptor && containsDeferredPromptValuesForContexts(descriptor.value, seen)) return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
function copySanitizedOwnProperties(source, target, seen) {
|
|
37
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
38
|
+
if (shouldSkipCollectionOwnKey(source, key)) continue;
|
|
39
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
40
|
+
if (descriptor == null) continue;
|
|
41
|
+
if ("value" in descriptor) descriptor.value = stripDeferredPromptValuesForContexts(descriptor.value, seen);
|
|
42
|
+
Object.defineProperty(target, key, descriptor);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function createArrayCloneLike(value$1) {
|
|
46
|
+
try {
|
|
47
|
+
const arrayCtor = value$1.constructor;
|
|
48
|
+
return Reflect.construct(Array, [value$1.length], arrayCtor);
|
|
49
|
+
} catch {
|
|
50
|
+
return new Array(value$1.length);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function createSetCloneLike(value$1) {
|
|
54
|
+
try {
|
|
55
|
+
const setCtor = value$1.constructor;
|
|
56
|
+
return Reflect.construct(Set, [], setCtor);
|
|
57
|
+
} catch {
|
|
58
|
+
return /* @__PURE__ */ new Set();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function createMapCloneLike(value$1) {
|
|
62
|
+
try {
|
|
63
|
+
const mapCtor = value$1.constructor;
|
|
64
|
+
return Reflect.construct(Map, [], mapCtor);
|
|
65
|
+
} catch {
|
|
66
|
+
return /* @__PURE__ */ new Map();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function containsDeferredPromptValuesForContexts(value$1, seen = /* @__PURE__ */ new WeakSet()) {
|
|
70
|
+
if (isDeferredPromptValue(value$1)) return true;
|
|
71
|
+
if (value$1 == null || typeof value$1 !== "object") return false;
|
|
72
|
+
if (seen.has(value$1)) return false;
|
|
73
|
+
seen.add(value$1);
|
|
74
|
+
if (Array.isArray(value$1)) {
|
|
75
|
+
if (value$1.some((item) => containsDeferredPromptValuesForContexts(item, seen))) return true;
|
|
76
|
+
return containsDeferredPromptValuesInOwnProperties(value$1, seen);
|
|
77
|
+
}
|
|
78
|
+
if (value$1 instanceof Set) {
|
|
79
|
+
for (const entryValue of value$1) if (containsDeferredPromptValuesForContexts(entryValue, seen)) return true;
|
|
80
|
+
return containsDeferredPromptValuesInOwnProperties(value$1, seen);
|
|
81
|
+
}
|
|
82
|
+
if (value$1 instanceof Map) {
|
|
83
|
+
for (const [key, entryValue] of value$1) if (containsDeferredPromptValuesForContexts(key, seen) || containsDeferredPromptValuesForContexts(entryValue, seen)) return true;
|
|
84
|
+
return containsDeferredPromptValuesInOwnProperties(value$1, seen);
|
|
85
|
+
}
|
|
86
|
+
return containsDeferredPromptValuesInOwnProperties(value$1, seen);
|
|
87
|
+
}
|
|
88
|
+
function stripDeferredPromptValuesForContexts(value$1, seen = /* @__PURE__ */ new WeakMap()) {
|
|
89
|
+
if (isDeferredPromptValue(value$1)) return void 0;
|
|
90
|
+
if (value$1 == null || typeof value$1 !== "object") return value$1;
|
|
91
|
+
const cached = seen.get(value$1);
|
|
92
|
+
if (cached !== void 0) return cached;
|
|
93
|
+
if (Array.isArray(value$1)) {
|
|
94
|
+
if (!containsDeferredPromptValuesForContexts(value$1)) return value$1;
|
|
95
|
+
const clone$1 = createArrayCloneLike(value$1);
|
|
96
|
+
seen.set(value$1, clone$1);
|
|
97
|
+
for (let i = 0; i < value$1.length; i++) clone$1[i] = stripDeferredPromptValuesForContexts(value$1[i], seen);
|
|
98
|
+
copySanitizedOwnProperties(value$1, clone$1, seen);
|
|
99
|
+
return clone$1;
|
|
100
|
+
}
|
|
101
|
+
if (value$1 instanceof Set) {
|
|
102
|
+
if (!containsDeferredPromptValuesForContexts(value$1)) return value$1;
|
|
103
|
+
const clone$1 = createSetCloneLike(value$1);
|
|
104
|
+
seen.set(value$1, clone$1);
|
|
105
|
+
for (const entryValue of value$1) clone$1.add(stripDeferredPromptValuesForContexts(entryValue, seen));
|
|
106
|
+
copySanitizedOwnProperties(value$1, clone$1, seen);
|
|
107
|
+
return clone$1;
|
|
108
|
+
}
|
|
109
|
+
if (value$1 instanceof Map) {
|
|
110
|
+
if (!containsDeferredPromptValuesForContexts(value$1)) return value$1;
|
|
111
|
+
const clone$1 = createMapCloneLike(value$1);
|
|
112
|
+
seen.set(value$1, clone$1);
|
|
113
|
+
for (const [key, entryValue] of value$1) clone$1.set(stripDeferredPromptValuesForContexts(key, seen), stripDeferredPromptValuesForContexts(entryValue, seen));
|
|
114
|
+
copySanitizedOwnProperties(value$1, clone$1, seen);
|
|
115
|
+
return clone$1;
|
|
116
|
+
}
|
|
117
|
+
if (!isPlainObject(value$1)) {
|
|
118
|
+
if (!containsDeferredPromptValuesForContexts(value$1)) return value$1;
|
|
119
|
+
return createSanitizedNonPlainContextView(value$1, seen);
|
|
120
|
+
}
|
|
121
|
+
const clone = Object.create(Object.getPrototypeOf(value$1));
|
|
122
|
+
seen.set(value$1, clone);
|
|
123
|
+
for (const key of Reflect.ownKeys(value$1)) {
|
|
124
|
+
const descriptor = Object.getOwnPropertyDescriptor(value$1, key);
|
|
125
|
+
if (descriptor == null) continue;
|
|
126
|
+
if ("value" in descriptor) descriptor.value = stripDeferredPromptValuesForContexts(descriptor.value, seen);
|
|
127
|
+
Object.defineProperty(clone, key, descriptor);
|
|
128
|
+
}
|
|
129
|
+
return clone;
|
|
130
|
+
}
|
|
131
|
+
function finalizeParsedForContext(context, parsed) {
|
|
132
|
+
if (parsed !== void 0 || !Reflect.has(context, phase1ConfigAnnotationsKey)) return parsed;
|
|
133
|
+
return { [phase2UndefinedParsedValueKey]: true };
|
|
134
|
+
}
|
|
135
|
+
function createSanitizedNonPlainContextView(value$1, seen) {
|
|
136
|
+
const proxy = new Proxy(value$1, {
|
|
137
|
+
get(target, key, receiver) {
|
|
138
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
139
|
+
if (descriptor != null && "value" in descriptor) return stripDeferredPromptValuesForContexts(descriptor.value, seen);
|
|
140
|
+
return Reflect.get(target, key, receiver);
|
|
141
|
+
},
|
|
142
|
+
getOwnPropertyDescriptor(target, key) {
|
|
143
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
144
|
+
if (descriptor == null || !("value" in descriptor)) return descriptor;
|
|
145
|
+
return {
|
|
146
|
+
...descriptor,
|
|
147
|
+
value: stripDeferredPromptValuesForContexts(descriptor.value, seen)
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
seen.set(value$1, proxy);
|
|
152
|
+
return proxy;
|
|
153
|
+
}
|
|
154
|
+
function prepareParsedForContexts(parsed) {
|
|
155
|
+
if (parsed == null || typeof parsed !== "object") return stripDeferredPromptValuesForContexts(parsed);
|
|
156
|
+
if (isDeferredPromptValue(parsed)) return void 0;
|
|
157
|
+
if (Array.isArray(parsed) || isPlainObject(parsed) || parsed instanceof Set || parsed instanceof Map) {
|
|
158
|
+
if (!containsDeferredPromptValuesForContexts(parsed)) return parsed;
|
|
159
|
+
return stripDeferredPromptValuesForContexts(parsed);
|
|
160
|
+
}
|
|
161
|
+
if (!containsDeferredPromptValuesForContexts(parsed)) return parsed;
|
|
162
|
+
return createSanitizedNonPlainContextView(parsed, /* @__PURE__ */ new WeakMap());
|
|
163
|
+
}
|
|
164
|
+
function withPreparedParsedForContext(context, preparedParsed, run) {
|
|
165
|
+
return run(finalizeParsedForContext(context, preparedParsed));
|
|
166
|
+
}
|
|
14
167
|
/**
|
|
15
168
|
* Creates help parsers based on the sub-config.
|
|
16
169
|
*/
|
|
@@ -850,10 +1003,14 @@ async function collectPhase1Annotations(contexts, options) {
|
|
|
850
1003
|
for (const context of contexts) {
|
|
851
1004
|
const result = context.getAnnotations(void 0, options);
|
|
852
1005
|
hasDynamic ||= needsTwoPhaseContext(context, result);
|
|
853
|
-
|
|
1006
|
+
const annotations = result instanceof Promise ? await result : result;
|
|
1007
|
+
const internalAnnotationsGetter = Reflect.get(context, phase1ConfigAnnotationsKey);
|
|
1008
|
+
const internalAnnotations = typeof internalAnnotationsGetter === "function" ? internalAnnotationsGetter.call(context, void 0, annotations) : void 0;
|
|
1009
|
+
annotationsList.push(internalAnnotations == null ? annotations : mergeAnnotations([annotations, internalAnnotations]));
|
|
854
1010
|
}
|
|
855
1011
|
return {
|
|
856
1012
|
annotations: mergeAnnotations(annotationsList),
|
|
1013
|
+
annotationsList,
|
|
857
1014
|
hasDynamic
|
|
858
1015
|
};
|
|
859
1016
|
}
|
|
@@ -867,11 +1024,21 @@ async function collectPhase1Annotations(contexts, options) {
|
|
|
867
1024
|
*/
|
|
868
1025
|
async function collectAnnotations(contexts, parsed, options) {
|
|
869
1026
|
const annotationsList = [];
|
|
1027
|
+
const preparedParsed = prepareParsedForContexts(parsed);
|
|
870
1028
|
for (const context of contexts) {
|
|
871
|
-
const
|
|
872
|
-
|
|
1029
|
+
const mergedAnnotations = await withPreparedParsedForContext(context, preparedParsed, async (contextParsed) => {
|
|
1030
|
+
const result = context.getAnnotations(contextParsed, options);
|
|
1031
|
+
const annotations = result instanceof Promise ? await result : result;
|
|
1032
|
+
const internalAnnotationsGetter = Reflect.get(context, phase1ConfigAnnotationsKey);
|
|
1033
|
+
const internalAnnotations = typeof internalAnnotationsGetter === "function" ? internalAnnotationsGetter.call(context, contextParsed, annotations) : void 0;
|
|
1034
|
+
return internalAnnotations == null ? annotations : mergeAnnotations([annotations, internalAnnotations]);
|
|
1035
|
+
});
|
|
1036
|
+
annotationsList.push(mergedAnnotations);
|
|
873
1037
|
}
|
|
874
|
-
return
|
|
1038
|
+
return {
|
|
1039
|
+
annotations: mergeAnnotations(annotationsList),
|
|
1040
|
+
annotationsList
|
|
1041
|
+
};
|
|
875
1042
|
}
|
|
876
1043
|
/**
|
|
877
1044
|
* Collects phase 1 annotations from all contexts synchronously and determines
|
|
@@ -889,10 +1056,13 @@ function collectPhase1AnnotationsSync(contexts, options) {
|
|
|
889
1056
|
const result = context.getAnnotations(void 0, options);
|
|
890
1057
|
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
891
1058
|
hasDynamic ||= needsTwoPhaseContext(context, result);
|
|
892
|
-
|
|
1059
|
+
const internalAnnotationsGetter = Reflect.get(context, phase1ConfigAnnotationsKey);
|
|
1060
|
+
const internalAnnotations = typeof internalAnnotationsGetter === "function" ? internalAnnotationsGetter.call(context, void 0, result) : void 0;
|
|
1061
|
+
annotationsList.push(internalAnnotations == null ? result : mergeAnnotations([result, internalAnnotations]));
|
|
893
1062
|
}
|
|
894
1063
|
return {
|
|
895
1064
|
annotations: mergeAnnotations(annotationsList),
|
|
1065
|
+
annotationsList,
|
|
896
1066
|
hasDynamic
|
|
897
1067
|
};
|
|
898
1068
|
}
|
|
@@ -919,12 +1089,27 @@ function needsTwoPhaseContext(context, result) {
|
|
|
919
1089
|
*/
|
|
920
1090
|
function collectAnnotationsSync(contexts, parsed, options) {
|
|
921
1091
|
const annotationsList = [];
|
|
1092
|
+
const preparedParsed = prepareParsedForContexts(parsed);
|
|
922
1093
|
for (const context of contexts) {
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
1094
|
+
const mergedAnnotations = withPreparedParsedForContext(context, preparedParsed, (contextParsed) => {
|
|
1095
|
+
const result = context.getAnnotations(contextParsed, options);
|
|
1096
|
+
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
1097
|
+
const internalAnnotationsGetter = Reflect.get(context, phase1ConfigAnnotationsKey);
|
|
1098
|
+
const internalAnnotations = typeof internalAnnotationsGetter === "function" ? internalAnnotationsGetter.call(context, contextParsed, result) : void 0;
|
|
1099
|
+
return internalAnnotations == null ? result : mergeAnnotations([result, internalAnnotations]);
|
|
1100
|
+
});
|
|
1101
|
+
annotationsList.push(mergedAnnotations);
|
|
926
1102
|
}
|
|
927
|
-
return
|
|
1103
|
+
return {
|
|
1104
|
+
annotations: mergeAnnotations(annotationsList),
|
|
1105
|
+
annotationsList
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
function mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList) {
|
|
1109
|
+
const mergedPerContext = [];
|
|
1110
|
+
const length = Math.max(phase1AnnotationsList.length, phase2AnnotationsList.length);
|
|
1111
|
+
for (let i = 0; i < length; i++) mergedPerContext.push(mergeAnnotations([phase2AnnotationsList[i] ?? {}, phase1AnnotationsList[i] ?? {}]));
|
|
1112
|
+
return mergeAnnotations(mergedPerContext);
|
|
928
1113
|
}
|
|
929
1114
|
/**
|
|
930
1115
|
* Disposes all contexts that implement `AsyncDisposable` or `Disposable`.
|
|
@@ -1022,7 +1207,7 @@ async function runWith(parser, programName, contexts, options) {
|
|
|
1022
1207
|
return Promise.resolve(runParser(parser, programName, args, options));
|
|
1023
1208
|
}
|
|
1024
1209
|
try {
|
|
1025
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, options);
|
|
1210
|
+
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, options);
|
|
1026
1211
|
if (!needsTwoPhase) {
|
|
1027
1212
|
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1028
1213
|
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
@@ -1047,8 +1232,8 @@ async function runWith(parser, programName, contexts, options) {
|
|
|
1047
1232
|
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1048
1233
|
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1049
1234
|
}
|
|
1050
|
-
const
|
|
1051
|
-
const finalAnnotations =
|
|
1235
|
+
const { annotationsList: phase2AnnotationsList } = await collectAnnotations(contexts, firstPassResult, options);
|
|
1236
|
+
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1052
1237
|
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1053
1238
|
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1054
1239
|
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
@@ -1079,7 +1264,7 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1079
1264
|
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1080
1265
|
if (contexts.length === 0) return runParser(parser, programName, args, options);
|
|
1081
1266
|
try {
|
|
1082
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, options);
|
|
1267
|
+
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, options);
|
|
1083
1268
|
if (!needsTwoPhase) {
|
|
1084
1269
|
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1085
1270
|
return runParser(augmentedParser, programName, args, options);
|
|
@@ -1093,8 +1278,8 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1093
1278
|
} catch {
|
|
1094
1279
|
return runParser(augmentedParser1, programName, args, options);
|
|
1095
1280
|
}
|
|
1096
|
-
const
|
|
1097
|
-
const finalAnnotations =
|
|
1281
|
+
const { annotationsList: phase2AnnotationsList } = collectAnnotationsSync(contexts, firstPassResult, options);
|
|
1282
|
+
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1098
1283
|
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1099
1284
|
return runParser(augmentedParser2, programName, args, options);
|
|
1100
1285
|
} finally {
|