mirror of
https://github.com/jakejarvis/rdapper.git
synced 2026-09-23 01:25:31 -04:00
chore: replace Biome with oxlint and oxfmt
This commit is contained in:
@@ -31,13 +31,7 @@ describe("WHOIS coalescing", () => {
|
||||
|
||||
const [first] = chain;
|
||||
if (!first) throw new Error("Expected first record");
|
||||
const base = normalizeWhois(
|
||||
"gitpod.io",
|
||||
"io",
|
||||
first.text,
|
||||
first.serverQueried,
|
||||
false,
|
||||
);
|
||||
const base = normalizeWhois("gitpod.io", "io", first.text, first.serverQueried, false);
|
||||
const merged = mergeWhoisRecords(base, []);
|
||||
expect(merged.isRegistered).toBe(true);
|
||||
expect(merged.creationDate).toBeDefined();
|
||||
|
||||
+4
-16
@@ -1,10 +1,7 @@
|
||||
import { uniq } from "../lib/text";
|
||||
import type { Contact, DomainRecord, Nameserver } from "../types";
|
||||
|
||||
function dedupeStatuses(
|
||||
a?: DomainRecord["statuses"],
|
||||
b?: DomainRecord["statuses"],
|
||||
) {
|
||||
function dedupeStatuses(a?: DomainRecord["statuses"], b?: DomainRecord["statuses"]) {
|
||||
const list = [...(a || []), ...(b || [])];
|
||||
const seen = new Set<string>();
|
||||
const out: NonNullable<DomainRecord["statuses"]> = [];
|
||||
@@ -48,10 +45,7 @@ function dedupeContacts(a?: Contact[], b?: Contact[]) {
|
||||
}
|
||||
|
||||
/** Conservative merge: start with base; fill missing scalars; union arrays; prefer more informative dates. */
|
||||
export function mergeWhoisRecords(
|
||||
base: DomainRecord,
|
||||
others: DomainRecord[],
|
||||
): DomainRecord {
|
||||
export function mergeWhoisRecords(base: DomainRecord, others: DomainRecord[]): DomainRecord {
|
||||
const merged: DomainRecord = { ...base };
|
||||
for (const cur of others) {
|
||||
merged.isRegistered = merged.isRegistered || cur.isRegistered;
|
||||
@@ -60,15 +54,9 @@ export function mergeWhoisRecords(
|
||||
merged.reseller = merged.reseller ?? cur.reseller;
|
||||
merged.statuses = dedupeStatuses(merged.statuses, cur.statuses);
|
||||
// Dates: prefer earliest creation, latest updated/expiration when available
|
||||
merged.creationDate = preferEarliestIso(
|
||||
merged.creationDate,
|
||||
cur.creationDate,
|
||||
);
|
||||
merged.creationDate = preferEarliestIso(merged.creationDate, cur.creationDate);
|
||||
merged.updatedDate = preferLatestIso(merged.updatedDate, cur.updatedDate);
|
||||
merged.expirationDate = preferLatestIso(
|
||||
merged.expirationDate,
|
||||
cur.expirationDate,
|
||||
);
|
||||
merged.expirationDate = preferLatestIso(merged.expirationDate, cur.expirationDate);
|
||||
merged.deletionDate = merged.deletionDate ?? cur.deletionDate;
|
||||
merged.transferLock = Boolean(merged.transferLock || cur.transferLock);
|
||||
merged.dnssec = merged.dnssec ?? cur.dnssec;
|
||||
|
||||
@@ -159,12 +159,7 @@ Name Server: NS2.EXAMPLE.COM
|
||||
DNSSEC: unsigned
|
||||
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
|
||||
`;
|
||||
const rec = normalizeWhois(
|
||||
"example.com",
|
||||
"com",
|
||||
text,
|
||||
"whois.verisign-grs.com",
|
||||
);
|
||||
const rec = normalizeWhois("example.com", "com", text, "whois.verisign-grs.com");
|
||||
expect(Boolean(rec.creationDate)).toBe(true);
|
||||
expect(Boolean(rec.expirationDate)).toBe(true);
|
||||
expect(rec.source).toBe("whois");
|
||||
@@ -178,12 +173,7 @@ Registrar URL: http://www.registrar.test
|
||||
Registrant Name: REDACTED FOR PRIVACY
|
||||
Registrant Organization: Example Org
|
||||
`;
|
||||
const rec = normalizeWhois(
|
||||
"example.com",
|
||||
"com",
|
||||
text,
|
||||
"whois.verisign-grs.com",
|
||||
);
|
||||
const rec = normalizeWhois("example.com", "com", text, "whois.verisign-grs.com");
|
||||
expect(rec.privacyEnabled).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
+15
-65
@@ -1,12 +1,7 @@
|
||||
import { toISO } from "../lib/dates";
|
||||
import { isPrivacyName } from "../lib/privacy";
|
||||
import { parseKeyValueLines, uniq } from "../lib/text";
|
||||
import type {
|
||||
Contact,
|
||||
DomainRecord,
|
||||
Nameserver,
|
||||
RegistrarInfo,
|
||||
} from "../types";
|
||||
import type { Contact, DomainRecord, Nameserver, RegistrarInfo } from "../types";
|
||||
|
||||
// Common WHOIS availability phrases seen across registries/registrars
|
||||
const WHOIS_AVAILABLE_PATTERNS: RegExp[] = [
|
||||
@@ -123,11 +118,7 @@ export function normalizeWhois(
|
||||
"organisation",
|
||||
"record maintained by",
|
||||
]);
|
||||
const ianaId = anyValue(map, [
|
||||
"registrar iana id",
|
||||
"sponsoring registrar iana id",
|
||||
"iana id",
|
||||
]);
|
||||
const ianaId = anyValue(map, ["registrar iana id", "sponsoring registrar iana id", "iana id"]);
|
||||
const url = anyValue(map, [
|
||||
"registrar url",
|
||||
"registrar website",
|
||||
@@ -135,16 +126,9 @@ export function normalizeWhois(
|
||||
"url of the registrar",
|
||||
"referrer",
|
||||
]);
|
||||
const abuseEmail = anyValue(map, [
|
||||
"registrar abuse contact email",
|
||||
"abuse contact email",
|
||||
]);
|
||||
const abusePhone = anyValue(map, [
|
||||
"registrar abuse contact phone",
|
||||
"abuse contact phone",
|
||||
]);
|
||||
if (!name && !ianaId && !url && !abuseEmail && !abusePhone)
|
||||
return undefined;
|
||||
const abuseEmail = anyValue(map, ["registrar abuse contact email", "abuse contact email"]);
|
||||
const abusePhone = anyValue(map, ["registrar abuse contact phone", "abuse contact phone"]);
|
||||
if (!name && !ianaId && !url && !abuseEmail && !abusePhone) return undefined;
|
||||
return {
|
||||
name: name || undefined,
|
||||
ianaId: ianaId || undefined,
|
||||
@@ -222,15 +206,11 @@ export function normalizeWhois(
|
||||
const registrant = contacts?.find((c) => c.type === "registrant");
|
||||
const privacyEnabled = !!(
|
||||
registrant &&
|
||||
(
|
||||
[registrant.name, registrant.organization].filter(Boolean) as string[]
|
||||
).some(isPrivacyName)
|
||||
([registrant.name, registrant.organization].filter(Boolean) as string[]).some(isPrivacyName)
|
||||
);
|
||||
|
||||
const dnssecRaw = (map.dnssec?.[0] || "").toLowerCase();
|
||||
const dnssec = dnssecRaw
|
||||
? { enabled: /signed|yes|true/.test(dnssecRaw) }
|
||||
: undefined;
|
||||
const dnssec = dnssecRaw ? { enabled: /signed|yes|true/.test(dnssecRaw) } : undefined;
|
||||
|
||||
// Simple lock derivation from statuses
|
||||
const transferLock = !!statuses?.some((s) =>
|
||||
@@ -268,10 +248,7 @@ export function normalizeWhois(
|
||||
return record;
|
||||
}
|
||||
|
||||
function anyValue(
|
||||
map: Record<string, string[]>,
|
||||
keys: string[],
|
||||
): string | undefined {
|
||||
function anyValue(map: Record<string, string[]>, keys: string[]): string | undefined {
|
||||
for (const k of keys) {
|
||||
const v = map[k];
|
||||
if (v?.length) return v[0];
|
||||
@@ -327,11 +304,7 @@ function collectContacts(map: Record<string, string[]>): Contact[] | undefined {
|
||||
nameKeys.push("owner name"); // .tm
|
||||
}
|
||||
|
||||
orgKeys.push(
|
||||
`${prefix} organization`,
|
||||
`${prefix} organisation`,
|
||||
`${prefix} org`,
|
||||
);
|
||||
orgKeys.push(`${prefix} organization`, `${prefix} organisation`, `${prefix} org`);
|
||||
if (prefix === "registrant") {
|
||||
orgKeys.push("trading as"); // .uk, .co.uk
|
||||
orgKeys.push("org"); // .ru
|
||||
@@ -340,42 +313,22 @@ function collectContacts(map: Record<string, string[]>): Contact[] | undefined {
|
||||
orgKeys.push("owner orgname"); // .tm
|
||||
}
|
||||
|
||||
emailKeys.push(
|
||||
`${prefix} email`,
|
||||
`${prefix} contact email`,
|
||||
`${prefix} e-mail`,
|
||||
);
|
||||
emailKeys.push(`${prefix} email`, `${prefix} contact email`, `${prefix} e-mail`);
|
||||
|
||||
phoneKeys.push(
|
||||
`${prefix} phone`,
|
||||
`${prefix} contact phone`,
|
||||
`${prefix} telephone`,
|
||||
);
|
||||
phoneKeys.push(`${prefix} phone`, `${prefix} contact phone`, `${prefix} telephone`);
|
||||
|
||||
faxKeys.push(`${prefix} fax`, `${prefix} facsimile`);
|
||||
|
||||
streetKeys.push(
|
||||
`${prefix} street`,
|
||||
`${prefix} address`,
|
||||
`${prefix}'s address`,
|
||||
);
|
||||
streetKeys.push(`${prefix} street`, `${prefix} address`, `${prefix}'s address`);
|
||||
if (prefix === "owner") {
|
||||
streetKeys.push("owner addr"); // .tm
|
||||
}
|
||||
|
||||
cityKeys.push(`${prefix} city`);
|
||||
|
||||
stateKeys.push(
|
||||
`${prefix} state`,
|
||||
`${prefix} province`,
|
||||
`${prefix} state/province`,
|
||||
);
|
||||
stateKeys.push(`${prefix} state`, `${prefix} province`, `${prefix} state/province`);
|
||||
|
||||
postalCodeKeys.push(
|
||||
`${prefix} postal code`,
|
||||
`${prefix} postcode`,
|
||||
`${prefix} zip`,
|
||||
);
|
||||
postalCodeKeys.push(`${prefix} postal code`, `${prefix} postcode`, `${prefix} zip`);
|
||||
|
||||
countryKeys.push(`${prefix} country`);
|
||||
}
|
||||
@@ -410,10 +363,7 @@ function collectContacts(map: Record<string, string[]>): Contact[] | undefined {
|
||||
return contacts.length ? contacts : undefined;
|
||||
}
|
||||
|
||||
function multi(
|
||||
map: Record<string, string[]>,
|
||||
keys: string[],
|
||||
): string[] | undefined {
|
||||
function multi(map: Record<string, string[]>, keys: string[]): string[] | undefined {
|
||||
for (const k of keys) {
|
||||
const v = map[k];
|
||||
if (v?.length) return v;
|
||||
|
||||
@@ -32,11 +32,10 @@ describe("WHOIS referral contradiction handling", () => {
|
||||
});
|
||||
|
||||
it("collects chain and does not append contradictory registrar", async () => {
|
||||
const chain = await collectWhoisReferralChain(
|
||||
"whois.nic.io",
|
||||
"raindrop.io",
|
||||
{ followWhoisReferral: true, maxWhoisReferralHops: 2 },
|
||||
);
|
||||
const chain = await collectWhoisReferralChain("whois.nic.io", "raindrop.io", {
|
||||
followWhoisReferral: true,
|
||||
maxWhoisReferralHops: 2,
|
||||
});
|
||||
expect(Array.isArray(chain)).toBe(true);
|
||||
// Mocked registrar is contradictory, so chain should contain only the TLD response
|
||||
expect(chain.length).toBe(1);
|
||||
|
||||
Reference in New Issue
Block a user