@optique/core 1.0.0-dev.908 → 1.0.0

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.
Files changed (109) hide show
  1. package/dist/annotation-state.cjs +425 -0
  2. package/dist/annotation-state.d.cts +24 -0
  3. package/dist/annotation-state.d.ts +24 -0
  4. package/dist/annotation-state.js +414 -0
  5. package/dist/annotations.cjs +2 -248
  6. package/dist/annotations.d.cts +2 -137
  7. package/dist/annotations.d.ts +2 -137
  8. package/dist/annotations.js +2 -238
  9. package/dist/completion.cjs +611 -100
  10. package/dist/completion.d.cts +1 -1
  11. package/dist/completion.d.ts +1 -1
  12. package/dist/completion.js +611 -100
  13. package/dist/constructs.cjs +3338 -827
  14. package/dist/constructs.d.cts +48 -7
  15. package/dist/constructs.d.ts +48 -7
  16. package/dist/constructs.js +3338 -827
  17. package/dist/context.cjs +0 -23
  18. package/dist/context.d.cts +119 -53
  19. package/dist/context.d.ts +119 -53
  20. package/dist/context.js +0 -22
  21. package/dist/dependency-metadata.cjs +139 -0
  22. package/dist/dependency-metadata.d.cts +112 -0
  23. package/dist/dependency-metadata.d.ts +112 -0
  24. package/dist/dependency-metadata.js +138 -0
  25. package/dist/dependency-runtime.cjs +698 -0
  26. package/dist/dependency-runtime.d.cts +149 -0
  27. package/dist/dependency-runtime.d.ts +149 -0
  28. package/dist/dependency-runtime.js +687 -0
  29. package/dist/dependency.cjs +7 -928
  30. package/dist/dependency.d.cts +2 -794
  31. package/dist/dependency.d.ts +2 -794
  32. package/dist/dependency.js +2 -899
  33. package/dist/displaywidth.cjs +44 -0
  34. package/dist/displaywidth.js +43 -0
  35. package/dist/doc.cjs +285 -23
  36. package/dist/doc.d.cts +57 -2
  37. package/dist/doc.d.ts +57 -2
  38. package/dist/doc.js +283 -25
  39. package/dist/execution-context.cjs +56 -0
  40. package/dist/execution-context.js +53 -0
  41. package/dist/extension.cjs +87 -0
  42. package/dist/extension.d.cts +97 -0
  43. package/dist/extension.d.ts +97 -0
  44. package/dist/extension.js +76 -0
  45. package/dist/facade.cjs +718 -523
  46. package/dist/facade.d.cts +87 -18
  47. package/dist/facade.d.ts +87 -18
  48. package/dist/facade.js +718 -523
  49. package/dist/index.cjs +14 -29
  50. package/dist/index.d.cts +10 -10
  51. package/dist/index.d.ts +10 -10
  52. package/dist/index.js +7 -7
  53. package/dist/input-trace.cjs +56 -0
  54. package/dist/input-trace.d.cts +77 -0
  55. package/dist/input-trace.d.ts +77 -0
  56. package/dist/input-trace.js +55 -0
  57. package/dist/internal/annotations.cjs +316 -0
  58. package/dist/internal/annotations.d.cts +140 -0
  59. package/dist/internal/annotations.d.ts +140 -0
  60. package/dist/internal/annotations.js +306 -0
  61. package/dist/internal/dependency.cjs +984 -0
  62. package/dist/internal/dependency.d.cts +539 -0
  63. package/dist/internal/dependency.d.ts +539 -0
  64. package/dist/internal/dependency.js +964 -0
  65. package/dist/{mode-dispatch.cjs → internal/mode-dispatch.cjs} +1 -3
  66. package/dist/{mode-dispatch.d.cts → internal/mode-dispatch.d.cts} +3 -7
  67. package/dist/{mode-dispatch.d.ts → internal/mode-dispatch.d.ts} +3 -7
  68. package/dist/{mode-dispatch.js → internal/mode-dispatch.js} +1 -3
  69. package/dist/internal/parser.cjs +728 -0
  70. package/dist/internal/parser.d.cts +947 -0
  71. package/dist/internal/parser.d.ts +947 -0
  72. package/dist/internal/parser.js +711 -0
  73. package/dist/message.cjs +84 -26
  74. package/dist/message.d.cts +49 -9
  75. package/dist/message.d.ts +49 -9
  76. package/dist/message.js +84 -27
  77. package/dist/modifiers.cjs +1023 -240
  78. package/dist/modifiers.d.cts +42 -1
  79. package/dist/modifiers.d.ts +42 -1
  80. package/dist/modifiers.js +1023 -240
  81. package/dist/parser.cjs +11 -463
  82. package/dist/parser.d.cts +3 -537
  83. package/dist/parser.d.ts +3 -537
  84. package/dist/parser.js +2 -433
  85. package/dist/phase2-seed.cjs +59 -0
  86. package/dist/phase2-seed.js +56 -0
  87. package/dist/primitives.cjs +557 -208
  88. package/dist/primitives.d.cts +10 -14
  89. package/dist/primitives.d.ts +10 -14
  90. package/dist/primitives.js +557 -208
  91. package/dist/program.cjs +5 -1
  92. package/dist/program.d.cts +5 -3
  93. package/dist/program.d.ts +5 -3
  94. package/dist/program.js +6 -1
  95. package/dist/suggestion.cjs +22 -8
  96. package/dist/suggestion.js +22 -8
  97. package/dist/usage-internals.cjs +3 -2
  98. package/dist/usage-internals.js +4 -2
  99. package/dist/usage.cjs +195 -40
  100. package/dist/usage.d.cts +92 -11
  101. package/dist/usage.d.ts +92 -11
  102. package/dist/usage.js +194 -41
  103. package/dist/validate.cjs +170 -0
  104. package/dist/validate.js +164 -0
  105. package/dist/valueparser.cjs +1278 -191
  106. package/dist/valueparser.d.cts +330 -20
  107. package/dist/valueparser.d.ts +330 -20
  108. package/dist/valueparser.js +1277 -192
  109. package/package.json +9 -9
