@optique/core 0.10.7 → 1.0.0-dev.1116

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 (56) hide show
  1. package/README.md +4 -6
  2. package/dist/annotations.cjs +209 -1
  3. package/dist/annotations.d.cts +78 -1
  4. package/dist/annotations.d.ts +78 -1
  5. package/dist/annotations.js +201 -1
  6. package/dist/completion.cjs +194 -52
  7. package/dist/completion.js +194 -52
  8. package/dist/constructs.cjs +310 -78
  9. package/dist/constructs.d.cts +525 -644
  10. package/dist/constructs.d.ts +525 -644
  11. package/dist/constructs.js +311 -79
  12. package/dist/context.cjs +43 -3
  13. package/dist/context.d.cts +113 -5
  14. package/dist/context.d.ts +113 -5
  15. package/dist/context.js +41 -3
  16. package/dist/dependency.cjs +172 -66
  17. package/dist/dependency.d.cts +22 -2
  18. package/dist/dependency.d.ts +22 -2
  19. package/dist/dependency.js +172 -66
  20. package/dist/doc.cjs +46 -1
  21. package/dist/doc.d.cts +24 -0
  22. package/dist/doc.d.ts +24 -0
  23. package/dist/doc.js +46 -1
  24. package/dist/facade.cjs +702 -322
  25. package/dist/facade.d.cts +124 -190
  26. package/dist/facade.d.ts +124 -190
  27. package/dist/facade.js +703 -323
  28. package/dist/index.cjs +5 -0
  29. package/dist/index.d.cts +5 -5
  30. package/dist/index.d.ts +5 -5
  31. package/dist/index.js +3 -3
  32. package/dist/message.cjs +7 -4
  33. package/dist/message.js +7 -4
  34. package/dist/mode-dispatch.cjs +23 -1
  35. package/dist/mode-dispatch.d.cts +55 -0
  36. package/dist/mode-dispatch.d.ts +55 -0
  37. package/dist/mode-dispatch.js +21 -1
  38. package/dist/modifiers.cjs +210 -55
  39. package/dist/modifiers.js +211 -56
  40. package/dist/parser.cjs +80 -47
  41. package/dist/parser.d.cts +18 -3
  42. package/dist/parser.d.ts +18 -3
  43. package/dist/parser.js +82 -50
  44. package/dist/primitives.cjs +102 -37
  45. package/dist/primitives.d.cts +81 -24
  46. package/dist/primitives.d.ts +81 -24
  47. package/dist/primitives.js +103 -39
  48. package/dist/usage.cjs +88 -6
  49. package/dist/usage.d.cts +51 -13
  50. package/dist/usage.d.ts +51 -13
  51. package/dist/usage.js +85 -7
  52. package/dist/valueparser.cjs +391 -106
  53. package/dist/valueparser.d.cts +62 -10
  54. package/dist/valueparser.d.ts +62 -10
  55. package/dist/valueparser.js +391 -106
  56. package/package.json +10 -1
@@ -206,6 +206,13 @@ declare function isValueParser<M extends Mode, T>(object: unknown): object is Va
206
206
  * @param options Configuration options for the choice parser.
207
207
  * @returns A {@link ValueParser} that checks if the input matches one of the
208
208
  * specified values.
209
+ * @throws {TypeError} If the choices array is empty.
210
+ * @throws {TypeError} If any choice is an empty string.
211
+ * @throws {TypeError} If any choice is not a string.
212
+ * @throws {TypeError} If choices contain a mix of strings and numbers.
213
+ * @throws {TypeError} If `caseInsensitive` is not a boolean.
214
+ * @throws {TypeError} If `caseInsensitive` is `true` and multiple choices
215
+ * normalize to the same lowercase value.
209
216
  */
210
217
  declare function choice<const T extends string>(choices: readonly T[], options?: ChoiceOptionsString): ValueParser<"sync", T>;
