rdapper 0.1.1 → 0.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.
- package/README.md +6 -1
- package/dist/index.d.ts +95 -5
- package/dist/index.js +1026 -114
- package/package.json +12 -9
- package/dist/lib/async.d.ts +0 -2
- package/dist/lib/async.js +0 -18
- package/dist/lib/constants.d.ts +0 -1
- package/dist/lib/constants.js +0 -1
- package/dist/lib/dates.d.ts +0 -1
- package/dist/lib/dates.js +0 -84
- package/dist/lib/domain.d.ts +0 -8
- package/dist/lib/domain.js +0 -64
- package/dist/lib/text.d.ts +0 -6
- package/dist/lib/text.js +0 -77
- package/dist/rdap/bootstrap.d.ts +0 -6
- package/dist/rdap/bootstrap.js +0 -30
- package/dist/rdap/client.d.ts +0 -9
- package/dist/rdap/client.js +0 -21
- package/dist/rdap/normalize.d.ts +0 -6
- package/dist/rdap/normalize.js +0 -214
- package/dist/types.d.ts +0 -83
- package/dist/types.js +0 -1
- package/dist/whois/client.d.ts +0 -10
- package/dist/whois/client.js +0 -46
- package/dist/whois/discovery.d.ts +0 -24
- package/dist/whois/discovery.js +0 -99
- package/dist/whois/normalize.d.ts +0 -6
- package/dist/whois/normalize.js +0 -214
- package/dist/whois/servers.d.ts +0 -1
- package/dist/whois/servers.js +0 -64
package/dist/types.d.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
export type LookupSource = "rdap" | "whois";
|
|
2
|
-
export interface RegistrarInfo {
|
|
3
|
-
name?: string;
|
|
4
|
-
ianaId?: string;
|
|
5
|
-
url?: string;
|
|
6
|
-
email?: string;
|
|
7
|
-
phone?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface Contact {
|
|
10
|
-
type: "registrant" | "admin" | "tech" | "billing" | "abuse" | "registrar" | "reseller" | "unknown";
|
|
11
|
-
name?: string;
|
|
12
|
-
organization?: string;
|
|
13
|
-
email?: string | string[];
|
|
14
|
-
phone?: string | string[];
|
|
15
|
-
fax?: string | string[];
|
|
16
|
-
street?: string[];
|
|
17
|
-
city?: string;
|
|
18
|
-
state?: string;
|
|
19
|
-
postalCode?: string;
|
|
20
|
-
country?: string;
|
|
21
|
-
countryCode?: string;
|
|
22
|
-
}
|
|
23
|
-
export interface Nameserver {
|
|
24
|
-
host: string;
|
|
25
|
-
ipv4?: string[];
|
|
26
|
-
ipv6?: string[];
|
|
27
|
-
}
|
|
28
|
-
export interface StatusEvent {
|
|
29
|
-
status: string;
|
|
30
|
-
description?: string;
|
|
31
|
-
raw?: string;
|
|
32
|
-
}
|
|
33
|
-
export interface DomainRecord {
|
|
34
|
-
domain: string;
|
|
35
|
-
tld: string;
|
|
36
|
-
isRegistered: boolean;
|
|
37
|
-
isIDN?: boolean;
|
|
38
|
-
unicodeName?: string;
|
|
39
|
-
punycodeName?: string;
|
|
40
|
-
registry?: string;
|
|
41
|
-
registrar?: RegistrarInfo;
|
|
42
|
-
reseller?: string;
|
|
43
|
-
statuses?: StatusEvent[];
|
|
44
|
-
creationDate?: string;
|
|
45
|
-
updatedDate?: string;
|
|
46
|
-
expirationDate?: string;
|
|
47
|
-
deletionDate?: string;
|
|
48
|
-
transferLock?: boolean;
|
|
49
|
-
dnssec?: {
|
|
50
|
-
enabled: boolean;
|
|
51
|
-
dsRecords?: Array<{
|
|
52
|
-
keyTag?: number;
|
|
53
|
-
algorithm?: number;
|
|
54
|
-
digestType?: number;
|
|
55
|
-
digest?: string;
|
|
56
|
-
}>;
|
|
57
|
-
};
|
|
58
|
-
nameservers?: Nameserver[];
|
|
59
|
-
contacts?: Contact[];
|
|
60
|
-
whoisServer?: string;
|
|
61
|
-
rdapServers?: string[];
|
|
62
|
-
rawRdap?: unknown;
|
|
63
|
-
rawWhois?: string;
|
|
64
|
-
source: LookupSource;
|
|
65
|
-
fetchedAt: string;
|
|
66
|
-
warnings?: string[];
|
|
67
|
-
}
|
|
68
|
-
export interface LookupOptions {
|
|
69
|
-
timeoutMs?: number;
|
|
70
|
-
rdapOnly?: boolean;
|
|
71
|
-
whoisOnly?: boolean;
|
|
72
|
-
followWhoisReferral?: boolean;
|
|
73
|
-
customBootstrapUrl?: string;
|
|
74
|
-
whoisHints?: Record<string, string>;
|
|
75
|
-
includeRaw?: boolean;
|
|
76
|
-
signal?: AbortSignal;
|
|
77
|
-
}
|
|
78
|
-
export interface LookupResult {
|
|
79
|
-
ok: boolean;
|
|
80
|
-
record?: DomainRecord;
|
|
81
|
-
error?: string;
|
|
82
|
-
}
|
|
83
|
-
export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
package/dist/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/whois/client.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { LookupOptions } from "../types.js";
|
|
2
|
-
export interface WhoisQueryResult {
|
|
3
|
-
serverQueried: string;
|
|
4
|
-
text: string;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Perform a WHOIS query against an RFC 3912 server over TCP 43.
|
|
8
|
-
* Returns the raw text and the server used.
|
|
9
|
-
*/
|
|
10
|
-
export declare function whoisQuery(server: string, query: string, options?: LookupOptions): Promise<WhoisQueryResult>;
|
package/dist/whois/client.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { createConnection } from "node:net";
|
|
2
|
-
import { withTimeout } from "../lib/async.js";
|
|
3
|
-
import { DEFAULT_TIMEOUT_MS } from "../lib/constants.js";
|
|
4
|
-
/**
|
|
5
|
-
* Perform a WHOIS query against an RFC 3912 server over TCP 43.
|
|
6
|
-
* Returns the raw text and the server used.
|
|
7
|
-
*/
|
|
8
|
-
export async function whoisQuery(server, query, options) {
|
|
9
|
-
const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
10
|
-
const port = 43;
|
|
11
|
-
const host = server.replace(/^whois:\/\//i, "");
|
|
12
|
-
const text = await withTimeout(queryTcp(host, port, query, options), timeoutMs, "WHOIS timeout");
|
|
13
|
-
return { serverQueried: server, text };
|
|
14
|
-
}
|
|
15
|
-
// Low-level WHOIS TCP client. Some registries require CRLF after the domain query.
|
|
16
|
-
function queryTcp(host, port, query, options) {
|
|
17
|
-
return new Promise((resolve, reject) => {
|
|
18
|
-
const socket = createConnection({ host, port });
|
|
19
|
-
let data = "";
|
|
20
|
-
let done = false;
|
|
21
|
-
const cleanup = () => {
|
|
22
|
-
if (done)
|
|
23
|
-
return;
|
|
24
|
-
done = true;
|
|
25
|
-
socket.destroy();
|
|
26
|
-
};
|
|
27
|
-
socket.setTimeout((options?.timeoutMs ?? DEFAULT_TIMEOUT_MS) - 1000, () => {
|
|
28
|
-
cleanup();
|
|
29
|
-
reject(new Error("WHOIS socket timeout"));
|
|
30
|
-
});
|
|
31
|
-
socket.on("error", (err) => {
|
|
32
|
-
cleanup();
|
|
33
|
-
reject(err);
|
|
34
|
-
});
|
|
35
|
-
socket.on("data", (chunk) => {
|
|
36
|
-
data += chunk.toString("utf8");
|
|
37
|
-
});
|
|
38
|
-
socket.on("end", () => {
|
|
39
|
-
cleanup();
|
|
40
|
-
resolve(data);
|
|
41
|
-
});
|
|
42
|
-
socket.on("connect", () => {
|
|
43
|
-
socket.write(`${query}\r\n`);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { LookupOptions } from "../types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Parse the IANA WHOIS response for a TLD and extract the WHOIS server
|
|
4
|
-
* without crossing line boundaries. Some TLDs (e.g. .np) leave the field
|
|
5
|
-
* blank, in which case this returns undefined.
|
|
6
|
-
*/
|
|
7
|
-
export declare function parseIanaWhoisServer(text: string): string | undefined;
|
|
8
|
-
/**
|
|
9
|
-
* Parse a likely registration information URL from an IANA WHOIS response.
|
|
10
|
-
* Looks at lines like:
|
|
11
|
-
* remarks: Registration information: http://example.tld
|
|
12
|
-
* url: https://registry.example
|
|
13
|
-
*/
|
|
14
|
-
export declare function parseIanaRegistrationInfoUrl(text: string): string | undefined;
|
|
15
|
-
/** Fetch raw IANA WHOIS text for a TLD (best-effort). */
|
|
16
|
-
export declare function getIanaWhoisTextForTld(tld: string, options?: LookupOptions): Promise<string | undefined>;
|
|
17
|
-
/**
|
|
18
|
-
* Best-effort discovery of the authoritative WHOIS server for a TLD via IANA root DB.
|
|
19
|
-
*/
|
|
20
|
-
export declare function ianaWhoisServerForTld(tld: string, options?: LookupOptions): Promise<string | undefined>;
|
|
21
|
-
/**
|
|
22
|
-
* Extract registrar referral WHOIS server from a WHOIS response, if present.
|
|
23
|
-
*/
|
|
24
|
-
export declare function extractWhoisReferral(text: string): string | undefined;
|
package/dist/whois/discovery.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { whoisQuery } from "./client.js";
|
|
2
|
-
import { WHOIS_TLD_EXCEPTIONS } from "./servers.js";
|
|
3
|
-
/**
|
|
4
|
-
* Parse the IANA WHOIS response for a TLD and extract the WHOIS server
|
|
5
|
-
* without crossing line boundaries. Some TLDs (e.g. .np) leave the field
|
|
6
|
-
* blank, in which case this returns undefined.
|
|
7
|
-
*/
|
|
8
|
-
export function parseIanaWhoisServer(text) {
|
|
9
|
-
// Search lines in priority order: whois, refer, whois server
|
|
10
|
-
const fields = ["whois", "refer", "whois server"];
|
|
11
|
-
const lines = String(text).split(/\r?\n/);
|
|
12
|
-
for (const field of fields) {
|
|
13
|
-
for (const raw of lines) {
|
|
14
|
-
const line = raw.trimEnd();
|
|
15
|
-
// Match beginning of line, allowing leading spaces, case-insensitive
|
|
16
|
-
const re = new RegExp(`^\\s*${field}\\s*:\\s*(.*?)$`, "i");
|
|
17
|
-
const m = line.match(re);
|
|
18
|
-
if (m) {
|
|
19
|
-
const value = (m[1] || "").trim();
|
|
20
|
-
if (value)
|
|
21
|
-
return value;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Parse a likely registration information URL from an IANA WHOIS response.
|
|
29
|
-
* Looks at lines like:
|
|
30
|
-
* remarks: Registration information: http://example.tld
|
|
31
|
-
* url: https://registry.example
|
|
32
|
-
*/
|
|
33
|
-
export function parseIanaRegistrationInfoUrl(text) {
|
|
34
|
-
const lines = String(text).split(/\r?\n/);
|
|
35
|
-
for (const raw of lines) {
|
|
36
|
-
const line = raw.trim();
|
|
37
|
-
if (!/^\s*(remarks|url|website)\s*:/i.test(line))
|
|
38
|
-
continue;
|
|
39
|
-
const urlMatch = line.match(/https?:\/\/\S+/i);
|
|
40
|
-
if (urlMatch?.[0])
|
|
41
|
-
return urlMatch[0];
|
|
42
|
-
}
|
|
43
|
-
return undefined;
|
|
44
|
-
}
|
|
45
|
-
/** Fetch raw IANA WHOIS text for a TLD (best-effort). */
|
|
46
|
-
export async function getIanaWhoisTextForTld(tld, options) {
|
|
47
|
-
try {
|
|
48
|
-
const res = await whoisQuery("whois.iana.org", tld.toLowerCase(), options);
|
|
49
|
-
return res.text;
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Best-effort discovery of the authoritative WHOIS server for a TLD via IANA root DB.
|
|
57
|
-
*/
|
|
58
|
-
export async function ianaWhoisServerForTld(tld, options) {
|
|
59
|
-
const key = tld.toLowerCase();
|
|
60
|
-
// 1) Explicit hint override
|
|
61
|
-
const hint = options?.whoisHints?.[key];
|
|
62
|
-
if (hint)
|
|
63
|
-
return normalizeServer(hint);
|
|
64
|
-
// 2) IANA WHOIS authoritative discovery over TCP 43
|
|
65
|
-
try {
|
|
66
|
-
const res = await whoisQuery("whois.iana.org", key, options);
|
|
67
|
-
const txt = res.text;
|
|
68
|
-
const server = parseIanaWhoisServer(txt);
|
|
69
|
-
if (server)
|
|
70
|
-
return normalizeServer(server);
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
// fallthrough to exceptions/guess
|
|
74
|
-
}
|
|
75
|
-
// 3) Curated exceptions
|
|
76
|
-
const exception = WHOIS_TLD_EXCEPTIONS[key];
|
|
77
|
-
if (exception)
|
|
78
|
-
return normalizeServer(exception);
|
|
79
|
-
return undefined;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Extract registrar referral WHOIS server from a WHOIS response, if present.
|
|
83
|
-
*/
|
|
84
|
-
export function extractWhoisReferral(text) {
|
|
85
|
-
const patterns = [
|
|
86
|
-
/^Registrar WHOIS Server:\s*(.+)$/im,
|
|
87
|
-
/^Whois Server:\s*(.+)$/im,
|
|
88
|
-
/^ReferralServer:\s*whois:\/\/(.+)$/im,
|
|
89
|
-
];
|
|
90
|
-
for (const re of patterns) {
|
|
91
|
-
const m = text.match(re);
|
|
92
|
-
if (m?.[1])
|
|
93
|
-
return m[1].trim();
|
|
94
|
-
}
|
|
95
|
-
return undefined;
|
|
96
|
-
}
|
|
97
|
-
function normalizeServer(server) {
|
|
98
|
-
return server.replace(/^whois:\/\//i, "").replace(/\/$/, "");
|
|
99
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { DomainRecord } from "../types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Convert raw WHOIS text into our normalized DomainRecord.
|
|
4
|
-
* Heuristics cover many gTLD and ccTLD formats; exact fields vary per registry.
|
|
5
|
-
*/
|
|
6
|
-
export declare function normalizeWhois(domain: string, tld: string, whoisText: string, whoisServer: string | undefined, fetchedAtISO: string, includeRaw?: boolean): DomainRecord;
|
package/dist/whois/normalize.js
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import { toISO } from "../lib/dates.js";
|
|
2
|
-
import { isWhoisAvailable } from "../lib/domain.js";
|
|
3
|
-
import { parseKeyValueLines, uniq } from "../lib/text.js";
|
|
4
|
-
/**
|
|
5
|
-
* Convert raw WHOIS text into our normalized DomainRecord.
|
|
6
|
-
* Heuristics cover many gTLD and ccTLD formats; exact fields vary per registry.
|
|
7
|
-
*/
|
|
8
|
-
export function normalizeWhois(domain, tld, whoisText, whoisServer, fetchedAtISO, includeRaw = false) {
|
|
9
|
-
const map = parseKeyValueLines(whoisText);
|
|
10
|
-
// Date extraction across common synonyms
|
|
11
|
-
const creationDate = anyValue(map, [
|
|
12
|
-
"creation date",
|
|
13
|
-
"created on",
|
|
14
|
-
"registered on",
|
|
15
|
-
"domain registration date",
|
|
16
|
-
"domain create date",
|
|
17
|
-
"created",
|
|
18
|
-
"registered",
|
|
19
|
-
]);
|
|
20
|
-
const updatedDate = anyValue(map, [
|
|
21
|
-
"updated date",
|
|
22
|
-
"last updated",
|
|
23
|
-
"last modified",
|
|
24
|
-
"modified",
|
|
25
|
-
]);
|
|
26
|
-
const expirationDate = anyValue(map, [
|
|
27
|
-
"registry expiry date",
|
|
28
|
-
"expiry date",
|
|
29
|
-
"expiration date",
|
|
30
|
-
"paid-till",
|
|
31
|
-
"expires on",
|
|
32
|
-
"renewal date",
|
|
33
|
-
]);
|
|
34
|
-
// Registrar info (thin registries like .com/.net require referral follow for full data)
|
|
35
|
-
const registrar = (() => {
|
|
36
|
-
const name = anyValue(map, [
|
|
37
|
-
"registrar",
|
|
38
|
-
"sponsoring registrar",
|
|
39
|
-
"registrar name",
|
|
40
|
-
]);
|
|
41
|
-
const ianaId = anyValue(map, ["registrar iana id", "iana id"]);
|
|
42
|
-
const url = anyValue(map, [
|
|
43
|
-
"registrar url",
|
|
44
|
-
"url of the registrar",
|
|
45
|
-
"referrer",
|
|
46
|
-
]);
|
|
47
|
-
const abuseEmail = anyValue(map, [
|
|
48
|
-
"registrar abuse contact email",
|
|
49
|
-
"abuse contact email",
|
|
50
|
-
]);
|
|
51
|
-
const abusePhone = anyValue(map, [
|
|
52
|
-
"registrar abuse contact phone",
|
|
53
|
-
"abuse contact phone",
|
|
54
|
-
]);
|
|
55
|
-
if (!name && !ianaId && !url && !abuseEmail && !abusePhone)
|
|
56
|
-
return undefined;
|
|
57
|
-
return {
|
|
58
|
-
name: name || undefined,
|
|
59
|
-
ianaId: ianaId || undefined,
|
|
60
|
-
url: url || undefined,
|
|
61
|
-
email: abuseEmail || undefined,
|
|
62
|
-
phone: abusePhone || undefined,
|
|
63
|
-
};
|
|
64
|
-
})();
|
|
65
|
-
// Statuses: multiple entries are expected; keep raw
|
|
66
|
-
const statusLines = map["domain status"] || map.status || [];
|
|
67
|
-
const statuses = statusLines.length
|
|
68
|
-
? statusLines.map((line) => ({ status: line.split(/\s+/)[0], raw: line }))
|
|
69
|
-
: undefined;
|
|
70
|
-
// Nameservers: also appear as "nserver" on some ccTLDs (.de, .ru) and as "name server"
|
|
71
|
-
const nsLines = [
|
|
72
|
-
...(map["name server"] || []),
|
|
73
|
-
...(map.nameserver || []),
|
|
74
|
-
...(map["name servers"] || []),
|
|
75
|
-
...(map.nserver || []),
|
|
76
|
-
];
|
|
77
|
-
const nameservers = nsLines.length
|
|
78
|
-
? uniq(nsLines
|
|
79
|
-
.map((line) => line.trim())
|
|
80
|
-
.filter(Boolean)
|
|
81
|
-
.map((line) => {
|
|
82
|
-
// Common formats: "ns1.example.com" or "ns1.example.com 192.0.2.1" or "ns1.example.com 2001:db8::1"
|
|
83
|
-
const parts = line.split(/\s+/);
|
|
84
|
-
const host = parts.shift()?.toLowerCase() || "";
|
|
85
|
-
const ipv4 = [];
|
|
86
|
-
const ipv6 = [];
|
|
87
|
-
for (const p of parts) {
|
|
88
|
-
if (/^\d+\.\d+\.\d+\.\d+$/.test(p))
|
|
89
|
-
ipv4.push(p);
|
|
90
|
-
else if (/^[0-9a-f:]+$/i.test(p))
|
|
91
|
-
ipv6.push(p);
|
|
92
|
-
}
|
|
93
|
-
if (!host)
|
|
94
|
-
return undefined;
|
|
95
|
-
const ns = { host };
|
|
96
|
-
if (ipv4.length)
|
|
97
|
-
ns.ipv4 = ipv4;
|
|
98
|
-
if (ipv6.length)
|
|
99
|
-
ns.ipv6 = ipv6;
|
|
100
|
-
return ns;
|
|
101
|
-
})
|
|
102
|
-
.filter((x) => !!x))
|
|
103
|
-
: undefined;
|
|
104
|
-
// Contacts: best-effort parse common keys
|
|
105
|
-
const contacts = collectContacts(map);
|
|
106
|
-
const dnssecRaw = (map.dnssec?.[0] || "").toLowerCase();
|
|
107
|
-
const dnssec = dnssecRaw
|
|
108
|
-
? { enabled: /signed|yes|true/.test(dnssecRaw) }
|
|
109
|
-
: undefined;
|
|
110
|
-
// Simple lock derivation from statuses
|
|
111
|
-
const transferLock = !!statuses?.some((s) => /transferprohibited/i.test(s.status));
|
|
112
|
-
const record = {
|
|
113
|
-
domain,
|
|
114
|
-
tld,
|
|
115
|
-
isRegistered: !isWhoisAvailable(whoisText),
|
|
116
|
-
isIDN: /(^|\.)xn--/i.test(domain),
|
|
117
|
-
unicodeName: undefined,
|
|
118
|
-
punycodeName: undefined,
|
|
119
|
-
registry: undefined,
|
|
120
|
-
registrar,
|
|
121
|
-
reseller: anyValue(map, ["reseller"]) || undefined,
|
|
122
|
-
statuses,
|
|
123
|
-
creationDate: toISO(creationDate || undefined),
|
|
124
|
-
updatedDate: toISO(updatedDate || undefined),
|
|
125
|
-
expirationDate: toISO(expirationDate || undefined),
|
|
126
|
-
deletionDate: undefined,
|
|
127
|
-
transferLock,
|
|
128
|
-
dnssec,
|
|
129
|
-
nameservers,
|
|
130
|
-
contacts,
|
|
131
|
-
whoisServer,
|
|
132
|
-
rdapServers: undefined,
|
|
133
|
-
rawRdap: undefined,
|
|
134
|
-
rawWhois: includeRaw ? whoisText : undefined,
|
|
135
|
-
source: "whois",
|
|
136
|
-
fetchedAt: fetchedAtISO,
|
|
137
|
-
warnings: undefined,
|
|
138
|
-
};
|
|
139
|
-
return record;
|
|
140
|
-
}
|
|
141
|
-
function anyValue(map, keys) {
|
|
142
|
-
for (const k of keys) {
|
|
143
|
-
const v = map[k];
|
|
144
|
-
if (v?.length)
|
|
145
|
-
return v[0];
|
|
146
|
-
}
|
|
147
|
-
return undefined;
|
|
148
|
-
}
|
|
149
|
-
function collectContacts(map) {
|
|
150
|
-
const roles = [
|
|
151
|
-
{ role: "registrant", prefix: "registrant" },
|
|
152
|
-
{ role: "admin", prefix: "admin" },
|
|
153
|
-
{ role: "tech", prefix: "tech" },
|
|
154
|
-
{ role: "billing", prefix: "billing" },
|
|
155
|
-
{ role: "abuse", prefix: "abuse" },
|
|
156
|
-
];
|
|
157
|
-
const contacts = [];
|
|
158
|
-
for (const r of roles) {
|
|
159
|
-
const name = anyValue(map, [
|
|
160
|
-
`${r.prefix} name`,
|
|
161
|
-
`${r.prefix} contact name`,
|
|
162
|
-
`${r.prefix}`,
|
|
163
|
-
]);
|
|
164
|
-
const org = anyValue(map, [`${r.prefix} organization`, `${r.prefix} org`]);
|
|
165
|
-
const email = anyValue(map, [
|
|
166
|
-
`${r.prefix} email`,
|
|
167
|
-
`${r.prefix} contact email`,
|
|
168
|
-
`${r.prefix} e-mail`,
|
|
169
|
-
]);
|
|
170
|
-
const phone = anyValue(map, [
|
|
171
|
-
`${r.prefix} phone`,
|
|
172
|
-
`${r.prefix} contact phone`,
|
|
173
|
-
`${r.prefix} telephone`,
|
|
174
|
-
]);
|
|
175
|
-
const fax = anyValue(map, [`${r.prefix} fax`, `${r.prefix} facsimile`]);
|
|
176
|
-
const street = multi(map, [`${r.prefix} street`, `${r.prefix} address`]);
|
|
177
|
-
const city = anyValue(map, [`${r.prefix} city`]);
|
|
178
|
-
const state = anyValue(map, [
|
|
179
|
-
`${r.prefix} state`,
|
|
180
|
-
`${r.prefix} province`,
|
|
181
|
-
`${r.prefix} state/province`,
|
|
182
|
-
]);
|
|
183
|
-
const postalCode = anyValue(map, [
|
|
184
|
-
`${r.prefix} postal code`,
|
|
185
|
-
`${r.prefix} postcode`,
|
|
186
|
-
`${r.prefix} zip`,
|
|
187
|
-
]);
|
|
188
|
-
const country = anyValue(map, [`${r.prefix} country`]);
|
|
189
|
-
if (name || org || email || phone || street?.length) {
|
|
190
|
-
contacts.push({
|
|
191
|
-
type: r.role,
|
|
192
|
-
name: name || undefined,
|
|
193
|
-
organization: org || undefined,
|
|
194
|
-
email: email || undefined,
|
|
195
|
-
phone: phone || undefined,
|
|
196
|
-
fax: fax || undefined,
|
|
197
|
-
street: street,
|
|
198
|
-
city: city || undefined,
|
|
199
|
-
state: state || undefined,
|
|
200
|
-
postalCode: postalCode || undefined,
|
|
201
|
-
country: country || undefined,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return contacts.length ? contacts : undefined;
|
|
206
|
-
}
|
|
207
|
-
function multi(map, keys) {
|
|
208
|
-
for (const k of keys) {
|
|
209
|
-
const v = map[k];
|
|
210
|
-
if (v?.length)
|
|
211
|
-
return v;
|
|
212
|
-
}
|
|
213
|
-
return undefined;
|
|
214
|
-
}
|
package/dist/whois/servers.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const WHOIS_TLD_EXCEPTIONS: Record<string, string>;
|
package/dist/whois/servers.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// Curated authoritative WHOIS servers by TLD (exceptions to default/referral logic)
|
|
2
|
-
// Source of truth checked against IANA delegation records; prefer RDAP first.
|
|
3
|
-
export const WHOIS_TLD_EXCEPTIONS = {
|
|
4
|
-
// gTLDs (port-43 still available at registry)
|
|
5
|
-
com: "whois.verisign-grs.com",
|
|
6
|
-
net: "whois.verisign-grs.com",
|
|
7
|
-
org: "whois.publicinterestregistry.org", // PIR
|
|
8
|
-
biz: "whois.nic.biz",
|
|
9
|
-
name: "whois.nic.name",
|
|
10
|
-
edu: "whois.educause.edu",
|
|
11
|
-
gov: "whois.nic.gov", // was whois.dotgov.gov
|
|
12
|
-
// ccTLDs & other TLDs with working port-43 WHOIS
|
|
13
|
-
de: "whois.denic.de",
|
|
14
|
-
jp: "whois.jprs.jp",
|
|
15
|
-
fr: "whois.nic.fr",
|
|
16
|
-
it: "whois.nic.it",
|
|
17
|
-
pl: "whois.dns.pl",
|
|
18
|
-
nl: "whois.domain-registry.nl",
|
|
19
|
-
be: "whois.dns.be",
|
|
20
|
-
se: "whois.iis.se",
|
|
21
|
-
no: "whois.norid.no",
|
|
22
|
-
fi: "whois.fi",
|
|
23
|
-
cz: "whois.nic.cz",
|
|
24
|
-
es: "whois.nic.es",
|
|
25
|
-
br: "whois.registro.br",
|
|
26
|
-
ca: "whois.cira.ca",
|
|
27
|
-
dk: "whois.punktum.dk", // was whois.dk-hostmaster.dk
|
|
28
|
-
hk: "whois.hkirc.hk",
|
|
29
|
-
sg: "whois.sgnic.sg",
|
|
30
|
-
in: "whois.nixiregistry.in", // was whois.registry.in
|
|
31
|
-
nz: "whois.irs.net.nz", // was whois.srs.net.nz
|
|
32
|
-
ch: "whois.nic.ch",
|
|
33
|
-
li: "whois.nic.li",
|
|
34
|
-
io: "whois.nic.io",
|
|
35
|
-
ai: "whois.nic.ai",
|
|
36
|
-
ru: "whois.tcinet.ru",
|
|
37
|
-
su: "whois.tcinet.ru",
|
|
38
|
-
us: "whois.nic.us",
|
|
39
|
-
co: "whois.nic.co",
|
|
40
|
-
me: "whois.nic.me",
|
|
41
|
-
tv: "whois.nic.tv",
|
|
42
|
-
cc: "ccwhois.verisign-grs.com",
|
|
43
|
-
eu: "whois.eu",
|
|
44
|
-
au: "whois.auda.org.au",
|
|
45
|
-
kr: "whois.kr",
|
|
46
|
-
tw: "whois.twnic.net.tw",
|
|
47
|
-
uk: "whois.nic.uk",
|
|
48
|
-
nu: "whois.iis.nu",
|
|
49
|
-
"xn--p1ai": "whois.tcinet.ru", // .рф
|
|
50
|
-
// CentralNic-operated public SLD zones (still WHOIS @ centralnic)
|
|
51
|
-
"uk.com": "whois.centralnic.com",
|
|
52
|
-
"uk.net": "whois.centralnic.com",
|
|
53
|
-
"gb.com": "whois.centralnic.com",
|
|
54
|
-
"gb.net": "whois.centralnic.com",
|
|
55
|
-
"eu.com": "whois.centralnic.com",
|
|
56
|
-
"us.com": "whois.centralnic.com",
|
|
57
|
-
"se.com": "whois.centralnic.com",
|
|
58
|
-
"de.com": "whois.centralnic.com",
|
|
59
|
-
"br.com": "whois.centralnic.com",
|
|
60
|
-
"ru.com": "whois.centralnic.com",
|
|
61
|
-
"cn.com": "whois.centralnic.com",
|
|
62
|
-
"sa.com": "whois.centralnic.com",
|
|
63
|
-
"co.com": "whois.centralnic.com",
|
|
64
|
-
};
|