@@ -1,6 +1,6 @@
1
1
  import { NonEmptyString, ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
2
2
  import { Message } from "./message.js";
3
- import { Mode, ModeIterable, ModeValue, Suggestion } from "./parser.js";
3
+ import { Mode, ModeIterable, ModeValue, Suggestion } from "./internal/parser.js";
4
4
 
5
5
  //#region src/valueparser.d.ts
6
6
 
@@ -23,7 +23,7 @@ interface ValueParser<M extends Mode = "sync", T = unknown> {
23
23
  *
24
24
  * @since 0.9.0
25
25
  */
26
- readonly $mode: M;
26
+ readonly mode: M;
27
27
  /**
28
28
  * The metavariable name for this parser. Used in help messages
29
29
  * to indicate what kind of value this parser expects. Usually
@@ -49,6 +49,33 @@ interface ValueParser<M extends Mode = "sync", T = unknown> {
49
49
  * @returns A string representation of the value.
50
50
  */
51
51
  format(value: T): string;
52
+ /**
53
+ * Normalizes a value of type {@link T} according to this parser's
54
+ * configuration. This applies the same canonicalization that
55
+ * {@link parse} would apply (e.g., case conversion, separator
56
+ * normalization). Built-in implementations delegate to {@link parse}
57
+ * internally, so values that would fail validation are returned
58
+ * unchanged rather than being canonicalized.
59
+ *
60
+ * When present, combinators like `withDefault()` call this method on
61
+ * default values so that runtime defaults match the representation
62
+ * that {@link parse} would produce.
63
+ *
64
+ * Parsers that do not apply any normalization during parsing do not
65
+ * need to implement this method.
66
+ *
67
+ * **Limitation:** For dependency-derived value parsers (created via
68
+ * `deriveFrom()` or `dependency().derive()`), this method uses the
69
+ * default dependency value to build the inner parser, not the
70
+ * dependency value resolved during the current parse. This is the
71
+ * same trade-off that {@link format} makes. As a result, defaults
72
+ * may not be normalized according to a non-default dependency value.
73
+ *
74
+ * @param value The value to normalize.
75
+ * @returns The normalized value.
76
+ * @since 1.0.0
77
+ */
78
+ normalize?(value: T): T;
52
79
  /**
53
80
  * Provides completion suggestions for values of this type.
54
81
  * This is optional and used for shell completion functionality.
@@ -69,6 +96,21 @@ interface ValueParser<M extends Mode = "sync", T = unknown> {
69
96
  * @since 0.10.0
70
97
  */
71
98
  readonly choices?: readonly T[];
99
+ /**
100
+ * A type-appropriate default value used as a stand-in during deferred
101
+ * prompt resolution. When an interactive prompt is deferred during
102
+ * two-phase parsing, this value is used instead of an internal sentinel
103
+ * so that `map()` transforms and two-pass contexts always receive a valid
104
+ * value of type {@link T}.
105
+ *
106
+ * The placeholder does not need to be meaningful; it only needs to be
107
+ * a valid inhabitant of the result type that will not crash downstream
108
+ * transforms. For example, `string()` uses `""`, `integer()` uses `0`,
109
+ * and `choice(["a", "b", "c"])` uses `"a"`.
110
+ *
111
+ * @since 1.0.0
112
+ */
113
+ readonly placeholder: T;
72
114
  }
73
115
  /**
74
116
  * Result type returned by {@link ValueParser#parse}.
@@ -83,12 +125,48 @@ type ValueParserResult<T> = {
83
125
  readonly success: true;
84
126
  /** The successfully parsed value of type {@link T}. */
85
127
  readonly value: T;
128
+ /**
129
+ * When `true`, indicates that the value is a placeholder stand-in for
130
+ * a deferred interactive prompt, not a real user-provided value.
131
+ * Combinators propagate this flag so that the two-phase parsing
132
+ * facade can strip deferred values before passing them to phase-two
133
+ * contexts.
134
+ *
135
+ * @since 1.0.0
136
+ */
137
+ readonly deferred?: true;
138
+ /**
139
+ * A recursive map describing which property keys in {@link value} hold
140
+ * deferred placeholder values. Set by `object()`, `tuple()`, `merge()`,
141
+ * and other combinators. Intentionally not propagated by `map()` because
142
+ * opaque transforms invalidate the inner key set. Used by the two-phase
143
+ * facade to selectively replace only deferred fields with `undefined`
144
+ * while preserving non-deferred fields for phase-two context annotation
145
+ * collection.
146
+ *
147
+ * Each entry maps a property key to either `null` (the entire field is
148
+ * deferred) or another `DeferredMap` (the field is an object whose own
149
+ * sub-fields are partially deferred).
150
+ *
151
+ * @since 1.0.0
152
+ */
153
+ readonly deferredKeys?: DeferredMap;
86
154
  } | {
87
155
  /** Indicates that the parsing operation failed. */
88
156
  readonly success: false;
89
157
  /** The error message describing why the parsing failed. */
90
158
  readonly error: Message;
91
159
  };
160
+ /**
161
+ * A recursive map that tracks which fields in a parsed object hold deferred
162
+ * placeholder values. Each entry maps a property key to either `null`
163
+ * (the field is fully deferred and should be replaced with `undefined`)
164
+ * or another `DeferredMap` (the field is partially deferred — recurse into
165
+ * its sub-fields).
166
+ *
167
+ * @since 1.0.0
168
+ */
169
+ type DeferredMap = ReadonlyMap<PropertyKey, DeferredMap | null>;
92
170
  /**
93
171
  * Options for creating a string parser.
94
172
  */
@@ -112,6 +190,14 @@ interface StringOptions {
112
190
  * to validate patterns before use.
113
191
  */
114
192
  readonly pattern?: RegExp;
193
+ /**
194
+ * A custom placeholder value used during deferred prompt resolution.
195
+ * Override the default `""` when a `pattern` constraint or downstream
196
+ * `map()` transform requires a non-empty or specially shaped string.
197
+ *
198
+ * @since 1.0.0
199
+ */
200
+ readonly placeholder?: string;
115
201
  /**
116
202
  * Custom error messages for various string parsing failures.
117
203
  * @since 0.5.0
@@ -193,6 +279,9 @@ type ChoiceOptions = ChoiceOptionsString;
193
279
  * A predicate function that checks if an object is a {@link ValueParser}.
194
280
  * @param object The object to check.
195
281
  * @return `true` if the object is a {@link ValueParser}, `false` otherwise.
282
+ * @throws {TypeError} If the object looks like a value parser (has `mode`,
283
+ * `metavar`, `parse`, and `format`) but is missing the required
284
+ * `placeholder` property.
196
285
  */
197
286
  declare function isValueParser<M extends Mode, T>(object: unknown): object is ValueParser<M, T>;
198
287
  /**
@@ -233,6 +322,31 @@ declare function choice<const T extends string>(choices: readonly T[], options?:
233
322
  * @since 0.9.0
234
323
  */
235
324
  declare function choice<const T extends number>(choices: readonly T[], options?: ChoiceOptionsNumber): ValueParser<"sync", T>;
325
+ /**
326
+ * Validates that an option value, if present, is a boolean.
327
+ * Throws a {@link TypeError} if the value is defined but not a boolean.
328
+ *
329
+ * @template T The type of the options object.
330
+ * @param options The options object to check.
331
+ * @param key The key of the option to validate.
332
+ * @throws {TypeError} If the option value is defined but not a boolean.
333
+ * @since 1.0.0
334
+ */
335
+ declare function checkBooleanOption<T extends object>(options: T | undefined, key: keyof T): void;
336
+ /**
337
+ * Validates that an option value, if present, is one of the allowed values.
338
+ * Throws a {@link TypeError} if the value is defined but not in the allowed
339
+ * list.
340
+ *
341
+ * @template T The type of the options object.
342
+ * @param options The options object to check.
343
+ * @param key The key of the option to validate.
344
+ * @param allowed The list of allowed values.
345
+ * @throws {TypeError} If the option value is defined but not in the allowed
346
+ * list.
347
+ * @since 1.0.0
348
+ */
349
+ declare function checkEnumOption<T extends object>(options: T | undefined, key: keyof T, allowed: readonly string[]): void;
236
350
  /**
237
351
  * Creates a {@link ValueParser} for strings.
238
352
  *
@@ -279,6 +393,14 @@ interface IntegerOptionsNumber {
279
393
  * no maximum is enforced.
280
394
  */
281
395
  readonly max?: number;
396
+ /**
397
+ * A custom placeholder value used during deferred prompt resolution.
398
+ * Override the default `0` when `min`/`max` constraints or downstream
399
+ * `map()` transforms require a specific value.
400
+ *
401
+ * @since 1.0.0
402
+ */
403
+ readonly placeholder?: number;
282
404
  /**
283
405
  * Custom error messages for integer parsing failures.
284
406
  * @since 0.5.0
@@ -337,6 +459,14 @@ interface IntegerOptionsBigInt {
337
459
  * no maximum is enforced.
338
460
  */
339
461
  readonly max?: bigint;
462
+ /**
463
+ * A custom placeholder value used during deferred prompt resolution.
464
+ * Override the default `0n` when `min`/`max` constraints or downstream
465
+ * `map()` transforms require a specific value.
466
+ *
467
+ * @since 1.0.0
468
+ */
469
+ readonly placeholder?: bigint;
340
470
  /**
341
471
  * Custom error messages for bigint integer parsing failures.
342
472
  * @since 0.5.0
@@ -411,6 +541,14 @@ interface FloatOptions {
411
541
  * @default `false`
412
542
  */
413
543
  readonly allowInfinity?: boolean;
544
+ /**
545
+ * A custom placeholder value used during deferred prompt resolution.
546
+ * Override the default `0` when `min`/`max` constraints or downstream
547
+ * `map()` transforms require a specific value.
548
+ *
549
+ * @since 1.0.0
550
+ */
551
+ readonly placeholder?: number;
414
552
  /**
415
553
  * Custom error messages for float parsing failures.
416
554
  * @since 0.5.0
@@ -491,6 +629,8 @@ interface UrlOptions {
491
629
  * object.
492
630
  * @param options Configuration options for the URL parser.
493
631
  * @returns A {@link ValueParser} that converts string input to `URL` objects.
632
+ * @throws {TypeError} If any `allowedProtocols` entry is not a valid protocol
633
+ * string ending with a colon (e.g., `"https:"`).
494
634
  */
495
635
  declare function url(options?: UrlOptions): ValueParser<"sync", URL>;
496
636
  /**
@@ -549,10 +689,38 @@ interface UuidOptions {
549
689
  readonly metavar?: NonEmptyString;
550
690
  /**
551
691
  * List of allowed UUID versions (e.g., `[4, 5]` for UUIDs version 4 and 5).
692
+ * Each version must be an integer between 1 and 8 (the standardized
693
+ * [RFC 9562] versions). Duplicate entries are automatically removed.
552
694
  * If specified, the parser will validate that the UUID matches one of the
553
- * allowed versions. If not specified, any valid UUID format is accepted.
695
+ * allowed versions. If not specified, the accepted versions depend on
696
+ * the {@link strict} option.
697
+ *
698
+ * [RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562
554
699
  */
555
700
  readonly allowedVersions?: readonly number[];
701
+ /**
702
+ * Whether to enforce strict [RFC 9562] validation. When `true` (the
703
+ * default), the parser validates that the version digit is one of the
704
+ * currently standardized versions (1 through 8) and that the variant bits
705
+ * follow the RFC 9562 layout (`10xx`, i.e., hex digits `8`, `9`, `a`,
706
+ * or `b` at position 20 of the UUID string).
707
+ *
708
+ * The nil UUID (`00000000-0000-0000-0000-000000000000`) and max UUID
709
+ * (`ffffffff-ffff-ffff-ffff-ffffffffffff`) are accepted as special
710
+ * standard values regardless of this setting.
711
+ *
712
+ * When `false`, the parser only validates the UUID format without
713
+ * checking version or variant fields.
714
+ *
715
+ * When {@link allowedVersions} is provided, it takes precedence over the
716
+ * strict version check, but variant bit validation still applies if
717
+ * `strict` is `true`.
718
+ *
719
+ * [RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562
720
+ * @default true
721
+ * @since 1.0.0
722
+ */
723
+ readonly strict?: boolean;
556
724
  /**
557
725
  * Custom error messages for UUID parsing failures.
558
726
  * @since 0.5.0
@@ -570,6 +738,12 @@ interface UuidOptions {
570
738
  * @since 0.5.0
571
739
  */
572
740
  disallowedVersion?: Message | ((version: number, allowedVersions: readonly number[]) => Message);
741
+ /**
742
+ * Custom error message when UUID variant bits are not RFC 9562 compliant.
743
+ * Can be a static message or a function that receives the input.
744
+ * @since 1.0.0
745
+ */
746
+ invalidVariant?: Message | ((input: string) => Message);
573
747
  };
574
748
  }
575
749
  /**
@@ -577,12 +751,23 @@ interface UuidOptions {
577
751
  *
578
752
  * This parser validates that the input is a well-formed UUID string in the
579
753
  * standard format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` where each `x`
580
- * is a hexadecimal digit. The parser can optionally restrict to specific
581
- * UUID versions.
754
+ * is a hexadecimal digit.
755
+ *
756
+ * By default, the parser enforces strict [RFC 9562] validation: it requires
757
+ * a standardized version digit (1 through 8) and the RFC 9562 variant bits
758
+ * (`10xx`). The nil and max UUIDs are accepted as special standard values.
759
+ * Set `strict: false` to disable the default RFC 9562 version/variant
760
+ * checks. An explicit {@link UuidOptions.allowedVersions} list still
761
+ * constrains the version nibble even in lenient mode.
582
762
  *
763
+ * [RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562
583
764
  * @param options Configuration options for the UUID parser.
584
765
  * @returns A {@link ValueParser} that converts string input to {@link Uuid}
585
766
  * strings.
767
+ * @throws {TypeError} If any element of
768
+ * {@link UuidOptions.allowedVersions} is not an integer.
769
+ * @throws {RangeError} If any element of
770
+ * {@link UuidOptions.allowedVersions} is outside the range 1 to 8.
586
771
  */
587
772
  declare function uuid(options?: UuidOptions): ValueParser<"sync", Uuid>;
588
773
  /**
@@ -617,6 +802,13 @@ interface PortOptionsNumber {
617
802
  * @default `false`
618
803
  */
619
804
  readonly disallowWellKnown?: boolean;
805
+ /**
806
+ * A custom placeholder value used during deferred prompt resolution.
807
+ * Defaults to `min` (which itself defaults to `1`).
808
+ *
809
+ * @since 1.0.0
810
+ */
811
+ readonly placeholder?: number;
620
812
  /**
621
813
  * Custom error messages for port parsing failures.
622
814
  * @since 0.10.0
@@ -679,6 +871,13 @@ interface PortOptionsBigInt {
679
871
  * @default `false`
680
872
  */
681
873
  readonly disallowWellKnown?: boolean;
874
+ /**
875
+ * A custom placeholder value used during deferred prompt resolution.
876
+ * Defaults to `min` (which itself defaults to `1n`).
877
+ *
878
+ * @since 1.0.0
879
+ */
880
+ readonly placeholder?: bigint;
682
881
  /**
683
882
  * Custom error messages for port parsing failures.
684
883
  * @since 0.10.0
@@ -877,6 +1076,13 @@ interface HostnameOptions {
877
1076
  * @default true
878
1077
  */
879
1078
  readonly allowLocalhost?: boolean;
1079
+ /**
1080
+ * A custom placeholder value used during deferred prompt resolution.
1081
+ * Override when `allowLocalhost` or other constraints reject the default.
1082
+ *
1083
+ * @since 1.0.0
1084
+ */
1085
+ readonly placeholder?: string;
880
1086
  /**
881
1087
  * Maximum hostname length in characters.
882
1088
  * @default 253
@@ -922,9 +1128,14 @@ interface HostnameOptions {
922
1128
  * - Labels can contain alphanumeric characters and hyphens
923
1129
  * - Labels cannot start or end with a hyphen
924
1130
  * - Total length ≤ 253 characters (default)
1131
+ * - Dotted all-numeric strings (e.g., `192.168.0.1`) are rejected as they
1132
+ * resemble IPv4 addresses rather than DNS hostnames
925
1133
  *
926
1134
  * @param options - Options for hostname validation.
927
1135
  * @returns A value parser for hostnames.
1136
+ * @throws {TypeError} If `allowWildcard`, `allowUnderscore`, or
1137
+ * `allowLocalhost` is not a boolean.
1138
+ * @throws {RangeError} If `maxLength` is not a positive integer.
928
1139
  * @since 0.10.0
929
1140
  *
930
1141
  * @example
@@ -966,7 +1177,9 @@ interface EmailOptions {
966
1177
  */
