@optique/core 1.0.0-dev.1109 → 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.
@@ -250,6 +250,12 @@ function _${programName.replace(/[^a-zA-Z0-9]/g, "_")} () {
250
250
  pattern="\${pattern//%3A/:}"; pattern="\${pattern//%25/%}"
251
251
  has_file_completion=1
252
252
 
253
+ # Enable glob_dots when hidden files are requested so that
254
+ # _files and _directories include dot-prefixed entries
255
+ local __was_glob_dots=0
256
+ [[ -o glob_dots ]] && __was_glob_dots=1
257
+ if [[ "\$hidden" == "1" ]]; then setopt glob_dots; fi
258
+
253
259
  # Use zsh's native file completion
254
260
  case "\$type" in
255
261
  file)
@@ -275,8 +281,8 @@ function _${programName.replace(/[^a-zA-Z0-9]/g, "_")} () {
275
281
  ;;
276
282
  esac
277
283
 
278
- # Note: zsh's _files and _directories handle hidden file filtering automatically
279
- # based on the completion context and user settings
284
+ # Restore glob_dots to its previous state
285
+ if [[ "\$__was_glob_dots" == "1" ]]; then setopt glob_dots; else unsetopt glob_dots; fi
280
286
  else
281
287
  # Regular literal completion
282
288
  if [[ -n "\$value" ]]; then
@@ -250,6 +250,12 @@ function _${programName.replace(/[^a-zA-Z0-9]/g, "_")} () {
250
250
  pattern="\${pattern//%3A/:}"; pattern="\${pattern//%25/%}"
251
251
  has_file_completion=1
252
252
 
253
+ # Enable glob_dots when hidden files are requested so that
254
+ # _files and _directories include dot-prefixed entries
255
+ local __was_glob_dots=0
256
+ [[ -o glob_dots ]] && __was_glob_dots=1
257
+ if [[ "\$hidden" == "1" ]]; then setopt glob_dots; fi
258
+
253
259
  # Use zsh's native file completion
254
260
  case "\$type" in
255
261
  file)
@@ -275,8 +281,8 @@ function _${programName.replace(/[^a-zA-Z0-9]/g, "_")} () {
275
281
  ;;
276
282
  esac
277
283
 
278
- # Note: zsh's _files and _directories handle hidden file filtering automatically
279
- # based on the completion context and user settings
284
+ # Restore glob_dots to its previous state
285
+ if [[ "\$__was_glob_dots" == "1" ]]; then setopt glob_dots; else unsetopt glob_dots; fi
280
286
  else
281
287
  # Regular literal completion
282
288
  if [[ -n "\$value" ]]; then
@@ -1832,6 +1832,9 @@ function macAddress(options) {
1832
1832
  * @returns A parser that accepts valid domain names as strings.
1833
1833
  * @throws {RangeError} If `maxLength` is not a positive integer.
1834
1834
  * @throws {RangeError} If `minLabels` is not a positive integer.
1835
+ * @throws {TypeError} If any `allowedTlds` entry is not a string, is empty,
1836
+ * contains dots, has leading/trailing whitespace, or is not a valid DNS
1837
+ * label.
1835
1838
  * @throws {TypeError} If `allowSubdomains` is `false` and `minLabels` is
1836
1839
  * greater than 2, since non-subdomain domains have exactly 2 labels.
1837
1840
  *
@@ -1847,7 +1850,7 @@ function macAddress(options) {
1847
1850
  * option("--root", domain({ allowSubdomains: false }))
1848
1851
  *
1849
1852
  * // Restrict to specific TLDs
1850
- * option("--domain", domain({ allowedTLDs: ["com", "org", "net"] }))
1853
+ * option("--domain", domain({ allowedTlds: ["com", "org", "net"] }))
1851
1854
  *
1852
1855
  * // Normalize to lowercase
1853
1856
  * option("--domain", domain({ lowercase: true }))
@@ -1858,7 +1861,19 @@ function macAddress(options) {
1858
1861
  function domain(options) {
1859
1862
  const metavar = options?.metavar ?? "DOMAIN";
1860
1863
  const allowSubdomains = options?.allowSubdomains ?? true;
1861
- const allowedTLDs = options?.allowedTLDs != null ? Object.freeze([...options.allowedTLDs]) : void 0;
1864
+ const allowedTlds = options?.allowedTlds != null ? Object.freeze([...options.allowedTlds]) : void 0;
1865
+ const labelRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
1866
+ if (allowedTlds !== void 0) for (const [i, tld] of allowedTlds.entries()) {
1867
+ if (typeof tld !== "string") {
1868
+ const actualType = Array.isArray(tld) ? "array" : typeof tld;
1869
+ throw new TypeError(`allowedTlds[${i}] must be a string, but got ${actualType}.`);
1870
+ }
1871
+ if (tld.length === 0) throw new TypeError(`allowedTlds[${i}] must not be an empty string.`);
1872
+ if (tld.includes(".")) throw new TypeError(`allowedTlds[${i}] must not contain dots: ${JSON.stringify(tld)}.`);
1873
+ if (tld !== tld.trim()) throw new TypeError(`allowedTlds[${i}] must not have leading or trailing whitespace: ${JSON.stringify(tld)}.`);
1874
+ if (!labelRegex.test(tld)) throw new TypeError(`allowedTlds[${i}] is not a valid DNS label: ${JSON.stringify(tld)}.`);
1875
+ }
1876
+ const allowedTldsLower = allowedTlds != null ? Object.freeze(allowedTlds.map((t) => t.toLowerCase())) : void 0;
1862
1877
  const minLabels = options?.minLabels ?? 2;
1863
1878
  const maxLength = options?.maxLength ?? 253;
1864
1879
  const lowercase = options?.lowercase ?? false;
@@ -1870,7 +1885,6 @@ function domain(options) {
1870
1885
  const tooFewLabels = options?.errors?.tooFewLabels;
1871
1886
  const subdomainsNotAllowed = options?.errors?.subdomainsNotAllowed;
1872
1887
  const tldNotAllowed = options?.errors?.tldNotAllowed;
1873
- const labelRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
1874
1888
  return {
1875
1889
  $mode: "sync",
1876
1890
  metavar,
@@ -2034,15 +2048,14 @@ function domain(options) {
2034
2048
  error: msg
2035
2049
  };
2036
2050
  }
2037
- if (allowedTLDs !== void 0) {
2051
+ if (allowedTlds !== void 0 && allowedTldsLower !== void 0) {
2038
2052
  const tld = labels[labels.length - 1];
2039
2053
  const tldLower = tld.toLowerCase();
2040
- const allowedTLDsLower = allowedTLDs.map((t) => t.toLowerCase());
2041
- if (!allowedTLDsLower.includes(tldLower)) {
2054
+ if (!allowedTldsLower.includes(tldLower)) {
2042
2055
  const errorMsg = tldNotAllowed;
2043
2056
  if (typeof errorMsg === "function") return {
2044
2057
  success: false,
2045
- error: errorMsg(tld, allowedTLDs)
2058
+ error: errorMsg(tld, allowedTlds)
2046
2059
  };
2047
2060
  const msg = errorMsg ?? [
2048
2061
  {
@@ -2055,7 +2068,7 @@ function domain(options) {
2055
2068
  },
2056
2069
  {
2057
2070
  type: "text",
2058
- text: ` is not allowed. Allowed TLDs: ${allowedTLDs.join(", ")}.`
2071
+ text: ` is not allowed. Allowed TLDs: ${allowedTlds.join(", ")}.`
2059
2072
  }
2060
2073
  ];
2061
2074
  return {
@@ -1479,7 +1479,7 @@ interface DomainOptions {
1479
1479
  * List of allowed top-level domains (e.g., ["com", "org", "net"]).
1480
1480
  * If specified, only domains with these TLDs are accepted.
1481
1481
  */
1482
- readonly allowedTLDs?: readonly string[];
1482
+ readonly allowedTlds?: readonly string[];
1483
1483
  /**
1484
1484
  * Minimum number of domain labels (parts separated by dots).
1485
1485
  *
@@ -1517,7 +1517,7 @@ interface DomainOptions {
1517
1517
  * Can be a static message or a function that receives the TLD
1518
1518
  * and allowed TLDs.
1519
1519
  */
1520
- tldNotAllowed?: Message | ((tld: string, allowedTLDs: readonly string[]) => Message);
1520
+ tldNotAllowed?: Message | ((tld: string, allowedTlds: readonly string[]) => Message);
1521
1521
  /**
1522
1522
  * Custom error message when domain has too few labels.
1523
1523
  * Can be a static message or a function that receives the domain
@@ -1544,6 +1544,9 @@ interface DomainOptions {
1544
1544
  * @returns A parser that accepts valid domain names as strings.
1545
1545
  * @throws {RangeError} If `maxLength` is not a positive integer.
1546
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.
1547
1550
  * @throws {TypeError} If `allowSubdomains` is `false` and `minLabels` is
1548
1551
  * greater than 2, since non-subdomain domains have exactly 2 labels.
1549
1552
  *
@@ -1559,7 +1562,7 @@ interface DomainOptions {
1559
1562
  * option("--root", domain({ allowSubdomains: false }))
1560
1563
  *
1561
1564
  * // Restrict to specific TLDs
1562
- * option("--domain", domain({ allowedTLDs: ["com", "org", "net"] }))
1565
+ * option("--domain", domain({ allowedTlds: ["com", "org", "net"] }))
1563
1566
  *
1564
1567
  * // Normalize to lowercase
1565
1568
  * option("--domain", domain({ lowercase: true }))
@@ -1479,7 +1479,7 @@ interface DomainOptions {
1479
1479
  * List of allowed top-level domains (e.g., ["com", "org", "net"]).
1480
1480
  * If specified, only domains with these TLDs are accepted.
1481
1481
  */
1482
- readonly allowedTLDs?: readonly string[];
1482
+ readonly allowedTlds?: readonly string[];
1483
1483
  /**
1484
1484
  * Minimum number of domain labels (parts separated by dots).
1485
1485
  *
@@ -1517,7 +1517,7 @@ interface DomainOptions {
1517
1517
  * Can be a static message or a function that receives the TLD
1518
1518
  * and allowed TLDs.
1519
1519
  */
1520
- tldNotAllowed?: Message | ((tld: string, allowedTLDs: readonly string[]) => Message);
1520
+ tldNotAllowed?: Message | ((tld: string, allowedTlds: readonly string[]) => Message);
1521
1521
  /**
1522
1522
  * Custom error message when domain has too few labels.
1523
1523
  * Can be a static message or a function that receives the domain
@@ -1544,6 +1544,9 @@ interface DomainOptions {
1544
1544
  * @returns A parser that accepts valid domain names as strings.
1545
1545
  * @throws {RangeError} If `maxLength` is not a positive integer.
1546
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.
1547
1550
  * @throws {TypeError} If `allowSubdomains` is `false` and `minLabels` is
1548
1551
  * greater than 2, since non-subdomain domains have exactly 2 labels.
1549
1552
  *
@@ -1559,7 +1562,7 @@ interface DomainOptions {
1559
1562
  * option("--root", domain({ allowSubdomains: false }))
1560
1563
  *
1561
1564
  * // Restrict to specific TLDs
1562
- * option("--domain", domain({ allowedTLDs: ["com", "org", "net"] }))
1565
+ * option("--domain", domain({ allowedTlds: ["com", "org", "net"] }))
1563
1566
  *
1564
1567
  * // Normalize to lowercase
1565
1568
  * option("--domain", domain({ lowercase: true }))
@@ -1832,6 +1832,9 @@ function macAddress(options) {
1832
1832
  * @returns A parser that accepts valid domain names as strings.
1833
1833
  * @throws {RangeError} If `maxLength` is not a positive integer.
1834
1834
  * @throws {RangeError} If `minLabels` is not a positive integer.
1835
+ * @throws {TypeError} If any `allowedTlds` entry is not a string, is empty,
1836
+ * contains dots, has leading/trailing whitespace, or is not a valid DNS
1837
+ * label.
1835
1838
  * @throws {TypeError} If `allowSubdomains` is `false` and `minLabels` is
1836
1839
  * greater than 2, since non-subdomain domains have exactly 2 labels.
1837
1840
  *
@@ -1847,7 +1850,7 @@ function macAddress(options) {
1847
1850
  * option("--root", domain({ allowSubdomains: false }))
1848
1851
  *
1849
1852
  * // Restrict to specific TLDs
1850
- * option("--domain", domain({ allowedTLDs: ["com", "org", "net"] }))
1853
+ * option("--domain", domain({ allowedTlds: ["com", "org", "net"] }))
1851
1854
  *
1852
1855
  * // Normalize to lowercase
1853
1856
  * option("--domain", domain({ lowercase: true }))
@@ -1858,7 +1861,19 @@ function macAddress(options) {
1858
1861
  function domain(options) {
1859
1862
  const metavar = options?.metavar ?? "DOMAIN";
1860
1863
  const allowSubdomains = options?.allowSubdomains ?? true;
1861
- const allowedTLDs = options?.allowedTLDs != null ? Object.freeze([...options.allowedTLDs]) : void 0;
1864
+ const allowedTlds = options?.allowedTlds != null ? Object.freeze([...options.allowedTlds]) : void 0;
1865
+ const labelRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
1866
+ if (allowedTlds !== void 0) for (const [i, tld] of allowedTlds.entries()) {
1867
+ if (typeof tld !== "string") {
1868
+ const actualType = Array.isArray(tld) ? "array" : typeof tld;
1869
+ throw new TypeError(`allowedTlds[${i}] must be a string, but got ${actualType}.`);
1870
+ }
1871
+ if (tld.length === 0) throw new TypeError(`allowedTlds[${i}] must not be an empty string.`);
1872
+ if (tld.includes(".")) throw new TypeError(`allowedTlds[${i}] must not contain dots: ${JSON.stringify(tld)}.`);
1873
+ if (tld !== tld.trim()) throw new TypeError(`allowedTlds[${i}] must not have leading or trailing whitespace: ${JSON.stringify(tld)}.`);
1874
+ if (!labelRegex.test(tld)) throw new TypeError(`allowedTlds[${i}] is not a valid DNS label: ${JSON.stringify(tld)}.`);
1875
+ }
1876
+ const allowedTldsLower = allowedTlds != null ? Object.freeze(allowedTlds.map((t) => t.toLowerCase())) : void 0;
1862
1877
  const minLabels = options?.minLabels ?? 2;
1863
1878
  const maxLength = options?.maxLength ?? 253;
1864
1879
  const lowercase = options?.lowercase ?? false;
@@ -1870,7 +1885,6 @@ function domain(options) {
1870
1885
  const tooFewLabels = options?.errors?.tooFewLabels;
1871
1886
  const subdomainsNotAllowed = options?.errors?.subdomainsNotAllowed;
1872
1887
  const tldNotAllowed = options?.errors?.tldNotAllowed;
1873
- const labelRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
1874
1888
  return {
1875
1889
  $mode: "sync",
1876
1890
  metavar,
@@ -2034,15 +2048,14 @@ function domain(options) {
2034
2048
  error: msg
2035
2049
  };
2036
2050
  }
2037
- if (allowedTLDs !== void 0) {
2051
+ if (allowedTlds !== void 0 && allowedTldsLower !== void 0) {
2038
2052
  const tld = labels[labels.length - 1];
2039
2053
  const tldLower = tld.toLowerCase();
2040
- const allowedTLDsLower = allowedTLDs.map((t) => t.toLowerCase());
2041
- if (!allowedTLDsLower.includes(tldLower)) {
2054
+ if (!allowedTldsLower.includes(tldLower)) {
2042
2055
  const errorMsg = tldNotAllowed;
2043
2056
  if (typeof errorMsg === "function") return {
2044
2057
  success: false,
2045
- error: errorMsg(tld, allowedTLDs)
2058
+ error: errorMsg(tld, allowedTlds)
2046
2059
  };
2047
2060
  const msg = errorMsg ?? [
2048
2061
  {
@@ -2055,7 +2068,7 @@ function domain(options) {
2055
2068
  },
2056
2069
  {
2057
2070
  type: "text",
2058
- text: ` is not allowed. Allowed TLDs: ${allowedTLDs.join(", ")}.`
2071
+ text: ` is not allowed. Allowed TLDs: ${allowedTlds.join(", ")}.`
2059
2072
  }
2060
2073
  ];
2061
2074
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.0-dev.1109+fa132665",
3
+ "version": "1.0.0-dev.1116+6084dd3a",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",