UNPKG

3.79 kBJavaScriptView Raw
1import { icannTrie, privateTrie } from "./serialized-tries";
2import { lookUpTldsInTrie } from "./trie/look-up";
3import { sanitize, SanitizationResultType, } from "./sanitize";
4import { parseTrie } from "./trie/parse-trie";
5export const RESERVED_TOP_LEVEL_DOMAINS = [
6 "localhost",
7 "local",
8 "example",
9 "invalid",
10 "test",
11];
12export var ParseResultType;
13(function (ParseResultType) {
14 /**
15 * This parse result is returned in case the given hostname does not adhere to [RFC 1034](https://tools.ietf.org/html/rfc1034).
16 */
17 ParseResultType["Invalid"] = "INVALID";
18 /**
19 * This parse result is returned if the given hostname was an IPv4 or IPv6.
20 */
21 ParseResultType["Ip"] = "IP";
22 /**
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`
26 */
27 ParseResultType["Reserved"] = "RESERVED";
28 /**
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.
30 */
31 ParseResultType["NotListed"] = "NOT_LISTED";
32 /**
33 * This parse result is returned when the given hostname belongs to a top-level domain that is listed in the public suffix list.
34 */
35 ParseResultType["Listed"] = "LISTED";
36})(ParseResultType || (ParseResultType = {}));
37const getAtIndex = (array, index) => {
38 return index >= 0 && index < array.length ? array[index] : undefined;
39};
40const splitLabelsIntoDomains = (labels, index) => {
41 return {
42 subDomains: labels.slice(0, Math.max(0, index)),
43 domain: getAtIndex(labels, index),
44 topLevelDomains: labels.slice(index + 1),
45 };
46};
47let parsedIcannTrie;
48let parsedPrivateTrie;
49/**
50 * Splits the given hostname in topLevelDomains, a domain and subDomains.
51 */
52export const parseDomain = (hostname) => {
53 const sanitizationResult = sanitize(hostname);
54 if (sanitizationResult.type === SanitizationResultType.Error) {
55 return {
56 type: ParseResultType.Invalid,
57 hostname,
58 errors: sanitizationResult.errors,
59 };
60 }
61 if (sanitizationResult.type === SanitizationResultType.ValidIp) {
62 return {
63 type: ParseResultType.Ip,
64 hostname: sanitizationResult.ip,
65 ipVersion: sanitizationResult.ipVersion,
66 };
67 }
68 const { labels, domain } = sanitizationResult;
69 if (hostname === "" ||
70 RESERVED_TOP_LEVEL_DOMAINS.includes(labels[labels.length - 1])) {
71 return {
72 type: ParseResultType.Reserved,
73 hostname: domain,
74 labels,
75 };
76 }
77 // 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);
80 const icannTlds = lookUpTldsInTrie(labels, parsedIcannTrie);
81 const privateTlds = lookUpTldsInTrie(labels, parsedPrivateTrie);
82 if (icannTlds.length === 0 && privateTlds.length === 0) {
83 return {
84 type: ParseResultType.NotListed,
85 hostname: domain,
86 labels,
87 };
88 }
89 const indexOfPublicSuffixDomain = labels.length - Math.max(privateTlds.length, icannTlds.length) - 1;
90 const indexOfIcannDomain = labels.length - icannTlds.length - 1;
91 return Object.assign({ type: ParseResultType.Listed, hostname: domain, labels, icann: splitLabelsIntoDomains(labels, indexOfIcannDomain) }, splitLabelsIntoDomains(labels, indexOfPublicSuffixDomain));
92};
93//# sourceMappingURL=parse-domain.js.map
\No newline at end of file