@optique/core 0.10.0-dev.291 → 0.10.0-dev.292

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.
@@ -0,0 +1,457 @@
1
+ import { NonEmptyString } from "./nonempty.js";
2
+ import { Message } from "./message.js";
3
+ import { ValueParser, ValueParserResult } from "./valueparser.js";
4
+ import { Mode } from "./parser.js";
5
+
6
+ //#region src/dependency.d.ts
7
+
8
+ /**
9
+ * A unique symbol used to identify dependency sources at compile time.
10
+ * This marker is used to distinguish {@link DependencySource} from regular
11
+ * {@link ValueParser} instances.
12
+ * @since 0.10.0
13
+ */
14
+ declare const DependencySourceMarker: unique symbol;
15
+ /**
16
+ * A unique symbol used to identify derived value parsers at compile time.
17
+ * This marker is used to distinguish {@link DerivedValueParser} from regular
18
+ * {@link ValueParser} instances.
19
+ * @since 0.10.0
20
+ */
21
+ declare const DerivedValueParserMarker: unique symbol;
22
+ /**
23
+ * A unique symbol used to store the dependency ID on value parsers.
24
+ * @since 0.10.0
25
+ */
26
+ declare const DependencyId: unique symbol;
27
+ /**
28
+ * A unique symbol used to access the parseWithDependency method on derived parsers.
29
+ * @since 0.10.0
30
+ */
31
+ declare const ParseWithDependency: unique symbol;
32
+ /**
33
+ * Options for creating a derived value parser.
34
+ *
35
+ * @template S The type of the source dependency value.
36
+ * @template T The type of the derived parser value.
37
+ * @since 0.10.0
38
+ */
39
+ interface DeriveOptions<S, T> {
40
+ /**
41
+ * The metavariable name for the derived parser. Used in help messages
42
+ * to indicate what kind of value this parser expects.
43
+ */
44
+ readonly metavar: NonEmptyString;
45
+ /**
46
+ * Factory function that creates a {@link ValueParser} based on the
47
+ * dependency source's value.
48
+ *
49
+ * @param sourceValue The value parsed from the dependency source.
50
+ * @returns A {@link ValueParser} for the derived value.
51
+ */
52
+ readonly factory: (sourceValue: S) => ValueParser<"sync", T>;
53
+ /**
54
+ * Default value to use when the dependency source is not provided.
55
+ * This allows the derived parser to work even when the dependency
56
+ * is optional.
57
+ *
58
+ * @returns The default value for the dependency source.
59
+ */
60
+ readonly defaultValue: () => S;
61
+ }
62
+ /**
63
+ * Represents a dependency source that can be used to create derived parsers.
64
+ *
65
+ * A dependency source wraps a {@link ValueParser} and provides methods to
66
+ * create derived parsers that depend on the parsed value. This enables
67
+ * inter-option dependencies where one option's valid values depend on
68
+ * another option's value.
69
+ *
70
+ * @template M The execution mode of the parser (`"sync"` or `"async"`).
71
+ * @template T The type of value this dependency source produces.
72
+ * @since 0.10.0
73
+ */
74
+ interface DependencySource<M extends Mode = "sync", T = unknown> extends ValueParser<M, T> {
75
+ /**
76
+ * Marker to identify this as a dependency source.
77
+ * @internal
78
+ */
79
+ readonly [DependencySourceMarker]: true;
80
+ /**
81
+ * Unique identifier for this dependency source.
82
+ * @internal
83
+ */
84
+ readonly [DependencyId]: symbol;
85
+ /**
86
+ * Creates a derived value parser whose behavior depends on this
87
+ * dependency source's value.
88
+ *
89
+ * The derived parser uses a factory function to create parsers based on
90
+ * the source value. Currently, only synchronous factory functions are
91
+ * supported.
92
+ *
93
+ * @template U The type of value the derived parser produces.
94
+ * @param options Configuration for the derived parser.
95
+ * @returns A {@link DerivedValueParser} that depends on this source.
96
+ */
97
+ derive<U>(options: DeriveOptions<T, U>): DerivedValueParser<M, U, T>;
98
+ }
99
+ /**
100
+ * Extracts the value type from a DependencySource.
101
+ * @template D The DependencySource type.
102
+ * @since 0.10.0
103
+ */
104
+ type DependencyValue<D> = D extends DependencySource<Mode, infer T> ? T : never;
105
+ /**
106
+ * Extracts the mode from a DependencySource.
107
+ * @template D The DependencySource type.
108
+ * @since 0.10.0
109
+ */
110
+ type DependencyMode<D> = D extends DependencySource<infer M, unknown> ? M : never;
111
+ /**
112
+ * Maps a tuple of DependencySources to a tuple of their value types.
113
+ * @template T The tuple of DependencySource types.
114
+ * @since 0.10.0
115
+ */
116
+ type DependencyValues<T extends readonly unknown[]> = { [K in keyof T]: T[K] extends DependencySource<Mode, infer V> ? V : never };
117
+ /**
118
+ * Combines modes from multiple dependency sources.
119
+ * If any source is async, the result is async.
120
+ * @template T The tuple of DependencySource types.
121
+ * @since 0.10.0
122
+ */
123
+ type CombinedDependencyMode<T extends readonly unknown[]> = "async" extends { [K in keyof T]: T[K] extends DependencySource<infer M, unknown> ? M : never }[number] ? "async" : "sync";
124
+ /**
125
+ * Represents any dependency source, used in type constraints.
126
+ * @since 0.10.0
127
+ */
128
+ type AnyDependencySource = DependencySource<Mode, any>;
129
+ /**
130
+ * Options for creating a derived value parser from multiple dependencies.
131
+ *
132
+ * @template Deps A tuple of DependencySource types.
133
+ * @template T The type of the derived parser value.
134
+ * @since 0.10.0
135
+ */
136
+ interface DeriveFromOptions<Deps extends readonly AnyDependencySource[], T> {
137
+ /**
138
+ * The metavariable name for the derived parser. Used in help messages
139
+ * to indicate what kind of value this parser expects.
140
+ */
141
+ readonly metavar: NonEmptyString;
142
+ /**
143
+ * The dependency sources that this derived parser depends on.
144
+ */
145
+ readonly dependencies: Deps;
146
+ /**
147
+ * Factory function that creates a {@link ValueParser} based on the
148
+ * dependency sources' values.
149
+ *
150
+ * @param values The values parsed from the dependency sources (in order).
151
+ * @returns A {@link ValueParser} for the derived value.
152
+ */
153
+ readonly factory: (...values: DependencyValues<Deps>) => ValueParser<"sync", T>;
154
+ /**
155
+ * Default values to use when the dependency sources are not provided.
156
+ * Must return a tuple with the same length and types as the dependencies.
157
+ *
158
+ * @returns A tuple of default values for each dependency source.
159
+ */
160
+ readonly defaultValues: () => DependencyValues<Deps>;
161
+ }
162
+ /**
163
+ * A value parser that depends on another parser's value.
164
+ *
165
+ * A derived value parser cannot be nested (i.e., you cannot call
166
+ * {@link DependencySource.derive} on a {@link DerivedValueParser}).
167
+ *
168
+ * @template M The execution mode of the parser (`"sync"` or `"async"`).
169
+ * @template T The type of value this parser produces.
170
+ * @template S The type of the source dependency value.
171
+ * @since 0.10.0
172
+ */
173
+ interface DerivedValueParser<M extends Mode = "sync", T = unknown, S = unknown> extends ValueParser<M, T> {
174
+ /**
175
+ * Marker to identify this as a derived value parser.
176
+ * @internal
177
+ */
178
+ readonly [DerivedValueParserMarker]: true;
179
+ /**
180
+ * The unique identifier of the dependency source this parser depends on.
181
+ * @internal
182
+ */
183
+ readonly [DependencyId]: symbol;
184
+ /**
185
+ * Parses the input using the actual dependency value instead of the default.
186
+ * This method is used during dependency resolution in `complete()`.
187
+ *
188
+ * @param input The raw input string to parse.
189
+ * @param dependencyValue The resolved dependency value.
190
+ * @returns The parse result.
191
+ * @internal
192
+ */
193
+ readonly [ParseWithDependency]: (input: string, dependencyValue: S) => ValueParserResult<T> | Promise<ValueParserResult<T>>;
194
+ }
195
+ /**
196
+ * Creates a dependency source from a {@link ValueParser}.
197
+ *
198
+ * A dependency source wraps an existing value parser and enables creating
199
+ * derived parsers that depend on the parsed value. This is useful for
200
+ * scenarios where one option's valid values depend on another option's value.
201
+ *
202
+ * @template M The execution mode of the value parser.
203
+ * @template T The type of value the parser produces.
204
+ * @param parser The value parser to wrap as a dependency source.
205
+ * @returns A {@link DependencySource} that can be used to create
206
+ * derived parsers.
207
+ * @example
208
+ * ```typescript
209
+ * import { dependency } from "@optique/core/dependency";
210
+ * import { string } from "@optique/core/valueparser";
211
+ *
212
+ * // Create a dependency source for a directory path
213
+ * const cwdParser = dependency(string({ metavar: "DIR" }));
214
+ *
215
+ * // Create a derived parser that depends on the directory
216
+ * const branchParser = cwdParser.derive({
217
+ * metavar: "BRANCH",
218
+ * factory: (dir) => gitBranch({ dir }),
219
+ * defaultValue: () => process.cwd(),
220
+ * });
221
+ * ```
222
+ * @since 0.10.0
223
+ */
224
+ declare function dependency<M extends Mode, T>(parser: ValueParser<M, T>): DependencySource<M, T>;
225
+ /**
226
+ * Checks if a value parser is a {@link DependencySource}.
227
+ *
228
+ * @param parser The value parser to check.
229
+ * @returns `true` if the parser is a dependency source, `false` otherwise.
230
+ * @since 0.10.0
231
+ */
232
+ declare function isDependencySource<M extends Mode, T>(parser: ValueParser<M, T>): parser is DependencySource<M, T>;
233
+ /**
234
+ * Checks if a value parser is a {@link DerivedValueParser}.
235
+ *
236
+ * @param parser The value parser to check.
237
+ * @returns `true` if the parser is a derived value parser, `false` otherwise.
238
+ * @since 0.10.0
239
+ */
240
+ declare function isDerivedValueParser<M extends Mode, T>(parser: ValueParser<M, T>): parser is DerivedValueParser<M, T, unknown>;
241
+ /**
242
+ * Creates a derived value parser from multiple dependency sources.
243
+ *
244
+ * This function allows creating a parser whose behavior depends on
245
+ * multiple other parsers' values. This is useful for scenarios where
246
+ * an option's valid values depend on a combination of other options.
247
+ *
248
+ * @template Deps A tuple of DependencySource types.
249
+ * @template T The type of value the derived parser produces.
250
+ * @param options Configuration for the derived parser.
251
+ * @returns A {@link DerivedValueParser} that depends on the given sources.
252
+ * @example
253
+ * ```typescript
254
+ * import { dependency, deriveFrom } from "@optique/core/dependency";
255
+ * import { string, choice } from "@optique/core/valueparser";
256
+ *
257
+ * const dirParser = dependency(string({ metavar: "DIR" }));
258
+ * const modeParser = dependency(choice(["dev", "prod"]));
259
+ *
260
+ * const configParser = deriveFrom({
261
+ * metavar: "CONFIG",
262
+ * dependencies: [dirParser, modeParser] as const,
263
+ * factory: (dir, mode) =>
264
+ * choice(mode === "dev"
265
+ * ? [`${dir}/dev.json`, `${dir}/dev.yaml`]
266
+ * : [`${dir}/prod.json`, `${dir}/prod.yaml`]),
267
+ * defaultValues: () => ["/config", "dev"],
268
+ * });
269
+ * ```
270
+ * @since 0.10.0
271
+ */
272
+ declare function deriveFrom<Deps extends readonly AnyDependencySource[], T>(options: DeriveFromOptions<Deps, T>): DerivedValueParser<CombinedDependencyMode<Deps>, T, DependencyValues<Deps>>;
273
+ /**
274
+ * A unique symbol used to identify deferred parse states.
275
+ * @since 0.10.0
276
+ */
277
+ declare const DeferredParseMarker: unique symbol;
278
+ /**
279
+ * Represents a deferred parse state for a DerivedValueParser.
280
+ *
281
+ * When a DerivedValueParser is used in an option or argument, the raw
282
+ * input string is stored along with the parser reference. The actual
283
+ * parsing is deferred until `complete()` time when all dependencies
284
+ * have been resolved.
285
+ *
286
+ * @template T The type of value this parser will produce after resolution.
287
+ * @since 0.10.0
288
+ */
289
+ interface DeferredParseState<T = unknown> {
290
+ /**
291
+ * Marker to identify this as a deferred parse state.
292
+ */
293
+ readonly [DeferredParseMarker]: true;
294
+ /**
295
+ * The raw input string to be parsed.
296
+ */
297
+ readonly rawInput: string;
298
+ /**
299
+ * The DerivedValueParser that will parse the input.
300
+ */
301
+ readonly parser: DerivedValueParser<Mode, T, unknown>;
302
+ /**
303
+ * The dependency ID that this parser depends on.
304
+ */
305
+ readonly dependencyId: symbol;
306
+ /**
307
+ * The preliminary parse result using the default dependency value.
308
+ * This is used as a fallback if dependency resolution is not needed
309
+ * or if the dependency was not provided.
310
+ */
311
+ readonly preliminaryResult: ValueParserResult<T>;
312
+ }
313
+ /**
314
+ * Checks if a value is a {@link DeferredParseState}.
315
+ *
316
+ * @param value The value to check.
317
+ * @returns `true` if the value is a deferred parse state, `false` otherwise.
318
+ * @since 0.10.0
319
+ */
320
+ declare function isDeferredParseState<T>(value: unknown): value is DeferredParseState<T>;
321
+ /**
322
+ * Creates a deferred parse state for a DerivedValueParser.
323
+ *
324
+ * @template T The type of value the parser will produce.
325
+ * @template S The type of the source dependency value.
326
+ * @param rawInput The raw input string to be parsed.
327
+ * @param parser The DerivedValueParser that will parse the input.
328
+ * @param preliminaryResult The parse result using default dependency value.
329
+ * @returns A DeferredParseState object.
330
+ * @since 0.10.0
331
+ */
332
+ declare function createDeferredParseState<T, S>(rawInput: string, parser: DerivedValueParser<Mode, T, S>, preliminaryResult: ValueParserResult<T>): DeferredParseState<T>;
333
+ /**
334
+ * A unique symbol used to identify dependency source parse states.
335
+ * @since 0.10.0
336
+ */
337
+ declare const DependencySourceStateMarker: unique symbol;
338
+ /**
339
+ * Represents a parse state from a DependencySource.
340
+ * This wraps the normal ValueParserResult with the dependency ID so that
341
+ * it can be matched with DeferredParseState during resolution.
342
+ *
343
+ * @template T The type of value this state contains.
344
+ * @since 0.10.0
345
+ */
346
+ interface DependencySourceState<T = unknown> {
347
+ /**
348
+ * Marker to identify this as a dependency source state.
349
+ */
350
+ readonly [DependencySourceStateMarker]: true;
351
+ /**
352
+ * The dependency ID of the source.
353
+ */
354
+ readonly [DependencyId]: symbol;
355
+ /**
356
+ * The underlying parse result.
357
+ */
358
+ readonly result: ValueParserResult<T>;
359
+ }
360
+ /**
361
+ * Checks if a value is a {@link DependencySourceState}.
362
+ *
363
+ * @param value The value to check.
364
+ * @returns `true` if the value is a dependency source state, `false` otherwise.
365
+ * @since 0.10.0
366
+ */
367
+ declare function isDependencySourceState<T>(value: unknown): value is DependencySourceState<T>;
368
+ /**
369
+ * Creates a dependency source state from a parse result.
370
+ *
371
+ * @template T The type of value the state contains.
372
+ * @param result The parse result.
373
+ * @param dependencyId The dependency ID.
374
+ * @returns A DependencySourceState object.
375
+ * @since 0.10.0
376
+ */
377
+ declare function createDependencySourceState<T>(result: ValueParserResult<T>, dependencyId: symbol): DependencySourceState<T>;
378
+ /**
379
+ * Represents a resolved dependency value stored during parsing.
380
+ * @since 0.10.0
381
+ */
382
+ interface ResolvedDependency<T = unknown> {
383
+ /**
384
+ * The dependency ID.
385
+ */
386
+ readonly id: symbol;
387
+ /**
388
+ * The resolved value.
389
+ */
390
+ readonly value: T;
391
+ }
392
+ /**
393
+ * A registry for storing resolved dependency values during parsing.
394
+ * This is used to pass dependency values from DependencySource options
395
+ * to DerivedValueParser options.
396
+ * @since 0.10.0
397
+ */
398
+ declare class DependencyRegistry {
399
+ private readonly values;
400
+ /**
401
+ * Registers a resolved dependency value.
402
+ * @param id The dependency ID.
403
+ * @param value The resolved value.
404
+ */
405
+ set<T>(id: symbol, value: T): void;
406
+ /**
407
+ * Gets a resolved dependency value.
408
+ * @param id The dependency ID.
409
+ * @returns The resolved value, or undefined if not found.
410
+ */
411
+ get<T>(id: symbol): T | undefined;
412
+ /**
413
+ * Checks if a dependency has been resolved.
414
+ * @param id The dependency ID.
415
+ * @returns `true` if the dependency has been resolved.
416
+ */
417
+ has(id: symbol): boolean;
418
+ /**
419
+ * Creates a copy of the registry.
420
+ */
421
+ clone(): DependencyRegistry;
422
+ }
423
+ /**
424
+ * Error types for dependency resolution failures.
425
+ * @since 0.10.0
426
+ */
427
+ type DependencyError = {
428
+ /**
429
+ * The dependency was used in multiple locations.
430
+ */
431
+ readonly kind: "duplicate";
432
+ readonly dependencyId: symbol;
433
+ readonly locations: readonly string[];
434
+ } | {
435
+ /**
436
+ * A derived parser references a dependency that was not provided.
437
+ */
438
+ readonly kind: "unresolved";
439
+ readonly dependencyId: symbol;
440
+ readonly derivedParserMetavar: string;
441
+ } | {
442
+ /**
443
+ * Circular dependency detected.
444
+ */
445
+ readonly kind: "circular";
446
+ readonly cycle: readonly symbol[];
447
+ };
448
+ /**
449
+ * Formats a {@link DependencyError} into a human-readable {@link Message}.
450
+ *
451
+ * @param error The dependency error to format.
452
+ * @returns A Message describing the error.
453
+ * @since 0.10.0
454
+ */
455
+ declare function formatDependencyError(error: DependencyError): Message;
456
+ //#endregion
457
+ export { AnyDependencySource, CombinedDependencyMode, DeferredParseMarker, DeferredParseState, DependencyError, DependencyId, DependencyMode, DependencyRegistry, DependencySource, DependencySourceMarker, DependencySourceState, DependencySourceStateMarker, DependencyValue, DependencyValues, DeriveFromOptions, DeriveOptions, DerivedValueParser, DerivedValueParserMarker, ParseWithDependency, ResolvedDependency, createDeferredParseState, createDependencySourceState, dependency, deriveFrom, formatDependencyError, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser };