parse-domain 8.2.2 → 8.3.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 (114) hide show
  1. package/README.md +9 -68
  2. package/bin/update.js +7 -15
  3. package/{build → dist}/config.d.ts +1 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/{build → dist}/config.js +1 -1
  6. package/{build → dist}/config.js.map +1 -1
  7. package/{build → dist}/from-url.d.ts +1 -0
  8. package/dist/from-url.d.ts.map +1 -0
  9. package/{build → dist}/from-url.js +2 -2
  10. package/dist/from-url.js.map +1 -0
  11. package/dist/main.d.ts +6 -0
  12. package/dist/main.d.ts.map +1 -0
  13. package/dist/main.js +6 -0
  14. package/dist/main.js.map +1 -0
  15. package/{build → dist}/parse-domain.d.ts +30 -29
  16. package/dist/parse-domain.d.ts.map +1 -0
  17. package/{build → dist}/parse-domain.js +28 -16
  18. package/dist/parse-domain.js.map +1 -0
  19. package/{build → dist}/psl/build-tries.d.ts +1 -0
  20. package/dist/psl/build-tries.d.ts.map +1 -0
  21. package/{build → dist}/psl/build-tries.js +5 -5
  22. package/dist/psl/build-tries.js.map +1 -0
  23. package/{build → dist}/psl/fetch-psl.d.ts +1 -0
  24. package/dist/psl/fetch-psl.d.ts.map +1 -0
  25. package/dist/psl/fetch-psl.js +10 -0
  26. package/dist/psl/fetch-psl.js.map +1 -0
  27. package/{build → dist}/punycode.d.ts +1 -0
  28. package/dist/punycode.d.ts.map +1 -0
  29. package/{build → dist}/sanitize.d.ts +8 -7
  30. package/dist/sanitize.d.ts.map +1 -0
  31. package/{build → dist}/sanitize.js +12 -8
  32. package/dist/sanitize.js.map +1 -0
  33. package/dist/scripts/update-psl-fixture.d.ts +2 -0
  34. package/dist/scripts/update-psl-fixture.d.ts.map +1 -0
  35. package/dist/scripts/update-psl-fixture.js +7 -0
  36. package/dist/scripts/update-psl-fixture.js.map +1 -0
  37. package/dist/scripts/update-tries.d.ts +2 -0
  38. package/dist/scripts/update-tries.d.ts.map +1 -0
  39. package/dist/scripts/update-tries.js +26 -0
  40. package/dist/scripts/update-tries.js.map +1 -0
  41. package/dist/serialized-tries.d.ts +3 -0
  42. package/dist/serialized-tries.d.ts.map +1 -0
  43. package/dist/serialized-tries.js +3 -0
  44. package/dist/serialized-tries.js.map +1 -0
  45. package/{build → dist}/smoke-test.d.ts +1 -0
  46. package/dist/smoke-test.d.ts.map +1 -0
  47. package/{build → dist}/smoke-test.js +1 -1
  48. package/dist/smoke-test.js.map +1 -0
  49. package/{build → dist}/trie/characters.d.ts +1 -0
  50. package/dist/trie/characters.d.ts.map +1 -0
  51. package/{build → dist}/trie/create-trie.d.ts +1 -0
  52. package/dist/trie/create-trie.d.ts.map +1 -0
  53. package/{build → dist}/trie/create-trie.js +3 -1
  54. package/dist/trie/create-trie.js.map +1 -0
  55. package/dist/trie/look-up.d.ts +4 -0
  56. package/dist/trie/look-up.d.ts.map +1 -0
  57. package/{build → dist}/trie/look-up.js +2 -2
  58. package/dist/trie/look-up.js.map +1 -0
  59. package/{build → dist}/trie/nodes.d.ts +1 -0
  60. package/dist/trie/nodes.d.ts.map +1 -0
  61. package/{build → dist}/trie/parse-trie.d.ts +1 -0
  62. package/dist/trie/parse-trie.d.ts.map +1 -0
  63. package/{build → dist}/trie/parse-trie.js +1 -1
  64. package/dist/trie/parse-trie.js.map +1 -0
  65. package/dist/trie/serialize-trie.d.ts +3 -0
  66. package/dist/trie/serialize-trie.d.ts.map +1 -0
  67. package/{build → dist}/trie/serialize-trie.js +3 -3
  68. package/dist/trie/serialize-trie.js.map +1 -0
  69. package/{build → dist}/type-util.d.ts +1 -0
  70. package/dist/type-util.d.ts.map +1 -0
  71. package/dist/type-util.js +1 -0
  72. package/{build → dist}/update-tries.d.ts +1 -0
  73. package/dist/update-tries.d.ts.map +1 -0
  74. package/dist/update-tries.js +14 -0
  75. package/dist/update-tries.js.map +1 -0
  76. package/package.json +34 -36
  77. package/serialized-tries/icann.js +1 -1
  78. package/serialized-tries/info.json +1 -1
  79. package/serialized-tries/private.js +1 -1
  80. package/build/from-url.js.map +0 -1
  81. package/build/main.d.ts +0 -3
  82. package/build/main.js +0 -6
  83. package/build/main.js.map +0 -1
  84. package/build/parse-domain.js.map +0 -1
  85. package/build/psl/build-tries.js.map +0 -1
  86. package/build/psl/fetch-psl.js +0 -19
  87. package/build/psl/fetch-psl.js.map +0 -1
  88. package/build/sanitize.js.map +0 -1
  89. package/build/scripts/update-psl-fixture.d.ts +0 -1
  90. package/build/scripts/update-psl-fixture.js +0 -20
  91. package/build/scripts/update-psl-fixture.js.map +0 -1
  92. package/build/scripts/update-tries.d.ts +0 -1
  93. package/build/scripts/update-tries.js +0 -39
  94. package/build/scripts/update-tries.js.map +0 -1
  95. package/build/serialized-tries.d.ts +0 -3
  96. package/build/serialized-tries.js +0 -4
  97. package/build/serialized-tries.js.map +0 -1
  98. package/build/smoke-test.js.map +0 -1
  99. package/build/trie/create-trie.js.map +0 -1
  100. package/build/trie/look-up.d.ts +0 -3
  101. package/build/trie/look-up.js.map +0 -1
  102. package/build/trie/parse-trie.js.map +0 -1
  103. package/build/trie/serialize-trie.d.ts +0 -2
  104. package/build/trie/serialize-trie.js.map +0 -1
  105. package/build/type-util.js +0 -2
  106. package/build/update-tries.js +0 -23
  107. package/build/update-tries.js.map +0 -1
  108. /package/{build → dist}/punycode.js +0 -0
  109. /package/{build → dist}/punycode.js.map +0 -0
  110. /package/{build → dist}/trie/characters.js +0 -0
  111. /package/{build → dist}/trie/characters.js.map +0 -0
  112. /package/{build → dist}/trie/nodes.js +0 -0
  113. /package/{build → dist}/trie/nodes.js.map +0 -0
  114. /package/{build → dist}/type-util.js.map +0 -0
