@optique/core 1.0.0-dev.1547 → 1.0.0-dev.1555

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/modifiers.js CHANGED
@@ -118,7 +118,7 @@ function optional(parser) {
118
118
  const wrappedDependencyMarker = innerHasWrappedDependency ? { [wrappedDependencySourceMarker]: parser[wrappedDependencySourceMarker] } : innerHasDirectDependency ? { [wrappedDependencySourceMarker]: syncParser.initialState } : {};
119
119
  const hasWrappedDependencySource = wrappedDependencySourceMarker in wrappedDependencyMarker;
120
120
  const wrappedPendingState = hasWrappedDependencySource ? wrappedDependencyMarker[wrappedDependencySourceMarker] : void 0;
121
- return {
121
+ const optionalParser = {
122
122
  $mode: parser.$mode,
123
123
  $valueType: [],
124
124
  $stateType: [],
@@ -175,6 +175,18 @@ function optional(parser) {
175
175
  return syncParser.getDocFragments(innerState, defaultValue);
176
176
  }
177
177
  };
178
+ if (typeof parser.normalizeValue === "function") {
179
+ const innerNormalize = parser.normalizeValue.bind(parser);
180
+ Object.defineProperty(optionalParser, "normalizeValue", {
181
+ value(v) {
182
+ if (v == null) return v;
183
+ return innerNormalize(v);
184
+ },
185
+ configurable: true,
186
+ enumerable: false
187
+ });
188
+ }
189
+ return optionalParser;
178
190
  }
179
191
  /**
180
192
  * Error type for structured error messages in {@link withDefault} default value callbacks.
@@ -257,12 +269,19 @@ function withDefault(parser, defaultValue, options) {
257
269
  return dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
258
270
  },
259
271
  complete(state) {
272
+ function evaluateDefault() {
273
+ const raw = typeof defaultValue === "function" ? defaultValue() : defaultValue;
274
+ if (typeof parser.normalizeValue === "function") try {
275
+ return parser.normalizeValue(raw);
276
+ } catch {}
277
+ return raw;
278
+ }
260
279
  if (!Array.isArray(state)) {
261
280
  if (transformsDependencyValue(parser)) {
262
281
  const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(void 0), () => parser.complete(void 0));
263
282
  const handleInnerResult = (res) => {
264
283
  if (isDependencySourceState(res)) try {
265
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
284
+ const value = evaluateDefault();
266
285
  return createDependencySourceState({
267
286
  success: true,
268
287
  value
@@ -274,7 +293,7 @@ function withDefault(parser, defaultValue, options) {
274
293
  };
275
294
  }
276
295
  try {
277
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
296
+ const value = evaluateDefault();
278
297
  return {
279
298
  success: true,
280
299
  value
@@ -289,7 +308,7 @@ function withDefault(parser, defaultValue, options) {
289
308
  return mapModeValue(parser.$mode, innerResult, handleInnerResult);
290
309
  }
291
310
  if (isWrappedDependencySource(parser)) try {
292
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
311
+ const value = evaluateDefault();
293
312
  const pendingState = parser[wrappedDependencySourceMarker];
294
313
  return createDependencySourceState({
295
314
  success: true,
@@ -306,7 +325,7 @@ function withDefault(parser, defaultValue, options) {
306
325
  return innerResult;
307
326
  }
308
327
  try {
309
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
328
+ const value = evaluateDefault();
310
329
  return {
311
330
  success: true,
312
331
  value
@@ -323,7 +342,7 @@ function withDefault(parser, defaultValue, options) {
323
342
  const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
324
343
  const handleInnerResult = (res) => {
325
344
  if (isDependencySourceState(res)) try {
326
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
345
+ const value = evaluateDefault();
327
346
  return createDependencySourceState({
328
347
  success: true,
329
348
  value
@@ -335,7 +354,7 @@ function withDefault(parser, defaultValue, options) {
335
354
  };
336
355
  }
337
356
  try {
338
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
357
+ const value = evaluateDefault();
339
358
  return {
340
359
  success: true,
341
360
  value
@@ -350,7 +369,7 @@ function withDefault(parser, defaultValue, options) {
350
369
  return mapModeValue(parser.$mode, innerResult, handleInnerResult);
351
370
  }
352
371
  try {
353
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
372
+ const value = evaluateDefault();
354
373
  return createDependencySourceState({
355
374
  success: true,
356
375
  value
@@ -373,7 +392,11 @@ function withDefault(parser, defaultValue, options) {
373
392
  kind: "available",
374
393
  state: state.state[0]
375
394
  };
376
- const fragments = syncParser.getDocFragments(innerState, getDocDefaultValue(upperDefaultValue));
395
+ let docDefault = getDocDefaultValue(upperDefaultValue);
396
+ if (docDefault != null && typeof parser.normalizeValue === "function") try {
397
+ docDefault = parser.normalizeValue(docDefault);
398
+ } catch {}
399
+ const fragments = syncParser.getDocFragments(innerState, docDefault);
377
400
  if (options?.message) {
378
401
  const modifiedFragments = fragments.fragments.map((fragment) => {
379
402
  if (fragment.type === "entry") return {
@@ -397,6 +420,20 @@ function withDefault(parser, defaultValue, options) {
397
420
  configurable: true,
398
421
  enumerable: false
399
422
  });
423
+ if (typeof parser.normalizeValue === "function") {
424
+ const innerNormalize = parser.normalizeValue.bind(parser);
425
+ Object.defineProperty(withDefaultParser, "normalizeValue", {
426
+ value(v) {
427
+ try {
428
+ return innerNormalize(v);
429
+ } catch {
430
+ return v;
431
+ }
432
+ },
433
+ configurable: true,
434
+ enumerable: false
435
+ });
436
+ }
400
437
  return withDefaultParser;
401
438
  }
402
439
  /**
@@ -510,6 +547,7 @@ function map(parser, transform) {
510
547
  return parser.getDocFragments(state, void 0);
511
548
  }
512
549
  };
550
+ delete mappedParser.normalizeValue;
513
551
  if ("placeholder" in parser) Object.defineProperty(mappedParser, "placeholder", {
514
552
  get() {
515
553
  try {
@@ -828,6 +866,27 @@ function multiple(parser, options = {}) {
828
866
  configurable: true,
829
867
  enumerable: false
830
868
  });
869
+ if (typeof parser.normalizeValue === "function") {
870
+ const innerNormalize = parser.normalizeValue.bind(parser);
871
+ Object.defineProperty(resultParser, "normalizeValue", {
872
+ value(values) {
873
+ if (!Array.isArray(values)) return values;
874
+ let changed = false;
875
+ const result = values.map((v) => {
876
+ try {
877
+ const n = innerNormalize(v);
878
+ if (n !== v) changed = true;
879
+ return n;
880
+ } catch {
881
+ return v;
882
+ }
883
+ });
884
+ return changed ? result : values;
885
+ },
886
+ configurable: true,
887
+ enumerable: false
888
+ });
889
+ }
831
890
  return resultParser;
832
891
  }
833
892
  /**
@@ -916,6 +975,11 @@ function nonEmpty(parser) {
916
975
  configurable: true,
917
976
  enumerable: false
918
977
  });
978
+ if (typeof parser.normalizeValue === "function") Object.defineProperty(nonEmptyParser, "normalizeValue", {
979
+ value: parser.normalizeValue.bind(parser),
980
+ configurable: true,
981
+ enumerable: false
982
+ });
919
983
  return nonEmptyParser;
920
984
  }
921
985
 
package/dist/parser.d.cts CHANGED
@@ -225,6 +225,26 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
225
225
  * @since 1.0.0
226
226
  */
227
227
  shouldDeferCompletion?(state: TState): boolean;
228
+ /**
229
+ * Normalizes a parsed value according to the underlying value parser's
230
+ * configuration. When present, {@link withDefault} calls this method
231
+ * on default values so that runtime defaults match the representation
232
+ * that the value parser's `parse()` would produce.
233
+ *
234
+ * Primitive parsers ({@link option}, {@link argument}) implement this
235
+ * by delegating to {@link ValueParser.normalize}. Combinator wrappers
236
+ * ({@link optional}, {@link withDefault}) forward it from inner parsers.
237
+ *
238
+ * Exclusive combinators ({@link or}, `longestMatch()`) and
239
+ * multi-source combinators (`merge()`) intentionally do *not*
240
+ * implement this method because the active branch or key ownership
241
+ * is unknown at default time.
242
+ *
243
+ * @param value The value to normalize.
244
+ * @returns The normalized value.
245
+ * @since 1.0.0
246
+ */
247
+ normalizeValue?(value: TValue): TValue;
228
248
  }
