diff --git a/README.md b/README.md index 23d8da3..43d68b6 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,10 @@ await isAvailable("likely-unregistered-thing-320485230458.com"); // => true - Returns the registrable domain string, or `null` for IPs/invalid input; [options](https://github.com/remusao/tldts/blob/master/packages/tldts-core/src/options.ts) are forwarded to `tldts` (e.g., `allowPrivateDomains`). - `isRegistered(domain, options?) => Promise` - `isAvailable(domain, options?) => Promise` +- `finalizeContact(contact, redactedHint?) => Contact` + - Cleans a contact: drops placeholder values (recording them in `redactedFields`), sets `privacyService`, resolves `country`/`countryCode`, and sets `redacted`. Safe to re-run on an already-cleaned contact, e.g. to upgrade contacts stored by an older version. +- `isPrivacyContact(contact) => boolean` + - True when the contact's name/organization is a privacy service or was redacted. ### CLI diff --git a/src/lib/contacts.test.ts b/src/lib/contacts.test.ts index 934d2b3..c593bf5 100644 --- a/src/lib/contacts.test.ts +++ b/src/lib/contacts.test.ts @@ -1,6 +1,6 @@ import { expect, test } from "vitest"; import { finalizeContact, redactionFields } from "./contacts"; -import { isPlaceholderValue } from "./privacy"; +import { isPlaceholderValue, isPrivacyName } from "./privacy"; import * as api from "../index"; test("finalizeContact drops placeholder name/organization and records redactedFields", () => { @@ -139,3 +139,32 @@ test("finalizeContact and isPrivacyContact are exported", () => { expect(api.finalizeContact).toBe(finalizeContact); expect(api.isPrivacyContact({ type: "registrant", privacyService: true })).toBe(true); }); + +test("bare 'not available' phrases are whole-value only", () => { + expect(isPlaceholderValue("Address not available in this region")).toBe(false); + expect(isPlaceholderValue("Not Available")).toBe(true); + expect(isPrivacyName("Not Available")).toBe(false); + expect(isPrivacyName("No Data Corp")).toBe(false); +}); + +test("redactionFields handles country code and multi-field names", () => { + expect(redactionFields("Registrant Country Code")).toEqual(["country"]); + expect(redactionFields("Registrant Street, City, Country")).toEqual([ + "street", + "city", + "country", + ]); +}); + +test("a dropped country keeps a separate countryCode, and survives re-finalizing", () => { + const c = finalizeContact({ type: "registrant", country: "N/A", countryCode: "US" }); + expect(c.countryCode).toBe("US"); + expect(c.country).toBe("United States"); + expect(c.redactedFields).toEqual(["country"]); + expect(c.redacted).toBe(true); + + const again = finalizeContact(structuredClone(c)); + expect(again.redactedFields).toEqual(["country"]); + expect(again.redacted).toBe(true); + expect(again).toEqual(c); +});