@optique/core 1.3.0-dev.2398 → 1.3.0-dev.2399

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.
@@ -9,6 +9,16 @@ const require_message = require('../message.cjs');
9
9
  */
10
10
  const dependencySourceMarker = Symbol.for("@optique/core/dependency/dependencySourceMarker");
11
11
  /**
12
+ * A unique symbol used to store a dependency source's own identity.
13
+ *
14
+ * This is distinct from {@link dependencyId}, which stores an upstream
15
+ * reference on a derived parser. A parser wrapped with `dependency()` after
16
+ * derivation carries both values.
17
+ * @internal
18
+ * @since 1.3.0
19
+ */
20
+ const dependencySourceId = Symbol.for("@optique/core/dependency/dependencySourceId");
21
+ /**
12
22
  * A unique symbol used to identify derived value parsers at compile time.
13
23
  * This marker is used to distinguish {@link DerivedValueParser} from regular
14
24
  * {@link ValueParser} instances.
@@ -66,6 +76,8 @@ const suggestWithDependency = Symbol.for("@optique/core/dependency/suggestWithDe
66
76
  * A dependency source wraps an existing value parser and enables creating
67
77
  * derived parsers that depend on the parsed value. This is useful for
68
78
  * scenarios where one option's valid values depend on another option's value.
79
+ * A derived parser can itself become a source by wrapping it with
80
+ * `dependency()`, allowing dependency chains of any depth.
69
81
  *
70
82
  * @template M The execution mode of the value parser.
71
83
  * @template T The type of value the parser produces.
@@ -87,15 +99,23 @@ const suggestWithDependency = Symbol.for("@optique/core/dependency/suggestWithDe
87
99
  * factory: (dir) => gitBranch({ dir }),
88
100
  * defaultValue: () => process.cwd(),
89
101
  * });
102
+ *
103
+ * // A derived parser can provide the next dependency level.
104
+ * const branchSource = dependency(branchParser);
105
+ * const commitParser = branchSource.deriveSync({
106
+ * metavar: "COMMIT",
107
+ * factory: (branch) => gitCommit({ branch }),
108
+ * defaultValue: () => "main",
109
+ * });
90
110
  * ```
91
111
  * @since 0.10.0
92
112
  */
93
113
  function dependency(parser) {
94
114
  const id = Symbol();
95
- const result = {
96
- ...parser,
115
+ const result = Object.create(Object.getPrototypeOf(parser), Object.getOwnPropertyDescriptors(parser));
116
+ Object.defineProperties(result, Object.getOwnPropertyDescriptors({
97
117
  [dependencySourceMarker]: true,
98
- [dependencyId]: id,
118
+ [dependencySourceId]: id,
99
119
  derive(options) {
100
120
  if (options.mode !== "sync" && options.mode !== "async") throw new TypeError("derive() requires an explicit mode field (\"sync\" or \"async\").");
101
121
  return createDerivedValueParser(id, parser, options, options.mode);
@@ -107,7 +127,7 @@ function dependency(parser) {
107
127
  deriveAsync(options) {
108
128
  return createAsyncDerivedParserFromAsyncFactory(id, options);
109
129
  }
110
- };
130
+ }));
111
131
  return result;
112
132
  }
113
133
  /**
@@ -166,7 +186,7 @@ function isDerivedValueParser(parser) {
166
186
  function deriveFrom(options) {
167
187
  if (options.mode !== "sync" && options.mode !== "async") throw new TypeError("deriveFrom() requires an explicit mode field (\"sync\" or \"async\").");
168
188
  const depsAsync = options.dependencies.some((dep) => dep.mode === "async");
169
- const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencyId] : Symbol();
189
+ const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencySourceId] : Symbol();
170
190
  const factoryReturnsAsync = options.mode === "async";
171
191
  const isAsync = depsAsync || factoryReturnsAsync;
172
192
  if (isAsync) {
@@ -191,7 +211,7 @@ function deriveFrom(options) {
191
211
  */
192
212
  function deriveFromSync(options) {
193
213
  const depsAsync = options.dependencies.some((dep) => dep.mode === "async");
194
- const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencyId] : Symbol();
214
+ const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencySourceId] : Symbol();
195
215
  if (depsAsync) return createAsyncDerivedFromParserFromSyncFactory(sourceId, options);
196
216
  return createSyncDerivedFromParser(sourceId, options);
197
217
  }
@@ -210,7 +230,7 @@ function deriveFromSync(options) {
210
230
  * @since 0.10.0
211
231
  */
212
232
  function deriveFromAsync(options) {
213
- const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencyId] : Symbol();
233
+ const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencySourceId] : Symbol();
214
234
  return createAsyncDerivedFromParserFromAsyncFactory(sourceId, options);
215
235
  }
216
236
  function isAsyncModeParser(parser) {
@@ -282,7 +302,7 @@ async function parseDerivedResultWithSnapshotAsync(parser, input, sourceValues)
282
302
  return attachDefaultDependencySnapshot(await parseDerivedResultAsync(parser, input), snapshot);
283
303
  }