229
249
  /**
230
250
  * The context of the parser, which includes the input buffer and the state.
package/dist/parser.d.ts CHANGED
@@ -225,6 +225,26 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
225
225
  * @since 1.0.0
226
226
  */
227
227
  shouldDeferCompletion?(state: TState): boolean;
228
+ /**
229
+ * Normalizes a parsed value according to the underlying value parser's
230
+ * configuration. When present, {@link withDefault} calls this method
231
+ * on default values so that runtime defaults match the representation
232
+ * that the value parser's `parse()` would produce.
233
+ *
234
+ * Primitive parsers ({@link option}, {@link argument}) implement this
235
+ * by delegating to {@link ValueParser.normalize}. Combinator wrappers
236
+ * ({@link optional}, {@link withDefault}) forward it from inner parsers.
237
+ *
238
+ * Exclusive combinators ({@link or}, `longestMatch()`) and
239
+ * multi-source combinators (`merge()`) intentionally do *not*
240
+ * implement this method because the active branch or key ownership
241
+ * is unknown at default time.
242
+ *
243
+ * @param value The value to normalize.
244
+ * @returns The normalized value.
245
+ * @since 1.0.0
246
+ */
247
+ normalizeValue?(value: TValue): TValue;
228
248
  }
229
249
  /**
230
250
  * The context of the parser, which includes the input buffer and the state.
@@ -564,6 +564,20 @@ function option(...args) {
564
564
  return `option(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
565
565
  }
566
566
  };
567
+ if (valueParser != null && typeof valueParser.normalize === "function") {
568
+ const normalize = valueParser.normalize.bind(valueParser);
569
+ Object.defineProperty(result, "normalizeValue", {
570
+ value(v) {
571
+ try {
572
+ return normalize(v);
573
+ } catch {
574
+ return v;
575
+ }
576
+ },
577
+ configurable: true,
578
+ enumerable: false
579
+ });
580
+ }
567
581
  if (valueParser != null) Object.defineProperty(result, "placeholder", {
568
582
  get() {
569
583
  try {
@@ -918,6 +932,20 @@ function argument(valueParser, options = {}) {
918
932
  return `argument()`;
919
933
  }
920
934
  };
935
+ if (typeof valueParser.normalize === "function") {
936
+ const normalize = valueParser.normalize.bind(valueParser);
937
+ Object.defineProperty(result, "normalizeValue", {
938
+ value(v) {
939
+ try {
940
+ return normalize(v);
941
+ } catch {
942
+ return v;
943
+ }
944
+ },
945
+ configurable: true,
946
+ enumerable: false
947
+ });
948
+ }
921
949
  Object.defineProperty(result, "placeholder", {
922
950
  get() {
923
951
  try {
@@ -1136,6 +1164,11 @@ function command(name, parser, options = {}) {
1136
1164
  return `command(${JSON.stringify(name)})`;
1137
1165
  }
1138
1166
  };
1167
+ if (typeof parser.normalizeValue === "function") Object.defineProperty(result, "normalizeValue", {
1168
+ value: parser.normalizeValue.bind(parser),
1169
+ configurable: true,
1170
+ enumerable: false
1171
+ });
1139
1172
  return result;
1140
1173
  }
1141
1174
  /**
@@ -564,6 +564,20 @@ function option(...args) {
564
564
  return `option(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
565
565
  }
566
566
  };
567
+ if (valueParser != null && typeof valueParser.normalize === "function") {
568
+ const normalize = valueParser.normalize.bind(valueParser);
569
+ Object.defineProperty(result, "normalizeValue", {
570
+ value(v) {
571
+ try {
572
+ return normalize(v);
573
+ } catch {
574
+ return v;
575
+ }
576
+ },
577
+ configurable: true,
578
+ enumerable: false
579
+ });
580
+ }
567
581
  if (valueParser != null) Object.defineProperty(result, "placeholder", {
568
582
  get() {
569
583
  try {
@@ -918,6 +932,20 @@ function argument(valueParser, options = {}) {
918
932
  return `argument()`;
919
933
  }
920
934
  };
935
+ if (typeof valueParser.normalize === "function") {
936
+ const normalize = valueParser.normalize.bind(valueParser);
937
+ Object.defineProperty(result, "normalizeValue", {
938
+ value(v) {
939
+ try {
940
+ return normalize(v);
941
+ } catch {
942
+ return v;
943
+ }
944
+ },
945
+ configurable: true,
946
+ enumerable: false
947
+ });
948
+ }
921
949
  Object.defineProperty(result, "placeholder", {
922
950
  get() {
923
951
  try {
@@ -1136,6 +1164,11 @@ function command(name, parser, options = {}) {
1136
1164
  return `command(${JSON.stringify(name)})`;
1137
1165
  }
1138
1166
  };
1167
+ if (typeof parser.normalizeValue === "function") Object.defineProperty(result, "normalizeValue", {
1168
+ value: parser.normalizeValue.bind(parser),
1169
+ configurable: true,
1170
+ enumerable: false
1171
+ });
1139
1172
  return result;
1140
1173
  }
1141
1174
  /**
package/dist/program.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ const require_validate = require('./validate.cjs');
1
2
 
2
3
  //#region src/program.ts
3
4
  /**
@@ -11,6 +12,8 @@
11
12
  * @template T - The type of value produced by the parser.
12
13
  * @param program - The program definition with parser and metadata.
13
14
  * @returns The same program object with inferred types.
15
+ * @throws {TypeError} If `program.metadata.name` is not a string, is empty,
16
+ * is whitespace-only, or contains control characters.
14
17
  *
15
18
  * @example
16
19
  * ```typescript
@@ -37,6 +40,7 @@
37
40
  * @since 1.0.0
38
41
  */
