@optique/core 1.2.0-dev.2302 → 1.2.0-dev.2310

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.
@@ -62,11 +62,13 @@ function mapMaybePromiseByMode(mode, value, mapFn) {
62
62
  * @internal
63
63
  */
64
64
  function wrapIterableForMode(mode, value) {
65
+ const canCheckAsyncIterator = value != null && (typeof value === "object" || typeof value === "function");
66
+ const isAsyncIterable = canCheckAsyncIterator && Symbol.asyncIterator in value;
65
67
  return dispatchIterableByMode(mode, () => {
66
- if (Symbol.asyncIterator in value) throw new TypeError("Synchronous mode cannot wrap AsyncIterable value.");
68
+ if (isAsyncIterable) throw new TypeError("Synchronous mode cannot wrap AsyncIterable value.");
67
69
  return value;
68
70
  }, () => {
69
- if (Symbol.asyncIterator in value) return value;
71
+ if (isAsyncIterable) return value;
70
72
  return async function* () {
71
73
  yield* value;
72
74
  }();
@@ -61,11 +61,13 @@ function mapMaybePromiseByMode(mode, value, mapFn) {
61
61
  * @internal
62
62
  */
63
63
  function wrapIterableForMode(mode, value) {
64
+ const canCheckAsyncIterator = value != null && (typeof value === "object" || typeof value === "function");
65
+ const isAsyncIterable = canCheckAsyncIterator && Symbol.asyncIterator in value;
64
66
  return dispatchIterableByMode(mode, () => {
65
- if (Symbol.asyncIterator in value) throw new TypeError("Synchronous mode cannot wrap AsyncIterable value.");
67
+ if (isAsyncIterable) throw new TypeError("Synchronous mode cannot wrap AsyncIterable value.");
66
68
  return value;
67
69
  }, () => {
68
- if (Symbol.asyncIterator in value) return value;
70
+ if (isAsyncIterable) return value;
69
71
  return async function* () {
70
72
  yield* value;
71
73
  }();
@@ -5,6 +5,12 @@ const require_suggestion = require('./suggestion.cjs');
5
5
  const require_nonempty = require('./nonempty.cjs');
6
6
 
7
7
  //#region src/valueparser.ts
8
+ function transformMappingFailure() {
9
+ return {
10
+ success: false,
11
+ error: require_message.message`Failed to transform value.`
12
+ };
13
+ }
8
14
  function transformValueParserResult(result, mapping) {
9
15
  if (!result.success) return result;
10
16
  const preserveSnapshot = (mapped) => {
@@ -18,16 +24,16 @@ function transformValueParserResult(result, mapping) {
18
24
  deferred: true
19
25
  });
20
26
  } catch {
27
+ return preserveSnapshot(transformMappingFailure());
28
+ }
29
+ try {
21
30
  return preserveSnapshot({
22
31
  success: true,
23
- value: void 0,
24
- deferred: true
32
+ value: mapping.map(result.value)
25
33
  });
34
+ } catch {
35
+ return preserveSnapshot(transformMappingFailure());
26
36
  }
27
- return preserveSnapshot({
28
- success: true,
29
- value: mapping.map(result.value)
30
- });
31
37
  }
32
38
  /**
33
39
  * A predicate function that checks if an object is a {@link ValueParser}.
@@ -217,9 +223,9 @@ function choice(choices, options = {}) {
217
223
  };
218
224
  }
219
225
  function biject(mapping) {
220
- if (Array.isArray(mapping)) throw new TypeError("Expected biject mapping to be a non-array object.");
221
- const keys = [];
222
- for (const key in mapping) if (Object.prototype.hasOwnProperty.call(mapping, key)) keys.push(key);
226
+ if (mapping === null || typeof mapping !== "object") throw new TypeError("Expected object.");
227
+ if (Array.isArray(mapping)) throw new TypeError("Expected object, got array.");
228
+ const keys = Object.keys(mapping);
223
229
  if (keys.length < 1) throw new RangeError("Expected at least one biject entry.");
224
230
  const source = choice(keys);
225
231
  const forward = /* @__PURE__ */ new Map();
@@ -305,7 +311,7 @@ function transform(parser, mapping) {
305
311
  placeholder: void 0,
306
312
  ...transformedChoices == null ? {} : { choices: transformedChoices },
307
313
  parse(input) {
308
- return require_mode_dispatch.mapModeValue(parser.mode, parser.parse(input), (result) => transformValueParserResult(result, mapping));
314
+ return require_mode_dispatch.mapMaybePromiseByMode(parser.mode, parser.parse(input), (result) => transformValueParserResult(result, mapping));
309
315
  },
310
316
  format(value) {
311
317
  return parser.format(mapping.unmap(value));
@@ -314,11 +320,12 @@ function transform(parser, mapping) {
314
320
  return mapping.map(normalize(mapping.unmap(value)));
315
321
  } },
316
322
  ...suggest == null ? {} : { suggest(prefix) {
317
- return suggest(prefix);
323
+ return require_mode_dispatch.wrapIterableForMode(parser.mode, suggest(prefix));
318
324
  } }
319
325
  };
320
326
  Object.defineProperty(transformed, "placeholder", {
321
327
  get() {
328
+ if (parser.placeholder === void 0) return void 0;
322
329
  try {
323
330
  return mapping.map(parser.placeholder);
324
331
  } catch {
@@ -326,17 +333,27 @@ function transform(parser, mapping) {
326
333
  }
327
334
  },
328
335
  configurable: true,
329
- enumerable: false
336
+ enumerable: true
330
337
  });
331
338
  if (typeof parser.validate === "function") {
332
339
  const validate = parser.validate.bind(parser);
333
340
  Object.defineProperty(transformed, "validate", {
334
341
  value(value) {
335
- const result = validate(mapping.unmap(value));
336
- return result.success ? {
337
- success: true,
338
- value: mapping.map(result.value)
339
- } : result;
342
+ let result;
343
+ try {
344
+ result = validate(mapping.unmap(value));
345
+ } catch {
346
+ return transformMappingFailure();
347
+ }
348
+ if (!result.success) return result;
349
+ try {
350
+ return {
351
+ success: true,
352
+ value: mapping.map(result.value)
353
+ };
354
+ } catch {
355
+ return transformMappingFailure();
356
+ }
340
357
  },
341
358
  configurable: true,
342
359
  enumerable: true
@@ -345,11 +362,21 @@ function transform(parser, mapping) {
345
362
  const syncParser = parser;
346
363
  Object.defineProperty(transformed, "validate", {
347
364
  value(value) {
348
- const result = syncParser.parse(syncParser.format(mapping.unmap(value)));
349
- return result.success ? {
350
- success: true,
351
- value: mapping.map(result.value)
352
- } : result;
365
+ let result;
366
+ try {
367
+ result = syncParser.parse(syncParser.format(mapping.unmap(value)));
368
+ } catch {
369
+ return transformMappingFailure();
370
+ }
371
+ if (!result.success) return result;
372
+ try {
373
+ return {
374
+ success: true,
375
+ value: mapping.map(result.value)
376
+ };
377
+ } catch {
378
+ return transformMappingFailure();
379
+ }
353
380
  },
354
381
  configurable: true,
355
382
  enumerable: true
@@ -420,8 +420,8 @@ declare function choice<const T extends number>(choices: readonly T[], options?:
420
420
  * @param mapping A mapping whose own enumerable string keys are valid inputs.
421
421
  * @returns A value parser that accepts one of the mapping keys and returns the
422
422
  * corresponding value.
423
- * @throws {TypeError} If `mapping` is an array, or if any key is the empty
424
- * string.
423
+ * @throws {TypeError} If `mapping` is not an object, if it is an array, or if
424
+ * any key is the empty string.
425
425
  * @throws {RangeError} If the mapping has no own enumerable string keys, or if
426
426
  * two keys map to the same value according to `Map` key equality.
427
427
  * @since 1.2.0
@@ -420,8 +420,8 @@ declare function choice<const T extends number>(choices: readonly T[], options?:
420
420
  * @param mapping A mapping whose own enumerable string keys are valid inputs.
421
421
  * @returns A value parser that accepts one of the mapping keys and returns the
422
422
  * corresponding value.
423
- * @throws {TypeError} If `mapping` is an array, or if any key is the empty
424
- * string.
423
+ * @throws {TypeError} If `mapping` is not an object, if it is an array, or if
424
+ * any key is the empty string.
425
425
  * @throws {RangeError} If the mapping has no own enumerable string keys, or if
426
426
  * two keys map to the same value according to `Map` key equality.
427
427
  * @since 1.2.0
@@ -1,10 +1,16 @@
1
1
  import { cloneMessage, lineBreak, message, metavar, text, valueSet } from "./message.js";
2
- import { mapMaybePromiseByMode, mapModeValue, wrapIterableForMode } from "./internal/mode-dispatch.js";
2
+ import { mapMaybePromiseByMode, wrapIterableForMode } from "./internal/mode-dispatch.js";
3
3
  import { defaultValues, dependencyId, dependencyIds, derivedValueParserMarker, getSnapshottedDefaultDependencyValues, isDerivedValueParser, parseWithDependency, singleDefaultValue, snapshotDefaultDependencyValues, suggestWithDependency } from "./internal/dependency.js";
4
4
  import { appendValueHint, appendValueSuggestions, deduplicateSuggestions } from "./suggestion.js";
5
5
  import { ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
6
6
 
7
7
  //#region src/valueparser.ts
8
+ function transformMappingFailure() {
9
+ return {
10
+ success: false,
11
+ error: message`Failed to transform value.`
12
+ };
13
+ }
8
14
  function transformValueParserResult(result, mapping) {
9
15
  if (!result.success) return result;
10
16
  const preserveSnapshot = (mapped) => {
@@ -18,16 +24,16 @@ function transformValueParserResult(result, mapping) {
18
24
  deferred: true
19
25
  });
20
26
  } catch {
27
+ return preserveSnapshot(transformMappingFailure());
28
+ }
29
+ try {
21
30
  return preserveSnapshot({
22
31
  success: true,
23
- value: void 0,
24
- deferred: true
32
+ value: mapping.map(result.value)
25
33
  });
34
+ } catch {
35
+ return preserveSnapshot(transformMappingFailure());
26
36
  }
27
- return preserveSnapshot({
28
- success: true,
29
- value: mapping.map(result.value)
30
- });
31
37
  }
32
38
  /**
33
39
  * A predicate function that checks if an object is a {@link ValueParser}.
@@ -217,9 +223,9 @@ function choice(choices, options = {}) {
217
223
  };
218
224
  }
219
225
  function biject(mapping) {
220
- if (Array.isArray(mapping)) throw new TypeError("Expected biject mapping to be a non-array object.");
221
- const keys = [];
222
- for (const key in mapping) if (Object.prototype.hasOwnProperty.call(mapping, key)) keys.push(key);
226
+ if (mapping === null || typeof mapping !== "object") throw new TypeError("Expected object.");
227
+ if (Array.isArray(mapping)) throw new TypeError("Expected object, got array.");
228
+ const keys = Object.keys(mapping);
223
229
  if (keys.length < 1) throw new RangeError("Expected at least one biject entry.");
224
230
  const source = choice(keys);
225
231
  const forward = /* @__PURE__ */ new Map();
@@ -305,7 +311,7 @@ function transform(parser, mapping) {
305
311
  placeholder: void 0,
306
312
  ...transformedChoices == null ? {} : { choices: transformedChoices },
307
313
  parse(input) {
308
- return mapModeValue(parser.mode, parser.parse(input), (result) => transformValueParserResult(result, mapping));
314
+ return mapMaybePromiseByMode(parser.mode, parser.parse(input), (result) => transformValueParserResult(result, mapping));
309
315
  },
310
316
  format(value) {
311
317
  return parser.format(mapping.unmap(value));
@@ -314,11 +320,12 @@ function transform(parser, mapping) {
314
320
  return mapping.map(normalize(mapping.unmap(value)));
315
321
  } },
316
322
  ...suggest == null ? {} : { suggest(prefix) {
317
- return suggest(prefix);
323
+ return wrapIterableForMode(parser.mode, suggest(prefix));
318
324
  } }
319
325
  };
320
326
  Object.defineProperty(transformed, "placeholder", {
321
327
  get() {
328
+ if (parser.placeholder === void 0) return void 0;
322
329
  try {
323
330
  return mapping.map(parser.placeholder);
324
331
  } catch {
@@ -326,17 +333,27 @@ function transform(parser, mapping) {
326
333
  }
327
334
  },
328
335
  configurable: true,
329
- enumerable: false
336
+ enumerable: true
330
337
  });
331
338
  if (typeof parser.validate === "function") {
332
339
  const validate = parser.validate.bind(parser);
333
340
  Object.defineProperty(transformed, "validate", {
334
341
  value(value) {
335
- const result = validate(mapping.unmap(value));
336
- return result.success ? {
337
- success: true,
338
- value: mapping.map(result.value)
339
- } : result;
342
+ let result;
343
+ try {
344
+ result = validate(mapping.unmap(value));
345
+ } catch {
346
+ return transformMappingFailure();
347
+ }
348
+ if (!result.success) return result;
349
+ try {
350
+ return {
351
+ success: true,
352
+ value: mapping.map(result.value)
353
+ };
354
+ } catch {
355
+ return transformMappingFailure();
356
+ }
340
357
  },
341
358
  configurable: true,
342
359
  enumerable: true
@@ -345,11 +362,21 @@ function transform(parser, mapping) {
345
362
  const syncParser = parser;
346
363
  Object.defineProperty(transformed, "validate", {
347
364
  value(value) {
348
- const result = syncParser.parse(syncParser.format(mapping.unmap(value)));
349
- return result.success ? {
350
- success: true,
351
- value: mapping.map(result.value)
352
- } : result;
365
+ let result;
366
+ try {
367
+ result = syncParser.parse(syncParser.format(mapping.unmap(value)));
368
+ } catch {
369
+ return transformMappingFailure();
370
+ }
371
+ if (!result.success) return result;
372
+ try {
373
+ return {
374
+ success: true,
375
+ value: mapping.map(result.value)
376
+ };
377
+ } catch {
378
+ return transformMappingFailure();
379
+ }
353
380
  },
354
381
  configurable: true,
355
382
  enumerable: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.2.0-dev.2302",
3
+ "version": "1.2.0-dev.2310",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",
@@ -225,7 +225,7 @@
225
225
  "fast-check": "^4.7.0",
226
226
  "tsdown": "^0.13.0",
227
227
  "typescript": "^5.8.3",
228
- "@optique/env": "1.2.0-dev.2302+77665cb5"
228
+ "@optique/env": "1.2.0-dev.2310+1dd4b70d"
229
229
  },
230
230
  "scripts": {
231
231
  "build": "tsdown",