284
304
  function createSyncDerivedFromParser(sourceId, options) {
285
- const alldependencyIds = options.dependencies.map((dep) => dep[dependencyId]);
305
+ const alldependencyIds = options.dependencies.map((dep) => dep[dependencySourceId]);
286
306
  return {
287
307
  mode: "sync",
288
308
  metavar: options.metavar,
@@ -387,7 +407,7 @@ function createSyncDerivedFromParser(sourceId, options) {
387
407
  * factory returns an async parser.
388
408
  */
389
409
  function createAsyncDerivedFromParserFromAsyncFactory(sourceId, options) {
390
- const alldependencyIds = options.dependencies.map((dep) => dep[dependencyId]);
410
+ const alldependencyIds = options.dependencies.map((dep) => dep[dependencySourceId]);
391
411
  return {
392
412
  mode: "async",
393
413
  metavar: options.metavar,
@@ -475,7 +495,7 @@ function createAsyncDerivedFromParserFromAsyncFactory(sourceId, options) {
475
495
  * sources are async but the factory returns a sync parser.
476
496
  */
477
497
  function createAsyncDerivedFromParserFromSyncFactory(sourceId, options) {
478
- const alldependencyIds = options.dependencies.map((dep) => dep[dependencyId]);
498
+ const alldependencyIds = options.dependencies.map((dep) => dep[dependencySourceId]);
479
499
  return {
480
500
  mode: "async",
481
501
  metavar: options.metavar,
@@ -1089,6 +1109,7 @@ exports.deferredParseMarker = deferredParseMarker;
1089
1109
  exports.dependency = dependency;
1090
1110
  exports.dependencyId = dependencyId;
1091
1111
  exports.dependencyIds = dependencyIds;
1112
+ exports.dependencySourceId = dependencySourceId;
1092
1113
  exports.dependencySourceMarker = dependencySourceMarker;
1093
1114
  exports.dependencySourceStateMarker = dependencySourceStateMarker;
1094
1115
  exports.deriveFrom = deriveFrom;
@@ -13,6 +13,16 @@ import { Mode, Suggestion } from "./parser.cjs";
13
13
  * @since 0.10.0
14
14
  */
15
15
  declare const dependencySourceMarker: unique symbol;
16
+ /**
17
+ * A unique symbol used to store a dependency source's own identity.
18
+ *
19
+ * This is distinct from {@link dependencyId}, which stores an upstream
20
+ * reference on a derived parser. A parser wrapped with `dependency()` after
21
+ * derivation carries both values.
22
+ * @internal
23
+ * @since 1.3.0
24
+ */
25
+ declare const dependencySourceId: unique symbol;
16
26
  /**
17
27
  * A unique symbol used to identify derived value parsers at compile time.
18
28
  * This marker is used to distinguish {@link DerivedValueParser} from regular
@@ -176,7 +186,7 @@ interface DependencySource<M extends Mode = "sync", T = unknown> extends ValuePa
176
186
  * Unique identifier for this dependency source.
177
187
  * @internal
178
188
  */
179
- readonly [dependencyId]: symbol;
189
+ readonly [dependencySourceId]: symbol;
180
190
  /**
181
191
  * Creates a derived value parser whose behavior depends on this
182
192
  * dependency source's value.
@@ -255,7 +265,7 @@ type CombinedDependencyMode<T extends readonly unknown[]> = "async" extends { [K
255
265
  */
256
266
  interface AnyDependencySource<M extends Mode = Mode> {
257
267
  readonly [dependencySourceMarker]: true;
258
- readonly [dependencyId]: symbol;
268
+ readonly [dependencySourceId]: symbol;
259
269
  readonly mode: M;
260
270
  }
261
271
  /**
@@ -355,9 +365,6 @@ interface DeriveFromAsyncOptions<Deps extends readonly AnyDependencySource[], T>
355
365
  /**
356
366
  * A value parser that depends on another parser's value.
357
367
  *
358
- * A derived value parser cannot be nested (i.e., you cannot call
359
- * {@link DependencySource.derive} on a {@link DerivedValueParser}).
360
- *
361
368
  * @template M The execution mode of the parser (`"sync"` or `"async"`).
362
369
  * @template T The type of value this parser produces.
363
370
  * @template S The type of the source dependency value.
@@ -424,6 +431,8 @@ interface DerivedValueParser<M extends Mode = "sync", T = unknown, S = unknown>
424
431
  * A dependency source wraps an existing value parser and enables creating
425
432
  * derived parsers that depend on the parsed value. This is useful for
426
433
  * scenarios where one option's valid values depend on another option's value.
434
+ * A derived parser can itself become a source by wrapping it with
435
+ * `dependency()`, allowing dependency chains of any depth.
427
436
  *
428
437
  * @template M The execution mode of the value parser.
429
438
  * @template T The type of value the parser produces.
@@ -445,6 +454,14 @@ interface DerivedValueParser<M extends Mode = "sync", T = unknown, S = unknown>
445
454
  * factory: (dir) => gitBranch({ dir }),
446
455
  * defaultValue: () => process.cwd(),
447
456
  * });
457
+ *
458
+ * // A derived parser can provide the next dependency level.
459
+ * const branchSource = dependency(branchParser);
460
+ * const commitParser = branchSource.deriveSync({
461
+ * metavar: "COMMIT",
462
+ * factory: (branch) => gitCommit({ branch }),
463
+ * defaultValue: () => "main",
464
+ * });
448
465
  * ```
449
466
  * @since 0.10.0
450
467
  */
@@ -845,4 +862,4 @@ type DependencyError = {
845
862
  */
846
863
  declare function formatDependencyError(error: DependencyError): Message;
847
864
  //#endregion
848
- export { AnyDependencySource, CombineMode, CombinedDependencyMode, DeferredParseState, DependencyError, DependencyMode, DependencyRegistry, DependencySource, DependencySourceState, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, PendingDependencySourceState, ResolvedDependency, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultDependencyValueSnapshot, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, formatDependencyError, getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, pendingDependencySourceStateMarker, singleDefaultValue, snapshotDefaultDependencyValues, suggestWithDependency, transformsDependencyValue, transformsDependencyValueMarker, wrappedDependencySourceMarker };
865
+ export { AnyDependencySource, CombineMode, CombinedDependencyMode, DeferredParseState, DependencyError, DependencyMode, DependencyRegistry, DependencySource, DependencySourceState, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, PendingDependencySourceState, ResolvedDependency, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultDependencyValueSnapshot, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceId, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, formatDependencyError, getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, pendingDependencySourceStateMarker, singleDefaultValue, snapshotDefaultDependencyValues, suggestWithDependency, transformsDependencyValue, transformsDependencyValueMarker, wrappedDependencySourceMarker };
@@ -13,6 +13,16 @@ import { Mode, Suggestion } from "./parser.js";
13
13
  * @since 0.10.0
14
14
  */
15
15
  declare const dependencySourceMarker: unique symbol;
16
+ /**
17
+ * A unique symbol used to store a dependency source's own identity.
18
+ *
19
+ * This is distinct from {@link dependencyId}, which stores an upstream
20
+ * reference on a derived parser. A parser wrapped with `dependency()` after
21
+ * derivation carries both values.
22
+ * @internal
23
+ * @since 1.3.0
24
+ */
25
+ declare const dependencySourceId: unique symbol;
16
26
  /**
17
27
  * A unique symbol used to identify derived value parsers at compile time.
18
28
  * This marker is used to distinguish {@link DerivedValueParser} from regular
@@ -176,7 +186,7 @@ interface DependencySource<M extends Mode = "sync", T = unknown> extends ValuePa
176
186
  * Unique identifier for this dependency source.
177
187
  * @internal
178
188
  */
179
- readonly [dependencyId]: symbol;
189
+ readonly [dependencySourceId]: symbol;
180
190
  /**
181
191
  * Creates a derived value parser whose behavior depends on this
182
192
  * dependency source's value.
@@ -255,7 +265,7 @@ type CombinedDependencyMode<T extends readonly unknown[]> = "async" extends { [K
255
265
  */
256
266
  interface AnyDependencySource<M extends Mode = Mode> {
257
267
  readonly [dependencySourceMarker]: true;
258
- readonly [dependencyId]: symbol;
268
+ readonly [dependencySourceId]: symbol;
259
269
  readonly mode: M;
260
270
  }
261
271
  /**
@@ -355,9 +365,6 @@ interface DeriveFromAsyncOptions<Deps extends readonly AnyDependencySource[], T>
355
365
  /**
356
366
  * A value parser that depends on another parser's value.
357
367
  *
358
- * A derived value parser cannot be nested (i.e., you cannot call
359
- * {@link DependencySource.derive} on a {@link DerivedValueParser}).
360
- *
361
368
  * @template M The execution mode of the parser (`"sync"` or `"async"`).
362
369
  * @template T The type of value this parser produces.
363
370
  * @template S The type of the source dependency value.
@@ -424,6 +431,8 @@ interface DerivedValueParser<M extends Mode = "sync", T = unknown, S = unknown>
424
431
  * A dependency source wraps an existing value parser and enables creating
425
432
  * derived parsers that depend on the parsed value. This is useful for
426
433
  * scenarios where one option's valid values depend on another option's value.
434
+ * A derived parser can itself become a source by wrapping it with
435
+ * `dependency()`, allowing dependency chains of any depth.
427
436
  *
428
437
  * @template M The execution mode of the value parser.
429
438
  * @template T The type of value the parser produces.
@@ -445,6 +454,14 @@ interface DerivedValueParser<M extends Mode = "sync", T = unknown, S = unknown>
445
454
  * factory: (dir) => gitBranch({ dir }),
446
455
  * defaultValue: () => process.cwd(),
447
456
  * });
457
+ *
458
+ * // A derived parser can provide the next dependency level.
459
+ * const branchSource = dependency(branchParser);
460
+ * const commitParser = branchSource.deriveSync({
461
+ * metavar: "COMMIT",
462
+ * factory: (branch) => gitCommit({ branch }),
463
+ * defaultValue: () => "main",
464
+ * });
448
465
  * ```
449
466
  * @since 0.10.0
450
467
  */
@@ -845,4 +862,4 @@ type DependencyError = {
845
862
  */
846
863
  declare function formatDependencyError(error: DependencyError): Message;
847
864
  //#endregion
848
- export { AnyDependencySource, CombineMode, CombinedDependencyMode, DeferredParseState, DependencyError, DependencyMode, DependencyRegistry, DependencySource, DependencySourceState, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, PendingDependencySourceState, ResolvedDependency, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultDependencyValueSnapshot, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, formatDependencyError, getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, pendingDependencySourceStateMarker, singleDefaultValue, snapshotDefaultDependencyValues, suggestWithDependency, transformsDependencyValue, transformsDependencyValueMarker, wrappedDependencySourceMarker };
865
+ export { AnyDependencySource, CombineMode, CombinedDependencyMode, DeferredParseState, DependencyError, DependencyMode, DependencyRegistry, DependencySource, DependencySourceState, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, PendingDependencySourceState, ResolvedDependency, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultDependencyValueSnapshot, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceId, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, formatDependencyError, getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, pendingDependencySourceStateMarker, singleDefaultValue, snapshotDefaultDependencyValues, suggestWithDependency, transformsDependencyValue, transformsDependencyValueMarker, wrappedDependencySourceMarker };
@@ -9,6 +9,16 @@ import { message } from "../message.js";
9
9
  */
10
10
  const dependencySourceMarker = Symbol.for("@optique/core/dependency/dependencySourceMarker");
11
11
  /**
12
+ * A unique symbol used to store a dependency source's own identity.
13
+ *
14
+ * This is distinct from {@link dependencyId}, which stores an upstream
15
+ * reference on a derived parser. A parser wrapped with `dependency()` after
16
+ * derivation carries both values.
17
+ * @internal
18
+ * @since 1.3.0
19
+ */
20
+ const dependencySourceId = Symbol.for("@optique/core/dependency/dependencySourceId");
21
+ /**
12
22
  * A unique symbol used to identify derived value parsers at compile time.
13
23
  * This marker is used to distinguish {@link DerivedValueParser} from regular
14
24
  * {@link ValueParser} instances.
@@ -66,6 +76,8 @@ const suggestWithDependency = Symbol.for("@optique/core/dependency/suggestWithDe
66
76
  * A dependency source wraps an existing value parser and enables creating
67
77
  * derived parsers that depend on the parsed value. This is useful for
68
78
  * scenarios where one option's valid values depend on another option's value.
79
+ * A derived parser can itself become a source by wrapping it with
80
+ * `dependency()`, allowing dependency chains of any depth.
69
81
  *
70
82
  * @template M The execution mode of the value parser.
71
83
  * @template T The type of value the parser produces.
@@ -87,15 +99,23 @@ const suggestWithDependency = Symbol.for("@optique/core/dependency/suggestWithDe
87
99
  * factory: (dir) => gitBranch({ dir }),
88
100
  * defaultValue: () => process.cwd(),
89
101
  * });
102
+ *
103
+ * // A derived parser can provide the next dependency level.
104
+ * const branchSource = dependency(branchParser);
105
+ * const commitParser = branchSource.deriveSync({
106
+ * metavar: "COMMIT",
107
+ * factory: (branch) => gitCommit({ branch }),
108
+ * defaultValue: () => "main",
109
+ * });
90
110
  * ```
91
111
  * @since 0.10.0
92
112
  */
93
113
  function dependency(parser) {
94
114
  const id = Symbol();
95
- const result = {
96
- ...parser,
115
+ const result = Object.create(Object.getPrototypeOf(parser), Object.getOwnPropertyDescriptors(parser));
116
+ Object.defineProperties(result, Object.getOwnPropertyDescriptors({
97
117
  [dependencySourceMarker]: true,
98
- [dependencyId]: id,
118
+ [dependencySourceId]: id,
99
119
  derive(options) {
100
120
  if (options.mode !== "sync" && options.mode !== "async") throw new TypeError("derive() requires an explicit mode field (\"sync\" or \"async\").");
101
121
  return createDerivedValueParser(id, parser, options, options.mode);
@@ -107,7 +127,7 @@ function dependency(parser) {
107
127
  deriveAsync(options) {
108
128
  return createAsyncDerivedParserFromAsyncFactory(id, options);
109
129
  }
110
- };
130
+ }));
111
131
  return result;
112
132
  }
113
133
  /**
@@ -166,7 +186,7 @@ function isDerivedValueParser(parser) {
166
186
  function deriveFrom(options) {
167
187
  if (options.mode !== "sync" && options.mode !== "async") throw new TypeError("deriveFrom() requires an explicit mode field (\"sync\" or \"async\").");
168
188
  const depsAsync = options.dependencies.some((dep) => dep.mode === "async");
169
- const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencyId] : Symbol();
189
+ const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencySourceId] : Symbol();
170
190
  const factoryReturnsAsync = options.mode === "async";
171
191
  const isAsync = depsAsync || factoryReturnsAsync;
172
192
  if (isAsync) {
@@ -191,7 +211,7 @@ function deriveFrom(options) {
191
211
  */
192
212
  function deriveFromSync(options) {
193
213
  const depsAsync = options.dependencies.some((dep) => dep.mode === "async");
194
- const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencyId] : Symbol();
214
+ const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencySourceId] : Symbol();
195
215
  if (depsAsync) return createAsyncDerivedFromParserFromSyncFactory(sourceId, options);
196
216
  return createSyncDerivedFromParser(sourceId, options);
197
217
  }
@@ -210,7 +230,7 @@ function deriveFromSync(options) {
210
230
  * @since 0.10.0
211
231
  */
212
232
  function deriveFromAsync(options) {
213
- const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencyId] : Symbol();
233
+ const sourceId = options.dependencies.length > 0 ? options.dependencies[0][dependencySourceId] : Symbol();
214
234
  return createAsyncDerivedFromParserFromAsyncFactory(sourceId, options);
215
235
  }
216
236
  function isAsyncModeParser(parser) {
@@ -282,7 +302,7 @@ async function parseDerivedResultWithSnapshotAsync(parser, input, sourceValues)
282
302
  return attachDefaultDependencySnapshot(await parseDerivedResultAsync(parser, input), snapshot);
283
303
  }
284
304
  function createSyncDerivedFromParser(sourceId, options) {
285
- const alldependencyIds = options.dependencies.map((dep) => dep[dependencyId]);
305
+ const alldependencyIds = options.dependencies.map((dep) => dep[dependencySourceId]);
286
306
  return {
287
307
  mode: "sync",
288
308
  metavar: options.metavar,
@@ -387,7 +407,7 @@ function createSyncDerivedFromParser(sourceId, options) {
387
407
  * factory returns an async parser.
388
408
  */
389
409
  function createAsyncDerivedFromParserFromAsyncFactory(sourceId, options) {
390
- const alldependencyIds = options.dependencies.map((dep) => dep[dependencyId]);
410
+ const alldependencyIds = options.dependencies.map((dep) => dep[dependencySourceId]);
391
411
  return {
392
412
  mode: "async",
393
413
  metavar: options.metavar,
@@ -475,7 +495,7 @@ function createAsyncDerivedFromParserFromAsyncFactory(sourceId, options) {
475
495
  * sources are async but the factory returns a sync parser.
476
496
  */
477
497
  function createAsyncDerivedFromParserFromSyncFactory(sourceId, options) {
478
- const alldependencyIds = options.dependencies.map((dep) => dep[dependencyId]);
498
+ const alldependencyIds = options.dependencies.map((dep) => dep[dependencySourceId]);
479
499
  return {
480
500
  mode: "async",
481
501
  metavar: options.metavar,
@@ -1079,4 +1099,4 @@ function formatDependencyError(error) {
1079
1099
  }
1080
1100
 
1081
1101
  //#endregion
1082
- export { DependencyRegistry, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultDependencyValueSnapshot, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, formatDependencyError, getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, pendingDependencySourceStateMarker, singleDefaultValue, snapshotDefaultDependencyValues, suggestWithDependency, transformsDependencyValue, transformsDependencyValueMarker, wrappedDependencySourceMarker };
1102
+ export { DependencyRegistry, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultDependencyValueSnapshot, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceId, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, formatDependencyError, getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, pendingDependencySourceStateMarker, singleDefaultValue, snapshotDefaultDependencyValues, suggestWithDependency, transformsDependencyValue, transformsDependencyValueMarker, wrappedDependencySourceMarker };
@@ -36,7 +36,8 @@ function isTerminalValueState(state) {
36
36
  * execution trace.
37
37
  * @internal
38
38
  */
39
- function createOptionParseState(parseResult) {
39
+ function createOptionParseState(parseResult, rawInput) {
40
+ require_dependency_runtime.recordDerivedRawInput(parseResult, rawInput);
40
41
  return parseResult;
41
42
  }
42
43
  function buildTraceEntry(kind, rawInput, consumed, valueParser, parseResult, optionNames$1) {
@@ -88,6 +89,13 @@ function resolveDerivedCompletionSync(derivedMetadata, state, exec) {
88
89
  }, traceEntry.rawInput, exec.dependencyRuntime);
89
90
  return replayed ?? traceEntry.preliminaryResult ?? state;
90
91
  }
92
+ function includeDependencyFailureChain(error, dependencyMetadata, exec) {
93
+ const sourceId = dependencyMetadata?.source?.sourceId;
94
+ if (sourceId == null || exec?.dependencyRuntime == null) return error;
95
+ const chain = exec.dependencyRuntime.getSourceFailureChain(sourceId);
96
+ if (chain == null || chain.length < 2) return error;
97
+ return require_message.message`${error} Dependency chain: ${chain.join(" -> ")}.`;
98
+ }
91
99
  async function resolveDerivedCompletionAsync(derivedMetadata, state, exec) {
92
100
  if (derivedMetadata?.derived == null || exec?.dependencyRuntime == null) return state;
93
101
  const traceEntry = exec.trace?.get(exec.path);
@@ -499,7 +507,7 @@ function option(...args) {
499
507
  success: true,
500
508
  next: {
501
509
  ...next,
502
- state: createOptionParseState(parseResult),
510
+ state: createOptionParseState(parseResult, rawInput),
503
511
  buffer: context.buffer.slice(2)
504
512
  },
505
513
  consumed: context.buffer.slice(0, 2)
@@ -511,7 +519,7 @@ function option(...args) {
511
519
  success: true,
512
520
  next: {
513
521
  ...next,
514
- state: createOptionParseState(parseResult),
522
+ state: createOptionParseState(parseResult, rawInput),
515
523
  buffer: context.buffer.slice(2)
516
524
  },
517
525
  consumed: context.buffer.slice(0, 2)
@@ -542,7 +550,7 @@ function option(...args) {
542
550
  success: true,
543
551
  next: {
544
552
  ...next,
545
- state: createOptionParseState(parseResult),
553
+ state: createOptionParseState(parseResult, rawInput),
546
554
  buffer: context.buffer.slice(1)
547
555
  },
548
556
  consumed: context.buffer.slice(0, 1)
@@ -554,7 +562,7 @@ function option(...args) {
554
562
  success: true,
555
563
  next: {
556
564
  ...next,
557
- state: createOptionParseState(parseResult),
565
+ state: createOptionParseState(parseResult, rawInput),
558
566
  buffer: context.buffer.slice(1)
559
567
  },
560
568
  consumed: context.buffer.slice(0, 1)
@@ -616,7 +624,7 @@ function option(...args) {
616
624
  const resolvedState = valueParser != null && dependencyMetadata?.derived != null ? resolveDerivedCompletionSync(dependencyMetadata, state, exec) : state;
617
625
  return resolvedState.success ? resolvedState : {
618
626
  success: false,
619
- error: formatInvalidValueError(resolvedState.error)
627
+ error: formatInvalidValueError(includeDependencyFailureChain(resolvedState.error, dependencyMetadata, exec))
620
628
  };
621
629
  };
622
630
  const completeAsync = async () => {
@@ -625,7 +633,7 @@ function option(...args) {
625
633
  const resolved = await resolveDerivedCompletionAsync(dependencyMetadata, state, exec);
626
634
  return resolved.success ? resolved : {
627
635
  success: false,
628
- error: formatInvalidValueError(resolved.error)
636
+ error: formatInvalidValueError(includeDependencyFailureChain(resolved.error, dependencyMetadata, exec))
629
637
  };
630
638
  };
631
639
  return require_mode_dispatch.dispatchByMode(mode, completeSync, completeAsync);
@@ -1242,7 +1250,7 @@ function argument(valueParser, options = {}) {
1242
1250
  next: {
1243
1251
  ...next,
1244
1252
  buffer: context.buffer.slice(i + 1),
1245
- state: createOptionParseState(parseResult),
1253
+ state: createOptionParseState(parseResult, rawInput),
1246
1254
  optionsTerminated
1247
1255
  },
1248
1256
  consumed: context.buffer.slice(0, i + 1)
@@ -1255,7 +1263,7 @@ function argument(valueParser, options = {}) {
1255
1263
  next: {
1256
1264
  ...next,
1257
1265
  buffer: context.buffer.slice(i + 1),
1258
- state: createOptionParseState(parseResult),
1266
+ state: createOptionParseState(parseResult, rawInput),
1259
1267
  optionsTerminated
1260
1268
  },
1261
1269
  consumed: context.buffer.slice(0, i + 1)
@@ -1272,7 +1280,7 @@ function argument(valueParser, options = {}) {
1272
1280
  const resolvedState = dependencyMetadata?.derived != null ? resolveDerivedCompletionSync(dependencyMetadata, state, exec) : state;
1273
1281
  return resolvedState.success ? resolvedState : {
1274
1282
  success: false,
1275
- error: formatInvalidValueError(resolvedState.error)
1283
+ error: formatInvalidValueError(includeDependencyFailureChain(resolvedState.error, dependencyMetadata, exec))
1276
1284
  };
1277
1285
  };
1278
1286
  const completeAsync = async () => {
@@ -1281,7 +1289,7 @@ function argument(valueParser, options = {}) {
1281
1289
  const resolved = await resolveDerivedCompletionAsync(dependencyMetadata, state, exec);
1282
1290
  return resolved.success ? resolved : {
1283
1291
  success: false,
1284
- error: formatInvalidValueError(resolved.error)
1292
+ error: formatInvalidValueError(includeDependencyFailureChain(resolved.error, dependencyMetadata, exec))
1285
1293
  };
1286
1294
  };
1287
1295
  return require_mode_dispatch.dispatchByMode(valueParser.mode, completeSync, completeAsync);
@@ -4,7 +4,7 @@ import { validateCommandNames, validateOptionNames } from "./validate.js";
4
4
  import { extractOptionNames, isDocHidden, isSuggestionHidden } from "./usage.js";
5
5
  import { dispatchByMode, dispatchIterableByMode, wrapForMode } from "./internal/mode-dispatch.js";
6
6
  import { getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDerivedValueParser, suggestWithDependency } from "./internal/dependency.js";
7
- import { effectfulSchedulingNodesKey, replayDerivedParser, replayDerivedParserAsync, sourceCollectionExpansionKey, staticSourceScopeKey } from "./dependency-runtime.js";
7
+ import { effectfulSchedulingNodesKey, recordDerivedRawInput, replayDerivedParser, replayDerivedParserAsync, sourceCollectionExpansionKey, staticSourceScopeKey } from "./dependency-runtime.js";
8
8
  import { getWrappedChildParseState, getWrappedChildState, isAnnotationWrappedInitialState, normalizeInjectedAnnotationState } from "./annotation-state.js";
9
9
  import { hiddenCommandAliasesKey } from "./internal/command-alias.js";
10
10
  import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
@@ -36,7 +36,8 @@ function isTerminalValueState(state) {
36
36
  * execution trace.
37
37
  * @internal
38
38
  */
39
- function createOptionParseState(parseResult) {
39
+ function createOptionParseState(parseResult, rawInput) {
40
+ recordDerivedRawInput(parseResult, rawInput);
40
41
  return parseResult;
41
42
  }
42
43
  function buildTraceEntry(kind, rawInput, consumed, valueParser, parseResult, optionNames$1) {
@@ -88,6 +89,13 @@ function resolveDerivedCompletionSync(derivedMetadata, state, exec) {
88
89
  }, traceEntry.rawInput, exec.dependencyRuntime);
89
90
  return replayed ?? traceEntry.preliminaryResult ?? state;
90
91
  }
92
+ function includeDependencyFailureChain(error, dependencyMetadata, exec) {
93
+ const sourceId = dependencyMetadata?.source?.sourceId;
94
+ if (sourceId == null || exec?.dependencyRuntime == null) return error;
95
+ const chain = exec.dependencyRuntime.getSourceFailureChain(sourceId);
96
+ if (chain == null || chain.length < 2) return error;
97
+ return message`${error} Dependency chain: ${chain.join(" -> ")}.`;
98
+ }
91
99
  async function resolveDerivedCompletionAsync(derivedMetadata, state, exec) {
92
100
  if (derivedMetadata?.derived == null || exec?.dependencyRuntime == null) return state;
93
101
  const traceEntry = exec.trace?.get(exec.path);
@@ -499,7 +507,7 @@ function option(...args) {
499
507
  success: true,
500
508
  next: {
501
509
  ...next,
502
- state: createOptionParseState(parseResult),
510
+ state: createOptionParseState(parseResult, rawInput),
503
511
  buffer: context.buffer.slice(2)
504
512
  },
505
513
  consumed: context.buffer.slice(0, 2)
@@ -511,7 +519,7 @@ function option(...args) {
511
519
  success: true,
512
520
  next: {
513
521
  ...next,
514
- state: createOptionParseState(parseResult),
522
+ state: createOptionParseState(parseResult, rawInput),
515
523
  buffer: context.buffer.slice(2)
516
524
  },
517
525
  consumed: context.buffer.slice(0, 2)
@@ -542,7 +550,7 @@ function option(...args) {
542
550
  success: true,
543
551
  next: {
544
552
  ...next,
545
- state: createOptionParseState(parseResult),
553
+ state: createOptionParseState(parseResult, rawInput),
546
554
  buffer: context.buffer.slice(1)
547
555
  },
548
556
  consumed: context.buffer.slice(0, 1)
@@ -554,7 +562,7 @@ function option(...args) {
554
562
  success: true,
555
563
  next: {
556
564
  ...next,
557
- state: createOptionParseState(parseResult),
565
+ state: createOptionParseState(parseResult, rawInput),
558
566
  buffer: context.buffer.slice(1)
559
567
  },
560
568
  consumed: context.buffer.slice(0, 1)
@@ -616,7 +624,7 @@ function option(...args) {
616
624
  const resolvedState = valueParser != null && dependencyMetadata?.derived != null ? resolveDerivedCompletionSync(dependencyMetadata, state, exec) : state;
617
625
  return resolvedState.success ? resolvedState : {
618
626
  success: false,
619
- error: formatInvalidValueError(resolvedState.error)
627
+ error: formatInvalidValueError(includeDependencyFailureChain(resolvedState.error, dependencyMetadata, exec))
620
628
  };
621
629
  };
622
630
  const completeAsync = async () => {
@@ -625,7 +633,7 @@ function option(...args) {
625
633
  const resolved = await resolveDerivedCompletionAsync(dependencyMetadata, state, exec);
626
634
  return resolved.success ? resolved : {
627
635
  success: false,
628
- error: formatInvalidValueError(resolved.error)
636
+ error: formatInvalidValueError(includeDependencyFailureChain(resolved.error, dependencyMetadata, exec))
629
637
  };
630
638
  };
631
639
  return dispatchByMode(mode, completeSync, completeAsync);
@@ -1242,7 +1250,7 @@ function argument(valueParser, options = {}) {
1242
1250
  next: {
1243
1251
  ...next,
1244
1252
  buffer: context.buffer.slice(i + 1),
1245
- state: createOptionParseState(parseResult),
1253
+ state: createOptionParseState(parseResult, rawInput),
1246
1254
  optionsTerminated
1247
1255
  },
1248
1256
  consumed: context.buffer.slice(0, i + 1)
@@ -1255,7 +1263,7 @@ function argument(valueParser, options = {}) {
1255
1263
  next: {
1256
1264
  ...next,
1257
1265
  buffer: context.buffer.slice(i + 1),
1258
- state: createOptionParseState(parseResult),
1266
+ state: createOptionParseState(parseResult, rawInput),
1259
1267
  optionsTerminated
1260
1268
  },
1261
1269
  consumed: context.buffer.slice(0, i + 1)
@@ -1272,7 +1280,7 @@ function argument(valueParser, options = {}) {
1272
1280
  const resolvedState = dependencyMetadata?.derived != null ? resolveDerivedCompletionSync(dependencyMetadata, state, exec) : state;
1273
1281
  return resolvedState.success ? resolvedState : {
1274
1282
  success: false,
1275
- error: formatInvalidValueError(resolvedState.error)
1283
+ error: formatInvalidValueError(includeDependencyFailureChain(resolvedState.error, dependencyMetadata, exec))
1276
1284
  };
1277
1285
  };
1278
1286
  const completeAsync = async () => {
@@ -1281,7 +1289,7 @@ function argument(valueParser, options = {}) {
1281
1289
  const resolved = await resolveDerivedCompletionAsync(dependencyMetadata, state, exec);
1282
1290
  return resolved.success ? resolved : {
1283
1291
  success: false,
1284
- error: formatInvalidValueError(resolved.error)
1292
+ error: formatInvalidValueError(includeDependencyFailureChain(resolved.error, dependencyMetadata, exec))
1285
1293
  };
1286
1294
  };
1287
1295
  return dispatchByMode(valueParser.mode, completeSync, completeAsync);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.3.0-dev.2398",
3
+ "version": "1.3.0-dev.2399",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",
@@ -221,7 +221,7 @@
221
221
  },
222
222
  "sideEffects": false,
223
223
  "devDependencies": {
224
- "@optique/env": "1.3.0-dev.2398+ee974c3d",
224
+ "@optique/env": "1.3.0-dev.2399+431a4b65",
225
225
  "@types/node": "^24.0.0",
226
226
  "fast-check": "^4.7.0",
227
227
  "tsdown": "^0.13.0",
@@ -52,6 +52,10 @@ Core rules
52
52
  - Async value parsers make the containing parser async. If you use packages
53
53
  such as *@optique/git*, remember to `await run(...)`, `await parse(...)`, or
54
54
  `await runParser(...)` as appropriate.
55
+ - Use `dependency()` when one value parser controls another's valid values.
56
+ For a multi-level chain, wrap the middle derivation too:
57
+ `dependency(source.deriveSync(...))`. Optique resolves such chains by
58
+ dependency order, independently of object/tuple field order.
55
59
  - Build subcommands with `command()` combined by `or()`. Put a literal field
56
60
  such as `command: constant("serve")` in each branch when you want a
57
61
  discriminated union.
@@ -228,6 +232,9 @@ Common mistakes checklist
228
232
  `message` values.
229
233
  - Do not forget to register source contexts when using `bindEnv()`,
230
234
  `bindConfig()`, or `bindDerivedDefault()`.
235
+ - Do not flatten a multi-level dependency graph into duplicated one-level
236
+ factories. Wrap each derived value that becomes a later source with
237
+ `dependency()` and derive the next parser from it.
231
238
  - Do not probe runtime capabilities eagerly before constructing a prompt
232
239
  parser. Put synchronous or asynchronous checks in the prompt config's
233
240
  `when` field and provide a typed `otherwise` value. The check then runs