@optique/core 1.2.0-dev.2230 → 1.2.0-dev.2234

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.
@@ -915,7 +915,37 @@ function makeFallbackDeferredValue(fallback, memoize) {
915
915
  }
916
916
  function deferredValue(parser, fallback, options) {
917
917
  const memoize = options?.memoize ?? false;
918
- return map(optional(map(parser, (value) => ({ value }))), (matched) => matched === void 0 ? makeFallbackDeferredValue(fallback, memoize) : makeSpecifiedDeferredValue(matched.value));
918
+ const base = optional(parser);
919
+ const complete = (state, exec) => require_mode_dispatch.mapModeValue(base.mode, base.complete(state, exec), (result) => {
920
+ if (!result.success) return result;
921
+ const value = result.value === void 0 ? makeFallbackDeferredValue(fallback, memoize) : makeSpecifiedDeferredValue(result.value);
922
+ return result.deferred ? {
923
+ success: true,
924
+ value,
925
+ deferred: true
926
+ } : {
927
+ success: true,
928
+ value
929
+ };
930
+ });
931
+ const descriptors = Object.getOwnPropertyDescriptors(base);
932
+ descriptors.complete = {
933
+ value: complete,
934
+ writable: true,
935
+ enumerable: true,
936
+ configurable: true
937
+ };
938
+ descriptors.$valueType = {
939
+ value: [],
940
+ writable: true,
941
+ enumerable: true,
942
+ configurable: true
943
+ };
944
+ delete descriptors.normalizeValue;
945
+ delete descriptors.validateValue;
946
+ delete descriptors[fluentParserMarker];
947
+ const deferredParser = Object.create(Object.getPrototypeOf(base), descriptors);
948
+ return fluent(deferredParser);
919
949
  }
920
950
  /**
921
951
  * Checks whether a value is a {@link DeferredValue} produced by
@@ -206,7 +206,7 @@ type DeferredValueSource = "specified" | "fallback";
206
206
  * @template C The handler-time context type passed to the fallback resolver.
207
207
  * @since 1.2.0
208
208
  */