package/README.md CHANGED
@@ -63,7 +63,8 @@ npm install parse-domain
63
63
  There is the utility function [`fromUrl`](#api-js-fromUrl) which tries to extract the hostname from a (partial) URL and puny-encodes it:
64
64
 
65
65
  ```javascript
66
- import { parseDomain, fromUrl } from "parse-domain";
66
+ import { toUnicode } from "punycode";
67
+ import { fromUrl, parseDomain } from "parse-domain";
67
68
 
68
69
  const { subDomains, domain, topLevelDomains } = parseDomain(
69
70
  fromUrl("https://www.münchen.de?query"),
@@ -74,8 +75,6 @@ console.log(domain); // "xn--mnchen-3ya"
74
75
  console.log(topLevelDomains); // ["de"]
75
76
 
76
77
  // You can use the 'punycode' NPM package to decode the domain again
77
- import { toUnicode } from "punycode";
78
-
79
78
  console.log(toUnicode(domain)); // "münchen"
80
79
  ```
81
80
 
@@ -326,9 +325,7 @@ Takes a URL-like string and tries to extract the hostname. Requires the global [
326
325
 
327
326
  ```ts
328
327
  export type ParseDomainOptions = {
329
- /**
330
- * If no validation is specified, Validation.Strict will be used.
331
- **/
328
+ /** If no validation is specified, Validation.Strict will be used. */
332
329
  validation?: Validation;
333
330
  };
334
331
  ```
@@ -342,17 +339,17 @@ An object that holds all possible [Validation](#api-ts-Validation) `validation`
342
339
  ```javascript
343
340
  export const Validation = {
344
341
  /**
345
- * Allows any octets as labels
346
- * but still restricts the length of labels and the overall domain.
342
+ * Allows any octets as labels but still restricts the length of labels and
343
+ * the overall domain.
347
344
  *
348
345
  * @see https://www.rfc-editor.org/rfc/rfc2181#section-11
349
- **/
346
+ */
350
347
  Lax: "LAX",
351
348
 
352
349
  /**
353
- * Only allows ASCII letters, digits and hyphens (aka LDH),
354
- * forbids hyphens at the beginning or end of a label
355
- * and requires top-level domain names not to be all-numeric.
350
+ * Only allows ASCII letters, digits and hyphens (aka LDH), forbids hyphens at
351
+ * the beginning or end of a label and requires top-level domain names not to
352
+ * be all-numeric.
356
353
  *
357
354
  * This is the default if no validation is configured.
358
355
  *
@@ -418,14 +415,6 @@ type ParseResultInvalid = {
418
415
  hostname: string | typeof NO_HOSTNAME;
419
416
  errors: Array<ValidationError>;
420
417
  };
421
-
422
- // Example
423
-
424
- {
425
- type: "INVALID",
426
- hostname: ".com",
427
- errors: [...]
428
- }
429
418
  ```
430
419
 
431
420
  <h3 id="api-ts-ValidationError">
@@ -440,14 +429,6 @@ type ValidationError = {
440
429
  message: string;
441
430
  column: number;
442
431
  };
443
-
444
- // Example
445
-
446
- {
447
- type: "LABEL_MIN_LENGTH",
448
- message: `Label "" is too short. Label is 0 octets long but should be at least 1.`,
449
- column: 1,
450
- }
451
432
  ```
452
433
 
453
434
  <h3 id="api-js-ValidationErrorType">
@@ -485,14 +466,6 @@ type ParseResultIp = {
485
466
  hostname: string;
486
467
  ipVersion: 4 | 6;
487
468
  };
488
-
489
- // Example
490
-
491
- {
492
- type: "IP",
493
- hostname: "192.168.0.1",
494
- ipVersion: 4
495
- }
496
469
  ```
497
470
 
498
471
  According to [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3.2.2), IPv6 addresses need to be surrounded by `[` and `]` in URLs. [`parseDomain`](#api-js-parseDomain) accepts both IPv6 address with and without square brackets:
@@ -520,14 +493,6 @@ type ParseResultReserved = {
520
493
  hostname: string;
521
494
  labels: Array<string>;
522
495
  };
523
-
524
- // Example
525
-
526
- {
527
- type: "RESERVED",
528
- hostname: "pecorino.local",
529
- labels: ["pecorino", "local"]
530
- }
531
496
  ```
532
497
 
533
498
  ⚠️ Reserved IPs, such as `127.0.0.1`, will not be reported as reserved, but as <a href="#-export-parseresultip">`ParseResultIp`</a>. See [#117](https://github.com/peerigon/parse-domain/issues/117).
@@ -544,14 +509,6 @@ type ParseResultNotListed = {
544
509
  hostname: string;
545
510
  labels: Array<string>;
546
511
  };
547
-
548
- // Example
549
-
550
- {
551
- type: "NOT_LISTED",
552
- hostname: "this.is.not-listed",
553
- labels: ["this", "is", "not-listed"]
554
- }
555
512
  ```
556
513
 
557
514
  <h3 id="api-ts-ParseResultListed">
@@ -574,22 +531,6 @@ type ParseResultListed = {
574
531
  topLevelDomains: Array<string>;
575
532
  };
576
533
  };
577
-
578
- // Example
579
-
580
- {
581
- type: "LISTED",
582
- hostname: "parse-domain.github.io",
583
- labels: ["parse-domain", "github", "io"]
584
- subDomains: [],
585
- domain: "parse-domain",
586
- topLevelDomains: ["github", "io"],
587
- icann: {
588
- subDomains: ["parse-domain"],
589
- domain: "github",
590
- topLevelDomains: ["io"]
591
- }
592
- }
593
534
  ```
594
535
 
595
536
  ## License
package/bin/update.js CHANGED
@@ -1,22 +1,14 @@
1
1
  #!/usr/bin/env node
2
+ import { EOL } from "node:os";
2
3
 
3
- import { EOL } from "os";
4
+ process.argv.push("--", "../../serialized-tries");
4
5
 
5
- (async () => {
6
- process.argv.push("--", "../../serialized-tries");
6
+ await import("../dist/scripts/update-tries.js");
7
7
 
8
- const updateTries = await import("../build/scripts/update-tries.js");
8
+ process.stderr.write("Running smoke test... ");
9
9
 
10
- await updateTries.done;
10
+ const { runSmokeTest } = await import("../dist/smoke-test.js");
11
11
 
12
- process.stderr.write("Running smoke test... ");
12
+ runSmokeTest();
13
13
 
14
- const smokeTest = await import("../build/smoke-test.js");
15
-
16
- smokeTest.runSmokeTest();
17
-
18
- process.stdout.write("ok" + EOL);
19
- })().catch((error) => {
20
- console.error(`parse-domain update failed: ${error}`);
21
- process.exit(1);
22
- });
14
+ process.stdout.write("ok" + EOL);
@@ -4,3 +4,4 @@ export declare const PUBLIC_SUFFIX_MARKER_ICANN_END = "// ===END ICANN DOMAINS==
4
4
  export declare const PUBLIC_SUFFIX_MARKER_PRIVATE_START = "// ===BEGIN PRIVATE DOMAINS===";
5
5
  export declare const PUBLIC_SUFFIX_MARKER_PRIVATE_END = "// ===END PRIVATE DOMAINS===";
6
6
  export declare const FETCH_PSL_EXPECTED_MIN_LENGTH = 313150;
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,yDAC0B,CAAC;AACzD,eAAO,MAAM,gCAAgC,iCAAiC,CAAC;AAC/E,eAAO,MAAM,8BAA8B,+BAA+B,CAAC;AAC3E,eAAO,MAAM,kCAAkC,mCACb,CAAC;AACnC,eAAO,MAAM,gCAAgC,iCAAiC,CAAC;AAC/E,eAAO,MAAM,6BAA6B,SAAU,CAAC"}
@@ -3,5 +3,5 @@ export const PUBLIC_SUFFIX_MARKER_ICANN_START = "// ===BEGIN ICANN DOMAINS===";
3
3
  export const PUBLIC_SUFFIX_MARKER_ICANN_END = "// ===END ICANN DOMAINS===";
4
4
  export const PUBLIC_SUFFIX_MARKER_PRIVATE_START = "// ===BEGIN PRIVATE DOMAINS===";
5
5
  export const PUBLIC_SUFFIX_MARKER_PRIVATE_END = "// ===END PRIVATE DOMAINS===";
6
- export const FETCH_PSL_EXPECTED_MIN_LENGTH = 313150;
6
+ export const FETCH_PSL_EXPECTED_MIN_LENGTH = 313_150;
7
7
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAC5B,sDAAsD,CAAC;AACzD,MAAM,CAAC,MAAM,gCAAgC,GAAG,8BAA8B,CAAC;AAC/E,MAAM,CAAC,MAAM,8BAA8B,GAAG,4BAA4B,CAAC;AAC3E,MAAM,CAAC,MAAM,kCAAkC,GAC7C,gCAAgC,CAAC;AACnC,MAAM,CAAC,MAAM,gCAAgC,GAAG,8BAA8B,CAAC;AAC/E,MAAM,CAAC,MAAM,6BAA6B,GAAG,MAAM,CAAC","sourcesContent":["export const PUBLIC_SUFFIX_URL =\n \"https://publicsuffix.org/list/public_suffix_list.dat\";\nexport const PUBLIC_SUFFIX_MARKER_ICANN_START = \"// ===BEGIN ICANN DOMAINS===\";\nexport const PUBLIC_SUFFIX_MARKER_ICANN_END = \"// ===END ICANN DOMAINS===\";\nexport const PUBLIC_SUFFIX_MARKER_PRIVATE_START =\n \"// ===BEGIN PRIVATE DOMAINS===\";\nexport const PUBLIC_SUFFIX_MARKER_PRIVATE_END = \"// ===END PRIVATE DOMAINS===\";\nexport const FETCH_PSL_EXPECTED_MIN_LENGTH = 313150;\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAC5B,sDAAsD,CAAC;AACzD,MAAM,CAAC,MAAM,gCAAgC,GAAG,8BAA8B,CAAC;AAC/E,MAAM,CAAC,MAAM,8BAA8B,GAAG,4BAA4B,CAAC;AAC3E,MAAM,CAAC,MAAM,kCAAkC,GAC7C,gCAAgC,CAAC;AACnC,MAAM,CAAC,MAAM,gCAAgC,GAAG,8BAA8B,CAAC;AAC/E,MAAM,CAAC,MAAM,6BAA6B,GAAG,OAAO,CAAC","sourcesContent":["export const PUBLIC_SUFFIX_URL =\n \"https://publicsuffix.org/list/public_suffix_list.dat\";\nexport const PUBLIC_SUFFIX_MARKER_ICANN_START = \"// ===BEGIN ICANN DOMAINS===\";\nexport const PUBLIC_SUFFIX_MARKER_ICANN_END = \"// ===END ICANN DOMAINS===\";\nexport const PUBLIC_SUFFIX_MARKER_PRIVATE_START =\n \"// ===BEGIN PRIVATE DOMAINS===\";\nexport const PUBLIC_SUFFIX_MARKER_PRIVATE_END = \"// ===END PRIVATE DOMAINS===\";\nexport const FETCH_PSL_EXPECTED_MIN_LENGTH = 313_150;\n"]}
@@ -1,2 +1,3 @@
1
1
  export declare const NO_HOSTNAME: unique symbol;
2
2
  export declare const fromUrl: (urlLike: string) => string | typeof NO_HOSTNAME;
3
+ //# sourceMappingURL=from-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-url.d.ts","sourceRoot":"","sources":["../src/from-url.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,EAAE,OAAO,MAA8B,CAAC;AAEhE,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,KAAG,MAAM,GAAG,OAAO,WA8BzD,CAAC"}
@@ -4,7 +4,7 @@ export const NO_HOSTNAME = Symbol("NO_HOSTNAME");
4
4
  export const fromUrl = (urlLike) => {
5
5
  /* istanbul ignore next */
6
6
  if (typeof URL !== "function") {
7
- throw new Error("Looks like the new URL() constructor is not globally available in your environment. Please make sure to use a polyfill.");
7
+ throw new TypeError("Looks like the new URL() constructor is not globally available in your environment. Please make sure to use a polyfill.");
8
8
  }
9
9
  // Extra check for non-TypeScript users
10
10
  if (typeof urlLike !== "string") {
@@ -23,7 +23,7 @@ export const fromUrl = (urlLike) => {
23
23
  try {
24
24
  return new URL(url).hostname;
25
25
  }
26
- catch (_a) {
26
+ catch {
27
27
  return NO_HOSTNAME;
28
28
  }
29
29
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-url.js","sourceRoot":"","sources":["../src/from-url.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,wBAAwB,CAAC;AAC5C,MAAM,kBAAkB,GACtB,wDAAwD,CAAC;AAE3D,MAAM,CAAC,MAAM,WAAW,GAAkB,MAAM,CAAC,aAAa,CAAC,CAAC;AAEhE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,OAAe,EAA+B,EAAE;IACtE,0BAA0B;IAC1B,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;QAC9B,MAAM,IAAI,SAAS,CACjB,yHAAyH,CAC1H,CAAC;IACJ,CAAC;IAED,uCAAuC;IACvC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,gDAAgD;IAChD,IAAI,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;QAChC,CAAC,CAAC,QAAQ,OAAO,EAAE;QACnB,CAAC,CAAC,wDAAwD;YACxD,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;gBACvB,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;oBACxB,CAAC,CAAC,OAAO;oBACT,CAAC,CAAC,UAAU,OAAO,EAAE,CAAC;IAE5B,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;IAElD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC,CAAC","sourcesContent":["const urlPattern = /^[a-z][*+.a-z-]+:\\/\\//i;\nconst invalidIpv6Pattern =\n /^([a-z][*+.a-z-]+:\\/\\/)([^[][^/?]*:[^/?]*:[^/?]*)(.*)/i;\n\nexport const NO_HOSTNAME: unique symbol = Symbol(\"NO_HOSTNAME\");\n\nexport const fromUrl = (urlLike: string): string | typeof NO_HOSTNAME => {\n /* istanbul ignore next */\n if (typeof URL !== \"function\") {\n throw new TypeError(\n \"Looks like the new URL() constructor is not globally available in your environment. Please make sure to use a polyfill.\",\n );\n }\n\n // Extra check for non-TypeScript users\n if (typeof urlLike !== \"string\") {\n return NO_HOSTNAME;\n }\n\n // URLs that start with // are protocol relative\n let url = urlLike.startsWith(\"//\")\n ? `http:${urlLike}`\n : // URLs that start with / do not have a hostname section\n urlLike.startsWith(\"/\")\n ? urlLike\n : urlPattern.test(urlLike)\n ? urlLike\n : `http://${urlLike}`;\n\n url = url.replace(invalidIpv6Pattern, \"$1[$2]$3\");\n\n try {\n return new URL(url).hostname;\n } catch {\n return NO_HOSTNAME;\n }\n};\n"]}
package/dist/main.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { parseDomain, ParseResultType } from "./parse-domain.js";
2
+ export type { ParseResult, ParseResultInvalid, ParseResultReserved, ParseResultNotListed, ParseResultListed, ParseResultIp, } from "./parse-domain.js";
3
+ export { fromUrl, NO_HOSTNAME } from "./from-url.js";
4
+ export { Validation, ValidationErrorType } from "./sanitize.js";
5
+ export type { ValidationError } from "./sanitize.js";
6
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
package/dist/main.js ADDED
@@ -0,0 +1,6 @@
1
+ /* istanbul ignore file */
2
+ // Jest will report function coverage errors here otherwise
3
+ export { parseDomain, ParseResultType } from "./parse-domain.js";
4
+ export { fromUrl, NO_HOSTNAME } from "./from-url.js";
5
+ export { Validation, ValidationErrorType } from "./sanitize.js";
6
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,2DAA2D;AAC3D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASjE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC","sourcesContent":["/* istanbul ignore file */\n// Jest will report function coverage errors here otherwise\nexport { parseDomain, ParseResultType } from \"./parse-domain.js\";\nexport type {\n ParseResult,\n ParseResultInvalid,\n ParseResultReserved,\n ParseResultNotListed,\n ParseResultListed,\n ParseResultIp,\n} from \"./parse-domain.js\";\nexport { fromUrl, NO_HOSTNAME } from \"./from-url.js\";\nexport { Validation, ValidationErrorType } from \"./sanitize.js\";\nexport type { ValidationError } from \"./sanitize.js\";\n"]}
@@ -1,50 +1,52 @@
1
- import { ValidationError, SanitizationResultValidIp, Validation } from "./sanitize.js";
2
1
  import { NO_HOSTNAME } from "./from-url.js";
2
+ import { Validation, type SanitizationResultValidIp, type ValidationError } from "./sanitize.js";
3
3
  export declare const RESERVED_TOP_LEVEL_DOMAINS: string[];
4
4
  export type Label = string;
5
5
  export declare enum ParseResultType {
6
6
  /**
7
- * This parse result is returned in case the given hostname does not adhere to [RFC 1034](https://tools.ietf.org/html/rfc1034).
7
+ * This parse result is returned in case the given hostname does not adhere to
8
+ * [RFC 1034](https://tools.ietf.org/html/rfc1034).
8
9
  */
9
10
  Invalid = "INVALID",
10
- /**
11
- * This parse result is returned if the given hostname was an IPv4 or IPv6.
12
- */
11
+ /** This parse result is returned if the given hostname was an IPv4 or IPv6. */
13
12
  Ip = "IP",
14
13
  /**
15
14
  * This parse result is returned when the given hostname
16
- * - is the root domain (the empty string `""`)
17
- * - belongs to the top-level domain `localhost`, `local`, `example`, `invalid` or `test`
15
+ *
16
+ * - Is the root domain (the empty string `""`)
17
+ * - Belongs to the top-level domain `localhost`, `local`, `example`, `invalid`
18
+ * or `test`
18
19
  */
19
20
  Reserved = "RESERVED",
20
21
  /**
21
- * This parse result is returned when the given hostname is valid and does not belong to a reserved top-level domain, but is not listed in the public suffix list.
22
+ * This parse result is returned when the given hostname is valid and does not
23
+ * belong to a reserved top-level domain, but is not listed in the public
24
+ * suffix list.
22
25
  */
23
26
  NotListed = "NOT_LISTED",
24
27
  /**
25
- * This parse result is returned when the given hostname belongs to a top-level domain that is listed in the public suffix list.
28
+ * This parse result is returned when the given hostname belongs to a
29
+ * top-level domain that is listed in the public suffix list.
26
30
  */
27
31
  Listed = "LISTED"
28
32
  }
29
33
  type ParseResultCommon<Type extends ParseResultType> = {
30
34
  /**
31
- * The type of the parse result. Use switch or if to distinguish between different results.
35
+ * The type of the parse result. Use switch or if to distinguish between
36
+ * different results.
32
37
  */
33
38
  type: Type;
34
- /**
35
- * The original hostname that was passed to parseDomain().
36
- */
39
+ /** The original hostname that was passed to parseDomain(). */
37
40
  hostname: Type extends ParseResultType.Invalid ? string | typeof NO_HOSTNAME : string;
38
41
  };
39
42
  export type ParseResultInvalid = ParseResultCommon<ParseResultType.Invalid> & {
40
- /**
41
- * An array of validation errors.
42
- */
43
+ /** An array of validation errors. */
43
44
  errors: Array<ValidationError>;
44
45
  };
45
46
  type ParseResultCommonValidDomain = {
46
47
  /**
47
- * An array of labels that were separated by a dot character in the given hostname.
48
+ * An array of labels that were separated by a dot character in the given
49
+ * hostname.
48
50
  */
49
51
  labels: Array<Label>;
50
52
  };
@@ -53,33 +55,32 @@ export type ParseResultReserved = ParseResultCommon<ParseResultType.Reserved> &
53
55
  export type ParseResultNotListed = ParseResultCommon<ParseResultType.NotListed> & ParseResultCommonValidDomain;
54
56
  type ParseResultListedDomains = {
55
57
  /**
56
- * An array of labels that belong to the subdomain. Can be empty if there was no subdomain in the given hostname.
58
+ * An array of labels that belong to the subdomain. Can be empty if there was
59
+ * no subdomain in the given hostname.
57
60
  */
58
61
  subDomains: Array<Label>;
59
62
  /**
60
- * The first label that belongs to the user-controlled section of the hostname. Can be undefined if just a top-level domain was passed to parseDomain().
63
+ * The first label that belongs to the user-controlled section of the
64
+ * hostname. Can be undefined if just a top-level domain was passed to
65
+ * parseDomain().
61
66
  */
62
67
  domain: Label | undefined;
63
- /**
64
- * An array of labels that are controlled by the domain registrar.
65
- */
68
+ /** An array of labels that are controlled by the domain registrar. */
66
69
  topLevelDomains: Array<Label>;
67
70
  };
68
71
  export type ParseResultListed = ParseResultCommon<ParseResultType.Listed> & ParseResultCommonValidDomain & ParseResultListedDomains & {
69
72
  /**
70
- * The parse result according to ICANN only without private top-level domains.
73
+ * The parse result according to ICANN only without private top-level
74
+ * domains.
71
75
  */
72
76
  icann: ParseResultListedDomains;
73
77
  };
74
78
  export type ParseResult = ParseResultInvalid | ParseResultIp | ParseResultReserved | ParseResultNotListed | ParseResultListed;
75
79
  export type ParseDomainOptions = {
76
- /**
77
- * If no validation is specified, Validation.Strict will be used.
78
- **/
80
+ /** If no validation is specified, Validation.Strict will be used. */
79
81
  validation?: Validation;
80
82
  };
81
- /**
82
- * Splits the given hostname in topLevelDomains, a domain and subDomains.
83
- */
83
+ /** Splits the given hostname in topLevelDomains, a domain and subDomains. */
84
84
  export declare const parseDomain: (hostname: string | typeof NO_HOSTNAME, options?: ParseDomainOptions) => ParseResult;
85
85
  export {};
86
+ //# sourceMappingURL=parse-domain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-domain.d.ts","sourceRoot":"","sources":["../src/parse-domain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAGL,UAAU,EACV,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAMvB,eAAO,MAAM,0BAA0B,UAMtC,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC;AAE3B,oBAAY,eAAe;IACzB;;;OAGG;IACH,OAAO,YAAY;IACnB,+EAA+E;IAC/E,EAAE,OAAO;IACT;;;;;;OAMG;IACH,QAAQ,aAAa;IACrB;;;;OAIG;IACH,SAAS,eAAe;IACxB;;;OAGG;IACH,MAAM,WAAW;CAClB;AAMD,KAAK,iBAAiB,CAAC,IAAI,SAAS,eAAe,IAAI;IACrD;;;OAGG;IACH,IAAI,EAAE,IAAI,CAAC;IACX,8DAA8D;IAC9D,QAAQ,EAAE,IAAI,SAAS,eAAe,CAAC,OAAO,GAC1C,MAAM,GAAG,OAAO,WAAW,GAC3B,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG;IAC5E,qCAAqC;IACrC,MAAM,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;CAChC,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAClC;;;OAGG;IACH,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC,eAAe,CAAC,EAAE,CAAC,GAC/D,IAAI,CAAC,yBAAyB,EAAE,WAAW,CAAC,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,eAAe,CAAC,QAAQ,CAAC,GAC3E,4BAA4B,CAAC;AAE/B,MAAM,MAAM,oBAAoB,GAC9B,iBAAiB,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,4BAA4B,CAAC;AAE9E,KAAK,wBAAwB,GAAG;IAC9B;;;OAGG;IACH,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB;;;;OAIG;IACH,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC;IAC1B,sEAAsE;IACtE,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,eAAe,CAAC,MAAM,CAAC,GACvE,4BAA4B,GAC5B,wBAAwB,GAAG;IACzB;;;OAGG;IACH,KAAK,EAAE,wBAAwB,CAAC;CACjC,CAAC;AAEJ,MAAM,MAAM,WAAW,GACnB,kBAAkB,GAClB,aAAa,GACb,mBAAmB,GACnB,oBAAoB,GACpB,iBAAiB,CAAC;AAuBtB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,qEAAqE;IACrE,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,WAAW,GACtB,UAAU,MAAM,GAAG,OAAO,WAAW,EACrC,UAAU,kBAAkB,KAC3B,WA8DF,CAAC"}
@@ -1,6 +1,7 @@
1
+ import { NO_HOSTNAME } from "./from-url.js";
2
+ import { SanitizationResultType, sanitize, Validation, } from "./sanitize.js";
1
3
  import { icannTrie, privateTrie } from "./serialized-tries.js";
2
4
  import { lookUpTldsInTrie } from "./trie/look-up.js";
3
- import { sanitize, SanitizationResultType, } from "./sanitize.js";
4
5
  import { parseTrie } from "./trie/parse-trie.js";
5
6
  export const RESERVED_TOP_LEVEL_DOMAINS = [
6
7
  "localhost",
@@ -12,25 +13,29 @@ export const RESERVED_TOP_LEVEL_DOMAINS = [
12
13
  export var ParseResultType;
13
14
  (function (ParseResultType) {
14
15
  /**
15
- * This parse result is returned in case the given hostname does not adhere to [RFC 1034](https://tools.ietf.org/html/rfc1034).
16
+ * This parse result is returned in case the given hostname does not adhere to
17
+ * [RFC 1034](https://tools.ietf.org/html/rfc1034).
16
18
  */
17
19
  ParseResultType["Invalid"] = "INVALID";
18
- /**
19
- * This parse result is returned if the given hostname was an IPv4 or IPv6.
20
- */
20
+ /** This parse result is returned if the given hostname was an IPv4 or IPv6. */
21
21
  ParseResultType["Ip"] = "IP";
22
22
  /**
23
23
  * This parse result is returned when the given hostname
24
- * - is the root domain (the empty string `""`)
25
- * - belongs to the top-level domain `localhost`, `local`, `example`, `invalid` or `test`
24
+ *
25
+ * - Is the root domain (the empty string `""`)
26
+ * - Belongs to the top-level domain `localhost`, `local`, `example`, `invalid`
27
+ * or `test`
26
28
  */
27
29
  ParseResultType["Reserved"] = "RESERVED";
28
30
  /**
29
- * This parse result is returned when the given hostname is valid and does not belong to a reserved top-level domain, but is not listed in the public suffix list.
31
+ * This parse result is returned when the given hostname is valid and does not
32
+ * belong to a reserved top-level domain, but is not listed in the public
33
+ * suffix list.
30
34
  */
31
35
  ParseResultType["NotListed"] = "NOT_LISTED";
32
36
  /**
33
- * This parse result is returned when the given hostname belongs to a top-level domain that is listed in the public suffix list.
37
+ * This parse result is returned when the given hostname belongs to a
38
+ * top-level domain that is listed in the public suffix list.
34
39
  */
35
40
  ParseResultType["Listed"] = "LISTED";
36
41
  })(ParseResultType || (ParseResultType = {}));
@@ -46,9 +51,7 @@ const splitLabelsIntoDomains = (labels, index) => {
46
51
  };
47
52
  let parsedIcannTrie;
48
53
  let parsedPrivateTrie;
49
- /**
50
- * Splits the given hostname in topLevelDomains, a domain and subDomains.
51
- */
54
+ /** Splits the given hostname in topLevelDomains, a domain and subDomains. */
52
55
  export const parseDomain = (hostname, options) => {
53
56
  const sanitizationResult = sanitize(hostname, options);
54
57
  if (sanitizationResult.type === SanitizationResultType.Error) {
@@ -66,8 +69,11 @@ export const parseDomain = (hostname, options) => {
66
69
  };
67
70
  }
68
71
  const { labels, domain } = sanitizationResult;
72
+ // We do not want to break compatibility with older engines unnecessarily.
73
+ // eslint-disable-next-line unicorn/prefer-at
74
+ const lastLabel = labels[labels.length - 1];
69
75
  if (hostname === "" ||
70
- RESERVED_TOP_LEVEL_DOMAINS.includes(labels[labels.length - 1])) {
76
+ (lastLabel !== undefined && RESERVED_TOP_LEVEL_DOMAINS.includes(lastLabel))) {
71
77
  return {
72
78
  type: ParseResultType.Reserved,
73
79
  hostname: domain,
@@ -75,8 +81,8 @@ export const parseDomain = (hostname, options) => {
75
81
  };
76
82
  }
77
83
  // Parse the serialized trie lazily
78
- parsedIcannTrie = parsedIcannTrie !== null && parsedIcannTrie !== void 0 ? parsedIcannTrie : parseTrie(icannTrie);
79
- parsedPrivateTrie = parsedPrivateTrie !== null && parsedPrivateTrie !== void 0 ? parsedPrivateTrie : parseTrie(privateTrie);
84
+ parsedIcannTrie = parsedIcannTrie ?? parseTrie(icannTrie);
85
+ parsedPrivateTrie = parsedPrivateTrie ?? parseTrie(privateTrie);
80
86
  const icannTlds = lookUpTldsInTrie(labels, parsedIcannTrie);
81
87
  const privateTlds = lookUpTldsInTrie(labels, parsedPrivateTrie);
82
88
  if (icannTlds.length === 0 && privateTlds.length === 0) {
@@ -88,6 +94,12 @@ export const parseDomain = (hostname, options) => {
88
94
  }
89
95
  const indexOfPublicSuffixDomain = labels.length - Math.max(privateTlds.length, icannTlds.length) - 1;
90
96
  const indexOfIcannDomain = labels.length - icannTlds.length - 1;
91
- return Object.assign({ type: ParseResultType.Listed, hostname: domain, labels, icann: splitLabelsIntoDomains(labels, indexOfIcannDomain) }, splitLabelsIntoDomains(labels, indexOfPublicSuffixDomain));
97
+ return {
98
+ type: ParseResultType.Listed,
99
+ hostname: domain,
100
+ labels,
101
+ icann: splitLabelsIntoDomains(labels, indexOfIcannDomain),
102
+ ...splitLabelsIntoDomains(labels, indexOfPublicSuffixDomain),
103
+ };
92
104
  };
93
105
  //# sourceMappingURL=parse-domain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-domain.js","sourceRoot":"","sources":["../src/parse-domain.ts"],"names":[],"mappings":"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","sourcesContent":["import { NO_HOSTNAME } from \"./from-url.js\";\nimport {\n SanitizationResultType,\n sanitize,\n Validation,\n type SanitizationResultValidIp,\n type ValidationError,\n} from \"./sanitize.js\";\nimport { icannTrie, privateTrie } from \"./serialized-tries.js\";\nimport { lookUpTldsInTrie } from \"./trie/look-up.js\";\nimport type { TrieRootNode } from \"./trie/nodes.js\";\nimport { parseTrie } from \"./trie/parse-trie.js\";\n\nexport const RESERVED_TOP_LEVEL_DOMAINS = [\n \"localhost\",\n \"local\",\n \"example\",\n \"invalid\",\n \"test\",\n];\n\nexport type Label = string;\n\nexport enum ParseResultType {\n /**\n * This parse result is returned in case the given hostname does not adhere to\n * [RFC 1034](https://tools.ietf.org/html/rfc1034).\n */\n Invalid = \"INVALID\",\n /** This parse result is returned if the given hostname was an IPv4 or IPv6. */\n Ip = \"IP\",\n /**\n * This parse result is returned when the given hostname\n *\n * - Is the root domain (the empty string `\"\"`)\n * - Belongs to the top-level domain `localhost`, `local`, `example`, `invalid`\n * or `test`\n */\n Reserved = \"RESERVED\",\n /**\n * This parse result is returned when the given hostname is valid and does not\n * belong to a reserved top-level domain, but is not listed in the public\n * suffix list.\n */\n NotListed = \"NOT_LISTED\",\n /**\n * This parse result is returned when the given hostname belongs to a\n * top-level domain that is listed in the public suffix list.\n */\n Listed = \"LISTED\",\n}\n\n// The following parse result types are organized in this complicated way\n// way because every property should only be described by a single JSDoc comment.\n// If we copy the types (hence duplicating the shared properties),\n// JSDoc comments would show up duplicated in the final return type as well.\ntype ParseResultCommon<Type extends ParseResultType> = {\n /**\n * The type of the parse result. Use switch or if to distinguish between\n * different results.\n */\n type: Type;\n /** The original hostname that was passed to parseDomain(). */\n hostname: Type extends ParseResultType.Invalid\n ? string | typeof NO_HOSTNAME\n : string;\n};\n\nexport type ParseResultInvalid = ParseResultCommon<ParseResultType.Invalid> & {\n /** An array of validation errors. */\n errors: Array<ValidationError>;\n};\n\ntype ParseResultCommonValidDomain = {\n /**\n * An array of labels that were separated by a dot character in the given\n * hostname.\n */\n labels: Array<Label>;\n};\n\nexport type ParseResultIp = ParseResultCommon<ParseResultType.Ip> &\n Pick<SanitizationResultValidIp, \"ipVersion\">;\n\nexport type ParseResultReserved = ParseResultCommon<ParseResultType.Reserved> &\n ParseResultCommonValidDomain;\n\nexport type ParseResultNotListed =\n ParseResultCommon<ParseResultType.NotListed> & ParseResultCommonValidDomain;\n\ntype ParseResultListedDomains = {\n /**\n * An array of labels that belong to the subdomain. Can be empty if there was\n * no subdomain in the given hostname.\n */\n subDomains: Array<Label>;\n /**\n * The first label that belongs to the user-controlled section of the\n * hostname. Can be undefined if just a top-level domain was passed to\n * parseDomain().\n */\n domain: Label | undefined;\n /** An array of labels that are controlled by the domain registrar. */\n topLevelDomains: Array<Label>;\n};\n\nexport type ParseResultListed = ParseResultCommon<ParseResultType.Listed> &\n ParseResultCommonValidDomain &\n ParseResultListedDomains & {\n /**\n * The parse result according to ICANN only without private top-level\n * domains.\n */\n icann: ParseResultListedDomains;\n };\n\nexport type ParseResult =\n | ParseResultInvalid\n | ParseResultIp\n | ParseResultReserved\n | ParseResultNotListed\n | ParseResultListed;\n\nconst getAtIndex = <Item>(\n array: Array<Item>,\n index: number,\n): Item | undefined => {\n return index >= 0 && index < array.length ? array[index] : undefined;\n};\n\nconst splitLabelsIntoDomains = (\n labels: Array<Label>,\n index: number,\n): ParseResultListedDomains => {\n return {\n subDomains: labels.slice(0, Math.max(0, index)),\n domain: getAtIndex(labels, index),\n topLevelDomains: labels.slice(index + 1),\n };\n};\n\nlet parsedIcannTrie: TrieRootNode | undefined;\nlet parsedPrivateTrie: TrieRootNode | undefined;\n\nexport type ParseDomainOptions = {\n /** If no validation is specified, Validation.Strict will be used. */\n validation?: Validation;\n};\n\n/** Splits the given hostname in topLevelDomains, a domain and subDomains. */\nexport const parseDomain = (\n hostname: string | typeof NO_HOSTNAME,\n options?: ParseDomainOptions,\n): ParseResult => {\n const sanitizationResult = sanitize(hostname, options);\n\n if (sanitizationResult.type === SanitizationResultType.Error) {\n return {\n type: ParseResultType.Invalid,\n hostname,\n errors: sanitizationResult.errors,\n };\n }\n\n if (sanitizationResult.type === SanitizationResultType.ValidIp) {\n return {\n type: ParseResultType.Ip,\n hostname: sanitizationResult.ip,\n ipVersion: sanitizationResult.ipVersion,\n };\n }\n\n const { labels, domain } = sanitizationResult;\n\n // We do not want to break compatibility with older engines unnecessarily.\n // eslint-disable-next-line unicorn/prefer-at\n const lastLabel = labels[labels.length - 1];\n if (\n hostname === \"\" ||\n (lastLabel !== undefined && RESERVED_TOP_LEVEL_DOMAINS.includes(lastLabel))\n ) {\n return {\n type: ParseResultType.Reserved,\n hostname: domain,\n labels,\n };\n }\n\n // Parse the serialized trie lazily\n parsedIcannTrie = parsedIcannTrie ?? parseTrie(icannTrie);\n parsedPrivateTrie = parsedPrivateTrie ?? parseTrie(privateTrie);\n\n const icannTlds = lookUpTldsInTrie(labels, parsedIcannTrie);\n const privateTlds = lookUpTldsInTrie(labels, parsedPrivateTrie);\n\n if (icannTlds.length === 0 && privateTlds.length === 0) {\n return {\n type: ParseResultType.NotListed,\n hostname: domain,\n labels,\n };\n }\n\n const indexOfPublicSuffixDomain =\n labels.length - Math.max(privateTlds.length, icannTlds.length) - 1;\n\n const indexOfIcannDomain = labels.length - icannTlds.length - 1;\n\n return {\n type: ParseResultType.Listed,\n hostname: domain,\n labels,\n icann: splitLabelsIntoDomains(labels, indexOfIcannDomain),\n ...splitLabelsIntoDomains(labels, indexOfPublicSuffixDomain),\n };\n};\n"]}
@@ -2,3 +2,4 @@ export declare const buildTries: (psl: string) => {
2
2
  icannTrie: import("../trie/nodes.js").TrieRootNode;
3
3
  privateTrie: import("../trie/nodes.js").TrieRootNode;
4
4
  };
5
+ //# sourceMappingURL=build-tries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-tries.d.ts","sourceRoot":"","sources":["../../src/psl/build-tries.ts"],"names":[],"mappings":"AAyDA,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM;;;CASrC,CAAC"}
@@ -1,4 +1,4 @@
1
- import { PUBLIC_SUFFIX_MARKER_ICANN_START, PUBLIC_SUFFIX_MARKER_ICANN_END, PUBLIC_SUFFIX_MARKER_PRIVATE_START, PUBLIC_SUFFIX_MARKER_PRIVATE_END, } from "../config.js";
1
+ import { PUBLIC_SUFFIX_MARKER_ICANN_END, PUBLIC_SUFFIX_MARKER_ICANN_START, PUBLIC_SUFFIX_MARKER_PRIVATE_END, PUBLIC_SUFFIX_MARKER_PRIVATE_START, } from "../config.js";
2
2
  import { toASCII } from "../punycode.js";
3
3
  import { createTrieFromList } from "../trie/create-trie.js";
4
4
  const matchNewLine = /\r?\n/u;
@@ -20,12 +20,12 @@ const parsePsl = (listContent) => {
20
20
  return {
21
21
  icann: extractByMarkers(listContent, PUBLIC_SUFFIX_MARKER_ICANN_START, PUBLIC_SUFFIX_MARKER_ICANN_END)
22
22
  .split(matchNewLine)
23
- .filter(containsRule)
24
- .map(toASCII),
23
+ .filter((line) => containsRule(line))
24
+ .map((line) => toASCII(line)),
25
25
  private: extractByMarkers(listContent, PUBLIC_SUFFIX_MARKER_PRIVATE_START, PUBLIC_SUFFIX_MARKER_PRIVATE_END)
26
26
  .split(matchNewLine)
27
- .filter(containsRule)
28
- .map(toASCII),
27
+ .filter((line) => containsRule(line))
28
+ .map((line) => toASCII(line)),
29
29
  };
30
30
  };
31
31
  export const buildTries = (psl) => {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-tries.js","sourceRoot":"","sources":["../../src/psl/build-tries.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,gCAAgC,EAChC,gCAAgC,EAChC,kCAAkC,GACnC,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,YAAY,GAAG,QAAQ,CAAC;AAC9B,MAAM,YAAY,GAAG,WAAW,CAAC;AACjC,MAAM,eAAe,GAAG,QAAQ,CAAC;AAEjC,MAAM,gBAAgB,GAAG,CACvB,WAAmB,EACnB,WAAmB,EACnB,SAAiB,EACjB,EAAE;IACF,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAE3C,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,wBAAwB,WAAW,wBAAwB,CAC5D,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,wBAAwB,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAAE,CACpC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC;AAE5E,MAAM,QAAQ,GAAG,CAAC,WAAmB,EAAE,EAAE;IACvC,OAAO;QACL,KAAK,EAAE,gBAAgB,CACrB,WAAW,EACX,gCAAgC,EAChC,8BAA8B,CAC/B;aACE,KAAK,CAAC,YAAY,CAAC;aACnB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;aACpC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,EAAE,gBAAgB,CACvB,WAAW,EACX,kCAAkC,EAClC,gCAAgC,CACjC;aACE,KAAK,CAAC,YAAY,CAAC;aACnB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;aACpC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KAChC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE;IACxC,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,kBAAkB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAE1D,OAAO;QACL,SAAS;QACT,WAAW;KACZ,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n PUBLIC_SUFFIX_MARKER_ICANN_END,\n PUBLIC_SUFFIX_MARKER_ICANN_START,\n PUBLIC_SUFFIX_MARKER_PRIVATE_END,\n PUBLIC_SUFFIX_MARKER_PRIVATE_START,\n} from \"../config.js\";\nimport { toASCII } from \"../punycode.js\";\nimport { createTrieFromList } from \"../trie/create-trie.js\";\n\nconst matchNewLine = /\\r?\\n/u;\nconst matchComment = /^\\s*\\/\\//u;\nconst matchWhitespace = /^\\s*$/u;\n\nconst extractByMarkers = (\n listContent: string,\n startMarker: string,\n endMarker: string,\n) => {\n const start = listContent.indexOf(startMarker);\n const end = listContent.indexOf(endMarker);\n\n if (start === -1) {\n throw new Error(\n `Missing start marker ${startMarker} in public suffix list`,\n );\n }\n if (end === -1) {\n throw new Error(`Missing end marker ${endMarker} in public suffix list`);\n }\n\n return listContent.slice(start, end);\n};\n\nconst containsRule = (line: string) =>\n matchComment.test(line) === false && matchWhitespace.test(line) === false;\n\nconst parsePsl = (listContent: string) => {\n return {\n icann: extractByMarkers(\n listContent,\n PUBLIC_SUFFIX_MARKER_ICANN_START,\n PUBLIC_SUFFIX_MARKER_ICANN_END,\n )\n .split(matchNewLine)\n .filter((line) => containsRule(line))\n .map((line) => toASCII(line)),\n private: extractByMarkers(\n listContent,\n PUBLIC_SUFFIX_MARKER_PRIVATE_START,\n PUBLIC_SUFFIX_MARKER_PRIVATE_END,\n )\n .split(matchNewLine)\n .filter((line) => containsRule(line))\n .map((line) => toASCII(line)),\n };\n};\n\nexport const buildTries = (psl: string) => {\n const parsedPsl = parsePsl(psl);\n const icannTrie = createTrieFromList(parsedPsl.icann);\n const privateTrie = createTrieFromList(parsedPsl.private);\n\n return {\n icannTrie,\n privateTrie,\n };\n};\n"]}
@@ -1 +1,2 @@
1
1
  export declare const fetchPsl: () => Promise<string>;
2
+ //# sourceMappingURL=fetch-psl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-psl.d.ts","sourceRoot":"","sources":["../../src/psl/fetch-psl.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,uBAWpB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { ok } from "node:assert";
2
+ import { FETCH_PSL_EXPECTED_MIN_LENGTH, PUBLIC_SUFFIX_URL } from "../config.js";
3
+ export const fetchPsl = async () => {
4
+ const response = await fetch(PUBLIC_SUFFIX_URL);
5
+ const pslContent = await response.text();
6
+ // Sanity check
7
+ ok(pslContent.length >= FETCH_PSL_EXPECTED_MIN_LENGTH, "Public suffix list is shorter than expected");
8
+ return pslContent;
9
+ };
10
+ //# sourceMappingURL=fetch-psl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-psl.js","sourceRoot":"","sources":["../../src/psl/fetch-psl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEhF,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;IACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEzC,eAAe;IACf,EAAE,CACA,UAAU,CAAC,MAAM,IAAI,6BAA6B,EAClD,6CAA6C,CAC9C,CAAC;IAEF,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { ok } from \"node:assert\";\nimport { FETCH_PSL_EXPECTED_MIN_LENGTH, PUBLIC_SUFFIX_URL } from \"../config.js\";\n\nexport const fetchPsl = async () => {\n const response = await fetch(PUBLIC_SUFFIX_URL);\n const pslContent = await response.text();\n\n // Sanity check\n ok(\n pslContent.length >= FETCH_PSL_EXPECTED_MIN_LENGTH,\n \"Public suffix list is shorter than expected\",\n );\n\n return pslContent;\n};\n"]}
@@ -1 +1,2 @@
1
1
  export declare const toASCII: (hostname: string) => string;
2
+ //# sourceMappingURL=punycode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"punycode.d.ts","sourceRoot":"","sources":["../src/punycode.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,GAAI,UAAU,MAAM,WAEvC,CAAC"}
@@ -1,18 +1,18 @@
1
1
  import { ipVersion } from "is-ip";
2
- import { Label } from "./parse-domain.js";
3
2
  import { NO_HOSTNAME } from "./from-url.js";
3
+ import type { Label } from "./parse-domain.js";
4
4
  export declare enum Validation {
5
5
  /**
6
- * Allows any octets as labels
7
- * but still restricts the length of labels and the overall domain.
6
+ * Allows any octets as labels but still restricts the length of labels and
7
+ * the overall domain.
8
8
  *
9
9
  * @see https://www.rfc-editor.org/rfc/rfc2181#section-11
10
- **/
10
+ */
11
11
  Lax = "LAX",
12
12
  /**
13
- * Only allows ASCII letters, digits and hyphens (aka LDH),
14
- * forbids hyphens at the beginning or end of a label
15
- * and requires top-level domain names not to be all-numeric.
13
+ * Only allows ASCII letters, digits and hyphens (aka LDH), forbids hyphens at
14
+ * the beginning or end of a label and requires top-level domain names not to
15
+ * be all-numeric.
16
16
  *
17
17
  * This is the default if no validation is configured.
18
18
  *
@@ -56,3 +56,4 @@ export type SanitizationResult = SanitizationResultValidIp | SanitizationResultV
56
56
  export declare const sanitize: (input: string | typeof NO_HOSTNAME, options?: {
57
57
  validation?: Validation;
58
58
  }) => SanitizationResult;
59
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAgB/C,oBAAY,UAAU;IACpB;;;;;OAKG;IACH,GAAG,QAAQ;IAEX;;;;;;;;OAQG;IACH,MAAM,WAAW;CAClB;AAED,oBAAY,mBAAmB;IAC7B,UAAU,gBAAgB;IAC1B,eAAe,sBAAsB;IACrC,cAAc,qBAAqB;IACnC,cAAc,qBAAqB;IACnC,qBAAqB,4BAA4B;IACjD,gBAAgB,uBAAuB;CACxC;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,oBAAY,sBAAsB;IAChC,OAAO,aAAa;IACpB,WAAW,iBAAiB;IAC5B,KAAK,UAAU;CAChB;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,sBAAsB,CAAC,OAAO,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,EAAE,sBAAsB,CAAC,WAAW,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,sBAAsB,CAAC,KAAK,CAAC;IACnC,MAAM,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B,yBAAyB,GACzB,6BAA6B,GAC7B,uBAAuB,CAAC;AA0D5B,eAAO,MAAM,QAAQ,GACnB,OAAO,MAAM,GAAG,OAAO,WAAW,EAClC,UAAS;IAAE,UAAU,CAAC,EAAE,UAAU,CAAA;CAAO,KACxC,kBA6DF,CAAC"}