@optique/core 0.10.0-dev.291 → 0.10.0-dev.293
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constructs.cjs +71 -2
- package/dist/constructs.js +71 -2
- package/dist/dependency.cjs +528 -0
- package/dist/dependency.d.cts +617 -0
- package/dist/dependency.d.ts +617 -0
- package/dist/dependency.js +510 -0
- package/dist/facade.cjs +1 -1
- package/dist/facade.js +1 -1
- package/dist/index.cjs +20 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3 -2
- package/dist/parser.d.cts +3 -3
- package/dist/parser.d.ts +3 -3
- package/dist/primitives.cjs +60 -12
- package/dist/primitives.d.cts +8 -2
- package/dist/primitives.d.ts +8 -2
- package/dist/primitives.js +60 -12
- package/package.json +9 -1
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/dependency.ts
|
|
3
|
+
/**
|
|
4
|
+
* A unique symbol used to identify dependency sources at compile time.
|
|
5
|
+
* This marker is used to distinguish {@link DependencySource} from regular
|
|
6
|
+
* {@link ValueParser} instances.
|
|
7
|
+
* @since 0.10.0
|
|
8
|
+
*/
|
|
9
|
+
const DependencySourceMarker = Symbol.for("@optique/core/dependency/DependencySourceMarker");
|
|
10
|
+
/**
|
|
11
|
+
* A unique symbol used to identify derived value parsers at compile time.
|
|
12
|
+
* This marker is used to distinguish {@link DerivedValueParser} from regular
|
|
13
|
+
* {@link ValueParser} instances.
|
|
14
|
+
* @since 0.10.0
|
|
15
|
+
*/
|
|
16
|
+
const DerivedValueParserMarker = Symbol.for("@optique/core/dependency/DerivedValueParserMarker");
|
|
17
|
+
/**
|
|
18
|
+
* A unique symbol used to store the dependency ID on value parsers.
|
|
19
|
+
* @since 0.10.0
|
|
20
|
+
*/
|
|
21
|
+
const DependencyId = Symbol.for("@optique/core/dependency/DependencyId");
|
|
22
|
+
/**
|
|
23
|
+
* A unique symbol used to access the parseWithDependency method on derived parsers.
|
|
24
|
+
* @since 0.10.0
|
|
25
|
+
*/
|
|
26
|
+
const ParseWithDependency = Symbol.for("@optique/core/dependency/ParseWithDependency");
|
|
27
|
+
/**
|
|
28
|
+
* Creates a dependency source from a {@link ValueParser}.
|
|
29
|
+
*
|
|
30
|
+
* A dependency source wraps an existing value parser and enables creating
|
|
31
|
+
* derived parsers that depend on the parsed value. This is useful for
|
|
32
|
+
* scenarios where one option's valid values depend on another option's value.
|
|
33
|
+
*
|
|
34
|
+
* @template M The execution mode of the value parser.
|
|
35
|
+
* @template T The type of value the parser produces.
|
|
36
|
+
* @param parser The value parser to wrap as a dependency source.
|
|
37
|
+
* @returns A {@link DependencySource} that can be used to create
|
|
38
|
+
* derived parsers.
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* import { dependency } from "@optique/core/dependency";
|
|
42
|
+
* import { string } from "@optique/core/valueparser";
|
|
43
|
+
*
|
|
44
|
+
* // Create a dependency source for a directory path
|
|
45
|
+
* const cwdParser = dependency(string({ metavar: "DIR" }));
|
|
46
|
+
*
|
|
47
|
+
* // Create a derived parser that depends on the directory
|
|
48
|
+
* const branchParser = cwdParser.derive({
|
|
49
|
+
* metavar: "BRANCH",
|
|
50
|
+
* factory: (dir) => gitBranch({ dir }),
|
|
51
|
+
* defaultValue: () => process.cwd(),
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
* @since 0.10.0
|
|
55
|
+
*/
|
|
56
|
+
function dependency(parser) {
|
|
57
|
+
const id = Symbol();
|
|
58
|
+
const result = {
|
|
59
|
+
...parser,
|
|
60
|
+
[DependencySourceMarker]: true,
|
|
61
|
+
[DependencyId]: id,
|
|
62
|
+
derive(options) {
|
|
63
|
+
return createDerivedValueParser(id, parser, options);
|
|
64
|
+
},
|
|
65
|
+
deriveSync(options) {
|
|
66
|
+
if (parser.$mode === "async") return createAsyncDerivedParserFromSyncFactory(id, options);
|
|
67
|
+
return createSyncDerivedParser(id, options);
|
|
68
|
+
},
|
|
69
|
+
deriveAsync(options) {
|
|
70
|
+
return createDerivedValueParser(id, parser, options);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Checks if a value parser is a {@link DependencySource}.
|
|
77
|
+
*
|
|
78
|
+
* @param parser The value parser to check.
|
|
79
|
+
* @returns `true` if the parser is a dependency source, `false` otherwise.
|
|
80
|
+
* @since 0.10.0
|
|
81
|
+
*/
|
|
82
|
+
function isDependencySource(parser) {
|
|
83
|
+
return DependencySourceMarker in parser && parser[DependencySourceMarker] === true;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Checks if a value parser is a {@link DerivedValueParser}.
|
|
87
|
+
*
|
|
88
|
+
* @param parser The value parser to check.
|
|
89
|
+
* @returns `true` if the parser is a derived value parser, `false` otherwise.
|
|
90
|
+
* @since 0.10.0
|
|
91
|
+
*/
|
|
92
|
+
function isDerivedValueParser(parser) {
|
|
93
|
+
return DerivedValueParserMarker in parser && parser[DerivedValueParserMarker] === true;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Creates a derived value parser from multiple dependency sources.
|
|
97
|
+
*
|
|
98
|
+
* This function allows creating a parser whose behavior depends on
|
|
99
|
+
* multiple other parsers' values. This is useful for scenarios where
|
|
100
|
+
* an option's valid values depend on a combination of other options.
|
|
101
|
+
*
|
|
102
|
+
* @template Deps A tuple of DependencySource types.
|
|
103
|
+
* @template T The type of value the derived parser produces.
|
|
104
|
+
* @param options Configuration for the derived parser.
|
|
105
|
+
* @returns A {@link DerivedValueParser} that depends on the given sources.
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* import { dependency, deriveFrom } from "@optique/core/dependency";
|
|
109
|
+
* import { string, choice } from "@optique/core/valueparser";
|
|
110
|
+
*
|
|
111
|
+
* const dirParser = dependency(string({ metavar: "DIR" }));
|
|
112
|
+
* const modeParser = dependency(choice(["dev", "prod"]));
|
|
113
|
+
*
|
|
114
|
+
* const configParser = deriveFrom({
|
|
115
|
+
* metavar: "CONFIG",
|
|
116
|
+
* dependencies: [dirParser, modeParser] as const,
|
|
117
|
+
* factory: (dir, mode) =>
|
|
118
|
+
* choice(mode === "dev"
|
|
119
|
+
* ? [`${dir}/dev.json`, `${dir}/dev.yaml`]
|
|
120
|
+
* : [`${dir}/prod.json`, `${dir}/prod.yaml`]),
|
|
121
|
+
* defaultValues: () => ["/config", "dev"],
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
* @since 0.10.0
|
|
125
|
+
*/
|
|
126
|
+
function deriveFrom(options) {
|
|
127
|
+
const depsAsync = options.dependencies.some((dep) => dep.$mode === "async");
|
|
128
|
+
const factoryReturnsAsync = determineFactoryModeForDeriveFrom(options);
|
|
129
|
+
const sourceId = options.dependencies.length > 0 ? options.dependencies[0][DependencyId] : Symbol();
|
|
130
|
+
const isAsync = depsAsync || factoryReturnsAsync;
|
|
131
|
+
if (isAsync) {
|
|
132
|
+
if (factoryReturnsAsync) return createAsyncDerivedFromParserFromAsyncFactory(sourceId, options);
|
|
133
|
+
return createAsyncDerivedFromParserFromSyncFactory(sourceId, options);
|
|
134
|
+
}
|
|
135
|
+
return createSyncDerivedFromParser(sourceId, options);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Creates a derived value parser from multiple dependency sources
|
|
139
|
+
* with a synchronous factory.
|
|
140
|
+
*
|
|
141
|
+
* This function allows creating a parser whose behavior depends on
|
|
142
|
+
* multiple other parsers' values. The factory explicitly returns
|
|
143
|
+
* a sync parser.
|
|
144
|
+
*
|
|
145
|
+
* @template Deps A tuple of DependencySource types.
|
|
146
|
+
* @template T The type of value the derived parser produces.
|
|
147
|
+
* @param options Configuration for the derived parser with sync factory.
|
|
148
|
+
* @returns A {@link DerivedValueParser} that depends on the given sources.
|
|
149
|
+
* @since 0.10.0
|
|
150
|
+
*/
|
|
151
|
+
function deriveFromSync(options) {
|
|
152
|
+
const depsAsync = options.dependencies.some((dep) => dep.$mode === "async");
|
|
153
|
+
const sourceId = options.dependencies.length > 0 ? options.dependencies[0][DependencyId] : Symbol();
|
|
154
|
+
if (depsAsync) return createAsyncDerivedFromParserFromSyncFactory(sourceId, options);
|
|
155
|
+
return createSyncDerivedFromParser(sourceId, options);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Creates a derived value parser from multiple dependency sources
|
|
159
|
+
* with an asynchronous factory.
|
|
160
|
+
*
|
|
161
|
+
* This function allows creating a parser whose behavior depends on
|
|
162
|
+
* multiple other parsers' values. The factory explicitly returns
|
|
163
|
+
* an async parser.
|
|
164
|
+
*
|
|
165
|
+
* @template Deps A tuple of DependencySource types.
|
|
166
|
+
* @template T The type of value the derived parser produces.
|
|
167
|
+
* @param options Configuration for the derived parser with async factory.
|
|
168
|
+
* @returns A {@link DerivedValueParser} that depends on the given sources.
|
|
169
|
+
* @since 0.10.0
|
|
170
|
+
*/
|
|
171
|
+
function deriveFromAsync(options) {
|
|
172
|
+
const sourceId = options.dependencies.length > 0 ? options.dependencies[0][DependencyId] : Symbol();
|
|
173
|
+
return createAsyncDerivedFromParserFromAsyncFactory(sourceId, options);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Determines if the factory returns an async parser for deriveFrom options.
|
|
177
|
+
*/
|
|
178
|
+
function determineFactoryModeForDeriveFrom(options) {
|
|
179
|
+
const defaultValues = options.defaultValues();
|
|
180
|
+
const parser = options.factory(...defaultValues);
|
|
181
|
+
return parser.$mode === "async";
|
|
182
|
+
}
|
|
183
|
+
function createSyncDerivedFromParser(sourceId, options) {
|
|
184
|
+
return {
|
|
185
|
+
$mode: "sync",
|
|
186
|
+
metavar: options.metavar,
|
|
187
|
+
[DerivedValueParserMarker]: true,
|
|
188
|
+
[DependencyId]: sourceId,
|
|
189
|
+
parse(input) {
|
|
190
|
+
const sourceValues = options.defaultValues();
|
|
191
|
+
const derivedParser = options.factory(...sourceValues);
|
|
192
|
+
return derivedParser.parse(input);
|
|
193
|
+
},
|
|
194
|
+
[ParseWithDependency](input, dependencyValue) {
|
|
195
|
+
const derivedParser = options.factory(...dependencyValue);
|
|
196
|
+
return derivedParser.parse(input);
|
|
197
|
+
},
|
|
198
|
+
format(value) {
|
|
199
|
+
const sourceValues = options.defaultValues();
|
|
200
|
+
const derivedParser = options.factory(...sourceValues);
|
|
201
|
+
return derivedParser.format(value);
|
|
202
|
+
},
|
|
203
|
+
*suggest(prefix) {
|
|
204
|
+
const sourceValues = options.defaultValues();
|
|
205
|
+
const derivedParser = options.factory(...sourceValues);
|
|
206
|
+
if (derivedParser.suggest) yield* derivedParser.suggest(prefix);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Creates an async derived parser from multiple dependencies when the
|
|
212
|
+
* factory returns an async parser.
|
|
213
|
+
*/
|
|
214
|
+
function createAsyncDerivedFromParserFromAsyncFactory(sourceId, options) {
|
|
215
|
+
return {
|
|
216
|
+
$mode: "async",
|
|
217
|
+
metavar: options.metavar,
|
|
218
|
+
[DerivedValueParserMarker]: true,
|
|
219
|
+
[DependencyId]: sourceId,
|
|
220
|
+
parse(input) {
|
|
221
|
+
const sourceValues = options.defaultValues();
|
|
222
|
+
const derivedParser = options.factory(...sourceValues);
|
|
223
|
+
return derivedParser.parse(input);
|
|
224
|
+
},
|
|
225
|
+
[ParseWithDependency](input, dependencyValue) {
|
|
226
|
+
const derivedParser = options.factory(...dependencyValue);
|
|
227
|
+
return derivedParser.parse(input);
|
|
228
|
+
},
|
|
229
|
+
format(value) {
|
|
230
|
+
const sourceValues = options.defaultValues();
|
|
231
|
+
const derivedParser = options.factory(...sourceValues);
|
|
232
|
+
return derivedParser.format(value);
|
|
233
|
+
},
|
|
234
|
+
async *suggest(prefix) {
|
|
235
|
+
const sourceValues = options.defaultValues();
|
|
236
|
+
const derivedParser = options.factory(...sourceValues);
|
|
237
|
+
if (derivedParser.suggest) for await (const suggestion of derivedParser.suggest(prefix)) yield suggestion;
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Creates an async derived parser from multiple dependencies when the
|
|
243
|
+
* sources are async but the factory returns a sync parser.
|
|
244
|
+
*/
|
|
245
|
+
function createAsyncDerivedFromParserFromSyncFactory(sourceId, options) {
|
|
246
|
+
return {
|
|
247
|
+
$mode: "async",
|
|
248
|
+
metavar: options.metavar,
|
|
249
|
+
[DerivedValueParserMarker]: true,
|
|
250
|
+
[DependencyId]: sourceId,
|
|
251
|
+
parse(input) {
|
|
252
|
+
const sourceValues = options.defaultValues();
|
|
253
|
+
const derivedParser = options.factory(...sourceValues);
|
|
254
|
+
return Promise.resolve(derivedParser.parse(input));
|
|
255
|
+
},
|
|
256
|
+
[ParseWithDependency](input, dependencyValue) {
|
|
257
|
+
const derivedParser = options.factory(...dependencyValue);
|
|
258
|
+
return Promise.resolve(derivedParser.parse(input));
|
|
259
|
+
},
|
|
260
|
+
format(value) {
|
|
261
|
+
const sourceValues = options.defaultValues();
|
|
262
|
+
const derivedParser = options.factory(...sourceValues);
|
|
263
|
+
return derivedParser.format(value);
|
|
264
|
+
},
|
|
265
|
+
async *suggest(prefix) {
|
|
266
|
+
const sourceValues = options.defaultValues();
|
|
267
|
+
const derivedParser = options.factory(...sourceValues);
|
|
268
|
+
if (derivedParser.suggest) yield* derivedParser.suggest(prefix);
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function createDerivedValueParser(sourceId, sourceParser, options) {
|
|
273
|
+
const factoryReturnsAsync = determineFactoryMode(options);
|
|
274
|
+
const isAsync = sourceParser.$mode === "async" || factoryReturnsAsync;
|
|
275
|
+
if (isAsync) {
|
|
276
|
+
if (factoryReturnsAsync) return createAsyncDerivedParserFromAsyncFactory(sourceId, options);
|
|
277
|
+
return createAsyncDerivedParserFromSyncFactory(sourceId, options);
|
|
278
|
+
}
|
|
279
|
+
return createSyncDerivedParser(sourceId, options);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Determines if the factory returns an async parser by calling it with
|
|
283
|
+
* the default value and checking the mode.
|
|
284
|
+
*/
|
|
285
|
+
function determineFactoryMode(options) {
|
|
286
|
+
const defaultValue = options.defaultValue();
|
|
287
|
+
const parser = options.factory(defaultValue);
|
|
288
|
+
return parser.$mode === "async";
|
|
289
|
+
}
|
|
290
|
+
function createSyncDerivedParser(sourceId, options) {
|
|
291
|
+
return {
|
|
292
|
+
$mode: "sync",
|
|
293
|
+
metavar: options.metavar,
|
|
294
|
+
[DerivedValueParserMarker]: true,
|
|
295
|
+
[DependencyId]: sourceId,
|
|
296
|
+
parse(input) {
|
|
297
|
+
const sourceValue = options.defaultValue();
|
|
298
|
+
const derivedParser = options.factory(sourceValue);
|
|
299
|
+
return derivedParser.parse(input);
|
|
300
|
+
},
|
|
301
|
+
[ParseWithDependency](input, dependencyValue) {
|
|
302
|
+
const derivedParser = options.factory(dependencyValue);
|
|
303
|
+
return derivedParser.parse(input);
|
|
304
|
+
},
|
|
305
|
+
format(value) {
|
|
306
|
+
const sourceValue = options.defaultValue();
|
|
307
|
+
const derivedParser = options.factory(sourceValue);
|
|
308
|
+
return derivedParser.format(value);
|
|
309
|
+
},
|
|
310
|
+
*suggest(prefix) {
|
|
311
|
+
const sourceValue = options.defaultValue();
|
|
312
|
+
const derivedParser = options.factory(sourceValue);
|
|
313
|
+
if (derivedParser.suggest) yield* derivedParser.suggest(prefix);
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Creates an async derived parser when the factory returns an async parser.
|
|
319
|
+
* The parse result is awaited since the factory returns an async parser.
|
|
320
|
+
*/
|
|
321
|
+
function createAsyncDerivedParserFromAsyncFactory(sourceId, options) {
|
|
322
|
+
return {
|
|
323
|
+
$mode: "async",
|
|
324
|
+
metavar: options.metavar,
|
|
325
|
+
[DerivedValueParserMarker]: true,
|
|
326
|
+
[DependencyId]: sourceId,
|
|
327
|
+
parse(input) {
|
|
328
|
+
const sourceValue = options.defaultValue();
|
|
329
|
+
const derivedParser = options.factory(sourceValue);
|
|
330
|
+
return derivedParser.parse(input);
|
|
331
|
+
},
|
|
332
|
+
[ParseWithDependency](input, dependencyValue) {
|
|
333
|
+
const derivedParser = options.factory(dependencyValue);
|
|
334
|
+
return derivedParser.parse(input);
|
|
335
|
+
},
|
|
336
|
+
format(value) {
|
|
337
|
+
const sourceValue = options.defaultValue();
|
|
338
|
+
const derivedParser = options.factory(sourceValue);
|
|
339
|
+
return derivedParser.format(value);
|
|
340
|
+
},
|
|
341
|
+
async *suggest(prefix) {
|
|
342
|
+
const sourceValue = options.defaultValue();
|
|
343
|
+
const derivedParser = options.factory(sourceValue);
|
|
344
|
+
if (derivedParser.suggest) for await (const suggestion of derivedParser.suggest(prefix)) yield suggestion;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Creates an async derived parser when the source is async but the factory
|
|
350
|
+
* returns a sync parser. The sync result is wrapped in a Promise.
|
|
351
|
+
*/
|
|
352
|
+
function createAsyncDerivedParserFromSyncFactory(sourceId, options) {
|
|
353
|
+
return {
|
|
354
|
+
$mode: "async",
|
|
355
|
+
metavar: options.metavar,
|
|
356
|
+
[DerivedValueParserMarker]: true,
|
|
357
|
+
[DependencyId]: sourceId,
|
|
358
|
+
parse(input) {
|
|
359
|
+
const sourceValue = options.defaultValue();
|
|
360
|
+
const derivedParser = options.factory(sourceValue);
|
|
361
|
+
return Promise.resolve(derivedParser.parse(input));
|
|
362
|
+
},
|
|
363
|
+
[ParseWithDependency](input, dependencyValue) {
|
|
364
|
+
const derivedParser = options.factory(dependencyValue);
|
|
365
|
+
return Promise.resolve(derivedParser.parse(input));
|
|
366
|
+
},
|
|
367
|
+
format(value) {
|
|
368
|
+
const sourceValue = options.defaultValue();
|
|
369
|
+
const derivedParser = options.factory(sourceValue);
|
|
370
|
+
return derivedParser.format(value);
|
|
371
|
+
},
|
|
372
|
+
async *suggest(prefix) {
|
|
373
|
+
const sourceValue = options.defaultValue();
|
|
374
|
+
const derivedParser = options.factory(sourceValue);
|
|
375
|
+
if (derivedParser.suggest) yield* derivedParser.suggest(prefix);
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* A unique symbol used to identify deferred parse states.
|
|
381
|
+
* @since 0.10.0
|
|
382
|
+
*/
|
|
383
|
+
const DeferredParseMarker = Symbol.for("@optique/core/dependency/DeferredParseMarker");
|
|
384
|
+
/**
|
|
385
|
+
* Checks if a value is a {@link DeferredParseState}.
|
|
386
|
+
*
|
|
387
|
+
* @param value The value to check.
|
|
388
|
+
* @returns `true` if the value is a deferred parse state, `false` otherwise.
|
|
389
|
+
* @since 0.10.0
|
|
390
|
+
*/
|
|
391
|
+
function isDeferredParseState(value) {
|
|
392
|
+
return typeof value === "object" && value !== null && DeferredParseMarker in value && value[DeferredParseMarker] === true;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Creates a deferred parse state for a DerivedValueParser.
|
|
396
|
+
*
|
|
397
|
+
* @template T The type of value the parser will produce.
|
|
398
|
+
* @template S The type of the source dependency value.
|
|
399
|
+
* @param rawInput The raw input string to be parsed.
|
|
400
|
+
* @param parser The DerivedValueParser that will parse the input.
|
|
401
|
+
* @param preliminaryResult The parse result using default dependency value.
|
|
402
|
+
* @returns A DeferredParseState object.
|
|
403
|
+
* @since 0.10.0
|
|
404
|
+
*/
|
|
405
|
+
function createDeferredParseState(rawInput, parser, preliminaryResult) {
|
|
406
|
+
return {
|
|
407
|
+
[DeferredParseMarker]: true,
|
|
408
|
+
rawInput,
|
|
409
|
+
parser,
|
|
410
|
+
dependencyId: parser[DependencyId],
|
|
411
|
+
preliminaryResult
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* A unique symbol used to identify dependency source parse states.
|
|
416
|
+
* @since 0.10.0
|
|
417
|
+
*/
|
|
418
|
+
const DependencySourceStateMarker = Symbol.for("@optique/core/dependency/DependencySourceStateMarker");
|
|
419
|
+
/**
|
|
420
|
+
* Checks if a value is a {@link DependencySourceState}.
|
|
421
|
+
*
|
|
422
|
+
* @param value The value to check.
|
|
423
|
+
* @returns `true` if the value is a dependency source state, `false` otherwise.
|
|
424
|
+
* @since 0.10.0
|
|
425
|
+
*/
|
|
426
|
+
function isDependencySourceState(value) {
|
|
427
|
+
return typeof value === "object" && value !== null && DependencySourceStateMarker in value && value[DependencySourceStateMarker] === true;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Creates a dependency source state from a parse result.
|
|
431
|
+
*
|
|
432
|
+
* @template T The type of value the state contains.
|
|
433
|
+
* @param result The parse result.
|
|
434
|
+
* @param dependencyId The dependency ID.
|
|
435
|
+
* @returns A DependencySourceState object.
|
|
436
|
+
* @since 0.10.0
|
|
437
|
+
*/
|
|
438
|
+
function createDependencySourceState(result, dependencyId) {
|
|
439
|
+
return {
|
|
440
|
+
[DependencySourceStateMarker]: true,
|
|
441
|
+
[DependencyId]: dependencyId,
|
|
442
|
+
result
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* A registry for storing resolved dependency values during parsing.
|
|
447
|
+
* This is used to pass dependency values from DependencySource options
|
|
448
|
+
* to DerivedValueParser options.
|
|
449
|
+
* @since 0.10.0
|
|
450
|
+
*/
|
|
451
|
+
var DependencyRegistry = class DependencyRegistry {
|
|
452
|
+
values = /* @__PURE__ */ new Map();
|
|
453
|
+
/**
|
|
454
|
+
* Registers a resolved dependency value.
|
|
455
|
+
* @param id The dependency ID.
|
|
456
|
+
* @param value The resolved value.
|
|
457
|
+
*/
|
|
458
|
+
set(id, value) {
|
|
459
|
+
this.values.set(id, value);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Gets a resolved dependency value.
|
|
463
|
+
* @param id The dependency ID.
|
|
464
|
+
* @returns The resolved value, or undefined if not found.
|
|
465
|
+
*/
|
|
466
|
+
get(id) {
|
|
467
|
+
return this.values.get(id);
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Checks if a dependency has been resolved.
|
|
471
|
+
* @param id The dependency ID.
|
|
472
|
+
* @returns `true` if the dependency has been resolved.
|
|
473
|
+
*/
|
|
474
|
+
has(id) {
|
|
475
|
+
return this.values.has(id);
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Creates a copy of the registry.
|
|
479
|
+
*/
|
|
480
|
+
clone() {
|
|
481
|
+
const copy = new DependencyRegistry();
|
|
482
|
+
for (const [id, value] of this.values) copy.values.set(id, value);
|
|
483
|
+
return copy;
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
/**
|
|
487
|
+
* Formats a {@link DependencyError} into a human-readable {@link Message}.
|
|
488
|
+
*
|
|
489
|
+
* @param error The dependency error to format.
|
|
490
|
+
* @returns A Message describing the error.
|
|
491
|
+
* @since 0.10.0
|
|
492
|
+
*/
|
|
493
|
+
function formatDependencyError(error) {
|
|
494
|
+
switch (error.kind) {
|
|
495
|
+
case "duplicate": return [{
|
|
496
|
+
type: "text",
|
|
497
|
+
text: `Dependency used in multiple locations: ${error.locations.join(", ")}.`
|
|
498
|
+
}];
|
|
499
|
+
case "unresolved": return [{
|
|
500
|
+
type: "text",
|
|
501
|
+
text: `Unresolved dependency for ${error.derivedParserMetavar}: the dependency was not provided.`
|
|
502
|
+
}];
|
|
503
|
+
case "circular": return [{
|
|
504
|
+
type: "text",
|
|
505
|
+
text: `Circular dependency detected.`
|
|
506
|
+
}];
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
//#endregion
|
|
511
|
+
exports.DeferredParseMarker = DeferredParseMarker;
|
|
512
|
+
exports.DependencyId = DependencyId;
|
|
513
|
+
exports.DependencyRegistry = DependencyRegistry;
|
|
514
|
+
exports.DependencySourceMarker = DependencySourceMarker;
|
|
515
|
+
exports.DependencySourceStateMarker = DependencySourceStateMarker;
|
|
516
|
+
exports.DerivedValueParserMarker = DerivedValueParserMarker;
|
|
517
|
+
exports.ParseWithDependency = ParseWithDependency;
|
|
518
|
+
exports.createDeferredParseState = createDeferredParseState;
|
|
519
|
+
exports.createDependencySourceState = createDependencySourceState;
|
|
520
|
+
exports.dependency = dependency;
|
|
521
|
+
exports.deriveFrom = deriveFrom;
|
|
522
|
+
exports.deriveFromAsync = deriveFromAsync;
|
|
523
|
+
exports.deriveFromSync = deriveFromSync;
|
|
524
|
+
exports.formatDependencyError = formatDependencyError;
|
|
525
|
+
exports.isDeferredParseState = isDeferredParseState;
|
|
526
|
+
exports.isDependencySource = isDependencySource;
|
|
527
|
+
exports.isDependencySourceState = isDependencySourceState;
|
|
528
|
+
exports.isDerivedValueParser = isDerivedValueParser;
|