mirror of
https://github.com/jakejarvis/rdapper.git
synced 2025-10-18 20:14:27 -04:00
Refactor domain lookup to utilize getDomainParts for TLD extraction and enhance WHOIS query handling with fallback options for multi-label public suffixes. Updated utility functions for improved clarity and functionality.
This commit is contained in:
@@ -2,7 +2,7 @@ import { normalizeRdap } from "./normalize-rdap.js";
|
||||
import { normalizeWhois } from "./normalize-whois.js";
|
||||
import { fetchRdapDomain, getRdapBaseUrlsForTld } from "./rdap.js";
|
||||
import type { DomainRecord, LookupOptions, LookupResult } from "./types.js";
|
||||
import { extractTld, isLikelyDomain, toISO } from "./utils.js";
|
||||
import { getDomainParts, isLikelyDomain, toISO } from "./utils.js";
|
||||
import {
|
||||
extractWhoisReferral,
|
||||
ianaWhoisServerForTld,
|
||||
@@ -21,7 +21,7 @@ export async function lookupDomain(
|
||||
if (!isLikelyDomain(domain)) {
|
||||
return { ok: false, error: "Input does not look like a domain" };
|
||||
}
|
||||
const tld = extractTld(domain);
|
||||
const { publicSuffix, tld } = getDomainParts(domain);
|
||||
// Avoid non-null assertion: fallback to a stable ISO string if parsing ever fails
|
||||
const now =
|
||||
toISO(new Date()) ?? new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
|
||||
@@ -60,6 +60,7 @@ export async function lookupDomain(
|
||||
if (!whoisServer) {
|
||||
return { ok: false, error: "No WHOIS server discovered for TLD" };
|
||||
}
|
||||
// Query the TLD server first; if it returns a referral, we follow it below.
|
||||
let res = await whoisQuery(whoisServer, domain, opts);
|
||||
if (opts?.followWhoisReferral !== false) {
|
||||
const referral = extractWhoisReferral(res.text);
|
||||
@@ -71,6 +72,30 @@ export async function lookupDomain(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If TLD registry returns no match and there was no referral, try multi-label public suffix candidates
|
||||
if (
|
||||
publicSuffix.includes(".") &&
|
||||
/no match|not found/i.test(res.text) &&
|
||||
opts?.followWhoisReferral !== false
|
||||
) {
|
||||
const candidates = [
|
||||
`whois.nic.${publicSuffix.toLowerCase()}`,
|
||||
// Widely used by many second-level public suffix registries
|
||||
"whois.centralnic.com",
|
||||
];
|
||||
for (const server of candidates) {
|
||||
try {
|
||||
const alt = await whoisQuery(server, domain, opts);
|
||||
if (alt.text && !/error/i.test(alt.text)) {
|
||||
res = alt;
|
||||
break;
|
||||
}
|
||||
} catch {
|
||||
// try next
|
||||
}
|
||||
}
|
||||
}
|
||||
const record: DomainRecord = normalizeWhois(
|
||||
domain,
|
||||
tld,
|
||||
|
23
src/utils.ts
23
src/utils.ts
@@ -192,10 +192,7 @@ export function sleep(ms: number): Promise<void> {
|
||||
export function extractTld(domain: string): string {
|
||||
const lower = domain.trim().toLowerCase();
|
||||
try {
|
||||
const parsed = psl.parse?.(lower);
|
||||
if (!("tld" in parsed)) {
|
||||
return lower;
|
||||
}
|
||||
const parsed = psl.parse?.(lower) as { tld?: string };
|
||||
const suffix = parsed?.tld;
|
||||
if (suffix) {
|
||||
const labels = String(suffix).split(".").filter(Boolean);
|
||||
@@ -208,6 +205,24 @@ export function extractTld(domain: string): string {
|
||||
return parts[parts.length - 1] ?? lower;
|
||||
}
|
||||
|
||||
export function getDomainParts(domain: string): { publicSuffix: string; tld: string } {
|
||||
const lower = domain.toLowerCase().trim();
|
||||
let publicSuffix: string | undefined;
|
||||
try {
|
||||
const parsed = psl.parse?.(lower) as { tld?: string };
|
||||
publicSuffix = parsed?.tld;
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
if (!publicSuffix) {
|
||||
const parts = lower.split(".").filter(Boolean);
|
||||
publicSuffix = parts.length ? parts[parts.length - 1] : lower;
|
||||
}
|
||||
const labels = publicSuffix.split(".").filter(Boolean);
|
||||
const tld = labels.length ? labels[labels.length - 1] : publicSuffix;
|
||||
return { publicSuffix, tld };
|
||||
}
|
||||
|
||||
export function isLikelyDomain(input: string): boolean {
|
||||
return /^[a-z0-9.-]+$/i.test(input) && input.includes(".");
|
||||
}
|
||||
|
Reference in New Issue
Block a user