39
42
  function defineProgram(program) {
43
+ require_validate.validateProgramName(program.metadata.name);
40
44
  return program;
41
45
  }
42
46
 
@@ -94,6 +94,8 @@ interface Program<M extends Mode, T> {
94
94
  * @template T - The type of value produced by the parser.
95
95
  * @param program - The program definition with parser and metadata.
96
96
  * @returns The same program object with inferred types.
97
+ * @throws {TypeError} If `program.metadata.name` is not a string, is empty,
98
+ * is whitespace-only, or contains control characters.
97
99
  *
98
100
  * @example
99
101
  * ```typescript
package/dist/program.d.ts CHANGED
@@ -94,6 +94,8 @@ interface Program<M extends Mode, T> {
94
94
  * @template T - The type of value produced by the parser.
95
95
  * @param program - The program definition with parser and metadata.
96
96
  * @returns The same program object with inferred types.
97
+ * @throws {TypeError} If `program.metadata.name` is not a string, is empty,
98
+ * is whitespace-only, or contains control characters.
97
99
  *
98
100
  * @example
99
101
  * ```typescript
package/dist/program.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { validateProgramName } from "./validate.js";
2
+
1
3
  //#region src/program.ts
2
4
  /**
3
5
  * Defines a CLI program with a parser and metadata.
@@ -10,6 +12,8 @@
10
12
  * @template T - The type of value produced by the parser.
11
13
  * @param program - The program definition with parser and metadata.
12
14
  * @returns The same program object with inferred types.
15
+ * @throws {TypeError} If `program.metadata.name` is not a string, is empty,
16
+ * is whitespace-only, or contains control characters.
13
17
  *
14
18
  * @example
15
19
  * ```typescript
@@ -36,6 +40,7 @@
36
40
  * @since 1.0.0
37
41
  */
38
42
  function defineProgram(program) {
43
+ validateProgramName(program.metadata.name);
39
44
  return program;
40
45
  }
41
46