209
- type DeferredValue<T, C = void> = ([C] extends [void] ? (() => T | Promise<T>) : ((ctx: C) => T | Promise<T>)) & {
209
+ type DeferredValue<T, C = void> = ([C] extends [void] ? (() => T | Promise<T>) : [undefined] extends [C] ? ((ctx?: C) => T | Promise<T>) : ((ctx: C) => T | Promise<T>)) & {
210
210
  /**
211
211
  * Which branch produced this value: `"specified"` when the wrapped parser
212
212
  * produced a value, `"fallback"` when the fallback resolver was selected.
@@ -232,11 +232,14 @@ interface DeferredValueOptions {
232
232
  *
233
233
  * The parsed field becomes a {@link DeferredValue}: a value-producing function.
234
234
  * When the wrapped parser produced a value, calling the function returns that
235
- * value and {@link DeferredValue.source} is `"specified"`. When the wrapped
236
- * parser did not produce a value, calling the function runs `fallback` and
237
- * `source` is `"fallback"`. The fallback runs at handler time, so its errors
238
- * are handler errors rather than parser errors. A value that is specified but
239
- * invalid still fails during parsing.
235
+ * value and {@link DeferredValue.source} is `"specified"`. A value resolved
236
+ * from a source such as `bindEnv()`/`bindConfig()` counts as produced. When
237
+ * the wrapped parser did not produce a value, calling the function runs
238
+ * `fallback` and `source` is `"fallback"`. Because a missing value is reported
239
+ * as `undefined`, a wrapped parser that yields `undefined` is treated as having
240
+ * produced no value and selects the fallback. The fallback runs at handler
241
+ * time, so its errors are handler errors rather than parser errors. A value
242
+ * that is specified but invalid still fails during parsing.
240
243
  *
241
244
  * Like {@link optional}, the wrapped parser keeps its place in usage and help;
242
245
  * only the result type changes. The fallback context type `C` is inferred from
@@ -416,6 +419,7 @@ interface ParserModifiers<M extends Mode = "sync", TValue = unknown, TState = un
416
419
  * @param fallback A resolver run at handler time when no value was specified.
417
420
  * @param options Optional {@link DeferredValueOptions}.
418
421
  * @returns A parser whose value is a {@link DeferredValue}.
422
+ * @since 1.2.0
419
423
  */
420
424
  deferredValue(fallback: () => TValue | Promise<TValue>, options?: DeferredValueOptions): FluentParser<M, DeferredValue<TValue>, [TState] | undefined>;
421
425
  deferredValue<C>(fallback: (ctx: C) => TValue | Promise<TValue>, options?: DeferredValueOptions): FluentParser<M, DeferredValue<TValue, C>, [TState] | undefined>;
@@ -206,7 +206,7 @@ type DeferredValueSource = "specified" | "fallback";
206
206
  * @template C The handler-time context type passed to the fallback resolver.
207
207
  * @since 1.2.0
208
208
  */
209
- type DeferredValue<T, C = void> = ([C] extends [void] ? (() => T | Promise<T>) : ((ctx: C) => T | Promise<T>)) & {
209
+ type DeferredValue<T, C = void> = ([C] extends [void] ? (() => T | Promise<T>) : [undefined] extends [C] ? ((ctx?: C) => T | Promise<T>) : ((ctx: C) => T | Promise<T>)) & {
210
210
  /**
211
211
  * Which branch produced this value: `"specified"` when the wrapped parser
212
212
  * produced a value, `"fallback"` when the fallback resolver was selected.
@@ -232,11 +232,14 @@ interface DeferredValueOptions {
232
232
  *
233
233
  * The parsed field becomes a {@link DeferredValue}: a value-producing function.
234
234
  * When the wrapped parser produced a value, calling the function returns that
235
- * value and {@link DeferredValue.source} is `"specified"`. When the wrapped
236
- * parser did not produce a value, calling the function runs `fallback` and
237
- * `source` is `"fallback"`. The fallback runs at handler time, so its errors
238
- * are handler errors rather than parser errors. A value that is specified but
239
- * invalid still fails during parsing.
235
+ * value and {@link DeferredValue.source} is `"specified"`. A value resolved
236
+ * from a source such as `bindEnv()`/`bindConfig()` counts as produced. When
237
+ * the wrapped parser did not produce a value, calling the function runs
238
+ * `fallback` and `source` is `"fallback"`. Because a missing value is reported
239
+ * as `undefined`, a wrapped parser that yields `undefined` is treated as having
240
+ * produced no value and selects the fallback. The fallback runs at handler
241
+ * time, so its errors are handler errors rather than parser errors. A value
242
+ * that is specified but invalid still fails during parsing.
240
243
  *
241
244
  * Like {@link optional}, the wrapped parser keeps its place in usage and help;
242
245
  * only the result type changes. The fallback context type `C` is inferred from
@@ -416,6 +419,7 @@ interface ParserModifiers<M extends Mode = "sync", TValue = unknown, TState = un
416
419
  * @param fallback A resolver run at handler time when no value was specified.
417
420
  * @param options Optional {@link DeferredValueOptions}.
418
421
  * @returns A parser whose value is a {@link DeferredValue}.
422
+ * @since 1.2.0
419
423
  */
420
424
  deferredValue(fallback: () => TValue | Promise<TValue>, options?: DeferredValueOptions): FluentParser<M, DeferredValue<TValue>, [TState] | undefined>;
421
425
  deferredValue<C>(fallback: (ctx: C) => TValue | Promise<TValue>, options?: DeferredValueOptions): FluentParser<M, DeferredValue<TValue, C>, [TState] | undefined>;
package/dist/modifiers.js CHANGED
@@ -915,7 +915,37 @@ function makeFallbackDeferredValue(fallback, memoize) {
915
915
  }
916
916
  function deferredValue(parser, fallback, options) {
917
917
  const memoize = options?.memoize ?? false;
918
- return map(optional(map(parser, (value) => ({ value }))), (matched) => matched === void 0 ? makeFallbackDeferredValue(fallback, memoize) : makeSpecifiedDeferredValue(matched.value));
918
+ const base = optional(parser);
919
+ const complete = (state, exec) => mapModeValue(base.mode, base.complete(state, exec), (result) => {
920
+ if (!result.success) return result;
921
+ const value = result.value === void 0 ? makeFallbackDeferredValue(fallback, memoize) : makeSpecifiedDeferredValue(result.value);
922
+ return result.deferred ? {
923
+ success: true,
924
+ value,
925
+ deferred: true
926
+ } : {
927
+ success: true,
928
+ value
929
+ };
930
+ });
931
+ const descriptors = Object.getOwnPropertyDescriptors(base);
932
+ descriptors.complete = {
933
+ value: complete,
934
+ writable: true,
935
+ enumerable: true,
936
+ configurable: true
937
+ };
938
+ descriptors.$valueType = {
939
+ value: [],
940
+ writable: true,
941
+ enumerable: true,
942
+ configurable: true
943
+ };
944
+ delete descriptors.normalizeValue;
945
+ delete descriptors.validateValue;
946
+ delete descriptors[fluentParserMarker];
947
+ const deferredParser = Object.create(Object.getPrototypeOf(base), descriptors);
948
+ return fluent(deferredParser);
919
949
  }
920
950
  /**
921
951
  * Checks whether a value is a {@link DeferredValue} produced by
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.2.0-dev.2230",
3
+ "version": "1.2.0-dev.2234",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",
@@ -208,7 +208,7 @@
208
208
  "fast-check": "^4.7.0",
209
209
  "tsdown": "^0.13.0",
210
210
  "typescript": "^5.8.3",
211
- "@optique/env": "1.2.0-dev.2230+7ac5924a"
211
+ "@optique/env": "1.2.0-dev.2234+763fcd3e"
212
212
  },
213
213
  "scripts": {
214
214
  "build": "tsdown",