refactor: extract vCard parser into its own module and expand parsed fields

- Move `parseVcard` out of `normalize.ts` into a new `src/rdap/vcard.ts` module; export `readJCard` (jCard → `VCardProp[]`) and `paramList` as reusable primitives
- Parse `KIND` into a typed `VCardKind` union and split structured `ORG` values into a top-level `org` plus an `orgUnits` array for sub-levels
- Parse `TITLE` and `ROLE` properties from the vCard
- Extract the PO box (element 0) and extended address (element 1) from `ADR` into `poBox` and the beginning of `street` respectively, rather than discarding them
- Strip `tel:` URI scheme from `TEL` entries whose `valueType` is `uri` (RFC 6350)
- Add `kind`, `organizationUnits`, `title`, `role`, and `poBox` to the `Contact` type and wire them through `extractContacts` in `normalize.ts`
- Document new `Contact` fields in README
- Add `vcard.test.ts` covering malformed input tolerance, `paramList` normalisation, ORG level splitting, unknown KIND, PO box extraction, and `tel:` URI stripping
This commit is contained in:
2026-09-19 23:20:15 -04:00
parent 3595e5b42c
commit 992c54ad28
6 changed files with 301 additions and 95 deletions
+5
View File
@@ -544,10 +544,15 @@ interface DomainRecord {
type:
"registrant" | "admin" | "tech" | "billing" | "abuse" | "registrar" | "reseller" | "unknown";
name?: string;
kind?: "individual" | "org" | "group" | "location"; // vCard KIND (RDAP only, when provided)
organization?: string;
organizationUnits?: string[]; // vCard ORG levels below the organization (RDAP only)
title?: string; // RDAP only
role?: string; // RDAP only
email?: string | string[];
phone?: string | string[];
fax?: string | string[];
poBox?: string; // RDAP only
street?: string[];
city?: string;
state?: string;