211
218
  /**
@@ -219,6 +226,10 @@ declare function choice<const T extends string>(choices: readonly T[], options?:
219
226
  * @param options Configuration options for the choice parser.
220
227
  * @returns A {@link ValueParser} that checks if the input matches one of the
221
228
  * specified values.
229
+ * @throws {TypeError} If the choices array is empty.
230
+ * @throws {TypeError} If any choice is not a number.
231
+ * @throws {TypeError} If any choice is `NaN`.
232
+ * @throws {TypeError} If choices contain a mix of strings and numbers.
222
233
  * @since 0.9.0
223
234
  */
224
235
  declare function choice<const T extends number>(choices: readonly T[], options?: ChoiceOptionsNumber): ValueParser<"sync", T>;
@@ -235,6 +246,8 @@ declare function choice<const T extends number>(choices: readonly T[], options?:
235
246
  * @param options Configuration options for the string parser.
236
247
  * @returns A {@link ValueParser} that parses strings according to the
237
248
  * specified options.
249
+ * @throws {TypeError} If `options.pattern` is provided but is not a
250
+ * `RegExp` instance.
238
251
  */
239
252
  declare function string(options?: StringOptions): ValueParser<"sync", string>;
240
253
  /**
@@ -277,6 +290,13 @@ interface IntegerOptionsNumber {
277
290
  * @since 0.5.0
278
291
  */
279
292
  invalidInteger?: Message | ((input: string) => Message);
293
+ /**
294
+ * Custom error message when integer is outside the safe integer range
295
+ * (`Number.MIN_SAFE_INTEGER` to `Number.MAX_SAFE_INTEGER`).
296
+ * Can be a static message or a function that receives the input string.
297
+ * @since 1.0.0
298
+ */
299
+ unsafeInteger?: Message | ((input: string) => Message);
280
300
  /**
281
301
  * Custom error message when integer is below minimum value.
282
302
  * Can be a static message or a function that receives the value and minimum.
@@ -905,6 +925,7 @@ interface HostnameOptions {
905
925
  *
906
926
  * @param options - Options for hostname validation.
907
927
  * @returns A value parser for hostnames.
928
+ * @throws {RangeError} If `maxLength` is not a positive integer.
908
929
  * @since 0.10.0
909
930
  *
910
931
  * @example
@@ -946,7 +967,9 @@ interface EmailOptions {
946
967
  */
947
968
  readonly allowDisplayName?: boolean;
948
969
  /**
949
- * If `true`, converts email to lowercase.
970
+ * If `true`, converts the domain part of the email to lowercase.
971
+ * The local part is preserved as-is, since it is technically
972
+ * case-sensitive per RFC 5321.
950
973
  * @default false
951
974
  */
952
975
  readonly lowercase?: boolean;
@@ -984,6 +1007,9 @@ interface EmailOptions {
984
1007
  *
985
1008
  * @param options - Options for email validation.
986
1009
  * @returns A value parser for email addresses.
1010
+ * @throws {TypeError} If any `allowedDomains` entry is not a string, has
1011
+ * leading/trailing whitespace, starts with `"@"`, is empty, lacks a dot,
1012
+ * has invalid hostname label syntax, or is an IPv4-like dotted-quad.
987
1013
  * @since 0.10.0
988
1014
  *
989
1015
  * @example
@@ -1029,8 +1055,8 @@ interface SocketAddressValue {
1029
1055
  */
1030
1056
  interface SocketAddressOptions {
1031
1057
  /**
1032
- * The metavariable name for this parser.
1033
- * @default "HOST:PORT"
1058
+ * The metavariable name for this parser. If not specified, it is derived
1059
+ * from the {@link separator} (e.g., `"HOST:PORT"` for `":"`).
1034
1060
  */
1035
1061
  readonly metavar?: NonEmptyString;
1036
1062
  /**
@@ -1103,6 +1129,8 @@ interface SocketAddressOptions {
1103
1129
  *
1104
1130
  * @param options - Options for socket address validation.
1105
1131
  * @returns A value parser for socket addresses.
1132
+ * @throws {TypeError} If `separator` contains digit characters, since digits
1133
+ * in the separator would cause ambiguous splitting of port input.
1106
1134
  * @since 0.10.0
1107
1135
  *
1108
1136
  * @example
@@ -1165,8 +1193,8 @@ interface PortRangeOptionsNumber {
1165
1193
  */
1166
1194
  readonly type?: "number";
1167
1195
  /**
1168
- * The metavariable name for this parser.
1169
- * @default "PORT-PORT"
1196
+ * The metavariable name for this parser. If not specified, it is derived
1197
+ * from the {@link separator} (e.g., `"PORT-PORT"` for `"-"`).
1170
1198
  */
1171
1199
  readonly metavar?: NonEmptyString;
1172
1200
  /**
@@ -1245,8 +1273,8 @@ interface PortRangeOptionsBigInt {
1245
1273
  */
1246
1274
  readonly type: "bigint";
1247
1275
  /**
1248
- * The metavariable name for this parser.
1249
- * @default "PORT-PORT"
1276
+ * The metavariable name for this parser. If not specified, it is derived
1277
+ * from the {@link separator} (e.g., `"PORT-PORT"` for `"-"`).
1250
1278
  */
1251
1279
  readonly metavar?: NonEmptyString;
1252
1280
  /**
@@ -1326,6 +1354,10 @@ interface PortRangeOptionsBigInt {
1326
1354
  *
1327
1355
  * @param options - Options for port range validation.
1328
1356
  * @returns A value parser for port ranges.
1357
+ * @throws {TypeError} If `options.type` is provided but is neither `"number"`
1358
+ * nor `"bigint"`.
1359
+ * @throws {TypeError} If `separator` contains digit characters, since digits
1360
+ * in the separator would cause ambiguous splitting of numeric port input.
1329
1361
  * @since 0.10.0
1330
1362
  *
1331
1363
  * @example
@@ -1447,13 +1479,19 @@ interface DomainOptions {
1447
1479
  * List of allowed top-level domains (e.g., ["com", "org", "net"]).
1448
1480
  * If specified, only domains with these TLDs are accepted.
1449
1481
  */
1450
- readonly allowedTLDs?: readonly string[];
1482
+ readonly allowedTlds?: readonly string[];
1451
1483
  /**
1452
1484
  * Minimum number of domain labels (parts separated by dots).
1453
1485
  *
1454
1486
  * @default 2
1455
1487
  */
1456
1488
  readonly minLabels?: number;
1489
+ /**
1490
+ * Maximum domain length in characters.
1491
+ * @default 253
1492
+ * @since 1.0.0
1493
+ */
1494
+ readonly maxLength?: number;
1457
1495
  /**
1458
1496
  * If `true`, converts domain to lowercase.
1459
1497
  *
@@ -1479,13 +1517,20 @@ interface DomainOptions {
1479
1517
  * Can be a static message or a function that receives the TLD
1480
1518
  * and allowed TLDs.
1481
1519
  */
1482
- tldNotAllowed?: Message | ((tld: string, allowedTLDs: readonly string[]) => Message);
1520
+ tldNotAllowed?: Message | ((tld: string, allowedTlds: readonly string[]) => Message);
1483
1521
  /**
1484
1522
  * Custom error message when domain has too few labels.
1485
1523
  * Can be a static message or a function that receives the domain
1486
1524
  * and minimum labels.
1487
1525
  */
1488
1526
  tooFewLabels?: Message | ((domain: string, minLabels: number) => Message);
1527
+ /**
1528
+ * Custom error message when domain is too long.
1529
+ * Can be a static message or a function that receives the domain
1530
+ * and max length.
1531
+ * @since 1.0.0
1532
+ */
1533
+ tooLong?: Message | ((domain: string, maxLength: number) => Message);
1489
1534
  };
1490
1535
  }
1491
1536
  /**
@@ -1497,6 +1542,13 @@ interface DomainOptions {
1497
1542
  *
1498
1543
  * @param options Parser options for domain validation.
1499
1544
  * @returns A parser that accepts valid domain names as strings.
1545
+ * @throws {RangeError} If `maxLength` is not a positive integer.
1546
+ * @throws {RangeError} If `minLabels` is not a positive integer.
1547
+ * @throws {TypeError} If any `allowedTlds` entry is not a string, is empty,
1548
+ * contains dots, has leading/trailing whitespace, or is not a valid DNS
1549
+ * label.
1550
+ * @throws {TypeError} If `allowSubdomains` is `false` and `minLabels` is
1551
+ * greater than 2, since non-subdomain domains have exactly 2 labels.
1500
1552
  *
1501
1553
  * @example
1502
1554
  * ``` typescript
@@ -1510,7 +1562,7 @@ interface DomainOptions {
1510
1562
  * option("--root", domain({ allowSubdomains: false }))
1511
1563
  *
1512
1564
  * // Restrict to specific TLDs
1513
- * option("--domain", domain({ allowedTLDs: ["com", "org", "net"] }))
1565
+ * option("--domain", domain({ allowedTlds: ["com", "org", "net"] }))
1514
1566
  *
1515
1567
  * // Normalize to lowercase
1516
1568
  * option("--domain", domain({ lowercase: true }))
@@ -206,6 +206,13 @@ declare function isValueParser<M extends Mode, T>(object: unknown): object is Va
206
206
  * @param options Configuration options for the choice parser.
207
207
  * @returns A {@link ValueParser} that checks if the input matches one of the
208
208
  * specified values.
209
+ * @throws {TypeError} If the choices array is empty.
210
+ * @throws {TypeError} If any choice is an empty string.
211
+ * @throws {TypeError} If any choice is not a string.
212
+ * @throws {TypeError} If choices contain a mix of strings and numbers.
213
+ * @throws {TypeError} If `caseInsensitive` is not a boolean.
214
+ * @throws {TypeError} If `caseInsensitive` is `true` and multiple choices
215
+ * normalize to the same lowercase value.
209
216
  */
210
217
  declare function choice<const T extends string>(choices: readonly T[], options?: ChoiceOptionsString): ValueParser<"sync", T>;
211
218
  /**
@@ -219,6 +226,10 @@ declare function choice<const T extends string>(choices: readonly T[], options?:
219
226
  * @param options Configuration options for the choice parser.
220
227
  * @returns A {@link ValueParser} that checks if the input matches one of the
221
228
  * specified values.
229
+ * @throws {TypeError} If the choices array is empty.
230
+ * @throws {TypeError} If any choice is not a number.
231
+ * @throws {TypeError} If any choice is `NaN`.
232
+ * @throws {TypeError} If choices contain a mix of strings and numbers.
222
233
  * @since 0.9.0
223
234
  */
224
235
  declare function choice<const T extends number>(choices: readonly T[], options?: ChoiceOptionsNumber): ValueParser<"sync", T>;
@@ -235,6 +246,8 @@ declare function choice<const T extends number>(choices: readonly T[], options?:
235
246
  * @param options Configuration options for the string parser.
236
247
  * @returns A {@link ValueParser} that parses strings according to the
237
248
  * specified options.
249
+ * @throws {TypeError} If `options.pattern` is provided but is not a
250
+ * `RegExp` instance.
238
251
  */
239
252
  declare function string(options?: StringOptions): ValueParser<"sync", string>;
240
253
  /**
@@ -277,6 +290,13 @@ interface IntegerOptionsNumber {
277
290
  * @since 0.5.0
278
291
  */
279
292
  invalidInteger?: Message | ((input: string) => Message);
293
+ /**
294
+ * Custom error message when integer is outside the safe integer range
295
+ * (`Number.MIN_SAFE_INTEGER` to `Number.MAX_SAFE_INTEGER`).
296
+ * Can be a static message or a function that receives the input string.
297
+ * @since 1.0.0
298
+ */
299
+ unsafeInteger?: Message | ((input: string) => Message);
280
300
  /**
281
301
  * Custom error message when integer is below minimum value.
282
302
  * Can be a static message or a function that receives the value and minimum.
@@ -905,6 +925,7 @@ interface HostnameOptions {
905
925
  *
906
926
  * @param options - Options for hostname validation.
907
927
  * @returns A value parser for hostnames.
928
+ * @throws {RangeError} If `maxLength` is not a positive integer.
908
929
  * @since 0.10.0
909
930
  *
910
931
  * @example
@@ -946,7 +967,9 @@ interface EmailOptions {
946
967
  */
947
968
  readonly allowDisplayName?: boolean;
948
969
  /**
949
- * If `true`, converts email to lowercase.
970
+ * If `true`, converts the domain part of the email to lowercase.
971
+ * The local part is preserved as-is, since it is technically
972
+ * case-sensitive per RFC 5321.
950
973
  * @default false
951
974
  */
952
975
  readonly lowercase?: boolean;
@@ -984,6 +1007,9 @@ interface EmailOptions {
984
1007
  *
985
1008
  * @param options - Options for email validation.
986
1009
  * @returns A value parser for email addresses.
1010
+ * @throws {TypeError} If any `allowedDomains` entry is not a string, has
1011
+ * leading/trailing whitespace, starts with `"@"`, is empty, lacks a dot,
1012
+ * has invalid hostname label syntax, or is an IPv4-like dotted-quad.
987
1013
  * @since 0.10.0
988
1014
  *
989
1015
  * @example
@@ -1029,8 +1055,8 @@ interface SocketAddressValue {
1029
1055
  */
1030
1056
  interface SocketAddressOptions {
1031
1057
  /**
1032
- * The metavariable name for this parser.
1033
- * @default "HOST:PORT"
1058
+ * The metavariable name for this parser. If not specified, it is derived
1059
+ * from the {@link separator} (e.g., `"HOST:PORT"` for `":"`).
1034
1060
  */
1035
1061
  readonly metavar?: NonEmptyString;
1036
1062
  /**
@@ -1103,6 +1129,8 @@ interface SocketAddressOptions {
1103
1129
  *
1104
1130
  * @param options - Options for socket address validation.
1105
1131
  * @returns A value parser for socket addresses.
1132
+ * @throws {TypeError} If `separator` contains digit characters, since digits
1133
+ * in the separator would cause ambiguous splitting of port input.
1106
1134
  * @since 0.10.0
1107
1135
  *
1108
1136
  * @example
@@ -1165,8 +1193,8 @@ interface PortRangeOptionsNumber {
1165
1193
  */
1166
1194
  readonly type?: "number";
1167
1195
  /**
1168
- * The metavariable name for this parser.
1169
- * @default "PORT-PORT"
1196
+ * The metavariable name for this parser. If not specified, it is derived
1197
+ * from the {@link separator} (e.g., `"PORT-PORT"` for `"-"`).
1170
1198
  */
1171
1199
  readonly metavar?: NonEmptyString;
1172
1200
  /**
@@ -1245,8 +1273,8 @@ interface PortRangeOptionsBigInt {
1245
1273
  */
1246
1274
  readonly type: "bigint";
1247
1275
  /**
1248
- * The metavariable name for this parser.
1249
- * @default "PORT-PORT"
1276
+ * The metavariable name for this parser. If not specified, it is derived
1277
+ * from the {@link separator} (e.g., `"PORT-PORT"` for `"-"`).
1250
1278
  */
1251
1279
  readonly metavar?: NonEmptyString;
1252
1280
  /**
@@ -1326,6 +1354,10 @@ interface PortRangeOptionsBigInt {
1326
1354
  *
1327
1355
  * @param options - Options for port range validation.
1328
1356
  * @returns A value parser for port ranges.
1357
+ * @throws {TypeError} If `options.type` is provided but is neither `"number"`
1358
+ * nor `"bigint"`.
1359
+ * @throws {TypeError} If `separator` contains digit characters, since digits
1360
+ * in the separator would cause ambiguous splitting of numeric port input.
1329
1361
  * @since 0.10.0
1330
1362
  *
1331
1363
  * @example
@@ -1447,13 +1479,19 @@ interface DomainOptions {
1447
1479
  * List of allowed top-level domains (e.g., ["com", "org", "net"]).
1448
1480
  * If specified, only domains with these TLDs are accepted.
1449
1481
  */
1450
- readonly allowedTLDs?: readonly string[];
1482
+ readonly allowedTlds?: readonly string[];
1451
1483
  /**
1452
1484
  * Minimum number of domain labels (parts separated by dots).
1453
1485
  *
1454
1486
  * @default 2
1455
1487
  */
1456
1488
  readonly minLabels?: number;
1489
+ /**
1490
+ * Maximum domain length in characters.
1491
+ * @default 253
1492
+ * @since 1.0.0
1493
+ */
1494
+ readonly maxLength?: number;
1457
1495
  /**
1458
1496
  * If `true`, converts domain to lowercase.
1459
1497
  *
@@ -1479,13 +1517,20 @@ interface DomainOptions {
1479
1517
  * Can be a static message or a function that receives the TLD
1480
1518
  * and allowed TLDs.
1481
1519
  */
1482
- tldNotAllowed?: Message | ((tld: string, allowedTLDs: readonly string[]) => Message);
1520
+ tldNotAllowed?: Message | ((tld: string, allowedTlds: readonly string[]) => Message);
1483
1521
  /**
1484
1522
  * Custom error message when domain has too few labels.
1485
1523
  * Can be a static message or a function that receives the domain
1486
1524
  * and minimum labels.
1487
1525
  */
1488
1526
  tooFewLabels?: Message | ((domain: string, minLabels: number) => Message);
1527
+ /**
1528
+ * Custom error message when domain is too long.
1529
+ * Can be a static message or a function that receives the domain
1530
+ * and max length.
1531
+ * @since 1.0.0
1532
+ */
1533
+ tooLong?: Message | ((domain: string, maxLength: number) => Message);
1489
1534
  };
1490
1535
  }
1491
1536
  /**
@@ -1497,6 +1542,13 @@ interface DomainOptions {
1497
1542
  *
1498
1543
  * @param options Parser options for domain validation.
1499
1544
  * @returns A parser that accepts valid domain names as strings.
1545
+ * @throws {RangeError} If `maxLength` is not a positive integer.
1546
+ * @throws {RangeError} If `minLabels` is not a positive integer.
1547
+ * @throws {TypeError} If any `allowedTlds` entry is not a string, is empty,
1548
+ * contains dots, has leading/trailing whitespace, or is not a valid DNS
1549
+ * label.
1550
+ * @throws {TypeError} If `allowSubdomains` is `false` and `minLabels` is
1551
+ * greater than 2, since non-subdomain domains have exactly 2 labels.
1500
1552
  *
1501
1553
  * @example
1502
1554
  * ``` typescript
@@ -1510,7 +1562,7 @@ interface DomainOptions {
1510
1562
  * option("--root", domain({ allowSubdomains: false }))
1511
1563
  *
1512
1564
  * // Restrict to specific TLDs
1513
- * option("--domain", domain({ allowedTLDs: ["com", "org", "net"] }))
1565
+ * option("--domain", domain({ allowedTlds: ["com", "org", "net"] }))
1514
1566
  *
1515
1567
  * // Normalize to lowercase
1516
1568
  * option("--domain", domain({ lowercase: true }))