tldts-core 7.1.2 → 7.2.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.
- package/dist/cjs/index.js +73 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/src/factory.js +10 -0
- package/dist/cjs/src/factory.js.map +1 -1
- package/dist/cjs/src/is-special-use.js +65 -0
- package/dist/cjs/src/is-special-use.js.map +1 -0
- package/dist/cjs/src/options.js +2 -1
- package/dist/cjs/src/options.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/es6/src/factory.js +10 -0
- package/dist/es6/src/factory.js.map +1 -1
- package/dist/es6/src/is-special-use.js +62 -0
- package/dist/es6/src/is-special-use.js.map +1 -0
- package/dist/es6/src/options.js +2 -1
- package/dist/es6/src/options.js.map +1 -1
- package/dist/es6/tsconfig.bundle.tsbuildinfo +1 -1
- package/dist/types/src/factory.d.ts +1 -0
- package/dist/types/src/is-special-use.d.ts +5 -0
- package/dist/types/src/options.d.ts +1 -0
- package/package.json +2 -2
- package/src/factory.ts +18 -0
- package/src/is-special-use.ts +65 -0
- package/src/options.ts +6 -0
package/dist/cjs/index.js
CHANGED
|
@@ -463,6 +463,68 @@ function isIp(hostname) {
|
|
|
463
463
|
return isProbablyIpv6(hostname) || isProbablyIpv4(hostname);
|
|
464
464
|
}
|
|
465
465
|
|
|
466
|
+
/**
|
|
467
|
+
* Special-use domain names from the IANA "Special-Use Domain Names" registry:
|
|
468
|
+
* the authoritative list, created by RFC 6761 and maintained as new RFCs add to
|
|
469
|
+
* it: https://www.iana.org/assignments/special-use-domain-names/
|
|
470
|
+
* Snapshot: 2026-05-24. (RFC 6761 is not obsoleted; draft-hoffman-rfc6761bis
|
|
471
|
+
* proposes to retire its prose but keep this registry, so the registry is the
|
|
472
|
+
* source of truth; re-sync this list against it.)
|
|
473
|
+
*
|
|
474
|
+
* These names never correspond to a public registration, yet neither
|
|
475
|
+
* `isIcann` nor `isPrivate` marks one as special-use: most are absent from the
|
|
476
|
+
* Public Suffix List (so `a.test` looks like a registrable domain), and the
|
|
477
|
+
* few that are listed (`onion`, `home.arpa`) appear there as ordinary ICANN
|
|
478
|
+
* suffixes. `isSpecialUse` is the single signal that covers them all.
|
|
479
|
+
*
|
|
480
|
+
* Per the registry and RFC 6761 ("and any names falling within these domains"),
|
|
481
|
+
* the designation covers each listed name AND all of its sub-domains. DNS labels
|
|
482
|
+
* are case-insensitive (RFC 4343); `hostname` is expected to be already
|
|
483
|
+
* lower-cased and trailing-dot-stripped, as produced by `extractHostname`, the
|
|
484
|
+
* same normalization the Public-Suffix-List lookup relies on.
|
|
485
|
+
*
|
|
486
|
+
* Two groups of registry entries are intentionally excluded: the numeric
|
|
487
|
+
* reverse-DNS delegation zones (`10.in-addr.arpa`, the `*.ip6.arpa` ranges, …),
|
|
488
|
+
* which are reverse-DNS PTR zones rather than hostnames and whose parents
|
|
489
|
+
* (`in-addr.arpa`/`ip6.arpa`) are already in the Public Suffix List; and the
|
|
490
|
+
* deprecated `eap-noob.arpa` entry.
|
|
491
|
+
*/
|
|
492
|
+
const SPECIAL_USE_DOMAINS = [
|
|
493
|
+
'test', // RFC 6761
|
|
494
|
+
'localhost', // RFC 6761
|
|
495
|
+
'invalid', // RFC 6761
|
|
496
|
+
'example', // RFC 6761
|
|
497
|
+
'example.com', // RFC 6761
|
|
498
|
+
'example.net', // RFC 6761
|
|
499
|
+
'example.org', // RFC 6761
|
|
500
|
+
'local', // RFC 6762 (mDNS)
|
|
501
|
+
'onion', // RFC 7686 (Tor)
|
|
502
|
+
'alt', // RFC 9476
|
|
503
|
+
'home.arpa', // RFC 8375
|
|
504
|
+
'ipv4only.arpa', // RFC 8880
|
|
505
|
+
'resolver.arpa', // RFC 9462
|
|
506
|
+
'service.arpa', // RFC 9665
|
|
507
|
+
'6tisch.arpa', // RFC 9031
|
|
508
|
+
'eap.arpa', // RFC 9965
|
|
509
|
+
];
|
|
510
|
+
/**
|
|
511
|
+
* Return `true` if `hostname` is, or is a sub-domain of, a special-use domain
|
|
512
|
+
* (see the registry note above). Expects an already-normalized `hostname`.
|
|
513
|
+
*/
|
|
514
|
+
function isSpecialUse(hostname) {
|
|
515
|
+
for (const name of SPECIAL_USE_DOMAINS) {
|
|
516
|
+
// Match on a label boundary: `hostname` is either exactly `name` or ends
|
|
517
|
+
// with `.name` (so `latest` is not matched by `test`, nor `myexample.com`
|
|
518
|
+
// by `example.com`).
|
|
519
|
+
if (hostname.endsWith(name) &&
|
|
520
|
+
(hostname.length === name.length ||
|
|
521
|
+
hostname.charCodeAt(hostname.length - name.length - 1) === 46) /* '.' */) {
|
|
522
|
+
return true;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
|
|
466
528
|
/**
|
|
467
529
|
* Implements fast shallow verification of hostnames. This does not perform a
|
|
468
530
|
* struct check on the content of labels (classes of Unicode characters, etc.)
|
|
@@ -529,11 +591,12 @@ function isValidHostname (hostname) {
|
|
|
529
591
|
lastCharCode !== 45);
|
|
530
592
|
}
|
|
531
593
|
|
|
532
|
-
function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, extractHostname = true, mixedInputs = true, validHosts = null, validateHostname = true, }) {
|
|
594
|
+
function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, detectSpecialUse = false, extractHostname = true, mixedInputs = true, validHosts = null, validateHostname = true, }) {
|
|
533
595
|
return {
|
|
534
596
|
allowIcannDomains,
|
|
535
597
|
allowPrivateDomains,
|
|
536
598
|
detectIp,
|
|
599
|
+
detectSpecialUse,
|
|
537
600
|
extractHostname,
|
|
538
601
|
mixedInputs,
|
|
539
602
|
validHosts,
|
|
@@ -572,6 +635,7 @@ function getEmptyResult() {
|
|
|
572
635
|
isIcann: null,
|
|
573
636
|
isIp: null,
|
|
574
637
|
isPrivate: null,
|
|
638
|
+
isSpecialUse: null,
|
|
575
639
|
publicSuffix: null,
|
|
576
640
|
subdomain: null,
|
|
577
641
|
};
|
|
@@ -583,6 +647,7 @@ function resetResult(result) {
|
|
|
583
647
|
result.isIcann = null;
|
|
584
648
|
result.isIp = null;
|
|
585
649
|
result.isPrivate = null;
|
|
650
|
+
result.isSpecialUse = null;
|
|
586
651
|
result.publicSuffix = null;
|
|
587
652
|
result.subdomain = null;
|
|
588
653
|
}
|
|
@@ -642,6 +707,13 @@ function parseImpl(url, step, suffixLookup, partialOptions, result) {
|
|
|
642
707
|
if (step === 0 /* FLAG.HOSTNAME */ || result.hostname === null) {
|
|
643
708
|
return result;
|
|
644
709
|
}
|
|
710
|
+
// Flag special-use domains, only when opted in (`detectSpecialUse`) and only
|
|
711
|
+
// for the full `parse()` result (FLAG.ALL). Computed here, before the
|
|
712
|
+
// public-suffix/domain early-returns below, so single-label names like
|
|
713
|
+
// `localhost` (which have no registrable domain) are still flagged.
|
|
714
|
+
if (step === 5 /* FLAG.ALL */ && options.detectSpecialUse) {
|
|
715
|
+
result.isSpecialUse = isSpecialUse(result.hostname);
|
|
716
|
+
}
|
|
645
717
|
// Extract public suffix
|
|
646
718
|
suffixLookup(result.hostname, options, result);
|
|
647
719
|
if (step === 2 /* FLAG.PUBLIC_SUFFIX */ || result.publicSuffix === null) {
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/domain.ts","../../src/domain-without-suffix.ts","../../src/extract-hostname.ts","../../src/is-ip.ts","../../src/is-valid.ts","../../src/options.ts","../../src/subdomain.ts","../../src/factory.ts","../../src/lookup/fast-path.ts"],"sourcesContent":["import { IOptions } from './options';\n\n/**\n * Check if `vhost` is a valid suffix of `hostname` (top-domain)\n *\n * It means that `vhost` needs to be a suffix of `hostname` and we then need to\n * make sure that: either they are equal, or the character preceding `vhost` in\n * `hostname` is a '.' (it should not be a partial label).\n *\n * * hostname = 'not.evil.com' and vhost = 'vil.com' => not ok\n * * hostname = 'not.evil.com' and vhost = 'evil.com' => ok\n * * hostname = 'not.evil.com' and vhost = 'not.evil.com' => ok\n */\nfunction shareSameDomainSuffix(hostname: string, vhost: string): boolean {\n if (hostname.endsWith(vhost)) {\n return (\n hostname.length === vhost.length ||\n hostname[hostname.length - vhost.length - 1] === '.'\n );\n }\n\n return false;\n}\n\n/**\n * Given a hostname and its public suffix, extract the general domain.\n */\nfunction extractDomainWithSuffix(\n hostname: string,\n publicSuffix: string,\n): string {\n // Locate the index of the last '.' in the part of the `hostname` preceding\n // the public suffix.\n //\n // examples:\n // 1. not.evil.co.uk => evil.co.uk\n // ^ ^\n // | | start of public suffix\n // | index of the last dot\n //\n // 2. example.co.uk => example.co.uk\n // ^ ^\n // | | start of public suffix\n // |\n // | (-1) no dot found before the public suffix\n const publicSuffixIndex = hostname.length - publicSuffix.length - 2;\n const lastDotBeforeSuffixIndex = hostname.lastIndexOf('.', publicSuffixIndex);\n\n // No '.' found, then `hostname` is the general domain (no sub-domain)\n if (lastDotBeforeSuffixIndex === -1) {\n return hostname;\n }\n\n // Extract the part between the last '.'\n return hostname.slice(lastDotBeforeSuffixIndex + 1);\n}\n\n/**\n * Detects the domain based on rules and upon and a host string\n */\nexport default function getDomain(\n suffix: string,\n hostname: string,\n options: IOptions,\n): string | null {\n // Check if `hostname` ends with a member of `validHosts`.\n if (options.validHosts !== null) {\n const validHosts = options.validHosts;\n for (const vhost of validHosts) {\n if (/*@__INLINE__*/ shareSameDomainSuffix(hostname, vhost)) {\n return vhost;\n }\n }\n }\n\n let numberOfLeadingDots = 0;\n if (hostname.startsWith('.')) {\n while (\n numberOfLeadingDots < hostname.length &&\n hostname[numberOfLeadingDots] === '.'\n ) {\n numberOfLeadingDots += 1;\n }\n }\n\n // If `hostname` is a valid public suffix, then there is no domain to return.\n // Since we already know that `getPublicSuffix` returns a suffix of `hostname`\n // there is no need to perform a string comparison and we only compare the\n // size.\n if (suffix.length === hostname.length - numberOfLeadingDots) {\n return null;\n }\n\n // To extract the general domain, we start by identifying the public suffix\n // (if any), then consider the domain to be the public suffix with one added\n // level of depth. (e.g.: if hostname is `not.evil.co.uk` and public suffix:\n // `co.uk`, then we take one more level: `evil`, giving the final result:\n // `evil.co.uk`).\n return /*@__INLINE__*/ extractDomainWithSuffix(hostname, suffix);\n}\n","/**\n * Return the part of domain without suffix.\n *\n * Example: for domain 'foo.com', the result would be 'foo'.\n */\nexport default function getDomainWithoutSuffix(\n domain: string,\n suffix: string,\n): string {\n // Note: here `domain` and `suffix` cannot have the same length because in\n // this case we set `domain` to `null` instead. It is thus safe to assume\n // that `suffix` is shorter than `domain`.\n return domain.slice(0, -suffix.length - 1);\n}\n","/**\n * Matches an ASCII tab (U+0009) or newline (U+000A / U+000D). The WHATWG URL\n * parser strips these before parsing; we only allocate a cleaned copy (and\n * re-parse) on the rare input that actually contains one.\n */\nconst CONTROL_CHARS = /[\\t\\n\\r]/g;\n\n/**\n * Classify scheme `url.slice(schemeStart, colonIndex)` as a WHATWG special\n * scheme without allocating a substring (case-insensitive via `| 32`).\n * Special schemes: ftp, file, http, https, ws, wss\n * (https://url.spec.whatwg.org/#special-scheme).\n *\n * @returns 0 = not special, 1 = special, 2 = file (its host sits only between\n * \"//\" and the next slash).\n */\nfunction getSpecialScheme(\n url: string,\n schemeStart: number,\n colonIndex: number,\n): number {\n const length = colonIndex - schemeStart;\n const c0 = url.charCodeAt(schemeStart) | 32;\n if (length === 2) {\n return c0 === 119 && (url.charCodeAt(schemeStart + 1) | 32) === 115 ? 1 : 0; // ws\n } else if (length === 3) {\n const c1 = url.charCodeAt(schemeStart + 1) | 32;\n const c2 = url.charCodeAt(schemeStart + 2) | 32;\n if (c0 === 119 && c1 === 115 && c2 === 115) return 1; // wss\n if (c0 === 102 && c1 === 116 && c2 === 112) return 1; // ftp\n return 0;\n } else if (length === 4) {\n const c1 = url.charCodeAt(schemeStart + 1) | 32;\n const c2 = url.charCodeAt(schemeStart + 2) | 32;\n const c3 = url.charCodeAt(schemeStart + 3) | 32;\n if (c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112) return 1; // http\n if (c0 === 102 && c1 === 105 && c2 === 108 && c3 === 101) return 2; // file\n return 0;\n } else if (length === 5) {\n return c0 === 104 &&\n (url.charCodeAt(schemeStart + 1) | 32) === 116 &&\n (url.charCodeAt(schemeStart + 2) | 32) === 116 &&\n (url.charCodeAt(schemeStart + 3) | 32) === 112 &&\n (url.charCodeAt(schemeStart + 4) | 32) === 115\n ? 1\n : 0; // https\n }\n return 0;\n}\n\n/**\n * Extract a hostname from `url`, matching a WHATWG URL parser's host-boundary\n * behaviour (https://url.spec.whatwg.org/#concept-basic-url-parser) for tldts'\n * scope. It deliberately does NOT normalise the host (no IDNA/punycode or IPv4\n * canonicalisation; IPv6 brackets are stripped, not compressed), strips trailing\n * dots, and stays lenient where a strict parser rejects (bare host:port,\n * out-of-range port, user@host) — all documented deviations.\n *\n * @param urlIsValidHostname - when true, `url` is already a valid hostname and is\n * returned by the same reference (factory.ts skips re-validation on that\n * identity), keeping the common path allocation-free.\n */\nexport default function extractHostname(\n url: string,\n urlIsValidHostname: boolean,\n): string | null {\n let start = 0;\n let end: number = url.length;\n let hasUpper = false;\n let isSpecial = false;\n\n if (!urlIsValidHostname) {\n // Data URLs never carry a host (and may be huge — short-circuit them).\n if (url.startsWith('data:')) {\n return null;\n }\n\n // WHATWG step 1: trim leading/trailing C0 control or space (<= U+0020).\n // Tab/newline elsewhere are handled lazily below.\n while (start < url.length && url.charCodeAt(start) <= 32) {\n start += 1;\n }\n while (end > start + 1 && url.charCodeAt(end - 1) <= 32) {\n end -= 1;\n }\n\n if (\n url.charCodeAt(start) === 47 /* '/' */ &&\n url.charCodeAt(start + 1) === 47 /* '/' */\n ) {\n // Scheme-relative reference (\"//host/path\").\n start += 2;\n } else {\n const indexOfProtocol = url.indexOf(':/', start);\n if (indexOfProtocol !== -1) {\n // \"scheme://…\". Classify the scheme, then position `start` at the host.\n const special = getSpecialScheme(url, start, indexOfProtocol);\n if (special === 1) {\n // Special scheme: skip the run of '/' and '\\' after it\n // (special-authority-(ignore-)slashes states; '\\' acts as '/').\n isSpecial = true;\n start = indexOfProtocol + 2;\n while (\n url.charCodeAt(start) === 47 /* '/' */ ||\n url.charCodeAt(start) === 92 /* '\\' */\n ) {\n start += 1;\n }\n } else if (special === 2) {\n // file: the host is only what sits between \"//\" and the next slash, so\n // \"file://h/x\" => \"h\" but \"file:///x\" / \"file:/x\" => no host.\n isSpecial = true;\n start = indexOfProtocol + 1;\n let slashes = 0;\n while (\n (url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) &&\n slashes < 2\n ) {\n start += 1;\n slashes += 1;\n }\n if (slashes < 2) {\n return null;\n }\n } else {\n // Unknown scheme: validate the WHATWG scheme grammar [A-Za-z0-9+.-];\n // a control char means it was split by a tab/newline (strip + re-parse).\n for (let i = start; i < indexOfProtocol; i += 1) {\n const code = url.charCodeAt(i) | 32;\n if (\n !(\n (\n (code >= 97 && code <= 122) || // [a, z]\n (code >= 48 && code <= 57) || // [0, 9]\n code === 46 || // '.'\n code === 45 || // '-'\n code === 43\n ) // '+'\n )\n ) {\n const raw = url.charCodeAt(i);\n if (raw === 9 || raw === 10 || raw === 13) {\n return extractHostname(\n url.replace(CONTROL_CHARS, ''),\n urlIsValidHostname,\n );\n }\n return null;\n }\n }\n // A non-special scheme has an authority only after \"//\" (else it is an\n // opaque path with no host). `indexOf(':/')` already gave the first '/'.\n if (url.charCodeAt(indexOfProtocol + 2) === 47 /* '/' */) {\n start = indexOfProtocol + 3;\n } else {\n return null;\n }\n }\n } else if (url.charCodeAt(start) !== 91 /* '[' */) {\n // Cold path: no scheme \"://\", and not a bare IPv6 literal (whose first\n // ':' would otherwise look like a scheme separator; \"[…]\" falls through\n // to the ipv6 handling below). May be a bare host, a host:port, a\n // user@host, a slash-less special scheme (\"https:host\"), or an opaque\n // URI (\"mailto:\", \"tel:\", \"urn:…\").\n let indexOfColon = -1;\n for (let i = start; i < end; i += 1) {\n const code = url.charCodeAt(i);\n if (code === 9 || code === 10 || code === 13) {\n return extractHostname(\n url.replace(CONTROL_CHARS, ''),\n urlIsValidHostname,\n );\n }\n if (code === 58 /* ':' */) {\n indexOfColon = i;\n break;\n }\n if (code === 47 || code === 92 || code === 63 || code === 35) {\n break;\n }\n }\n\n if (indexOfColon !== -1) {\n // An '@' before the next delimiter => the ':' is userinfo, not a\n // scheme (\"user:pass@host\", \"mailto:a@b\"): keep the whole authority.\n let hasIdentifier = false;\n for (let i = indexOfColon + 1; i < end; i += 1) {\n const code = url.charCodeAt(i);\n if (code === 47 || code === 92 || code === 63 || code === 35) {\n break;\n }\n if (code === 64 /* '@' */) {\n hasIdentifier = true;\n break;\n }\n }\n\n if (!hasIdentifier) {\n // All-digits after ':' => a bare \"host:port\" (tldts accepts\n // hostnames too); keep `start` and let the port handling trim it.\n let allDigits = true;\n let i = indexOfColon + 1;\n for (; i < end; i += 1) {\n const code = url.charCodeAt(i);\n if (code === 47 || code === 92 || code === 63 || code === 35) {\n break;\n }\n if (code < 48 /* '0' */ || code > 57 /* '9' */) {\n allDigits = false;\n break;\n }\n }\n if (i === indexOfColon + 1) {\n allDigits = false; // nothing after ':' => not a port\n }\n\n if (!allDigits) {\n const special = getSpecialScheme(url, start, indexOfColon);\n if (special === 0) {\n // No \"://\" anywhere on the cold path, so a non-special scheme has\n // no authority: opaque path, no host (\"mailto:x\", \"foo:bar\").\n return null;\n }\n isSpecial = true;\n start = indexOfColon + 1;\n if (special === 2) {\n // file (e.g. \"file:\\\\host\"): host only between \"//\" and next slash.\n let slashes = 0;\n while (\n (url.charCodeAt(start) === 47 ||\n url.charCodeAt(start) === 92) &&\n slashes < 2\n ) {\n start += 1;\n slashes += 1;\n }\n if (slashes < 2) {\n return null;\n }\n } else {\n while (\n url.charCodeAt(start) === 47 ||\n url.charCodeAt(start) === 92\n ) {\n start += 1;\n }\n }\n }\n }\n }\n }\n }\n\n // Find the host's end: first '/', '?' or '#' (and '\\' for special URLs,\n // which WHATWG treats like '/'). Track the last '@', ']' and ':' for\n // userinfo, ipv6 and port; flag uppercase and a stray tab/newline. The loop\n // is split on `code < 64` so common host characters take fewer comparisons.\n let indexOfIdentifier = -1;\n let indexOfClosingBracket = -1;\n let indexOfPort = -1;\n let hasControl = false;\n for (let i = start; i < end; i += 1) {\n const code: number = url.charCodeAt(i);\n if (code < 64) {\n if (code === 47 || code === 35 || code === 63) {\n end = i;\n break;\n } else if (code === 58 /* ':' */) {\n indexOfPort = i;\n } else if (code === 9 || code === 10 || code === 13) {\n hasControl = true;\n }\n } else if (isSpecial && code === 92 /* '\\' */) {\n end = i;\n break;\n } else if (code === 64 /* '@' */) {\n indexOfIdentifier = i;\n } else if (code === 93 /* ']' */) {\n indexOfClosingBracket = i;\n } else if (code >= 65 && code <= 90) {\n hasUpper = true;\n }\n }\n\n // A tab/newline inside the authority: strip everything and re-parse (rare).\n if (hasControl) {\n return extractHostname(\n url.replace(CONTROL_CHARS, ''),\n urlIsValidHostname,\n );\n }\n\n // Skip userinfo. '>= start' so an empty userinfo (\"http://@host\") works too.\n if (\n indexOfIdentifier !== -1 &&\n indexOfIdentifier >= start &&\n indexOfIdentifier < end\n ) {\n start = indexOfIdentifier + 1;\n }\n\n if (url.charCodeAt(start) === 91 /* '[' */) {\n // ipv6 address: return what is between the brackets, or null if unclosed.\n if (indexOfClosingBracket !== -1) {\n return url.slice(start + 1, indexOfClosingBracket).toLowerCase();\n }\n return null;\n } else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end) {\n end = indexOfPort; // trim ':port'\n }\n\n // Empty authority (\"http://\", \"file:///path\", \"//\"); only reachable here via\n // extraction — a bare valid hostname never lands here.\n if (start >= end) {\n return null;\n }\n }\n\n // Trim trailing dots\n while (end > start + 1 && url.charCodeAt(end - 1) === 46 /* '.' */) {\n end -= 1;\n }\n\n const hostname: string =\n start !== 0 || end !== url.length ? url.slice(start, end) : url;\n\n if (hasUpper) {\n return hostname.toLowerCase();\n }\n\n return hostname;\n}\n","/**\n * Check if a hostname is an IP. You should be aware that this only works\n * because `hostname` is already garanteed to be a valid hostname!\n */\nfunction isProbablyIpv4(hostname: string): boolean {\n // Cannot be shorted than 1.1.1.1\n if (hostname.length < 7) {\n return false;\n }\n\n // Cannot be longer than: 255.255.255.255\n if (hostname.length > 15) {\n return false;\n }\n\n let numberOfDots = 0;\n\n for (let i = 0; i < hostname.length; i += 1) {\n const code = hostname.charCodeAt(i);\n\n if (code === 46 /* '.' */) {\n numberOfDots += 1;\n } else if (code < 48 /* '0' */ || code > 57 /* '9' */) {\n return false;\n }\n }\n\n return (\n numberOfDots === 3 &&\n hostname.charCodeAt(0) !== 46 /* '.' */ &&\n hostname.charCodeAt(hostname.length - 1) !== 46 /* '.' */\n );\n}\n\n/**\n * Similar to isProbablyIpv4.\n */\nfunction isProbablyIpv6(hostname: string): boolean {\n if (hostname.length < 3) {\n return false;\n }\n\n let start = hostname.startsWith('[') ? 1 : 0;\n let end = hostname.length;\n\n if (hostname[end - 1] === ']') {\n end -= 1;\n }\n\n // We only consider the maximum size of a normal IPV6. Note that this will\n // fail on so-called \"IPv4 mapped IPv6 addresses\" but this is a corner-case\n // and a proper validation library should be used for these.\n if (end - start > 39) {\n return false;\n }\n\n let hasColon = false;\n\n for (; start < end; start += 1) {\n const code = hostname.charCodeAt(start);\n\n if (code === 58 /* ':' */) {\n hasColon = true;\n } else if (\n !(\n (\n (code >= 48 && code <= 57) || // 0-9\n (code >= 97 && code <= 102) || // a-f\n (code >= 65 && code <= 70)\n ) // A-F (RFC 4291 §2.2: an IPv6 hextet is hex digits only)\n )\n ) {\n return false;\n }\n }\n\n return hasColon;\n}\n\n/**\n * Check if `hostname` is *probably* a valid ip addr (either ipv6 or ipv4).\n * This *will not* work on any string. We need `hostname` to be a valid\n * hostname.\n */\nexport default function isIp(hostname: string): boolean {\n return isProbablyIpv6(hostname) || isProbablyIpv4(hostname);\n}\n","/**\n * Implements fast shallow verification of hostnames. This does not perform a\n * struct check on the content of labels (classes of Unicode characters, etc.)\n * but instead check that the structure is valid (number of labels, length of\n * labels, etc.).\n *\n * If you need stricter validation, consider using an external library.\n */\n\nfunction isValidAscii(code: number): boolean {\n return (\n (code >= 97 && code <= 122) || (code >= 48 && code <= 57) || code > 127\n );\n}\n\n/**\n * Check if a hostname string is valid. It's usually a preliminary check before\n * trying to use getDomain or anything else.\n *\n * Beware: it does not check if the TLD exists.\n */\nexport default function (hostname: string): boolean {\n if (hostname.length > 255) {\n return false;\n }\n\n if (hostname.length === 0) {\n return false;\n }\n\n if (\n /*@__INLINE__*/ !isValidAscii(hostname.charCodeAt(0)) &&\n hostname.charCodeAt(0) !== 46 && // '.' (dot)\n hostname.charCodeAt(0) !== 95 // '_' (underscore)\n ) {\n return false;\n }\n\n // Validate hostname according to RFC\n let lastDotIndex = -1;\n let lastCharCode = -1;\n const len = hostname.length;\n\n for (let i = 0; i < len; i += 1) {\n const code = hostname.charCodeAt(i);\n if (code === 46 /* '.' */) {\n if (\n // Check that previous label is < 63 bytes long (64 = 63 + '.')\n i - lastDotIndex > 64 ||\n // Check that previous character was not already a '.'\n lastCharCode === 46 ||\n // Check that the previous label does not end with '-' (RFC 1035 §2.3.1 LDH).\n // '_' is intentionally NOT restricted: DNS allows any octet (RFC 2181 §11) and\n // WHATWG URL does not treat '_' as a forbidden host code point.\n lastCharCode === 45\n ) {\n return false;\n }\n\n lastDotIndex = i;\n } else if (\n !(/*@__INLINE__*/ (isValidAscii(code) || code === 45 || code === 95))\n ) {\n // Check if there is a forbidden character in the label\n return false;\n }\n\n lastCharCode = code;\n }\n\n return (\n // Check that last label is shorter than 63 chars\n len - lastDotIndex - 1 <= 63 &&\n // Check that the last character is an allowed trailing label character.\n // Since we already checked that the char is a valid hostname character,\n // we only need to check that it's different from '-'.\n lastCharCode !== 45\n );\n}\n","export interface IOptions {\n allowIcannDomains: boolean;\n allowPrivateDomains: boolean;\n detectIp: boolean;\n extractHostname: boolean;\n mixedInputs: boolean;\n validHosts: string[] | null;\n validateHostname: boolean;\n}\n\nfunction setDefaultsImpl({\n allowIcannDomains = true,\n allowPrivateDomains = false,\n detectIp = true,\n extractHostname = true,\n mixedInputs = true,\n validHosts = null,\n validateHostname = true,\n}: Partial<IOptions>): IOptions {\n return {\n allowIcannDomains,\n allowPrivateDomains,\n detectIp,\n extractHostname,\n mixedInputs,\n validHosts,\n validateHostname,\n };\n}\n\nconst DEFAULT_OPTIONS = /*@__INLINE__*/ setDefaultsImpl({});\n\nexport function setDefaults(options?: Partial<IOptions>): IOptions {\n if (options === undefined) {\n return DEFAULT_OPTIONS;\n }\n\n return /*@__INLINE__*/ setDefaultsImpl(options);\n}\n","/**\n * Returns the subdomain of a hostname string\n */\nexport default function getSubdomain(hostname: string, domain: string): string {\n // If `hostname` and `domain` are the same, then there is no sub-domain\n if (domain.length === hostname.length) {\n return '';\n }\n\n return hostname.slice(0, -domain.length - 1);\n}\n","/**\n * Implement a factory allowing to plug different implementations of suffix\n * lookup (e.g.: using a trie or the packed hashes datastructures). This is used\n * and exposed in `tldts.ts` and `tldts-experimental.ts` bundle entrypoints.\n */\n\nimport getDomain from './domain';\nimport getDomainWithoutSuffix from './domain-without-suffix';\nimport extractHostname from './extract-hostname';\nimport isIp from './is-ip';\nimport isValidHostname from './is-valid';\nimport { IPublicSuffix, ISuffixLookupOptions } from './lookup/interface';\nimport { IOptions, setDefaults } from './options';\nimport getSubdomain from './subdomain';\n\nexport interface IResult {\n // `hostname` is either a registered name (including but not limited to a\n // hostname), or an IP address. IPv4 addresses must be in dot-decimal\n // notation, and IPv6 addresses must be enclosed in brackets ([]). This is\n // directly extracted from the input URL.\n hostname: string | null;\n\n // Is `hostname` an IP? (IPv4 or IPv6)\n isIp: boolean | null;\n\n // `hostname` split between subdomain, domain and its public suffix (if any)\n subdomain: string | null;\n domain: string | null;\n publicSuffix: string | null;\n domainWithoutSuffix: string | null;\n\n // Specifies if `publicSuffix` comes from the ICANN or PRIVATE section of the list\n isIcann: boolean | null;\n isPrivate: boolean | null;\n}\n\nexport function getEmptyResult(): IResult {\n return {\n domain: null,\n domainWithoutSuffix: null,\n hostname: null,\n isIcann: null,\n isIp: null,\n isPrivate: null,\n publicSuffix: null,\n subdomain: null,\n };\n}\n\nexport function resetResult(result: IResult): void {\n result.domain = null;\n result.domainWithoutSuffix = null;\n result.hostname = null;\n result.isIcann = null;\n result.isIp = null;\n result.isPrivate = null;\n result.publicSuffix = null;\n result.subdomain = null;\n}\n\n// Flags representing steps in the `parse` function. They are used to implement\n// an early stop mechanism (simulating some form of laziness) to avoid doing\n// more work than necessary to perform a given action (e.g.: we don't need to\n// extract the domain and subdomain if we are only interested in public suffix).\nexport const enum FLAG {\n HOSTNAME,\n IS_VALID,\n PUBLIC_SUFFIX,\n DOMAIN,\n SUB_DOMAIN,\n ALL,\n}\n\nexport function parseImpl(\n url: string,\n step: FLAG,\n suffixLookup: (\n _1: string,\n _2: ISuffixLookupOptions,\n _3: IPublicSuffix,\n ) => void,\n partialOptions: Partial<IOptions> | undefined,\n result: IResult,\n): IResult {\n const options: IOptions = /*@__INLINE__*/ setDefaults(partialOptions);\n\n // Very fast approximate check to make sure `url` is a string. This is needed\n // because the library will not necessarily be used in a typed setup and\n // values of arbitrary types might be given as argument.\n if (typeof url !== 'string') {\n return result;\n }\n\n // Extract hostname from `url` only if needed. This can be made optional\n // using `options.extractHostname`. This option will typically be used\n // whenever we are sure the inputs to `parse` are already hostnames and not\n // arbitrary URLs.\n //\n // `mixedInput` allows to specify if we expect a mix of URLs and hostnames\n // as input. If only hostnames are expected then `extractHostname` can be\n // set to `false` to speed-up parsing. If only URLs are expected then\n // `mixedInputs` can be set to `false`. The `mixedInputs` is only a hint\n // and will not change the behavior of the library.\n // Whether `url` itself was already a valid hostname (only computed on the\n // mixedInputs path). Lets us skip the post-extraction validation below when\n // extractHostname returned `url` unchanged (same reference).\n let urlIsValid = false;\n if (!options.extractHostname) {\n result.hostname = url;\n } else if (options.mixedInputs) {\n urlIsValid = isValidHostname(url);\n result.hostname = extractHostname(url, urlIsValid);\n } else {\n result.hostname = extractHostname(url, false);\n }\n\n // Check if `hostname` is a valid ip address\n if (options.detectIp && result.hostname !== null) {\n result.isIp = isIp(result.hostname);\n if (result.isIp) {\n return result;\n }\n }\n\n // Perform hostname validation if enabled. If hostname is not valid, no need to\n // go further as there will be no valid domain or sub-domain. This validation\n // is applied before any early returns to ensure consistent behavior across\n // all API methods including getHostname().\n if (\n options.validateHostname &&\n options.extractHostname &&\n result.hostname !== null &&\n // Skip the re-scan when `url` was already validated and extractHostname\n // returned it unchanged (same reference => identical string, still valid).\n !(urlIsValid && result.hostname === url) &&\n !isValidHostname(result.hostname)\n ) {\n result.hostname = null;\n return result;\n }\n\n if (step === FLAG.HOSTNAME || result.hostname === null) {\n return result;\n }\n\n // Extract public suffix\n suffixLookup(result.hostname, options, result);\n if (step === FLAG.PUBLIC_SUFFIX || result.publicSuffix === null) {\n return result;\n }\n\n // Extract domain\n result.domain = getDomain(result.publicSuffix, result.hostname, options);\n if (step === FLAG.DOMAIN || result.domain === null) {\n return result;\n }\n\n // Extract subdomain\n result.subdomain = getSubdomain(result.hostname, result.domain);\n if (step === FLAG.SUB_DOMAIN) {\n return result;\n }\n\n // Extract domain without suffix\n result.domainWithoutSuffix = getDomainWithoutSuffix(\n result.domain,\n result.publicSuffix,\n );\n\n return result;\n}\n","import { IPublicSuffix, ISuffixLookupOptions } from './interface';\n\nexport default function (\n hostname: string,\n options: ISuffixLookupOptions,\n out: IPublicSuffix,\n): boolean {\n // Fast path for very popular suffixes; this allows to by-pass lookup\n // completely as well as any extra allocation or string manipulation.\n if (!options.allowPrivateDomains && hostname.length > 3) {\n const last: number = hostname.length - 1;\n const c3: number = hostname.charCodeAt(last);\n const c2: number = hostname.charCodeAt(last - 1);\n const c1: number = hostname.charCodeAt(last - 2);\n const c0: number = hostname.charCodeAt(last - 3);\n\n if (\n c3 === 109 /* 'm' */ &&\n c2 === 111 /* 'o' */ &&\n c1 === 99 /* 'c' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'com';\n return true;\n } else if (\n c3 === 103 /* 'g' */ &&\n c2 === 114 /* 'r' */ &&\n c1 === 111 /* 'o' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'org';\n return true;\n } else if (\n c3 === 117 /* 'u' */ &&\n c2 === 100 /* 'd' */ &&\n c1 === 101 /* 'e' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'edu';\n return true;\n } else if (\n c3 === 118 /* 'v' */ &&\n c2 === 111 /* 'o' */ &&\n c1 === 103 /* 'g' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'gov';\n return true;\n } else if (\n c3 === 116 /* 't' */ &&\n c2 === 101 /* 'e' */ &&\n c1 === 110 /* 'n' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'net';\n return true;\n } else if (\n c3 === 101 /* 'e' */ &&\n c2 === 100 /* 'd' */ &&\n c1 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'de';\n return true;\n }\n }\n\n return false;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/domain.ts","../../src/domain-without-suffix.ts","../../src/extract-hostname.ts","../../src/is-ip.ts","../../src/is-special-use.ts","../../src/is-valid.ts","../../src/options.ts","../../src/subdomain.ts","../../src/factory.ts","../../src/lookup/fast-path.ts"],"sourcesContent":["import { IOptions } from './options';\n\n/**\n * Check if `vhost` is a valid suffix of `hostname` (top-domain)\n *\n * It means that `vhost` needs to be a suffix of `hostname` and we then need to\n * make sure that: either they are equal, or the character preceding `vhost` in\n * `hostname` is a '.' (it should not be a partial label).\n *\n * * hostname = 'not.evil.com' and vhost = 'vil.com' => not ok\n * * hostname = 'not.evil.com' and vhost = 'evil.com' => ok\n * * hostname = 'not.evil.com' and vhost = 'not.evil.com' => ok\n */\nfunction shareSameDomainSuffix(hostname: string, vhost: string): boolean {\n if (hostname.endsWith(vhost)) {\n return (\n hostname.length === vhost.length ||\n hostname[hostname.length - vhost.length - 1] === '.'\n );\n }\n\n return false;\n}\n\n/**\n * Given a hostname and its public suffix, extract the general domain.\n */\nfunction extractDomainWithSuffix(\n hostname: string,\n publicSuffix: string,\n): string {\n // Locate the index of the last '.' in the part of the `hostname` preceding\n // the public suffix.\n //\n // examples:\n // 1. not.evil.co.uk => evil.co.uk\n // ^ ^\n // | | start of public suffix\n // | index of the last dot\n //\n // 2. example.co.uk => example.co.uk\n // ^ ^\n // | | start of public suffix\n // |\n // | (-1) no dot found before the public suffix\n const publicSuffixIndex = hostname.length - publicSuffix.length - 2;\n const lastDotBeforeSuffixIndex = hostname.lastIndexOf('.', publicSuffixIndex);\n\n // No '.' found, then `hostname` is the general domain (no sub-domain)\n if (lastDotBeforeSuffixIndex === -1) {\n return hostname;\n }\n\n // Extract the part between the last '.'\n return hostname.slice(lastDotBeforeSuffixIndex + 1);\n}\n\n/**\n * Detects the domain based on rules and upon and a host string\n */\nexport default function getDomain(\n suffix: string,\n hostname: string,\n options: IOptions,\n): string | null {\n // Check if `hostname` ends with a member of `validHosts`.\n if (options.validHosts !== null) {\n const validHosts = options.validHosts;\n for (const vhost of validHosts) {\n if (/*@__INLINE__*/ shareSameDomainSuffix(hostname, vhost)) {\n return vhost;\n }\n }\n }\n\n let numberOfLeadingDots = 0;\n if (hostname.startsWith('.')) {\n while (\n numberOfLeadingDots < hostname.length &&\n hostname[numberOfLeadingDots] === '.'\n ) {\n numberOfLeadingDots += 1;\n }\n }\n\n // If `hostname` is a valid public suffix, then there is no domain to return.\n // Since we already know that `getPublicSuffix` returns a suffix of `hostname`\n // there is no need to perform a string comparison and we only compare the\n // size.\n if (suffix.length === hostname.length - numberOfLeadingDots) {\n return null;\n }\n\n // To extract the general domain, we start by identifying the public suffix\n // (if any), then consider the domain to be the public suffix with one added\n // level of depth. (e.g.: if hostname is `not.evil.co.uk` and public suffix:\n // `co.uk`, then we take one more level: `evil`, giving the final result:\n // `evil.co.uk`).\n return /*@__INLINE__*/ extractDomainWithSuffix(hostname, suffix);\n}\n","/**\n * Return the part of domain without suffix.\n *\n * Example: for domain 'foo.com', the result would be 'foo'.\n */\nexport default function getDomainWithoutSuffix(\n domain: string,\n suffix: string,\n): string {\n // Note: here `domain` and `suffix` cannot have the same length because in\n // this case we set `domain` to `null` instead. It is thus safe to assume\n // that `suffix` is shorter than `domain`.\n return domain.slice(0, -suffix.length - 1);\n}\n","/**\n * Matches an ASCII tab (U+0009) or newline (U+000A / U+000D). The WHATWG URL\n * parser strips these before parsing; we only allocate a cleaned copy (and\n * re-parse) on the rare input that actually contains one.\n */\nconst CONTROL_CHARS = /[\\t\\n\\r]/g;\n\n/**\n * Classify scheme `url.slice(schemeStart, colonIndex)` as a WHATWG special\n * scheme without allocating a substring (case-insensitive via `| 32`).\n * Special schemes: ftp, file, http, https, ws, wss\n * (https://url.spec.whatwg.org/#special-scheme).\n *\n * @returns 0 = not special, 1 = special, 2 = file (its host sits only between\n * \"//\" and the next slash).\n */\nfunction getSpecialScheme(\n url: string,\n schemeStart: number,\n colonIndex: number,\n): number {\n const length = colonIndex - schemeStart;\n const c0 = url.charCodeAt(schemeStart) | 32;\n if (length === 2) {\n return c0 === 119 && (url.charCodeAt(schemeStart + 1) | 32) === 115 ? 1 : 0; // ws\n } else if (length === 3) {\n const c1 = url.charCodeAt(schemeStart + 1) | 32;\n const c2 = url.charCodeAt(schemeStart + 2) | 32;\n if (c0 === 119 && c1 === 115 && c2 === 115) return 1; // wss\n if (c0 === 102 && c1 === 116 && c2 === 112) return 1; // ftp\n return 0;\n } else if (length === 4) {\n const c1 = url.charCodeAt(schemeStart + 1) | 32;\n const c2 = url.charCodeAt(schemeStart + 2) | 32;\n const c3 = url.charCodeAt(schemeStart + 3) | 32;\n if (c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112) return 1; // http\n if (c0 === 102 && c1 === 105 && c2 === 108 && c3 === 101) return 2; // file\n return 0;\n } else if (length === 5) {\n return c0 === 104 &&\n (url.charCodeAt(schemeStart + 1) | 32) === 116 &&\n (url.charCodeAt(schemeStart + 2) | 32) === 116 &&\n (url.charCodeAt(schemeStart + 3) | 32) === 112 &&\n (url.charCodeAt(schemeStart + 4) | 32) === 115\n ? 1\n : 0; // https\n }\n return 0;\n}\n\n/**\n * Extract a hostname from `url`, matching a WHATWG URL parser's host-boundary\n * behaviour (https://url.spec.whatwg.org/#concept-basic-url-parser) for tldts'\n * scope. It deliberately does NOT normalise the host (no IDNA/punycode or IPv4\n * canonicalisation; IPv6 brackets are stripped, not compressed), strips trailing\n * dots, and stays lenient where a strict parser rejects (bare host:port,\n * out-of-range port, user@host) — all documented deviations.\n *\n * @param urlIsValidHostname - when true, `url` is already a valid hostname and is\n * returned by the same reference (factory.ts skips re-validation on that\n * identity), keeping the common path allocation-free.\n */\nexport default function extractHostname(\n url: string,\n urlIsValidHostname: boolean,\n): string | null {\n let start = 0;\n let end: number = url.length;\n let hasUpper = false;\n let isSpecial = false;\n\n if (!urlIsValidHostname) {\n // Data URLs never carry a host (and may be huge — short-circuit them).\n if (url.startsWith('data:')) {\n return null;\n }\n\n // WHATWG step 1: trim leading/trailing C0 control or space (<= U+0020).\n // Tab/newline elsewhere are handled lazily below.\n while (start < url.length && url.charCodeAt(start) <= 32) {\n start += 1;\n }\n while (end > start + 1 && url.charCodeAt(end - 1) <= 32) {\n end -= 1;\n }\n\n if (\n url.charCodeAt(start) === 47 /* '/' */ &&\n url.charCodeAt(start + 1) === 47 /* '/' */\n ) {\n // Scheme-relative reference (\"//host/path\").\n start += 2;\n } else {\n const indexOfProtocol = url.indexOf(':/', start);\n if (indexOfProtocol !== -1) {\n // \"scheme://…\". Classify the scheme, then position `start` at the host.\n const special = getSpecialScheme(url, start, indexOfProtocol);\n if (special === 1) {\n // Special scheme: skip the run of '/' and '\\' after it\n // (special-authority-(ignore-)slashes states; '\\' acts as '/').\n isSpecial = true;\n start = indexOfProtocol + 2;\n while (\n url.charCodeAt(start) === 47 /* '/' */ ||\n url.charCodeAt(start) === 92 /* '\\' */\n ) {\n start += 1;\n }\n } else if (special === 2) {\n // file: the host is only what sits between \"//\" and the next slash, so\n // \"file://h/x\" => \"h\" but \"file:///x\" / \"file:/x\" => no host.\n isSpecial = true;\n start = indexOfProtocol + 1;\n let slashes = 0;\n while (\n (url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) &&\n slashes < 2\n ) {\n start += 1;\n slashes += 1;\n }\n if (slashes < 2) {\n return null;\n }\n } else {\n // Unknown scheme: validate the WHATWG scheme grammar [A-Za-z0-9+.-];\n // a control char means it was split by a tab/newline (strip + re-parse).\n for (let i = start; i < indexOfProtocol; i += 1) {\n const code = url.charCodeAt(i) | 32;\n if (\n !(\n (\n (code >= 97 && code <= 122) || // [a, z]\n (code >= 48 && code <= 57) || // [0, 9]\n code === 46 || // '.'\n code === 45 || // '-'\n code === 43\n ) // '+'\n )\n ) {\n const raw = url.charCodeAt(i);\n if (raw === 9 || raw === 10 || raw === 13) {\n return extractHostname(\n url.replace(CONTROL_CHARS, ''),\n urlIsValidHostname,\n );\n }\n return null;\n }\n }\n // A non-special scheme has an authority only after \"//\" (else it is an\n // opaque path with no host). `indexOf(':/')` already gave the first '/'.\n if (url.charCodeAt(indexOfProtocol + 2) === 47 /* '/' */) {\n start = indexOfProtocol + 3;\n } else {\n return null;\n }\n }\n } else if (url.charCodeAt(start) !== 91 /* '[' */) {\n // Cold path: no scheme \"://\", and not a bare IPv6 literal (whose first\n // ':' would otherwise look like a scheme separator; \"[…]\" falls through\n // to the ipv6 handling below). May be a bare host, a host:port, a\n // user@host, a slash-less special scheme (\"https:host\"), or an opaque\n // URI (\"mailto:\", \"tel:\", \"urn:…\").\n let indexOfColon = -1;\n for (let i = start; i < end; i += 1) {\n const code = url.charCodeAt(i);\n if (code === 9 || code === 10 || code === 13) {\n return extractHostname(\n url.replace(CONTROL_CHARS, ''),\n urlIsValidHostname,\n );\n }\n if (code === 58 /* ':' */) {\n indexOfColon = i;\n break;\n }\n if (code === 47 || code === 92 || code === 63 || code === 35) {\n break;\n }\n }\n\n if (indexOfColon !== -1) {\n // An '@' before the next delimiter => the ':' is userinfo, not a\n // scheme (\"user:pass@host\", \"mailto:a@b\"): keep the whole authority.\n let hasIdentifier = false;\n for (let i = indexOfColon + 1; i < end; i += 1) {\n const code = url.charCodeAt(i);\n if (code === 47 || code === 92 || code === 63 || code === 35) {\n break;\n }\n if (code === 64 /* '@' */) {\n hasIdentifier = true;\n break;\n }\n }\n\n if (!hasIdentifier) {\n // All-digits after ':' => a bare \"host:port\" (tldts accepts\n // hostnames too); keep `start` and let the port handling trim it.\n let allDigits = true;\n let i = indexOfColon + 1;\n for (; i < end; i += 1) {\n const code = url.charCodeAt(i);\n if (code === 47 || code === 92 || code === 63 || code === 35) {\n break;\n }\n if (code < 48 /* '0' */ || code > 57 /* '9' */) {\n allDigits = false;\n break;\n }\n }\n if (i === indexOfColon + 1) {\n allDigits = false; // nothing after ':' => not a port\n }\n\n if (!allDigits) {\n const special = getSpecialScheme(url, start, indexOfColon);\n if (special === 0) {\n // No \"://\" anywhere on the cold path, so a non-special scheme has\n // no authority: opaque path, no host (\"mailto:x\", \"foo:bar\").\n return null;\n }\n isSpecial = true;\n start = indexOfColon + 1;\n if (special === 2) {\n // file (e.g. \"file:\\\\host\"): host only between \"//\" and next slash.\n let slashes = 0;\n while (\n (url.charCodeAt(start) === 47 ||\n url.charCodeAt(start) === 92) &&\n slashes < 2\n ) {\n start += 1;\n slashes += 1;\n }\n if (slashes < 2) {\n return null;\n }\n } else {\n while (\n url.charCodeAt(start) === 47 ||\n url.charCodeAt(start) === 92\n ) {\n start += 1;\n }\n }\n }\n }\n }\n }\n }\n\n // Find the host's end: first '/', '?' or '#' (and '\\' for special URLs,\n // which WHATWG treats like '/'). Track the last '@', ']' and ':' for\n // userinfo, ipv6 and port; flag uppercase and a stray tab/newline. The loop\n // is split on `code < 64` so common host characters take fewer comparisons.\n let indexOfIdentifier = -1;\n let indexOfClosingBracket = -1;\n let indexOfPort = -1;\n let hasControl = false;\n for (let i = start; i < end; i += 1) {\n const code: number = url.charCodeAt(i);\n if (code < 64) {\n if (code === 47 || code === 35 || code === 63) {\n end = i;\n break;\n } else if (code === 58 /* ':' */) {\n indexOfPort = i;\n } else if (code === 9 || code === 10 || code === 13) {\n hasControl = true;\n }\n } else if (isSpecial && code === 92 /* '\\' */) {\n end = i;\n break;\n } else if (code === 64 /* '@' */) {\n indexOfIdentifier = i;\n } else if (code === 93 /* ']' */) {\n indexOfClosingBracket = i;\n } else if (code >= 65 && code <= 90) {\n hasUpper = true;\n }\n }\n\n // A tab/newline inside the authority: strip everything and re-parse (rare).\n if (hasControl) {\n return extractHostname(\n url.replace(CONTROL_CHARS, ''),\n urlIsValidHostname,\n );\n }\n\n // Skip userinfo. '>= start' so an empty userinfo (\"http://@host\") works too.\n if (\n indexOfIdentifier !== -1 &&\n indexOfIdentifier >= start &&\n indexOfIdentifier < end\n ) {\n start = indexOfIdentifier + 1;\n }\n\n if (url.charCodeAt(start) === 91 /* '[' */) {\n // ipv6 address: return what is between the brackets, or null if unclosed.\n if (indexOfClosingBracket !== -1) {\n return url.slice(start + 1, indexOfClosingBracket).toLowerCase();\n }\n return null;\n } else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end) {\n end = indexOfPort; // trim ':port'\n }\n\n // Empty authority (\"http://\", \"file:///path\", \"//\"); only reachable here via\n // extraction — a bare valid hostname never lands here.\n if (start >= end) {\n return null;\n }\n }\n\n // Trim trailing dots\n while (end > start + 1 && url.charCodeAt(end - 1) === 46 /* '.' */) {\n end -= 1;\n }\n\n const hostname: string =\n start !== 0 || end !== url.length ? url.slice(start, end) : url;\n\n if (hasUpper) {\n return hostname.toLowerCase();\n }\n\n return hostname;\n}\n","/**\n * Check if a hostname is an IP. You should be aware that this only works\n * because `hostname` is already garanteed to be a valid hostname!\n */\nfunction isProbablyIpv4(hostname: string): boolean {\n // Cannot be shorted than 1.1.1.1\n if (hostname.length < 7) {\n return false;\n }\n\n // Cannot be longer than: 255.255.255.255\n if (hostname.length > 15) {\n return false;\n }\n\n let numberOfDots = 0;\n\n for (let i = 0; i < hostname.length; i += 1) {\n const code = hostname.charCodeAt(i);\n\n if (code === 46 /* '.' */) {\n numberOfDots += 1;\n } else if (code < 48 /* '0' */ || code > 57 /* '9' */) {\n return false;\n }\n }\n\n return (\n numberOfDots === 3 &&\n hostname.charCodeAt(0) !== 46 /* '.' */ &&\n hostname.charCodeAt(hostname.length - 1) !== 46 /* '.' */\n );\n}\n\n/**\n * Similar to isProbablyIpv4.\n */\nfunction isProbablyIpv6(hostname: string): boolean {\n if (hostname.length < 3) {\n return false;\n }\n\n let start = hostname.startsWith('[') ? 1 : 0;\n let end = hostname.length;\n\n if (hostname[end - 1] === ']') {\n end -= 1;\n }\n\n // We only consider the maximum size of a normal IPV6. Note that this will\n // fail on so-called \"IPv4 mapped IPv6 addresses\" but this is a corner-case\n // and a proper validation library should be used for these.\n if (end - start > 39) {\n return false;\n }\n\n let hasColon = false;\n\n for (; start < end; start += 1) {\n const code = hostname.charCodeAt(start);\n\n if (code === 58 /* ':' */) {\n hasColon = true;\n } else if (\n !(\n (\n (code >= 48 && code <= 57) || // 0-9\n (code >= 97 && code <= 102) || // a-f\n (code >= 65 && code <= 70)\n ) // A-F (RFC 4291 §2.2: an IPv6 hextet is hex digits only)\n )\n ) {\n return false;\n }\n }\n\n return hasColon;\n}\n\n/**\n * Check if `hostname` is *probably* a valid ip addr (either ipv6 or ipv4).\n * This *will not* work on any string. We need `hostname` to be a valid\n * hostname.\n */\nexport default function isIp(hostname: string): boolean {\n return isProbablyIpv6(hostname) || isProbablyIpv4(hostname);\n}\n","/**\n * Special-use domain names from the IANA \"Special-Use Domain Names\" registry:\n * the authoritative list, created by RFC 6761 and maintained as new RFCs add to\n * it: https://www.iana.org/assignments/special-use-domain-names/\n * Snapshot: 2026-05-24. (RFC 6761 is not obsoleted; draft-hoffman-rfc6761bis\n * proposes to retire its prose but keep this registry, so the registry is the\n * source of truth; re-sync this list against it.)\n *\n * These names never correspond to a public registration, yet neither\n * `isIcann` nor `isPrivate` marks one as special-use: most are absent from the\n * Public Suffix List (so `a.test` looks like a registrable domain), and the\n * few that are listed (`onion`, `home.arpa`) appear there as ordinary ICANN\n * suffixes. `isSpecialUse` is the single signal that covers them all.\n *\n * Per the registry and RFC 6761 (\"and any names falling within these domains\"),\n * the designation covers each listed name AND all of its sub-domains. DNS labels\n * are case-insensitive (RFC 4343); `hostname` is expected to be already\n * lower-cased and trailing-dot-stripped, as produced by `extractHostname`, the\n * same normalization the Public-Suffix-List lookup relies on.\n *\n * Two groups of registry entries are intentionally excluded: the numeric\n * reverse-DNS delegation zones (`10.in-addr.arpa`, the `*.ip6.arpa` ranges, …),\n * which are reverse-DNS PTR zones rather than hostnames and whose parents\n * (`in-addr.arpa`/`ip6.arpa`) are already in the Public Suffix List; and the\n * deprecated `eap-noob.arpa` entry.\n */\nconst SPECIAL_USE_DOMAINS: readonly string[] = [\n 'test', // RFC 6761\n 'localhost', // RFC 6761\n 'invalid', // RFC 6761\n 'example', // RFC 6761\n 'example.com', // RFC 6761\n 'example.net', // RFC 6761\n 'example.org', // RFC 6761\n 'local', // RFC 6762 (mDNS)\n 'onion', // RFC 7686 (Tor)\n 'alt', // RFC 9476\n 'home.arpa', // RFC 8375\n 'ipv4only.arpa', // RFC 8880\n 'resolver.arpa', // RFC 9462\n 'service.arpa', // RFC 9665\n '6tisch.arpa', // RFC 9031\n 'eap.arpa', // RFC 9965\n];\n\n/**\n * Return `true` if `hostname` is, or is a sub-domain of, a special-use domain\n * (see the registry note above). Expects an already-normalized `hostname`.\n */\nexport default function isSpecialUse(hostname: string): boolean {\n for (const name of SPECIAL_USE_DOMAINS) {\n // Match on a label boundary: `hostname` is either exactly `name` or ends\n // with `.name` (so `latest` is not matched by `test`, nor `myexample.com`\n // by `example.com`).\n if (\n hostname.endsWith(name) &&\n (hostname.length === name.length ||\n hostname.charCodeAt(hostname.length - name.length - 1) === 46) /* '.' */\n ) {\n return true;\n }\n }\n\n return false;\n}\n","/**\n * Implements fast shallow verification of hostnames. This does not perform a\n * struct check on the content of labels (classes of Unicode characters, etc.)\n * but instead check that the structure is valid (number of labels, length of\n * labels, etc.).\n *\n * If you need stricter validation, consider using an external library.\n */\n\nfunction isValidAscii(code: number): boolean {\n return (\n (code >= 97 && code <= 122) || (code >= 48 && code <= 57) || code > 127\n );\n}\n\n/**\n * Check if a hostname string is valid. It's usually a preliminary check before\n * trying to use getDomain or anything else.\n *\n * Beware: it does not check if the TLD exists.\n */\nexport default function (hostname: string): boolean {\n if (hostname.length > 255) {\n return false;\n }\n\n if (hostname.length === 0) {\n return false;\n }\n\n if (\n /*@__INLINE__*/ !isValidAscii(hostname.charCodeAt(0)) &&\n hostname.charCodeAt(0) !== 46 && // '.' (dot)\n hostname.charCodeAt(0) !== 95 // '_' (underscore)\n ) {\n return false;\n }\n\n // Validate hostname according to RFC\n let lastDotIndex = -1;\n let lastCharCode = -1;\n const len = hostname.length;\n\n for (let i = 0; i < len; i += 1) {\n const code = hostname.charCodeAt(i);\n if (code === 46 /* '.' */) {\n if (\n // Check that previous label is < 63 bytes long (64 = 63 + '.')\n i - lastDotIndex > 64 ||\n // Check that previous character was not already a '.'\n lastCharCode === 46 ||\n // Check that the previous label does not end with '-' (RFC 1035 §2.3.1 LDH).\n // '_' is intentionally NOT restricted: DNS allows any octet (RFC 2181 §11) and\n // WHATWG URL does not treat '_' as a forbidden host code point.\n lastCharCode === 45\n ) {\n return false;\n }\n\n lastDotIndex = i;\n } else if (\n !(/*@__INLINE__*/ (isValidAscii(code) || code === 45 || code === 95))\n ) {\n // Check if there is a forbidden character in the label\n return false;\n }\n\n lastCharCode = code;\n }\n\n return (\n // Check that last label is shorter than 63 chars\n len - lastDotIndex - 1 <= 63 &&\n // Check that the last character is an allowed trailing label character.\n // Since we already checked that the char is a valid hostname character,\n // we only need to check that it's different from '-'.\n lastCharCode !== 45\n );\n}\n","export interface IOptions {\n allowIcannDomains: boolean;\n allowPrivateDomains: boolean;\n detectIp: boolean;\n // Detect RFC 6761 / IANA special-use domains and expose the result as\n // `isSpecialUse` on `parse()`. Off by default so the common path stays\n // allocation-free with no extra work; enable it to populate the field.\n detectSpecialUse: boolean;\n extractHostname: boolean;\n mixedInputs: boolean;\n validHosts: string[] | null;\n validateHostname: boolean;\n}\n\nfunction setDefaultsImpl({\n allowIcannDomains = true,\n allowPrivateDomains = false,\n detectIp = true,\n detectSpecialUse = false,\n extractHostname = true,\n mixedInputs = true,\n validHosts = null,\n validateHostname = true,\n}: Partial<IOptions>): IOptions {\n return {\n allowIcannDomains,\n allowPrivateDomains,\n detectIp,\n detectSpecialUse,\n extractHostname,\n mixedInputs,\n validHosts,\n validateHostname,\n };\n}\n\nconst DEFAULT_OPTIONS = /*@__INLINE__*/ setDefaultsImpl({});\n\nexport function setDefaults(options?: Partial<IOptions>): IOptions {\n if (options === undefined) {\n return DEFAULT_OPTIONS;\n }\n\n return /*@__INLINE__*/ setDefaultsImpl(options);\n}\n","/**\n * Returns the subdomain of a hostname string\n */\nexport default function getSubdomain(hostname: string, domain: string): string {\n // If `hostname` and `domain` are the same, then there is no sub-domain\n if (domain.length === hostname.length) {\n return '';\n }\n\n return hostname.slice(0, -domain.length - 1);\n}\n","/**\n * Implement a factory allowing to plug different implementations of suffix\n * lookup (e.g.: using a trie or the packed hashes datastructures). This is used\n * and exposed in `tldts.ts` and `tldts-experimental.ts` bundle entrypoints.\n */\n\nimport getDomain from './domain';\nimport getDomainWithoutSuffix from './domain-without-suffix';\nimport extractHostname from './extract-hostname';\nimport isIp from './is-ip';\nimport isSpecialUse from './is-special-use';\nimport isValidHostname from './is-valid';\nimport { IPublicSuffix, ISuffixLookupOptions } from './lookup/interface';\nimport { IOptions, setDefaults } from './options';\nimport getSubdomain from './subdomain';\n\nexport interface IResult {\n // `hostname` is either a registered name (including but not limited to a\n // hostname), or an IP address. IPv4 addresses must be in dot-decimal\n // notation, and IPv6 addresses must be enclosed in brackets ([]). This is\n // directly extracted from the input URL.\n hostname: string | null;\n\n // Is `hostname` an IP? (IPv4 or IPv6)\n isIp: boolean | null;\n\n // `hostname` split between subdomain, domain and its public suffix (if any)\n subdomain: string | null;\n domain: string | null;\n publicSuffix: string | null;\n domainWithoutSuffix: string | null;\n\n // Specifies if `publicSuffix` comes from the ICANN or PRIVATE section of the list\n isIcann: boolean | null;\n isPrivate: boolean | null;\n\n // Is `hostname` a special-use domain from the IANA registry (RFC 6761 et al.:\n // e.g. `localhost`, `*.test`, `*.local`, `*.onion`, `home.arpa`)? `isIcann`/\n // `isPrivate` do not identify these (most are not in the Public Suffix List;\n // the few that are appear as ordinary ICANN suffixes). `null` unless the\n // `detectSpecialUse` option is enabled (see is-special-use.ts).\n isSpecialUse: boolean | null;\n}\n\nexport function getEmptyResult(): IResult {\n return {\n domain: null,\n domainWithoutSuffix: null,\n hostname: null,\n isIcann: null,\n isIp: null,\n isPrivate: null,\n isSpecialUse: null,\n publicSuffix: null,\n subdomain: null,\n };\n}\n\nexport function resetResult(result: IResult): void {\n result.domain = null;\n result.domainWithoutSuffix = null;\n result.hostname = null;\n result.isIcann = null;\n result.isIp = null;\n result.isPrivate = null;\n result.isSpecialUse = null;\n result.publicSuffix = null;\n result.subdomain = null;\n}\n\n// Flags representing steps in the `parse` function. They are used to implement\n// an early stop mechanism (simulating some form of laziness) to avoid doing\n// more work than necessary to perform a given action (e.g.: we don't need to\n// extract the domain and subdomain if we are only interested in public suffix).\nexport const enum FLAG {\n HOSTNAME,\n IS_VALID,\n PUBLIC_SUFFIX,\n DOMAIN,\n SUB_DOMAIN,\n ALL,\n}\n\nexport function parseImpl(\n url: string,\n step: FLAG,\n suffixLookup: (\n _1: string,\n _2: ISuffixLookupOptions,\n _3: IPublicSuffix,\n ) => void,\n partialOptions: Partial<IOptions> | undefined,\n result: IResult,\n): IResult {\n const options: IOptions = /*@__INLINE__*/ setDefaults(partialOptions);\n\n // Very fast approximate check to make sure `url` is a string. This is needed\n // because the library will not necessarily be used in a typed setup and\n // values of arbitrary types might be given as argument.\n if (typeof url !== 'string') {\n return result;\n }\n\n // Extract hostname from `url` only if needed. This can be made optional\n // using `options.extractHostname`. This option will typically be used\n // whenever we are sure the inputs to `parse` are already hostnames and not\n // arbitrary URLs.\n //\n // `mixedInput` allows to specify if we expect a mix of URLs and hostnames\n // as input. If only hostnames are expected then `extractHostname` can be\n // set to `false` to speed-up parsing. If only URLs are expected then\n // `mixedInputs` can be set to `false`. The `mixedInputs` is only a hint\n // and will not change the behavior of the library.\n // Whether `url` itself was already a valid hostname (only computed on the\n // mixedInputs path). Lets us skip the post-extraction validation below when\n // extractHostname returned `url` unchanged (same reference).\n let urlIsValid = false;\n if (!options.extractHostname) {\n result.hostname = url;\n } else if (options.mixedInputs) {\n urlIsValid = isValidHostname(url);\n result.hostname = extractHostname(url, urlIsValid);\n } else {\n result.hostname = extractHostname(url, false);\n }\n\n // Check if `hostname` is a valid ip address\n if (options.detectIp && result.hostname !== null) {\n result.isIp = isIp(result.hostname);\n if (result.isIp) {\n return result;\n }\n }\n\n // Perform hostname validation if enabled. If hostname is not valid, no need to\n // go further as there will be no valid domain or sub-domain. This validation\n // is applied before any early returns to ensure consistent behavior across\n // all API methods including getHostname().\n if (\n options.validateHostname &&\n options.extractHostname &&\n result.hostname !== null &&\n // Skip the re-scan when `url` was already validated and extractHostname\n // returned it unchanged (same reference => identical string, still valid).\n !(urlIsValid && result.hostname === url) &&\n !isValidHostname(result.hostname)\n ) {\n result.hostname = null;\n return result;\n }\n\n if (step === FLAG.HOSTNAME || result.hostname === null) {\n return result;\n }\n\n // Flag special-use domains, only when opted in (`detectSpecialUse`) and only\n // for the full `parse()` result (FLAG.ALL). Computed here, before the\n // public-suffix/domain early-returns below, so single-label names like\n // `localhost` (which have no registrable domain) are still flagged.\n if (step === FLAG.ALL && options.detectSpecialUse) {\n result.isSpecialUse = isSpecialUse(result.hostname);\n }\n\n // Extract public suffix\n suffixLookup(result.hostname, options, result);\n if (step === FLAG.PUBLIC_SUFFIX || result.publicSuffix === null) {\n return result;\n }\n\n // Extract domain\n result.domain = getDomain(result.publicSuffix, result.hostname, options);\n if (step === FLAG.DOMAIN || result.domain === null) {\n return result;\n }\n\n // Extract subdomain\n result.subdomain = getSubdomain(result.hostname, result.domain);\n if (step === FLAG.SUB_DOMAIN) {\n return result;\n }\n\n // Extract domain without suffix\n result.domainWithoutSuffix = getDomainWithoutSuffix(\n result.domain,\n result.publicSuffix,\n );\n\n return result;\n}\n","import { IPublicSuffix, ISuffixLookupOptions } from './interface';\n\nexport default function (\n hostname: string,\n options: ISuffixLookupOptions,\n out: IPublicSuffix,\n): boolean {\n // Fast path for very popular suffixes; this allows to by-pass lookup\n // completely as well as any extra allocation or string manipulation.\n if (!options.allowPrivateDomains && hostname.length > 3) {\n const last: number = hostname.length - 1;\n const c3: number = hostname.charCodeAt(last);\n const c2: number = hostname.charCodeAt(last - 1);\n const c1: number = hostname.charCodeAt(last - 2);\n const c0: number = hostname.charCodeAt(last - 3);\n\n if (\n c3 === 109 /* 'm' */ &&\n c2 === 111 /* 'o' */ &&\n c1 === 99 /* 'c' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'com';\n return true;\n } else if (\n c3 === 103 /* 'g' */ &&\n c2 === 114 /* 'r' */ &&\n c1 === 111 /* 'o' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'org';\n return true;\n } else if (\n c3 === 117 /* 'u' */ &&\n c2 === 100 /* 'd' */ &&\n c1 === 101 /* 'e' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'edu';\n return true;\n } else if (\n c3 === 118 /* 'v' */ &&\n c2 === 111 /* 'o' */ &&\n c1 === 103 /* 'g' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'gov';\n return true;\n } else if (\n c3 === 116 /* 't' */ &&\n c2 === 101 /* 'e' */ &&\n c1 === 110 /* 'n' */ &&\n c0 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'net';\n return true;\n } else if (\n c3 === 101 /* 'e' */ &&\n c2 === 100 /* 'd' */ &&\n c1 === 46 /* '.' */\n ) {\n out.isIcann = true;\n out.isPrivate = false;\n out.publicSuffix = 'de';\n return true;\n }\n }\n\n return false;\n}\n"],"names":[],"mappings":"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"}
|
package/dist/cjs/src/factory.js
CHANGED
|
@@ -12,6 +12,7 @@ const domain_1 = require("./domain");
|
|
|
12
12
|
const domain_without_suffix_1 = require("./domain-without-suffix");
|
|
13
13
|
const extract_hostname_1 = require("./extract-hostname");
|
|
14
14
|
const is_ip_1 = require("./is-ip");
|
|
15
|
+
const is_special_use_1 = require("./is-special-use");
|
|
15
16
|
const is_valid_1 = require("./is-valid");
|
|
16
17
|
const options_1 = require("./options");
|
|
17
18
|
const subdomain_1 = require("./subdomain");
|
|
@@ -23,6 +24,7 @@ function getEmptyResult() {
|
|
|
23
24
|
isIcann: null,
|
|
24
25
|
isIp: null,
|
|
25
26
|
isPrivate: null,
|
|
27
|
+
isSpecialUse: null,
|
|
26
28
|
publicSuffix: null,
|
|
27
29
|
subdomain: null,
|
|
28
30
|
};
|
|
@@ -34,6 +36,7 @@ function resetResult(result) {
|
|
|
34
36
|
result.isIcann = null;
|
|
35
37
|
result.isIp = null;
|
|
36
38
|
result.isPrivate = null;
|
|
39
|
+
result.isSpecialUse = null;
|
|
37
40
|
result.publicSuffix = null;
|
|
38
41
|
result.subdomain = null;
|
|
39
42
|
}
|
|
@@ -93,6 +96,13 @@ function parseImpl(url, step, suffixLookup, partialOptions, result) {
|
|
|
93
96
|
if (step === 0 /* FLAG.HOSTNAME */ || result.hostname === null) {
|
|
94
97
|
return result;
|
|
95
98
|
}
|
|
99
|
+
// Flag special-use domains, only when opted in (`detectSpecialUse`) and only
|
|
100
|
+
// for the full `parse()` result (FLAG.ALL). Computed here, before the
|
|
101
|
+
// public-suffix/domain early-returns below, so single-label names like
|
|
102
|
+
// `localhost` (which have no registrable domain) are still flagged.
|
|
103
|
+
if (step === 5 /* FLAG.ALL */ && options.detectSpecialUse) {
|
|
104
|
+
result.isSpecialUse = (0, is_special_use_1.default)(result.hostname);
|
|
105
|
+
}
|
|
96
106
|
// Extract public suffix
|
|
97
107
|
suffixLookup(result.hostname, options, result);
|
|
98
108
|
if (step === 2 /* FLAG.PUBLIC_SUFFIX */ || result.publicSuffix === null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/factory.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = isSpecialUse;
|
|
4
|
+
/**
|
|
5
|
+
* Special-use domain names from the IANA "Special-Use Domain Names" registry:
|
|
6
|
+
* the authoritative list, created by RFC 6761 and maintained as new RFCs add to
|
|
7
|
+
* it: https://www.iana.org/assignments/special-use-domain-names/
|
|
8
|
+
* Snapshot: 2026-05-24. (RFC 6761 is not obsoleted; draft-hoffman-rfc6761bis
|
|
9
|
+
* proposes to retire its prose but keep this registry, so the registry is the
|
|
10
|
+
* source of truth; re-sync this list against it.)
|
|
11
|
+
*
|
|
12
|
+
* These names never correspond to a public registration, yet neither
|
|
13
|
+
* `isIcann` nor `isPrivate` marks one as special-use: most are absent from the
|
|
14
|
+
* Public Suffix List (so `a.test` looks like a registrable domain), and the
|
|
15
|
+
* few that are listed (`onion`, `home.arpa`) appear there as ordinary ICANN
|
|
16
|
+
* suffixes. `isSpecialUse` is the single signal that covers them all.
|
|
17
|
+
*
|
|
18
|
+
* Per the registry and RFC 6761 ("and any names falling within these domains"),
|
|
19
|
+
* the designation covers each listed name AND all of its sub-domains. DNS labels
|
|
20
|
+
* are case-insensitive (RFC 4343); `hostname` is expected to be already
|
|
21
|
+
* lower-cased and trailing-dot-stripped, as produced by `extractHostname`, the
|
|
22
|
+
* same normalization the Public-Suffix-List lookup relies on.
|
|
23
|
+
*
|
|
24
|
+
* Two groups of registry entries are intentionally excluded: the numeric
|
|
25
|
+
* reverse-DNS delegation zones (`10.in-addr.arpa`, the `*.ip6.arpa` ranges, …),
|
|
26
|
+
* which are reverse-DNS PTR zones rather than hostnames and whose parents
|
|
27
|
+
* (`in-addr.arpa`/`ip6.arpa`) are already in the Public Suffix List; and the
|
|
28
|
+
* deprecated `eap-noob.arpa` entry.
|
|
29
|
+
*/
|
|
30
|
+
const SPECIAL_USE_DOMAINS = [
|
|
31
|
+
'test', // RFC 6761
|
|
32
|
+
'localhost', // RFC 6761
|
|
33
|
+
'invalid', // RFC 6761
|
|
34
|
+
'example', // RFC 6761
|
|
35
|
+
'example.com', // RFC 6761
|
|
36
|
+
'example.net', // RFC 6761
|
|
37
|
+
'example.org', // RFC 6761
|
|
38
|
+
'local', // RFC 6762 (mDNS)
|
|
39
|
+
'onion', // RFC 7686 (Tor)
|
|
40
|
+
'alt', // RFC 9476
|
|
41
|
+
'home.arpa', // RFC 8375
|
|
42
|
+
'ipv4only.arpa', // RFC 8880
|
|
43
|
+
'resolver.arpa', // RFC 9462
|
|
44
|
+
'service.arpa', // RFC 9665
|
|
45
|
+
'6tisch.arpa', // RFC 9031
|
|
46
|
+
'eap.arpa', // RFC 9965
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Return `true` if `hostname` is, or is a sub-domain of, a special-use domain
|
|
50
|
+
* (see the registry note above). Expects an already-normalized `hostname`.
|
|
51
|
+
*/
|
|
52
|
+
function isSpecialUse(hostname) {
|
|
53
|
+
for (const name of SPECIAL_USE_DOMAINS) {
|
|
54
|
+
// Match on a label boundary: `hostname` is either exactly `name` or ends
|
|
55
|
+
// with `.name` (so `latest` is not matched by `test`, nor `myexample.com`
|
|
56
|
+
// by `example.com`).
|
|
57
|
+
if (hostname.endsWith(name) &&
|
|
58
|
+
(hostname.length === name.length ||
|
|
59
|
+
hostname.charCodeAt(hostname.length - name.length - 1) === 46) /* '.' */) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=is-special-use.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-special-use.js","sourceRoot":"","sources":["../../../src/is-special-use.ts"],"names":[],"mappings":";;AAiDA,+BAeC;AAhED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,mBAAmB,GAAsB;IAC7C,MAAM,EAAE,WAAW;IACnB,WAAW,EAAE,WAAW;IACxB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,aAAa,EAAE,WAAW;IAC1B,aAAa,EAAE,WAAW;IAC1B,aAAa,EAAE,WAAW;IAC1B,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,iBAAiB;IAC1B,KAAK,EAAE,WAAW;IAClB,WAAW,EAAE,WAAW;IACxB,eAAe,EAAE,WAAW;IAC5B,eAAe,EAAE,WAAW;IAC5B,cAAc,EAAE,WAAW;IAC3B,aAAa,EAAE,WAAW;IAC1B,UAAU,EAAE,WAAW;CACxB,CAAC;AAEF;;;GAGG;AACH,SAAwB,YAAY,CAAC,QAAgB;IACnD,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;QACvC,yEAAyE;QACzE,0EAA0E;QAC1E,qBAAqB;QACrB,IACE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;YACvB,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;gBAC9B,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAC1E,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/cjs/src/options.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setDefaults = setDefaults;
|
|
4
|
-
function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, extractHostname = true, mixedInputs = true, validHosts = null, validateHostname = true, }) {
|
|
4
|
+
function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, detectSpecialUse = false, extractHostname = true, mixedInputs = true, validHosts = null, validateHostname = true, }) {
|
|
5
5
|
return {
|
|
6
6
|
allowIcannDomains,
|
|
7
7
|
allowPrivateDomains,
|
|
8
8
|
detectIp,
|
|
9
|
+
detectSpecialUse,
|
|
9
10
|
extractHostname,
|
|
10
11
|
mixedInputs,
|
|
11
12
|
validHosts,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/options.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/options.ts"],"names":[],"mappings":";;AAsCA,kCAMC;AA9BD,SAAS,eAAe,CAAC,EACvB,iBAAiB,GAAG,IAAI,EACxB,mBAAmB,GAAG,KAAK,EAC3B,QAAQ,GAAG,IAAI,EACf,gBAAgB,GAAG,KAAK,EACxB,eAAe,GAAG,IAAI,EACtB,WAAW,GAAG,IAAI,EAClB,UAAU,GAAG,IAAI,EACjB,gBAAgB,GAAG,IAAI,GACL;IAClB,OAAO;QACL,iBAAiB;QACjB,mBAAmB;QACnB,QAAQ;QACR,gBAAgB;QAChB,eAAe;QACf,WAAW;QACX,UAAU;QACV,gBAAgB;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG,eAAe,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;AAE5D,SAAgB,WAAW,CAAC,OAA2B;IACrD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;AAClD,CAAC"}
|