967
1178
  readonly allowDisplayName?: boolean;
968
1179
  /**
969
- * If `true`, converts email to lowercase.
1180
+ * If `true`, converts the domain part of the email to lowercase.
1181
+ * The local part is preserved as-is, since it is technically
1182
+ * case-sensitive per RFC 5321.
970
1183
  * @default false
971
1184
  */
972
1185
  readonly lowercase?: boolean;
@@ -975,6 +1188,13 @@ interface EmailOptions {
975
1188
  * If specified, only emails from these domains are accepted.
976
1189
  */
977
1190
  readonly allowedDomains?: readonly string[];
1191
+ /**
1192
+ * Override the default placeholder value used for deferred parsing.
1193
+ * When not specified, the placeholder is derived from the first entry in
1194
+ * {@link allowedDomains} (or `"example.com"` when no domains are set).
1195
+ * @since 1.0.0
1196
+ */
1197
+ readonly placeholder?: string | readonly string[];
978
1198
  /**
979
1199
  * Custom error messages for email parsing failures.
980
1200
  */
@@ -1004,6 +1224,11 @@ interface EmailOptions {
1004
1224
  *
1005
1225
  * @param options - Options for email validation.
1006
1226
  * @returns A value parser for email addresses.
1227
+ * @throws {TypeError} If any `allowedDomains` entry is not a string, has
1228
+ * leading/trailing whitespace, starts with `"@"`, is empty, lacks a dot,
1229
+ * has invalid hostname label syntax, or is an IPv4-like dotted-quad.
1230
+ * @throws {TypeError} If `placeholder` type does not match `allowMultiple`
1231
+ * mode (string for single, array for multiple).
1007
1232
  * @since 0.10.0
1008
1233
  *
1009
1234
  * @example
@@ -1049,8 +1274,8 @@ interface SocketAddressValue {
1049
1274
  */
1050
1275
  interface SocketAddressOptions {
1051
1276
  /**
1052
- * The metavariable name for this parser.
1053
- * @default "HOST:PORT"
1277
+ * The metavariable name for this parser. If not specified, it is derived
1278
+ * from the {@link separator} (e.g., `"HOST:PORT"` for `":"`).
1054
1279
  */
1055
1280
  readonly metavar?: NonEmptyString;
1056
1281
  /**
@@ -1123,6 +1348,9 @@ interface SocketAddressOptions {
1123
1348
  *
1124
1349
  * @param options - Options for socket address validation.
1125
1350
  * @returns A value parser for socket addresses.
1351
+ * @throws {TypeError} If `separator` is an empty string.
1352
+ * @throws {TypeError} If `separator` contains digit characters, since digits
1353
+ * in the separator would cause ambiguous splitting of port input.
1126
1354
  * @since 0.10.0
1127
1355
  *
1128
1356
  * @example
@@ -1185,8 +1413,8 @@ interface PortRangeOptionsNumber {
1185
1413
  */
1186
1414
  readonly type?: "number";
1187
1415
  /**
1188
- * The metavariable name for this parser.
1189
- * @default "PORT-PORT"
1416
+ * The metavariable name for this parser. If not specified, it is derived
1417
+ * from the {@link separator} (e.g., `"PORT-PORT"` for `"-"`).
1190
1418
  */
1191
1419
  readonly metavar?: NonEmptyString;
1192
1420
  /**
@@ -1265,8 +1493,8 @@ interface PortRangeOptionsBigInt {
1265
1493
  */
1266
1494
  readonly type: "bigint";
1267
1495
  /**
1268
- * The metavariable name for this parser.
1269
- * @default "PORT-PORT"
1496
+ * The metavariable name for this parser. If not specified, it is derived
1497
+ * from the {@link separator} (e.g., `"PORT-PORT"` for `"-"`).
1270
1498
  */
1271
1499
  readonly metavar?: NonEmptyString;
1272
1500
  /**
@@ -1346,6 +1574,11 @@ interface PortRangeOptionsBigInt {
1346
1574
  *
1347
1575
  * @param options - Options for port range validation.
1348
1576
  * @returns A value parser for port ranges.
1577
+ * @throws {TypeError} If `options.type` is provided but is neither `"number"`
1578
+ * nor `"bigint"`.
1579
+ * @throws {TypeError} If `separator` is an empty string.
1580
+ * @throws {TypeError} If `separator` contains digit characters, since digits
1581
+ * in the separator would cause ambiguous splitting of numeric port input.
1349
1582
  * @since 0.10.0
1350
1583
  *
1351
1584
  * @example
@@ -1417,10 +1650,14 @@ interface MacAddressOptions {
1417
1650
  * Creates a value parser for MAC (Media Access Control) addresses.
1418
1651
  *
1419
1652
  * Validates MAC-48 addresses (6 octets, 12 hex digits) in various formats:
1420
- * - Colon-separated: `00:1A:2B:3C:4D:5E`
1421
- * - Hyphen-separated: `00-1A-2B-3C-4D-5E`
1422
- * - Dot-separated (Cisco): `001A.2B3C.4D5E`
1423
- * - No separator: `001A2B3C4D5E`
1653
+ * - Colon-separated: `00:1A:2B:3C:4D:5E` (1–2 hex digits per octet)
1654
+ * - Hyphen-separated: `00-1A-2B-3C-4D-5E` (1–2 hex digits per octet)
1655
+ * - Dot-separated (Cisco): `001A.2B3C.4D5E` (exactly 4 hex digits per group)
1656
+ * - No separator: `001A2B3C4D5E` (exactly 12 hex digits)
1657
+ *
1658
+ * Colon-separated and hyphen-separated formats accept single-digit octets
1659
+ * (e.g., `0:1:2:3:4:5`), which are automatically zero-padded to canonical
1660
+ * two-digit form (e.g., `00:01:02:03:04:05`).
1424
1661
  *
1425
1662
  * Returns the MAC address as a formatted string according to `case` and
1426
1663
  * `outputSeparator` options.
@@ -1467,13 +1704,27 @@ interface DomainOptions {
1467
1704
  * List of allowed top-level domains (e.g., ["com", "org", "net"]).
1468
1705
  * If specified, only domains with these TLDs are accepted.
1469
1706
  */
1470
- readonly allowedTLDs?: readonly string[];
1707
+ readonly allowedTlds?: readonly string[];
1471
1708
  /**
1472
1709
  * Minimum number of domain labels (parts separated by dots).
1473
1710
  *
1474
1711
  * @default 2
1475
1712
  */
1476
1713
  readonly minLabels?: number;
1714
+ /**
1715
+ * Maximum domain length in characters.
1716
+ * @default 253
1717
+ * @since 1.0.0
1718
+ */
1719
+ readonly maxLength?: number;
1720
+ /**
1721
+ * A custom placeholder value used during deferred prompt resolution.
1722
+ * Override when `allowedTlds`, `minLabels`, or other constraints
1723
+ * reject the default `"example.com"`.
1724
+ *
1725
+ * @since 1.0.0
1726
+ */
1727
+ readonly placeholder?: string;
1477
1728
  /**
1478
1729
  * If `true`, converts domain to lowercase.
1479
1730
  *
@@ -1499,13 +1750,20 @@ interface DomainOptions {
1499
1750
  * Can be a static message or a function that receives the TLD
1500
1751
  * and allowed TLDs.
1501
1752
  */
1502
- tldNotAllowed?: Message | ((tld: string, allowedTLDs: readonly string[]) => Message);
1753
+ tldNotAllowed?: Message | ((tld: string, allowedTlds: readonly string[]) => Message);
1503
1754
  /**
1504
1755
  * Custom error message when domain has too few labels.
1505
1756
  * Can be a static message or a function that receives the domain
1506
1757
  * and minimum labels.
1507
1758
  */
1508
1759
  tooFewLabels?: Message | ((domain: string, minLabels: number) => Message);
1760
+ /**
1761
+ * Custom error message when domain is too long.
1762
+ * Can be a static message or a function that receives the domain
1763
+ * and max length.
1764
+ * @since 1.0.0
1765
+ */
1766
+ tooLong?: Message | ((domain: string, maxLength: number) => Message);
1509
1767
  };
1510
1768
  }
1511
1769
  /**
@@ -1517,6 +1775,14 @@ interface DomainOptions {
1517
1775
  *
1518
1776
  * @param options Parser options for domain validation.
1519
1777
  * @returns A parser that accepts valid domain names as strings.
1778
+ * @throws {RangeError} If `maxLength` is not a positive integer.
1779
+ * @throws {RangeError} If `minLabels` is not a positive integer.
1780
+ * @throws {TypeError} If `allowSubdomains` or `lowercase` is not a boolean.
1781
+ * @throws {TypeError} If any `allowedTlds` entry is not a string, is empty,
1782
+ * contains dots, has leading/trailing whitespace, or is not a valid DNS
1783
+ * label.
1784
+ * @throws {TypeError} If `allowSubdomains` is `false` and `minLabels` is
1785
+ * greater than 2, since non-subdomain domains have exactly 2 labels.
1520
1786
  *
1521
1787
  * @example
1522
1788
  * ``` typescript
@@ -1530,7 +1796,7 @@ interface DomainOptions {
1530
1796
  * option("--root", domain({ allowSubdomains: false }))
1531
1797
  *
1532
1798
  * // Restrict to specific TLDs
1533
- * option("--domain", domain({ allowedTLDs: ["com", "org", "net"] }))
1799
+ * option("--domain", domain({ allowedTlds: ["com", "org", "net"] }))
1534
1800
  *
1535
1801
  * // Normalize to lowercase
1536
1802
  * option("--domain", domain({ lowercase: true }))
@@ -1827,6 +2093,50 @@ interface CidrOptions {
1827
2093
  * Can be a static message or a function that receives the prefix and maximum.
1828
2094
  */
1829
2095
  prefixAboveMaximum?: Message | ((prefix: number, max: number) => Message);
2096
+ /**
2097
+ * Custom error message when a private IPv4 address is used but disallowed.
2098
+ * Can be a static message or a function that receives the IP.
2099
+ * @since 1.0.0
2100
+ */
2101
+ privateNotAllowed?: Message | ((ip: string) => Message);
2102
+ /**
2103
+ * Custom error message when a loopback address is used but disallowed.
2104
+ * Can be a static message or a function that receives the IP.
2105
+ * @since 1.0.0
2106
+ */
2107
+ loopbackNotAllowed?: Message | ((ip: string) => Message);
2108
+ /**
2109
+ * Custom error message when a link-local address is used but disallowed.
2110
+ * Can be a static message or a function that receives the IP.
2111
+ * @since 1.0.0
2112
+ */
2113
+ linkLocalNotAllowed?: Message | ((ip: string) => Message);
2114
+ /**
2115
+ * Custom error message when a multicast address is used but disallowed.
2116
+ * Can be a static message or a function that receives the IP.
2117
+ * @since 1.0.0
2118
+ */
2119
+ multicastNotAllowed?: Message | ((ip: string) => Message);
2120
+ /**
2121
+ * Custom error message when the broadcast address is used but disallowed
2122
+ * (IPv4 only).
2123
+ * Can be a static message or a function that receives the IP.
2124
+ * @since 1.0.0
2125
+ */
2126
+ broadcastNotAllowed?: Message | ((ip: string) => Message);
2127
+ /**
2128
+ * Custom error message when the zero address is used but disallowed.
2129
+ * Can be a static message or a function that receives the IP.
2130
+ * @since 1.0.0
2131
+ */
2132
+ zeroNotAllowed?: Message | ((ip: string) => Message);
2133
+ /**
2134
+ * Custom error message when a unique local address is used but disallowed
2135
+ * (IPv6 only).
2136
+ * Can be a static message or a function that receives the IP.
2137
+ * @since 1.0.0
2138
+ */
2139
+ uniqueLocalNotAllowed?: Message | ((ip: string) => Message);
1830
2140
  };
1831
2141
  }
