@optique/core 1.0.0-dev.1596 → 1.0.0-dev.1602
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/dependency-metadata.cjs +140 -0
- package/dist/dependency-metadata.d.cts +108 -0
- package/dist/dependency-metadata.d.ts +108 -0
- package/dist/dependency-metadata.js +139 -0
- package/dist/dependency-runtime.d.cts +123 -0
- package/dist/dependency-runtime.d.ts +123 -0
- package/dist/dependency.cjs +14 -0
- package/dist/dependency.d.cts +19 -1
- package/dist/dependency.d.ts +19 -1
- package/dist/dependency.js +14 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/modifiers.cjs +64 -0
- package/dist/modifiers.js +64 -0
- package/dist/parser.d.cts +17 -0
- package/dist/parser.d.ts +17 -0
- package/dist/primitives.cjs +7 -0
- package/dist/primitives.js +7 -0
- package/dist/valueparser.cjs +10 -14
- package/dist/valueparser.js +10 -14
- package/package.json +1 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
const require_dependency = require('./dependency.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/dependency-metadata.ts
|
|
4
|
+
/**
|
|
5
|
+
* Extracts {@link ParserDependencyMetadata} from a value parser by reading
|
|
6
|
+
* old-protocol markers (`dependencySourceMarker`, `derivedValueParserMarker`,
|
|
7
|
+
* etc.).
|
|
8
|
+
*
|
|
9
|
+
* Returns `undefined` if the parser has no dependency-related markers.
|
|
10
|
+
*
|
|
11
|
+
* @param valueParser The value parser to inspect.
|
|
12
|
+
* @returns Metadata, or `undefined` for plain parsers.
|
|
13
|
+
* @internal
|
|
14
|
+
* @since 1.0.0
|
|
15
|
+
*/
|
|
16
|
+
function extractDependencyMetadata(valueParser) {
|
|
17
|
+
if (require_dependency.isDependencySource(valueParser)) return { source: {
|
|
18
|
+
kind: "source",
|
|
19
|
+
sourceId: valueParser[require_dependency.dependencyId],
|
|
20
|
+
extractSourceValue: extractFromBareState,
|
|
21
|
+
preservesSourceValue: true
|
|
22
|
+
} };
|
|
23
|
+
if (require_dependency.isDerivedValueParser(valueParser)) {
|
|
24
|
+
const isMultiSource = require_dependency.dependencyIds in valueParser && valueParser[require_dependency.dependencyIds] != null;
|
|
25
|
+
const allIds = isMultiSource ? valueParser[require_dependency.dependencyIds] : [valueParser[require_dependency.dependencyId]];
|
|
26
|
+
let defaultValuesFn;
|
|
27
|
+
if (require_dependency.defaultValues in valueParser && valueParser[require_dependency.defaultValues] != null) defaultValuesFn = valueParser[require_dependency.defaultValues];
|
|
28
|
+
else if (require_dependency.singleDefaultValue in valueParser && valueParser[require_dependency.singleDefaultValue] != null) {
|
|
29
|
+
const singleFn = valueParser[require_dependency.singleDefaultValue];
|
|
30
|
+
defaultValuesFn = () => [singleFn()];
|
|
31
|
+
}
|
|
32
|
+
const parser = valueParser;
|
|
33
|
+
const replayParse = (rawInput, depValues) => {
|
|
34
|
+
const depArg = isMultiSource ? depValues : depValues[0];
|
|
35
|
+
return parser[require_dependency.parseWithDependency](rawInput, depArg);
|
|
36
|
+
};
|
|
37
|
+
const suggestFn = require_dependency.suggestWithDependency in parser ? parser[require_dependency.suggestWithDependency] : void 0;
|
|
38
|
+
const replaySuggest = suggestFn != null ? (prefix, depValues) => {
|
|
39
|
+
const depArg = isMultiSource ? depValues : depValues[0];
|
|
40
|
+
return suggestFn(prefix, depArg);
|
|
41
|
+
} : void 0;
|
|
42
|
+
return { derived: {
|
|
43
|
+
kind: "derived",
|
|
44
|
+
dependencyIds: allIds,
|
|
45
|
+
getDefaultDependencyValues: defaultValuesFn,
|
|
46
|
+
replayParse,
|
|
47
|
+
replaySuggest
|
|
48
|
+
} };
|
|
49
|
+
}
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extracts the source parse result from a bare `DependencySourceState`.
|
|
54
|
+
* Used as the base `extractSourceValue` for plain dependency sources.
|
|
55
|
+
*/
|
|
56
|
+
function extractFromBareState(state) {
|
|
57
|
+
if (!require_dependency.isDependencySourceState(state)) return void 0;
|
|
58
|
+
return state.result;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Wraps an inner `extractSourceValue` to unwrap `[innerState]` first.
|
|
62
|
+
* Used by `optional()` and `withDefault()` which wrap state in a
|
|
63
|
+
* single-element array.
|
|
64
|
+
*/
|
|
65
|
+
function unwrapArrayThenExtract(innerExtract) {
|
|
66
|
+
return (state) => {
|
|
67
|
+
if (Array.isArray(state) && state.length === 1) return innerExtract(state[0]);
|
|
68
|
+
return innerExtract(state);
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Composes dependency metadata through a modifier wrapper.
|
|
73
|
+
*
|
|
74
|
+
* - `"optional"`: composes `extractSourceValue` with array unwrapping.
|
|
75
|
+
* - `"withDefault"`: adds `getMissingSourceValue` if the inner parser
|
|
76
|
+
* preserves a dependency source.
|
|
77
|
+
* - `"map"`: sets `transformsSourceValue` and clears
|
|
78
|
+
* `preservesSourceValue`.
|
|
79
|
+
*
|
|
80
|
+
* Returns `undefined` if `inner` is `undefined`.
|
|
81
|
+
*
|
|
82
|
+
* @param inner The inner parser's metadata.
|
|
83
|
+
* @param wrapperKind The type of modifier being applied.
|
|
84
|
+
* @param options Additional options for certain wrapper kinds.
|
|
85
|
+
* @returns Composed metadata, or `undefined`.
|
|
86
|
+
* @internal
|
|
87
|
+
* @since 1.0.0
|
|
88
|
+
*/
|
|
89
|
+
function composeDependencyMetadata(inner, wrapperKind, options) {
|
|
90
|
+
if (inner === void 0) return void 0;
|
|
91
|
+
switch (wrapperKind) {
|
|
92
|
+
case "optional": {
|
|
93
|
+
if (inner.source != null && inner.source.extractSourceValue != null) return {
|
|
94
|
+
...inner,
|
|
95
|
+
source: {
|
|
96
|
+
...inner.source,
|
|
97
|
+
extractSourceValue: unwrapArrayThenExtract(inner.source.extractSourceValue)
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
return inner;
|
|
101
|
+
}
|
|
102
|
+
case "withDefault": {
|
|
103
|
+
const wrappedExtract = inner.source?.extractSourceValue != null ? unwrapArrayThenExtract(inner.source.extractSourceValue) : void 0;
|
|
104
|
+
if (inner.source != null && inner.source.preservesSourceValue) return {
|
|
105
|
+
...inner,
|
|
106
|
+
source: {
|
|
107
|
+
...inner.source,
|
|
108
|
+
...wrappedExtract != null && { extractSourceValue: wrappedExtract },
|
|
109
|
+
getMissingSourceValue: options?.defaultValue
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
if (wrappedExtract != null && inner.source != null) return {
|
|
113
|
+
...inner,
|
|
114
|
+
source: {
|
|
115
|
+
...inner.source,
|
|
116
|
+
extractSourceValue: wrappedExtract
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
return inner;
|
|
120
|
+
}
|
|
121
|
+
case "map": {
|
|
122
|
+
const result = {
|
|
123
|
+
...inner,
|
|
124
|
+
transform: { transformsSourceValue: true }
|
|
125
|
+
};
|
|
126
|
+
if (inner.source != null) return {
|
|
127
|
+
...result,
|
|
128
|
+
source: {
|
|
129
|
+
...inner.source,
|
|
130
|
+
preservesSourceValue: false
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
exports.composeDependencyMetadata = composeDependencyMetadata;
|
|
140
|
+
exports.extractDependencyMetadata = extractDependencyMetadata;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { ValueParserResult } from "./valueparser.cjs";
|
|
2
|
+
import { Suggestion } from "./parser.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/dependency-metadata.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Metadata for a parser that is a dependency source.
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
* @since 1.0.0
|
|
11
|
+
*/
|
|
12
|
+
interface DependencySourceCapability {
|
|
13
|
+
/** Discriminant tag. */
|
|
14
|
+
readonly kind: "source";
|
|
15
|
+
/** The unique dependency source identifier. */
|
|
16
|
+
readonly sourceId: symbol;
|
|
17
|
+
/**
|
|
18
|
+
* Extracts the dependency source parse result from the parser's state.
|
|
19
|
+
*
|
|
20
|
+
* Each wrapper composes this method to handle its state shape:
|
|
21
|
+
* - plain source: reads from `DependencySourceState`
|
|
22
|
+
* - `optional()` / `withDefault()`: unwraps `[innerState]` first
|
|
23
|
+
* - `map()`: reads the pre-transform value from inner state
|
|
24
|
+
*
|
|
25
|
+
* Returns the `ValueParserResult` (which may be successful with any
|
|
26
|
+
* value including `undefined`, or failed), or `undefined` if the state
|
|
27
|
+
* does not contain a source result at all (unpopulated / wrong shape).
|
|
28
|
+
*/
|
|
29
|
+
readonly extractSourceValue: (state: unknown) => ValueParserResult<unknown> | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* When present, provides a missing-source value (e.g., from a
|
|
32
|
+
* `withDefault()` wrapper). Called during the `fillMissingSourceDefaults`
|
|
33
|
+
* phase of the dependency runtime.
|
|
34
|
+
*/
|
|
35
|
+
readonly getMissingSourceValue?: () => ValueParserResult<unknown> | Promise<ValueParserResult<unknown>>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the parser's output value is the actual dependency source value.
|
|
38
|
+
* `false` when a transform like `map()` has been applied.
|
|
39
|
+
*/
|
|
40
|
+
readonly preservesSourceValue: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Metadata for a parser that depends on one or more dependency sources.
|
|
44
|
+
*
|
|
45
|
+
* @internal
|
|
46
|
+
* @since 1.0.0
|
|
47
|
+
*/
|
|
48
|
+
interface DerivedDependencyCapability {
|
|
49
|
+
/** Discriminant tag. */
|
|
50
|
+
readonly kind: "derived";
|
|
51
|
+
/** The dependency source IDs this parser depends on. */
|
|
52
|
+
readonly dependencyIds: readonly symbol[];
|
|
53
|
+
/**
|
|
54
|
+
* Returns default values for each dependency, used when the
|
|
55
|
+
* corresponding sources are not provided.
|
|
56
|
+
*/
|
|
57
|
+
readonly getDefaultDependencyValues?: () => readonly unknown[];
|
|
58
|
+
/**
|
|
59
|
+
* Replays a parse with the given raw input and resolved dependency values.
|
|
60
|
+
*/
|
|
61
|
+
readonly replayParse: (rawInput: string, dependencyValues: readonly unknown[]) => ValueParserResult<unknown> | Promise<ValueParserResult<unknown>>;
|
|
62
|
+
/**
|
|
63
|
+
* Replays suggestions with the given prefix and resolved dependency values.
|
|
64
|
+
*/
|
|
65
|
+
readonly replaySuggest?: (prefix: string, dependencyValues: readonly unknown[]) => Iterable<Suggestion> | AsyncIterable<Suggestion>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Metadata indicating that a wrapper transforms the dependency source value.
|
|
69
|
+
*
|
|
70
|
+
* @internal
|
|
71
|
+
* @since 1.0.0
|
|
72
|
+
*/
|
|
73
|
+
interface DependencyTransformCapability {
|
|
74
|
+
/** Whether the wrapper transforms the source value. */
|
|
75
|
+
readonly transformsSourceValue: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Composed dependency metadata for a parser node.
|
|
79
|
+
*
|
|
80
|
+
* A parser may have any combination of source, derived, and transform
|
|
81
|
+
* capabilities. In practice, a parser is typically either a source or
|
|
82
|
+
* derived, never both.
|
|
83
|
+
*
|
|
84
|
+
* @internal
|
|
85
|
+
* @since 1.0.0
|
|
86
|
+
*/
|
|
87
|
+
interface ParserDependencyMetadata {
|
|
88
|
+
/** Present if the parser is (or wraps) a dependency source. */
|
|
89
|
+
readonly source?: DependencySourceCapability;
|
|
90
|
+
/** Present if the parser depends on one or more sources. */
|
|
91
|
+
readonly derived?: DerivedDependencyCapability;
|
|
92
|
+
/** Present if a transform has been applied. */
|
|
93
|
+
readonly transform?: DependencyTransformCapability;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Extracts {@link ParserDependencyMetadata} from a value parser by reading
|
|
97
|
+
* old-protocol markers (`dependencySourceMarker`, `derivedValueParserMarker`,
|
|
98
|
+
* etc.).
|
|
99
|
+
*
|
|
100
|
+
* Returns `undefined` if the parser has no dependency-related markers.
|
|
101
|
+
*
|
|
102
|
+
* @param valueParser The value parser to inspect.
|
|
103
|
+
* @returns Metadata, or `undefined` for plain parsers.
|
|
104
|
+
* @internal
|
|
105
|
+
* @since 1.0.0
|
|
106
|
+
*/
|
|
107
|
+
//#endregion
|
|
108
|
+
export { ParserDependencyMetadata };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { ValueParserResult } from "./valueparser.js";
|
|
2
|
+
import { Suggestion } from "./parser.js";
|
|
3
|
+
|
|
4
|
+
//#region src/dependency-metadata.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Metadata for a parser that is a dependency source.
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
* @since 1.0.0
|
|
11
|
+
*/
|
|
12
|
+
interface DependencySourceCapability {
|
|
13
|
+
/** Discriminant tag. */
|
|
14
|
+
readonly kind: "source";
|
|
15
|
+
/** The unique dependency source identifier. */
|
|
16
|
+
readonly sourceId: symbol;
|
|
17
|
+
/**
|
|
18
|
+
* Extracts the dependency source parse result from the parser's state.
|
|
19
|
+
*
|
|
20
|
+
* Each wrapper composes this method to handle its state shape:
|
|
21
|
+
* - plain source: reads from `DependencySourceState`
|
|
22
|
+
* - `optional()` / `withDefault()`: unwraps `[innerState]` first
|
|
23
|
+
* - `map()`: reads the pre-transform value from inner state
|
|
24
|
+
*
|
|
25
|
+
* Returns the `ValueParserResult` (which may be successful with any
|
|
26
|
+
* value including `undefined`, or failed), or `undefined` if the state
|
|
27
|
+
* does not contain a source result at all (unpopulated / wrong shape).
|
|
28
|
+
*/
|
|
29
|
+
readonly extractSourceValue: (state: unknown) => ValueParserResult<unknown> | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* When present, provides a missing-source value (e.g., from a
|
|
32
|
+
* `withDefault()` wrapper). Called during the `fillMissingSourceDefaults`
|
|
33
|
+
* phase of the dependency runtime.
|
|
34
|
+
*/
|
|
35
|
+
readonly getMissingSourceValue?: () => ValueParserResult<unknown> | Promise<ValueParserResult<unknown>>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the parser's output value is the actual dependency source value.
|
|
38
|
+
* `false` when a transform like `map()` has been applied.
|
|
39
|
+
*/
|
|
40
|
+
readonly preservesSourceValue: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Metadata for a parser that depends on one or more dependency sources.
|
|
44
|
+
*
|
|
45
|
+
* @internal
|
|
46
|
+
* @since 1.0.0
|
|
47
|
+
*/
|
|
48
|
+
interface DerivedDependencyCapability {
|
|
49
|
+
/** Discriminant tag. */
|
|
50
|
+
readonly kind: "derived";
|
|
51
|
+
/** The dependency source IDs this parser depends on. */
|
|
52
|
+
readonly dependencyIds: readonly symbol[];
|
|
53
|
+
/**
|
|
54
|
+
* Returns default values for each dependency, used when the
|
|
55
|
+
* corresponding sources are not provided.
|
|
56
|
+
*/
|
|
57
|
+
readonly getDefaultDependencyValues?: () => readonly unknown[];
|
|
58
|
+
/**
|
|
59
|
+
* Replays a parse with the given raw input and resolved dependency values.
|
|
60
|
+
*/
|
|
61
|
+
readonly replayParse: (rawInput: string, dependencyValues: readonly unknown[]) => ValueParserResult<unknown> | Promise<ValueParserResult<unknown>>;
|
|
62
|
+
/**
|
|
63
|
+
* Replays suggestions with the given prefix and resolved dependency values.
|
|
64
|
+
*/
|
|
65
|
+
readonly replaySuggest?: (prefix: string, dependencyValues: readonly unknown[]) => Iterable<Suggestion> | AsyncIterable<Suggestion>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Metadata indicating that a wrapper transforms the dependency source value.
|
|
69
|
+
*
|
|
70
|
+
* @internal
|
|
71
|
+
* @since 1.0.0
|
|
72
|
+
*/
|
|
73
|
+
interface DependencyTransformCapability {
|
|
74
|
+
/** Whether the wrapper transforms the source value. */
|
|
75
|
+
readonly transformsSourceValue: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Composed dependency metadata for a parser node.
|
|
79
|
+
*
|
|
80
|
+
* A parser may have any combination of source, derived, and transform
|
|
81
|
+
* capabilities. In practice, a parser is typically either a source or
|
|
82
|
+
* derived, never both.
|
|
83
|
+
*
|
|
84
|
+
* @internal
|
|
85
|
+
* @since 1.0.0
|
|
86
|
+
*/
|
|
87
|
+
interface ParserDependencyMetadata {
|
|
88
|
+
/** Present if the parser is (or wraps) a dependency source. */
|
|
89
|
+
readonly source?: DependencySourceCapability;
|
|
90
|
+
/** Present if the parser depends on one or more sources. */
|
|
91
|
+
readonly derived?: DerivedDependencyCapability;
|
|
92
|
+
/** Present if a transform has been applied. */
|
|
93
|
+
readonly transform?: DependencyTransformCapability;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Extracts {@link ParserDependencyMetadata} from a value parser by reading
|
|
97
|
+
* old-protocol markers (`dependencySourceMarker`, `derivedValueParserMarker`,
|
|
98
|
+
* etc.).
|
|
99
|
+
*
|
|
100
|
+
* Returns `undefined` if the parser has no dependency-related markers.
|
|
101
|
+
*
|
|
102
|
+
* @param valueParser The value parser to inspect.
|
|
103
|
+
* @returns Metadata, or `undefined` for plain parsers.
|
|
104
|
+
* @internal
|
|
105
|
+
* @since 1.0.0
|
|
106
|
+
*/
|
|
107
|
+
//#endregion
|
|
108
|
+
export { ParserDependencyMetadata };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { defaultValues, dependencyId, dependencyIds, isDependencySource, isDependencySourceState, isDerivedValueParser, parseWithDependency, singleDefaultValue, suggestWithDependency } from "./dependency.js";
|
|
2
|
+
|
|
3
|
+
//#region src/dependency-metadata.ts
|
|
4
|
+
/**
|
|
5
|
+
* Extracts {@link ParserDependencyMetadata} from a value parser by reading
|
|
6
|
+
* old-protocol markers (`dependencySourceMarker`, `derivedValueParserMarker`,
|
|
7
|
+
* etc.).
|
|
8
|
+
*
|
|
9
|
+
* Returns `undefined` if the parser has no dependency-related markers.
|
|
10
|
+
*
|
|
11
|
+
* @param valueParser The value parser to inspect.
|
|
12
|
+
* @returns Metadata, or `undefined` for plain parsers.
|
|
13
|
+
* @internal
|
|
14
|
+
* @since 1.0.0
|
|
15
|
+
*/
|
|
16
|
+
function extractDependencyMetadata(valueParser) {
|
|
17
|
+
if (isDependencySource(valueParser)) return { source: {
|
|
18
|
+
kind: "source",
|
|
19
|
+
sourceId: valueParser[dependencyId],
|
|
20
|
+
extractSourceValue: extractFromBareState,
|
|
21
|
+
preservesSourceValue: true
|
|
22
|
+
} };
|
|
23
|
+
if (isDerivedValueParser(valueParser)) {
|
|
24
|
+
const isMultiSource = dependencyIds in valueParser && valueParser[dependencyIds] != null;
|
|
25
|
+
const allIds = isMultiSource ? valueParser[dependencyIds] : [valueParser[dependencyId]];
|
|
26
|
+
let defaultValuesFn;
|
|
27
|
+
if (defaultValues in valueParser && valueParser[defaultValues] != null) defaultValuesFn = valueParser[defaultValues];
|
|
28
|
+
else if (singleDefaultValue in valueParser && valueParser[singleDefaultValue] != null) {
|
|
29
|
+
const singleFn = valueParser[singleDefaultValue];
|
|
30
|
+
defaultValuesFn = () => [singleFn()];
|
|
31
|
+
}
|
|
32
|
+
const parser = valueParser;
|
|
33
|
+
const replayParse = (rawInput, depValues) => {
|
|
34
|
+
const depArg = isMultiSource ? depValues : depValues[0];
|
|
35
|
+
return parser[parseWithDependency](rawInput, depArg);
|
|
36
|
+
};
|
|
37
|
+
const suggestFn = suggestWithDependency in parser ? parser[suggestWithDependency] : void 0;
|
|
38
|
+
const replaySuggest = suggestFn != null ? (prefix, depValues) => {
|
|
39
|
+
const depArg = isMultiSource ? depValues : depValues[0];
|
|
40
|
+
return suggestFn(prefix, depArg);
|
|
41
|
+
} : void 0;
|
|
42
|
+
return { derived: {
|
|
43
|
+
kind: "derived",
|
|
44
|
+
dependencyIds: allIds,
|
|
45
|
+
getDefaultDependencyValues: defaultValuesFn,
|
|
46
|
+
replayParse,
|
|
47
|
+
replaySuggest
|
|
48
|
+
} };
|
|
49
|
+
}
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extracts the source parse result from a bare `DependencySourceState`.
|
|
54
|
+
* Used as the base `extractSourceValue` for plain dependency sources.
|
|
55
|
+
*/
|
|
56
|
+
function extractFromBareState(state) {
|
|
57
|
+
if (!isDependencySourceState(state)) return void 0;
|
|
58
|
+
return state.result;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Wraps an inner `extractSourceValue` to unwrap `[innerState]` first.
|
|
62
|
+
* Used by `optional()` and `withDefault()` which wrap state in a
|
|
63
|
+
* single-element array.
|
|
64
|
+
*/
|
|
65
|
+
function unwrapArrayThenExtract(innerExtract) {
|
|
66
|
+
return (state) => {
|
|
67
|
+
if (Array.isArray(state) && state.length === 1) return innerExtract(state[0]);
|
|
68
|
+
return innerExtract(state);
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Composes dependency metadata through a modifier wrapper.
|
|
73
|
+
*
|
|
74
|
+
* - `"optional"`: composes `extractSourceValue` with array unwrapping.
|
|
75
|
+
* - `"withDefault"`: adds `getMissingSourceValue` if the inner parser
|
|
76
|
+
* preserves a dependency source.
|
|
77
|
+
* - `"map"`: sets `transformsSourceValue` and clears
|
|
78
|
+
* `preservesSourceValue`.
|
|
79
|
+
*
|
|
80
|
+
* Returns `undefined` if `inner` is `undefined`.
|
|
81
|
+
*
|
|
82
|
+
* @param inner The inner parser's metadata.
|
|
83
|
+
* @param wrapperKind The type of modifier being applied.
|
|
84
|
+
* @param options Additional options for certain wrapper kinds.
|
|
85
|
+
* @returns Composed metadata, or `undefined`.
|
|
86
|
+
* @internal
|
|
87
|
+
* @since 1.0.0
|
|
88
|
+
*/
|
|
89
|
+
function composeDependencyMetadata(inner, wrapperKind, options) {
|
|
90
|
+
if (inner === void 0) return void 0;
|
|
91
|
+
switch (wrapperKind) {
|
|
92
|
+
case "optional": {
|
|
93
|
+
if (inner.source != null && inner.source.extractSourceValue != null) return {
|
|
94
|
+
...inner,
|
|
95
|
+
source: {
|
|
96
|
+
...inner.source,
|
|
97
|
+
extractSourceValue: unwrapArrayThenExtract(inner.source.extractSourceValue)
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
return inner;
|
|
101
|
+
}
|
|
102
|
+
case "withDefault": {
|
|
103
|
+
const wrappedExtract = inner.source?.extractSourceValue != null ? unwrapArrayThenExtract(inner.source.extractSourceValue) : void 0;
|
|
104
|
+
if (inner.source != null && inner.source.preservesSourceValue) return {
|
|
105
|
+
...inner,
|
|
106
|
+
source: {
|
|
107
|
+
...inner.source,
|
|
108
|
+
...wrappedExtract != null && { extractSourceValue: wrappedExtract },
|
|
109
|
+
getMissingSourceValue: options?.defaultValue
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
if (wrappedExtract != null && inner.source != null) return {
|
|
113
|
+
...inner,
|
|
114
|
+
source: {
|
|
115
|
+
...inner.source,
|
|
116
|
+
extractSourceValue: wrappedExtract
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
return inner;
|
|
120
|
+
}
|
|
121
|
+
case "map": {
|
|
122
|
+
const result = {
|
|
123
|
+
...inner,
|
|
124
|
+
transform: { transformsSourceValue: true }
|
|
125
|
+
};
|
|
126
|
+
if (inner.source != null) return {
|
|
127
|
+
...result,
|
|
128
|
+
source: {
|
|
129
|
+
...inner.source,
|
|
130
|
+
preservesSourceValue: false
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
export { composeDependencyMetadata, extractDependencyMetadata };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { DependencyRegistryLike } from "./registry-types.cjs";
|
|
2
|
+
import { ValueParserResult } from "./valueparser.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/dependency-runtime.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The origin of a dependency source value.
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
* @since 1.0.0
|
|
11
|
+
*/
|
|
12
|
+
type DependencyValueOrigin = "cli" | "default" | "config" | "env" | "prompt" | "derived-precomplete";
|
|
13
|
+
/**
|
|
14
|
+
* A request to resolve one or more dependency values.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
* @since 1.0.0
|
|
18
|
+
*/
|
|
19
|
+
interface DependencyRequest {
|
|
20
|
+
/** The dependency source IDs to resolve. */
|
|
21
|
+
readonly dependencyIds: readonly symbol[];
|
|
22
|
+
/** Optional default values (one per ID) for missing sources. */
|
|
23
|
+
readonly defaultValues?: readonly unknown[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The result of a dependency resolution request.
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
* @since 1.0.0
|
|
30
|
+
*/
|
|
31
|
+
interface DependencyResolution {
|
|
32
|
+
/**
|
|
33
|
+
* - `"resolved"`: all dependency values are available.
|
|
34
|
+
* - `"partial"`: some are available, some are missing.
|
|
35
|
+
* - `"missing"`: none are available.
|
|
36
|
+
*/
|
|
37
|
+
readonly kind: "resolved" | "partial" | "missing";
|
|
38
|
+
/** The resolved values (one per requested ID, `undefined` for missing). */
|
|
39
|
+
readonly values: readonly unknown[];
|
|
40
|
+
/** For each position, whether the value came from a default. */
|
|
41
|
+
readonly usedDefaults: readonly boolean[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A failure that occurred while evaluating a missing-source default.
|
|
45
|
+
* Returned by `fillMissingSourceDefaults()` so the caller can propagate
|
|
46
|
+
* the error instead of silently treating the source as absent.
|
|
47
|
+
*
|
|
48
|
+
* @internal
|
|
49
|
+
* @since 1.0.0
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A key for caching replayed parse results.
|
|
54
|
+
*
|
|
55
|
+
* @internal
|
|
56
|
+
* @since 1.0.0
|
|
57
|
+
*/
|
|
58
|
+
interface ReplayKey {
|
|
59
|
+
/** Path from root to the parser node. */
|
|
60
|
+
readonly path: readonly PropertyKey[];
|
|
61
|
+
/** The raw input string that was parsed. */
|
|
62
|
+
readonly rawInput: string;
|
|
63
|
+
/** A stable fingerprint of the dependency values used. */
|
|
64
|
+
readonly dependencyFingerprint: string;
|
|
65
|
+
/**
|
|
66
|
+
* A per-parser identity string that disambiguates different derived
|
|
67
|
+
* parsers sharing the same path (e.g., alternative branches).
|
|
68
|
+
* @since 1.0.0
|
|
69
|
+
*/
|
|
70
|
+
readonly parserFingerprint: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A runtime node representing a child parser's position, metadata, and state.
|
|
74
|
+
* Used as input to the shared runtime helpers.
|
|
75
|
+
*
|
|
76
|
+
* @internal
|
|
77
|
+
* @since 1.0.0
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Dependency runtime context for centralized dependency resolution.
|
|
82
|
+
*
|
|
83
|
+
* @internal
|
|
84
|
+
* @since 1.0.0
|
|
85
|
+
*/
|
|
86
|
+
interface DependencyRuntimeContext {
|
|
87
|
+
/** The underlying registry (for bridge interop). */
|
|
88
|
+
readonly registry: DependencyRegistryLike;
|
|
89
|
+
/** Register a source value with its origin. */
|
|
90
|
+
registerSource(sourceId: symbol, value: unknown, origin: DependencyValueOrigin): void;
|
|
91
|
+
/** Check if a source has been registered. */
|
|
92
|
+
hasSource(sourceId: symbol): boolean;
|
|
93
|
+
/** Get a registered source value. */
|
|
94
|
+
getSource(sourceId: symbol): unknown;
|
|
95
|
+
/** Resolve dependency values for a request. */
|
|
96
|
+
resolveDependencies(request: DependencyRequest): DependencyResolution;
|
|
97
|
+
/** Get a cached replay result. */
|
|
98
|
+
getReplayResult(key: ReplayKey): ValueParserResult<unknown> | undefined;
|
|
99
|
+
/** Cache a replay result. */
|
|
100
|
+
setReplayResult(key: ReplayKey, result: ValueParserResult<unknown>): void;
|
|
101
|
+
/**
|
|
102
|
+
* Mark a source as explicitly failed (user provided input that did
|
|
103
|
+
* not pass validation). Derived parsers should not fall back to
|
|
104
|
+
* defaults for failed sources.
|
|
105
|
+
*/
|
|
106
|
+
markSourceFailed(sourceId: symbol): void;
|
|
107
|
+
/**
|
|
108
|
+
* Check if a source was explicitly attempted but failed validation.
|
|
109
|
+
*/
|
|
110
|
+
isSourceFailed(sourceId: symbol): boolean;
|
|
111
|
+
/** Resolve dependencies for suggestions (same semantics as resolve). */
|
|
112
|
+
getSuggestionDependencies(request: DependencyRequest): DependencyResolution;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Creates a new {@link DependencyRuntimeContext}.
|
|
116
|
+
*
|
|
117
|
+
* @param registry Optional existing registry to wrap for bridge interop.
|
|
118
|
+
* @returns A new runtime context.
|
|
119
|
+
* @internal
|
|
120
|
+
* @since 1.0.0
|
|
121
|
+
*/
|
|
122
|
+
//#endregion
|
|
123
|
+
export { DependencyRuntimeContext };
|