@optique/core 1.0.0-dev.908 → 1.0.0
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/annotation-state.cjs +425 -0
- package/dist/annotation-state.d.cts +24 -0
- package/dist/annotation-state.d.ts +24 -0
- package/dist/annotation-state.js +414 -0
- package/dist/annotations.cjs +2 -248
- package/dist/annotations.d.cts +2 -137
- package/dist/annotations.d.ts +2 -137
- package/dist/annotations.js +2 -238
- package/dist/completion.cjs +611 -100
- package/dist/completion.d.cts +1 -1
- package/dist/completion.d.ts +1 -1
- package/dist/completion.js +611 -100
- package/dist/constructs.cjs +3338 -827
- package/dist/constructs.d.cts +48 -7
- package/dist/constructs.d.ts +48 -7
- package/dist/constructs.js +3338 -827
- package/dist/context.cjs +0 -23
- package/dist/context.d.cts +119 -53
- package/dist/context.d.ts +119 -53
- package/dist/context.js +0 -22
- package/dist/dependency-metadata.cjs +139 -0
- package/dist/dependency-metadata.d.cts +112 -0
- package/dist/dependency-metadata.d.ts +112 -0
- package/dist/dependency-metadata.js +138 -0
- package/dist/dependency-runtime.cjs +698 -0
- package/dist/dependency-runtime.d.cts +149 -0
- package/dist/dependency-runtime.d.ts +149 -0
- package/dist/dependency-runtime.js +687 -0
- package/dist/dependency.cjs +7 -928
- package/dist/dependency.d.cts +2 -794
- package/dist/dependency.d.ts +2 -794
- package/dist/dependency.js +2 -899
- package/dist/displaywidth.cjs +44 -0
- package/dist/displaywidth.js +43 -0
- package/dist/doc.cjs +285 -23
- package/dist/doc.d.cts +57 -2
- package/dist/doc.d.ts +57 -2
- package/dist/doc.js +283 -25
- package/dist/execution-context.cjs +56 -0
- package/dist/execution-context.js +53 -0
- package/dist/extension.cjs +87 -0
- package/dist/extension.d.cts +97 -0
- package/dist/extension.d.ts +97 -0
- package/dist/extension.js +76 -0
- package/dist/facade.cjs +718 -523
- package/dist/facade.d.cts +87 -18
- package/dist/facade.d.ts +87 -18
- package/dist/facade.js +718 -523
- package/dist/index.cjs +14 -29
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +7 -7
- package/dist/input-trace.cjs +56 -0
- package/dist/input-trace.d.cts +77 -0
- package/dist/input-trace.d.ts +77 -0
- package/dist/input-trace.js +55 -0
- package/dist/internal/annotations.cjs +316 -0
- package/dist/internal/annotations.d.cts +140 -0
- package/dist/internal/annotations.d.ts +140 -0
- package/dist/internal/annotations.js +306 -0
- package/dist/internal/dependency.cjs +984 -0
- package/dist/internal/dependency.d.cts +539 -0
- package/dist/internal/dependency.d.ts +539 -0
- package/dist/internal/dependency.js +964 -0
- package/dist/{mode-dispatch.cjs → internal/mode-dispatch.cjs} +1 -3
- package/dist/{mode-dispatch.d.cts → internal/mode-dispatch.d.cts} +3 -7
- package/dist/{mode-dispatch.d.ts → internal/mode-dispatch.d.ts} +3 -7
- package/dist/{mode-dispatch.js → internal/mode-dispatch.js} +1 -3
- package/dist/internal/parser.cjs +728 -0
- package/dist/internal/parser.d.cts +947 -0
- package/dist/internal/parser.d.ts +947 -0
- package/dist/internal/parser.js +711 -0
- package/dist/message.cjs +84 -26
- package/dist/message.d.cts +49 -9
- package/dist/message.d.ts +49 -9
- package/dist/message.js +84 -27
- package/dist/modifiers.cjs +1023 -240
- package/dist/modifiers.d.cts +42 -1
- package/dist/modifiers.d.ts +42 -1
- package/dist/modifiers.js +1023 -240
- package/dist/parser.cjs +11 -463
- package/dist/parser.d.cts +3 -537
- package/dist/parser.d.ts +3 -537
- package/dist/parser.js +2 -433
- package/dist/phase2-seed.cjs +59 -0
- package/dist/phase2-seed.js +56 -0
- package/dist/primitives.cjs +557 -208
- package/dist/primitives.d.cts +10 -14
- package/dist/primitives.d.ts +10 -14
- package/dist/primitives.js +557 -208
- package/dist/program.cjs +5 -1
- package/dist/program.d.cts +5 -3
- package/dist/program.d.ts +5 -3
- package/dist/program.js +6 -1
- package/dist/suggestion.cjs +22 -8
- package/dist/suggestion.js +22 -8
- package/dist/usage-internals.cjs +3 -2
- package/dist/usage-internals.js +4 -2
- package/dist/usage.cjs +195 -40
- package/dist/usage.d.cts +92 -11
- package/dist/usage.d.ts +92 -11
- package/dist/usage.js +194 -41
- package/dist/validate.cjs +170 -0
- package/dist/validate.js +164 -0
- package/dist/valueparser.cjs +1278 -191
- package/dist/valueparser.d.cts +330 -20
- package/dist/valueparser.d.ts +330 -20
- package/dist/valueparser.js +1277 -192
- package/package.json +9 -9
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/internal/annotations.ts
|
|
3
|
+
/**
|
|
4
|
+
* Runtime context extension system for Optique parsers.
|
|
5
|
+
*
|
|
6
|
+
* This module provides the annotations system that allows external runtime data
|
|
7
|
+
* to be passed to parsers during the parsing session. This enables use cases like
|
|
8
|
+
* config file fallbacks, environment-based validation, and shared context.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
* @since 0.10.0
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Annotation key symbol for storing data in parser state.
|
|
15
|
+
* @since 0.10.0
|
|
16
|
+
*/
|
|
17
|
+
const annotationKey = Symbol.for("@optique/core/parser/annotation");
|
|
18
|
+
/**
|
|
19
|
+
* Internal marker attached during the first pass of `runWith()` so wrappers
|
|
20
|
+
* with side effects can defer work until two-pass contexts have resolved.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
const firstPassAnnotationKey = Symbol.for("@optique/core/parser/firstPass");
|
|
25
|
+
/**
|
|
26
|
+
* Internal key for preserving primitive parser state values when annotations
|
|
27
|
+
* are injected into non-object states.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
const annotationStateValueKey = Symbol.for("@optique/core/parser/annotationStateValue");
|
|
31
|
+
/**
|
|
32
|
+
* Internal marker key that indicates annotation wrapping was injected by
|
|
33
|
+
* Optique internals for non-object states.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
const annotationWrapperKey = Symbol.for("@optique/core/parser/annotationWrapper");
|
|
37
|
+
/**
|
|
38
|
+
* Internal symbol keys that define Optique's primitive-state annotation
|
|
39
|
+
* wrapper shape.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
const annotationWrapperKeys = new Set([
|
|
43
|
+
annotationKey,
|
|
44
|
+
annotationStateValueKey,
|
|
45
|
+
annotationWrapperKey
|
|
46
|
+
]);
|
|
47
|
+
const injectedAnnotationWrappers = /* @__PURE__ */ new WeakSet();
|
|
48
|
+
function hasInjectedAnnotationWrapperShape(value) {
|
|
49
|
+
const valueRecord = value;
|
|
50
|
+
if (valueRecord[annotationWrapperKey] !== true) return false;
|
|
51
|
+
const ownKeys = Reflect.ownKeys(valueRecord);
|
|
52
|
+
if (ownKeys.length !== 3 || !ownKeys.every((key) => annotationWrapperKeys.has(key))) return false;
|
|
53
|
+
const annotations = Object.getOwnPropertyDescriptor(value, annotationKey);
|
|
54
|
+
const wrappedState = Object.getOwnPropertyDescriptor(value, annotationStateValueKey);
|
|
55
|
+
const wrapper = Object.getOwnPropertyDescriptor(value, annotationWrapperKey);
|
|
56
|
+
return annotations?.enumerable === true && annotations.writable === true && annotations.configurable === true && annotations.value != null && typeof annotations.value === "object" && wrappedState?.enumerable === false && wrappedState.writable === true && wrappedState.configurable === true && wrapper?.enumerable === false && wrapper.writable === true && wrapper.configurable === true && wrapper.value === true;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Extracts annotations from parser state.
|
|
60
|
+
*
|
|
61
|
+
* @param state Parser state that may contain annotations
|
|
62
|
+
* @returns Annotations object or undefined if no annotations are present
|
|
63
|
+
* @since 0.10.0
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const annotations = getAnnotations(state);
|
|
68
|
+
* const myData = annotations?.[myDataKey];
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
function getAnnotations(state) {
|
|
72
|
+
if (state == null || typeof state !== "object") return void 0;
|
|
73
|
+
const stateObj = state;
|
|
74
|
+
const annotations = stateObj[annotationKey];
|
|
75
|
+
if (annotations != null && typeof annotations === "object") return annotations;
|
|
76
|
+
return void 0;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Reattaches annotations to a freshly created array state.
|
|
80
|
+
*
|
|
81
|
+
* Array spread copies elements but drops symbol properties, so parsers that
|
|
82
|
+
* rebuild array states need to copy annotations back explicitly.
|
|
83
|
+
*
|
|
84
|
+
* @param source The original state that may carry annotations.
|
|
85
|
+
* @param target The freshly created array state.
|
|
86
|
+
* @returns The target array, with annotations copied when available.
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
function annotateFreshArray(source, target) {
|
|
90
|
+
const annotations = getAnnotations(source);
|
|
91
|
+
if (annotations === void 0) return target;
|
|
92
|
+
const annotated = target;
|
|
93
|
+
annotated[annotationKey] = annotations;
|
|
94
|
+
return annotated;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Propagates annotations from one parser state to another.
|
|
98
|
+
*
|
|
99
|
+
* This is mainly used by parsers that rebuild array states with spread syntax.
|
|
100
|
+
* Array spread copies elements but drops custom symbol properties, so we need
|
|
101
|
+
* to reattach annotations explicitly when present. `inheritAnnotations()`
|
|
102
|
+
* supports primitive and nullish targets via wrapper injection, plus arrays,
|
|
103
|
+
* plain objects, and built-in container/value types that Optique clones
|
|
104
|
+
* explicitly (`Date`, `Map`, `Set`, and `RegExp`). Non-plain custom objects
|
|
105
|
+
* are returned unchanged to avoid mutating shared parser state.
|
|
106
|
+
*
|
|
107
|
+
* @param source The original state that may carry annotations.
|
|
108
|
+
* @param target The new state to receive annotations when it is a supported
|
|
109
|
+
* target shape.
|
|
110
|
+
* @returns A cloned or wrapped target with annotations copied when available,
|
|
111
|
+
* or the original unsupported non-plain target unchanged.
|
|
112
|
+
* @since 1.0.0
|
|
113
|
+
*/
|
|
114
|
+
function inheritAnnotations(source, target) {
|
|
115
|
+
const annotations = getAnnotations(source);
|
|
116
|
+
if (annotations === void 0) return target;
|
|
117
|
+
if (target == null || typeof target !== "object") return injectAnnotations(target, annotations);
|
|
118
|
+
if (isInjectedAnnotationWrapper(target)) return injectAnnotations(target, annotations);
|
|
119
|
+
if (Array.isArray(target)) {
|
|
120
|
+
const cloned$1 = [...target];
|
|
121
|
+
cloned$1[annotationKey] = annotations;
|
|
122
|
+
return cloned$1;
|
|
123
|
+
}
|
|
124
|
+
if (target instanceof Date) {
|
|
125
|
+
const cloned$1 = new Date(target.getTime());
|
|
126
|
+
cloned$1[annotationKey] = annotations;
|
|
127
|
+
return cloned$1;
|
|
128
|
+
}
|
|
129
|
+
if (target instanceof Map) {
|
|
130
|
+
const cloned$1 = new Map(target);
|
|
131
|
+
cloned$1[annotationKey] = annotations;
|
|
132
|
+
return cloned$1;
|
|
133
|
+
}
|
|
134
|
+
if (target instanceof Set) {
|
|
135
|
+
const cloned$1 = new Set(target);
|
|
136
|
+
cloned$1[annotationKey] = annotations;
|
|
137
|
+
return cloned$1;
|
|
138
|
+
}
|
|
139
|
+
if (target instanceof RegExp) {
|
|
140
|
+
const cloned$1 = new RegExp(target);
|
|
141
|
+
cloned$1.lastIndex = target.lastIndex;
|
|
142
|
+
cloned$1[annotationKey] = annotations;
|
|
143
|
+
return cloned$1;
|
|
144
|
+
}
|
|
145
|
+
if (Object.getPrototypeOf(target) !== Object.prototype && Object.getPrototypeOf(target) !== null) return target;
|
|
146
|
+
const cloned = Object.create(Object.getPrototypeOf(target), Object.getOwnPropertyDescriptors(target));
|
|
147
|
+
cloned[annotationKey] = annotations;
|
|
148
|
+
return cloned;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Returns whether an annotations record carries at least one own symbol key.
|
|
152
|
+
*
|
|
153
|
+
* An annotations object with no own symbol keys is treated as a no-op by the
|
|
154
|
+
* injection pipeline: it should behave identically to omitting the
|
|
155
|
+
* `annotations` option entirely. `null` and `undefined` are accepted for
|
|
156
|
+
* call-site convenience and always return `false`.
|
|
157
|
+
*
|
|
158
|
+
* @param annotations The annotations record to check.
|
|
159
|
+
* @returns `true` when the record has at least one own symbol key.
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
function hasMeaningfulAnnotations(annotations) {
|
|
163
|
+
return annotations != null && Object.getOwnPropertySymbols(annotations).length > 0;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Injects annotations into parser state while preserving state shape.
|
|
167
|
+
*
|
|
168
|
+
* - Primitive, null, and undefined states are wrapped with internal metadata.
|
|
169
|
+
* - Array states are cloned and annotated without mutating the original.
|
|
170
|
+
* - Plain object states are shallow-cloned with annotations attached.
|
|
171
|
+
* - Built-in object states (Date/Map/Set/RegExp) are cloned by constructor.
|
|
172
|
+
* - Other non-plain object states are cloned via prototype/descriptors.
|
|
173
|
+
* - If the `annotations` record is nullish or has no own symbol keys, the
|
|
174
|
+
* state is returned unchanged.
|
|
175
|
+
*
|
|
176
|
+
* @param state The parser state to annotate.
|
|
177
|
+
* @param annotations The annotations to inject.
|
|
178
|
+
* @returns Annotated state.
|
|
179
|
+
* @since 1.0.0
|
|
180
|
+
*/
|
|
181
|
+
function injectAnnotations(state, annotations) {
|
|
182
|
+
if (!hasMeaningfulAnnotations(annotations)) return state;
|
|
183
|
+
if (state == null || typeof state !== "object") {
|
|
184
|
+
const wrapper = {};
|
|
185
|
+
Object.defineProperties(wrapper, {
|
|
186
|
+
[annotationKey]: {
|
|
187
|
+
value: annotations,
|
|
188
|
+
enumerable: true,
|
|
189
|
+
writable: true,
|
|
190
|
+
configurable: true
|
|
191
|
+
},
|
|
192
|
+
[annotationStateValueKey]: {
|
|
193
|
+
value: state,
|
|
194
|
+
enumerable: false,
|
|
195
|
+
writable: true,
|
|
196
|
+
configurable: true
|
|
197
|
+
},
|
|
198
|
+
[annotationWrapperKey]: {
|
|
199
|
+
value: true,
|
|
200
|
+
enumerable: false,
|
|
201
|
+
writable: true,
|
|
202
|
+
configurable: true
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
injectedAnnotationWrappers.add(wrapper);
|
|
206
|
+
return wrapper;
|
|
207
|
+
}
|
|
208
|
+
if (Array.isArray(state)) {
|
|
209
|
+
const cloned$1 = [...state];
|
|
210
|
+
cloned$1[annotationKey] = annotations;
|
|
211
|
+
return cloned$1;
|
|
212
|
+
}
|
|
213
|
+
if (isInjectedAnnotationWrapper(state)) {
|
|
214
|
+
const unwrapped = unwrapInjectedAnnotationWrapper(state);
|
|
215
|
+
if (unwrapped !== state) return injectAnnotations(unwrapped, annotations);
|
|
216
|
+
const cloned$1 = Object.create(Object.getPrototypeOf(state), Object.getOwnPropertyDescriptors(state));
|
|
217
|
+
cloned$1[annotationKey] = annotations;
|
|
218
|
+
injectedAnnotationWrappers.add(cloned$1);
|
|
219
|
+
return cloned$1;
|
|
220
|
+
}
|
|
221
|
+
if (state instanceof Date) {
|
|
222
|
+
const cloned$1 = new Date(state.getTime());
|
|
223
|
+
cloned$1[annotationKey] = annotations;
|
|
224
|
+
return cloned$1;
|
|
225
|
+
}
|
|
226
|
+
if (state instanceof Map) {
|
|
227
|
+
const cloned$1 = new Map(state);
|
|
228
|
+
cloned$1[annotationKey] = annotations;
|
|
229
|
+
return cloned$1;
|
|
230
|
+
}
|
|
231
|
+
if (state instanceof Set) {
|
|
232
|
+
const cloned$1 = new Set(state);
|
|
233
|
+
cloned$1[annotationKey] = annotations;
|
|
234
|
+
return cloned$1;
|
|
235
|
+
}
|
|
236
|
+
if (state instanceof RegExp) {
|
|
237
|
+
const cloned$1 = new RegExp(state);
|
|
238
|
+
cloned$1.lastIndex = state.lastIndex;
|
|
239
|
+
cloned$1[annotationKey] = annotations;
|
|
240
|
+
return cloned$1;
|
|
241
|
+
}
|
|
242
|
+
const proto = Object.getPrototypeOf(state);
|
|
243
|
+
if (proto === Object.prototype || proto === null) {
|
|
244
|
+
const cloned$1 = Object.create(proto, Object.getOwnPropertyDescriptors(state));
|
|
245
|
+
cloned$1[annotationKey] = annotations;
|
|
246
|
+
return cloned$1;
|
|
247
|
+
}
|
|
248
|
+
const cloned = Object.create(proto, Object.getOwnPropertyDescriptors(state));
|
|
249
|
+
cloned[annotationKey] = annotations;
|
|
250
|
+
return cloned;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Unwraps a primitive-state annotation wrapper injected by Optique internals.
|
|
254
|
+
*
|
|
255
|
+
* @param value Value to potentially unwrap.
|
|
256
|
+
* @returns The unwrapped primitive value when the input is an injected wrapper;
|
|
257
|
+
* otherwise the original value.
|
|
258
|
+
* @internal
|
|
259
|
+
*/
|
|
260
|
+
function unwrapInjectedAnnotationWrapper(value) {
|
|
261
|
+
if (value == null || typeof value !== "object") return value;
|
|
262
|
+
if (!hasInjectedAnnotationWrapperShape(value)) return value;
|
|
263
|
+
const valueRecord = value;
|
|
264
|
+
return valueRecord[annotationStateValueKey];
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Returns whether the given value is an internal primitive-state annotation
|
|
268
|
+
* wrapper that was injected by Optique.
|
|
269
|
+
*
|
|
270
|
+
* @param value Value to check.
|
|
271
|
+
* @returns `true` if the value is an injected internal wrapper.
|
|
272
|
+
* @internal
|
|
273
|
+
*/
|
|
274
|
+
function isInjectedAnnotationWrapper(value) {
|
|
275
|
+
return value != null && typeof value === "object" && (injectedAnnotationWrappers.has(value) || hasInjectedAnnotationWrapperShape(value));
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Returns whether the given value is an injected annotation state wrapper.
|
|
279
|
+
*
|
|
280
|
+
* This is the public name for Optique's primitive-state annotation wrapper
|
|
281
|
+
* predicate. Use it when custom parsers need to detect whether annotations
|
|
282
|
+
* were attached by wrapping a primitive or nullish state value.
|
|
283
|
+
*
|
|
284
|
+
* @param value Value to check.
|
|
285
|
+
* @returns `true` if the value is an injected annotation state wrapper.
|
|
286
|
+
* @since 1.0.0
|
|
287
|
+
*/
|
|
288
|
+
function isInjectedAnnotationState(value) {
|
|
289
|
+
return isInjectedAnnotationWrapper(value);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Unwraps an injected annotation state wrapper when present.
|
|
293
|
+
*
|
|
294
|
+
* This is the public name for Optique's primitive-state annotation unwrapping
|
|
295
|
+
* helper. It returns the original value unchanged for non-wrapper inputs.
|
|
296
|
+
*
|
|
297
|
+
* @param value Value to potentially unwrap.
|
|
298
|
+
* @returns The unwrapped primitive value when the input is an injected
|
|
299
|
+
* annotation state wrapper; otherwise the original value.
|
|
300
|
+
* @since 1.0.0
|
|
301
|
+
*/
|
|
302
|
+
function unwrapInjectedAnnotationState(value) {
|
|
303
|
+
return unwrapInjectedAnnotationWrapper(value);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
//#endregion
|
|
307
|
+
exports.annotateFreshArray = annotateFreshArray;
|
|
308
|
+
exports.annotationKey = annotationKey;
|
|
309
|
+
exports.getAnnotations = getAnnotations;
|
|
310
|
+
exports.hasMeaningfulAnnotations = hasMeaningfulAnnotations;
|
|
311
|
+
exports.inheritAnnotations = inheritAnnotations;
|
|
312
|
+
exports.injectAnnotations = injectAnnotations;
|
|
313
|
+
exports.isInjectedAnnotationState = isInjectedAnnotationState;
|
|
314
|
+
exports.isInjectedAnnotationWrapper = isInjectedAnnotationWrapper;
|
|
315
|
+
exports.unwrapInjectedAnnotationState = unwrapInjectedAnnotationState;
|
|
316
|
+
exports.unwrapInjectedAnnotationWrapper = unwrapInjectedAnnotationWrapper;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
//#region src/internal/annotations.d.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Annotations that can be passed to parsers during execution.
|
|
5
|
+
* Allows external packages to provide additional data that parsers can access
|
|
6
|
+
* during complete() or parse() phases.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const myDataKey = Symbol.for("@my-package/data");
|
|
11
|
+
* const result = parse(parser, args, {
|
|
12
|
+
* annotations: {
|
|
13
|
+
* [myDataKey]: { foo: "bar" }
|
|
14
|
+
* }
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
* @since 0.10.0
|
|
18
|
+
*/
|
|
19
|
+
type Annotations = Record<symbol, unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Options for parse functions.
|
|
22
|
+
* @since 0.10.0
|
|
23
|
+
*/
|
|
24
|
+
interface ParseOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Annotations to attach to the parsing session.
|
|
27
|
+
* Parsers can access these annotations via getAnnotations(state).
|
|
28
|
+
*/
|
|
29
|
+
readonly annotations?: Annotations;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Extracts annotations from parser state.
|
|
33
|
+
*
|
|
34
|
+
* @param state Parser state that may contain annotations
|
|
35
|
+
* @returns Annotations object or undefined if no annotations are present
|
|
36
|
+
* @since 0.10.0
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const annotations = getAnnotations(state);
|
|
41
|
+
* const myData = annotations?.[myDataKey];
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function getAnnotations(state: unknown): Annotations | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Reattaches annotations to a freshly created array state.
|
|
47
|
+
*
|
|
48
|
+
* Array spread copies elements but drops symbol properties, so parsers that
|
|
49
|
+
* rebuild array states need to copy annotations back explicitly.
|
|
50
|
+
*
|
|
51
|
+
* @param source The original state that may carry annotations.
|
|
52
|
+
* @param target The freshly created array state.
|
|
53
|
+
* @returns The target array, with annotations copied when available.
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Propagates annotations from one parser state to another.
|
|
59
|
+
*
|
|
60
|
+
* This is mainly used by parsers that rebuild array states with spread syntax.
|
|
61
|
+
* Array spread copies elements but drops custom symbol properties, so we need
|
|
62
|
+
* to reattach annotations explicitly when present. `inheritAnnotations()`
|
|
63
|
+
* supports primitive and nullish targets via wrapper injection, plus arrays,
|
|
64
|
+
* plain objects, and built-in container/value types that Optique clones
|
|
65
|
+
* explicitly (`Date`, `Map`, `Set`, and `RegExp`). Non-plain custom objects
|
|
66
|
+
* are returned unchanged to avoid mutating shared parser state.
|
|
67
|
+
*
|
|
68
|
+
* @param source The original state that may carry annotations.
|
|
69
|
+
* @param target The new state to receive annotations when it is a supported
|
|
70
|
+
* target shape.
|
|
71
|
+
* @returns A cloned or wrapped target with annotations copied when available,
|
|
72
|
+
* or the original unsupported non-plain target unchanged.
|
|
73
|
+
* @since 1.0.0
|
|
74
|
+
*/
|
|
75
|
+
declare function inheritAnnotations<T>(source: unknown, target: T): T;
|
|
76
|
+
/**
|
|
77
|
+
* Returns whether an annotations record carries at least one own symbol key.
|
|
78
|
+
*
|
|
79
|
+
* An annotations object with no own symbol keys is treated as a no-op by the
|
|
80
|
+
* injection pipeline: it should behave identically to omitting the
|
|
81
|
+
* `annotations` option entirely. `null` and `undefined` are accepted for
|
|
82
|
+
* call-site convenience and always return `false`.
|
|
83
|
+
*
|
|
84
|
+
* @param annotations The annotations record to check.
|
|
85
|
+
* @returns `true` when the record has at least one own symbol key.
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Injects annotations into parser state while preserving state shape.
|
|
91
|
+
*
|
|
92
|
+
* - Primitive, null, and undefined states are wrapped with internal metadata.
|
|
93
|
+
* - Array states are cloned and annotated without mutating the original.
|
|
94
|
+
* - Plain object states are shallow-cloned with annotations attached.
|
|
95
|
+
* - Built-in object states (Date/Map/Set/RegExp) are cloned by constructor.
|
|
96
|
+
* - Other non-plain object states are cloned via prototype/descriptors.
|
|
97
|
+
* - If the `annotations` record is nullish or has no own symbol keys, the
|
|
98
|
+
* state is returned unchanged.
|
|
99
|
+
*
|
|
100
|
+
* @param state The parser state to annotate.
|
|
101
|
+
* @param annotations The annotations to inject.
|
|
102
|
+
* @returns Annotated state.
|
|
103
|
+
* @since 1.0.0
|
|
104
|
+
*/
|
|
105
|
+
declare function injectAnnotations<TState>(state: TState, annotations: Annotations | null | undefined): TState;
|
|
106
|
+
/**
|
|
107
|
+
* Unwraps a primitive-state annotation wrapper injected by Optique internals.
|
|
108
|
+
*
|
|
109
|
+
* @param value Value to potentially unwrap.
|
|
110
|
+
* @returns The unwrapped primitive value when the input is an injected wrapper;
|
|
111
|
+
* otherwise the original value.
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Returns whether the given value is an injected annotation state wrapper.
|
|
117
|
+
*
|
|
118
|
+
* This is the public name for Optique's primitive-state annotation wrapper
|
|
119
|
+
* predicate. Use it when custom parsers need to detect whether annotations
|
|
120
|
+
* were attached by wrapping a primitive or nullish state value.
|
|
121
|
+
*
|
|
122
|
+
* @param value Value to check.
|
|
123
|
+
* @returns `true` if the value is an injected annotation state wrapper.
|
|
124
|
+
* @since 1.0.0
|
|
125
|
+
*/
|
|
126
|
+
declare function isInjectedAnnotationState(value: unknown): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Unwraps an injected annotation state wrapper when present.
|
|
129
|
+
*
|
|
130
|
+
* This is the public name for Optique's primitive-state annotation unwrapping
|
|
131
|
+
* helper. It returns the original value unchanged for non-wrapper inputs.
|
|
132
|
+
*
|
|
133
|
+
* @param value Value to potentially unwrap.
|
|
134
|
+
* @returns The unwrapped primitive value when the input is an injected
|
|
135
|
+
* annotation state wrapper; otherwise the original value.
|
|
136
|
+
* @since 1.0.0
|
|
137
|
+
*/
|
|
138
|
+
declare function unwrapInjectedAnnotationState<T>(value: T): T;
|
|
139
|
+
//#endregion
|
|
140
|
+
export { Annotations, ParseOptions, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, unwrapInjectedAnnotationState };
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
//#region src/internal/annotations.d.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Annotations that can be passed to parsers during execution.
|
|
5
|
+
* Allows external packages to provide additional data that parsers can access
|
|
6
|
+
* during complete() or parse() phases.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const myDataKey = Symbol.for("@my-package/data");
|
|
11
|
+
* const result = parse(parser, args, {
|
|
12
|
+
* annotations: {
|
|
13
|
+
* [myDataKey]: { foo: "bar" }
|
|
14
|
+
* }
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
* @since 0.10.0
|
|
18
|
+
*/
|
|
19
|
+
type Annotations = Record<symbol, unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Options for parse functions.
|
|
22
|
+
* @since 0.10.0
|
|
23
|
+
*/
|
|
24
|
+
interface ParseOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Annotations to attach to the parsing session.
|
|
27
|
+
* Parsers can access these annotations via getAnnotations(state).
|
|
28
|
+
*/
|
|
29
|
+
readonly annotations?: Annotations;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Extracts annotations from parser state.
|
|
33
|
+
*
|
|
34
|
+
* @param state Parser state that may contain annotations
|
|
35
|
+
* @returns Annotations object or undefined if no annotations are present
|
|
36
|
+
* @since 0.10.0
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const annotations = getAnnotations(state);
|
|
41
|
+
* const myData = annotations?.[myDataKey];
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function getAnnotations(state: unknown): Annotations | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Reattaches annotations to a freshly created array state.
|
|
47
|
+
*
|
|
48
|
+
* Array spread copies elements but drops symbol properties, so parsers that
|
|
49
|
+
* rebuild array states need to copy annotations back explicitly.
|
|
50
|
+
*
|
|
51
|
+
* @param source The original state that may carry annotations.
|
|
52
|
+
* @param target The freshly created array state.
|
|
53
|
+
* @returns The target array, with annotations copied when available.
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Propagates annotations from one parser state to another.
|
|
59
|
+
*
|
|
60
|
+
* This is mainly used by parsers that rebuild array states with spread syntax.
|
|
61
|
+
* Array spread copies elements but drops custom symbol properties, so we need
|
|
62
|
+
* to reattach annotations explicitly when present. `inheritAnnotations()`
|
|
63
|
+
* supports primitive and nullish targets via wrapper injection, plus arrays,
|
|
64
|
+
* plain objects, and built-in container/value types that Optique clones
|
|
65
|
+
* explicitly (`Date`, `Map`, `Set`, and `RegExp`). Non-plain custom objects
|
|
66
|
+
* are returned unchanged to avoid mutating shared parser state.
|
|
67
|
+
*
|
|
68
|
+
* @param source The original state that may carry annotations.
|
|
69
|
+
* @param target The new state to receive annotations when it is a supported
|
|
70
|
+
* target shape.
|
|
71
|
+
* @returns A cloned or wrapped target with annotations copied when available,
|
|
72
|
+
* or the original unsupported non-plain target unchanged.
|
|
73
|
+
* @since 1.0.0
|
|
74
|
+
*/
|
|
75
|
+
declare function inheritAnnotations<T>(source: unknown, target: T): T;
|
|
76
|
+
/**
|
|
77
|
+
* Returns whether an annotations record carries at least one own symbol key.
|
|
78
|
+
*
|
|
79
|
+
* An annotations object with no own symbol keys is treated as a no-op by the
|
|
80
|
+
* injection pipeline: it should behave identically to omitting the
|
|
81
|
+
* `annotations` option entirely. `null` and `undefined` are accepted for
|
|
82
|
+
* call-site convenience and always return `false`.
|
|
83
|
+
*
|
|
84
|
+
* @param annotations The annotations record to check.
|
|
85
|
+
* @returns `true` when the record has at least one own symbol key.
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Injects annotations into parser state while preserving state shape.
|
|
91
|
+
*
|
|
92
|
+
* - Primitive, null, and undefined states are wrapped with internal metadata.
|
|
93
|
+
* - Array states are cloned and annotated without mutating the original.
|
|
94
|
+
* - Plain object states are shallow-cloned with annotations attached.
|
|
95
|
+
* - Built-in object states (Date/Map/Set/RegExp) are cloned by constructor.
|
|
96
|
+
* - Other non-plain object states are cloned via prototype/descriptors.
|
|
97
|
+
* - If the `annotations` record is nullish or has no own symbol keys, the
|
|
98
|
+
* state is returned unchanged.
|
|
99
|
+
*
|
|
100
|
+
* @param state The parser state to annotate.
|
|
101
|
+
* @param annotations The annotations to inject.
|
|
102
|
+
* @returns Annotated state.
|
|
103
|
+
* @since 1.0.0
|
|
104
|
+
*/
|
|
105
|
+
declare function injectAnnotations<TState>(state: TState, annotations: Annotations | null | undefined): TState;
|
|
106
|
+
/**
|
|
107
|
+
* Unwraps a primitive-state annotation wrapper injected by Optique internals.
|
|
108
|
+
*
|
|
109
|
+
* @param value Value to potentially unwrap.
|
|
110
|
+
* @returns The unwrapped primitive value when the input is an injected wrapper;
|
|
111
|
+
* otherwise the original value.
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Returns whether the given value is an injected annotation state wrapper.
|
|
117
|
+
*
|
|
118
|
+
* This is the public name for Optique's primitive-state annotation wrapper
|
|
119
|
+
* predicate. Use it when custom parsers need to detect whether annotations
|
|
120
|
+
* were attached by wrapping a primitive or nullish state value.
|
|
121
|
+
*
|
|
122
|
+
* @param value Value to check.
|
|
123
|
+
* @returns `true` if the value is an injected annotation state wrapper.
|
|
124
|
+
* @since 1.0.0
|
|
125
|
+
*/
|
|
126
|
+
declare function isInjectedAnnotationState(value: unknown): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Unwraps an injected annotation state wrapper when present.
|
|
129
|
+
*
|
|
130
|
+
* This is the public name for Optique's primitive-state annotation unwrapping
|
|
131
|
+
* helper. It returns the original value unchanged for non-wrapper inputs.
|
|
132
|
+
*
|
|
133
|
+
* @param value Value to potentially unwrap.
|
|
134
|
+
* @returns The unwrapped primitive value when the input is an injected
|
|
135
|
+
* annotation state wrapper; otherwise the original value.
|
|
136
|
+
* @since 1.0.0
|
|
137
|
+
*/
|
|
138
|
+
declare function unwrapInjectedAnnotationState<T>(value: T): T;
|
|
139
|
+
//#endregion
|
|
140
|
+
export { Annotations, ParseOptions, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, unwrapInjectedAnnotationState };
|