1832
2142
  /**
@@ -1856,4 +2166,4 @@ interface CidrOptions {
1856
2166
  */
1857
2167
  declare function cidr(options?: CidrOptions): ValueParser<"sync", CidrValue>;
1858
2168
  //#endregion
1859
- export { ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, DomainOptions, EmailOptions, FloatOptions, HostnameOptions, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, LocaleOptions, MacAddressOptions, type Mode, type ModeIterable, type ModeValue, type NonEmptyString, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, SocketAddressOptions, SocketAddressValue, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, choice, cidr, domain, email, ensureNonEmptyString, float, hostname, integer, ip, ipv4, ipv6, isNonEmptyString, isValueParser, locale, macAddress, port, portRange, socketAddress, string, url, uuid };
2169
+ export { ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, DeferredMap, DomainOptions, EmailOptions, FloatOptions, HostnameOptions, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, LocaleOptions, MacAddressOptions, type Mode, type ModeIterable, type ModeValue, type NonEmptyString, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, SocketAddressOptions, SocketAddressValue, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, checkBooleanOption, checkEnumOption, choice, cidr, domain, email, ensureNonEmptyString, float, hostname, integer, ip, ipv4, ipv6, isNonEmptyString, isValueParser, locale, macAddress, port, portRange, socketAddress, string, url, uuid };