Commit Graph
88 Commits
Author SHA1 Message Date
jake 3595e5b42c refactor: replace runtime Intl.DisplayNames with a static CLDR-generated country table
- Add `scripts/generate-countries.mjs` to enumerate all current ISO 3166-1 alpha-2 codes via CLDR and emit `src/lib/countries-data.ts`; retired, exceptionally-reserved, and CLDR-only pseudo codes are explicitly excluded, XK (Kosovo) is kept
- Replace the live `Intl.DisplayNames` calls in `countries.ts` with a direct lookup against the generated `COUNTRY_NAMES` record, eliminating variance between Node/ICU versions
- Build the reverse `nameToCode` map from `COUNTRY_NAMES` entries instead of a double-nested loop over the alphabet
- Fix `countryCodeFromName` to fall through to `ALIASES` for two-letter inputs that aren't valid codes (e.g. `"UK"` → `"GB"`)
- Add `myanmar` / `"myanmar burma"` aliases so the CLDR-style name and the legacy WHOIS variant both resolve to `MM`
- Extend `countries.test.ts` to assert pinned names, XK presence, retired/reserved code exclusion, and `UK` alias behaviour
2026-09-19 23:14:43 -04:00
jake 89fa13ffef feat: add contact redacted flag, placeholder detection, and country name/code resolution
- Add `redacted?: boolean` to `Contact`; set when any field was dropped as a placeholder, the name matches a privacy-service heuristic, or an RFC 9537 redaction targets that entity's role
- Add `isPlaceholderValue` to `privacy.ts` to identify boilerplate registrar strings (`"Please query the RDDS…"`, `"redacted"`, `"n/a"`, etc.) used in place of real email/phone/fax values; drop them from the contact during finalization
- Add `countries.ts` backed by `Intl.DisplayNames` (with a curated `ALIASES` table for common alternate names) providing `countryNameFromCode`, `countryCodeFromName`, and `resolveCountry`; a two-letter `country` value is now treated as a code and expanded to a full name
- Introduce `finalizeContact` in `contacts.ts` to centralise all contact post-processing (placeholder stripping, country resolution, `redacted` flag); call it from both RDAP and WHOIS normalizers
- Wire RFC 9537 redaction role-matching into `extractContacts` via a new `redactionTargetsRole` helper so entities targeted by a `redacted` entry automatically receive `redacted: true`
- Add `countries.test.ts` and extend RDAP/WHOIS normalizer tests to cover placeholder stripping, country fill-in, and redaction flag propagation
2026-09-19 23:07:38 -04:00
jake 1d04be5c74 fix: tighten isPrivacyName to avoid false positives on ambiguous privacy words
- Split keyword list into `PRIVACY_STRONG_KEYWORDS` (matched as plain substrings) and two weaker sets (`PRIVACY_WEAK_WORDS` / `PRIVACY_CONTEXT_WORDS`) that only trigger when at least two distinct terms appear together, preventing names like "Private Equity Partners LLC" or "Protection One" from being misclassified
- Remove empty-placeholder values (`-`, `n/a`, `none`, etc.) from the privacy check; they are not privacy notices and should be handled separately by callers
- Add `privacy.test.ts` covering redaction notices, known privacy-service names, ordinary names with ambiguous words, and empty placeholders
- Update README comment to clarify that `privacyEnabled` is set by name heuristics (privacy-service and redaction phrases) or RFC 9537 redactions
2026-09-19 23:04:01 -04:00
jake 386006dc61 feat: add RFC 9537 redaction support, vCard address/fax parsing, and registrar address fields
- Parse the top-level RDAP `redacted` array (RFC 9537) into a new `redactions` field on `DomainRecord`; set `privacyEnabled` when any redaction references "registrant"
- Expose `street`, `city`, `state`, `postalCode`, `country`, and `countryCode` on both `RegistrarInfo` and `Contact`; extract ISO 3166-1 alpha-2 from the vCard `cc` parameter (RFC 8605)
- Split `tel` entries by fax type parameter (`"fax"` / `["work","fax"]`) into separate `tel` and `fax` lists; collect multiple email addresses as an array, collapsing singletons to a plain string
- Prefer an exact `registration` event match over `reregistration` when extracting `creationDate` (RFC 9083)
- Merge `redacted` arrays in `mergeRdapDocs`, deduplicating by JSON identity
- Split `adr` street on `\r?\n` only (not commas) to avoid splitting inline comma-separated addresses
2026-09-19 23:01:30 -04:00
jake e77fc7f4ed 0.15.1 2026-09-19 12:32:07 -04:00
jake 93f877c357 fix: extend Retry-After parsing to RDAP 503 and fix block pattern across newlines
- Parse `Retry-After` on RDAP `503` responses (previously only `429`), exposing `retryAfterMs` on the attempt and on the top-level result when `rdapOnly` makes it terminal
- Fix the WHOIS `BLOCK_PATTERNS` regex to use `[\s\S]` instead of `.` so a block notice that spans multiple lines (e.g. `"Your IP address\nhas been blocked"`) is still classified as `blocked`
- Update README to document `retryAfterMs` on `LookupResult`, clarify `rate_limited` / `blocked` / `unparseable` semantics, and note referral-host validation behaviour
2026-09-19 12:30:06 -04:00
jake 35959b208b feat: surface retryAfterMs, add blocked error code, and harden private-address guard
- Parse `Retry-After` headers (delay-seconds or HTTP-date) into `retryAfterMs` via a new `parseRetryAfterMs` helper and expose the value on both `LookupAttempt` and `LookupResult` so callers can honour server-requested back-off without parsing the error string
- Propagate `retryAfterMs` through `classifyError`, `traced`, `failure`, and the `rdap_unavailable` path so the value surfaces on the top-level result
- Add `blocked` to `LookupErrorCode` for WHOIS servers that permanently refuse a client (distinct from `rate_limited`, which is a temporary throttle that may succeed on retry)
- Add `blockPrivateAddresses` to `WhoisTransportOptions`; when set, a custom `dns.lookup` shim rejects the connection before it opens if any resolved address is non-public, covering DNS rebinding and hostnames that resolve to private ranges
- Expand `isPrivateIp` / `isSafeWhoisReferralHost` to reject IPv4-mapped (`::ffff:7f00:1`), NAT64 (`64:ff9b::`), 6to4 (`2002:7f00::`), Teredo (`2001:0:`), deprecated site-local (`fec0::`), and bracketed IPv6 literals
2026-09-19 12:25:30 -04:00
jake 208fd6c69f 0.15.0 2026-09-19 12:17:47 -04:00
jake 3023c5dd1b feat: add SSRF host validation, rate_limited/unparseable error codes, and referral chain warnings
- Add `isSafeWhoisReferralHost` to reject private/loopback/link-local IPs and malformed hostnames before following WHOIS referrals (SSRF guard)
- Detect WHOIS throttle replies in the referral chain: drop the registrar response, keep the registry record, and surface a warning instead of returning bad data
- Add `looksEmptyWhois` guard in the main lookup path: a "registered" record with no parseable fields now fails with `errorCode: "unparseable"` rather than resolving silently
- Map RDAP 429 responses to a structured `rate_limited` error (including `Retry-After` header) so callers can distinguish throttling from generic HTTP errors and the fallback to WHOIS is recorded in `attempts`
- Add `rate_limited` and `unparseable` to `LookupErrorCode`
- Change `collectWhoisReferralChain` to return `{ results, warnings }` instead of a bare array; warnings are merged onto the final `DomainRecord`
- Remove the `followWhoisReferrals` fallback path from `index.ts` (dead code after the chain API stabilised)
2026-09-19 12:14:19 -04:00
jake 61c5897317 0.14.0 2026-09-19 00:56:46 -04:00
jake 56051dccd0 chore: fix lockfile 2026-09-19 00:56:30 -04:00
jake be8e88592f feat: add ccTLD-specific date formats, noisy-token parsing, and .gg/.je/.br/.ua normalization, closes #20 and #25
- Add `toISOFromTokens` to extract ISO dates from noisy values (e.g. ".ua" `0-UANIC 20111004161638`, `OK-UNTIL 20261004161638`)
- Parse compact `YYYYMMDDHHMMSS` (.ua) and `YYYYMMDD` (.br, including ticket suffix like `20260319 #31066859`) date formats
- Parse ordinal/prose dates used by .gg/.je (`28th December 2018 at 05:54:43.861`)
- Teach `parseKeyValueLines` to collect indented continuation lines for header-style blocks (.gg/.je) without mistaking URLs or times as key separators
- Extract .gg/.je expiry from `Relevant dates:` sentences and split inline registrar URL (`epag (http://www.epag.de)`)
- Map .ua `status: OK-UNTIL <timestamp>` to `expirationDate` when no explicit expiry field is present
- Treat RDAP `pending release` / `release process: waiting` statuses as `isRegistered: false` (previously always `true`)
- Mark WHOIS `.br` `release process: waiting` as available
2026-09-19 00:51:55 -04:00
jake e736045de1 fix: treat WHOIS empty-close as no_data and ETIMEDOUT as structured timeout
- A server that accepts the connection and closes it without sending data now rejects with `errorCode: "no_data"` and `stage: "read"` instead of resolving with an empty string
- OS-level `ETIMEDOUT` errors are mapped to the same `timeout` / `stage` shape as the library's own timer, with `stage` derived from whether the socket had connected yet
- `ECONNRESET` after data arrives is no longer marked `partial: true`; it was a complete reply and the reset just signalled the end of the stream
- `stage` on `LookupAttempt` is now documented as covering all WHOIS failures (not only timeout failures)
2026-09-18 14:47:31 -04:00
jake 69f85ee925 feat: add attempt tracking, deadlineMs, and structured error codes
- Resolve `LookupResult` with an `attempts` array describing every network operation (phase, server, duration, error) so failures recovered by fallback remain visible
- Add `deadlineMs` option for a hard cap on total lookup time, distinct from per-operation `timeoutMs` (lowered default from 15 s to 10 s)
- Add `errorCode` (machine-readable `LookupErrorCode`), `errorPhase`, and `errorServer` to `LookupResult`; `timeout` covers both per-op and deadline timeouts, `aborted` means the caller's signal fired
- WHOIS timeouts now distinguish `connect` vs `read` stage and resolve with partial text (marked `partial: true`) when data arrived before the socket stalled
- Drop Node 18 support; minimum engine is now 20
2026-09-18 14:41:16 -04:00
jake 87e20f4a47 chore: replace Biome with oxlint and oxfmt 2026-09-18 14:21:15 -04:00
jake 5ff837b2bb chore(deps): update dependencies and build configuration 2026-09-18 14:10:09 -04:00
jake a37ab8a6d8 0.13.0 2026-01-10 13:35:11 -05:00
jake 0f64809bb1 chore: add GitHub Actions workflow for testing across multiple Node.js versions 2026-01-10 13:34:27 -05:00
jake 6ef4291d0e 0.12.1 2025-12-30 12:53:25 -05:00
jake e6b2e94614 fix: update tsdown outputs from .js to .mjs 2025-12-30 12:53:17 -05:00
jake c6da4c1f69 0.12.0 2025-12-30 12:45:00 -05:00
jake ab1326d99c fix: improve transfer lock status detection 2025-12-30 12:43:55 -05:00
jake 1b73b7dc8d chore: bump deps 2025-12-30 12:41:13 -05:00
jake b72324fd95 0.11.0 2025-10-30 19:07:47 -04:00
jake 619185b5d6 Add support for custom fetch function and/or IANA bootstrap data (#21) 2025-10-30 19:07:12 -04:00
jake 8c8dec5a37 0.10.4 2025-10-27 15:01:07 -04:00
jake 2a92375116 Add support for DD-MM-YYYY date format in toISO function and update tests (fixes #19) 2025-10-27 14:59:14 -04:00
jake fd29899f4e 0.10.3 2025-10-27 14:44:25 -04:00
jake 9d87ef8ecb Add to list of parser strings to improve WHOIS data normalization 2025-10-27 14:42:43 -04:00
jake 1c6fbad1f7 0.10.2 2025-10-22 17:45:40 -04:00
jake 87b85f7d3d Add query transformation for non-English WHOIS servers, specifically for whois.jprs.jp (fixes #15) 2025-10-22 17:45:19 -04:00
jake c3b6477094 0.10.1 2025-10-22 17:38:36 -04:00
jake b8357e38bc Fix .hk, .ee, .il date parsing (fixes #13, #14, #16) 2025-10-22 17:37:37 -04:00
jake f90c481c94 0.10.0 2025-10-20 15:06:29 -04:00
jake b3adbf8307 Rename lookupDomain() to lookup() (with backwards compatibility) 2025-10-20 15:05:59 -04:00
jake 5cbefe6a14 Update README.md with clearer usage instructions 2025-10-20 14:48:16 -04:00
jake 52e5c54f9f 0.9.1 2025-10-20 14:30:48 -04:00
jake b9d4d42e19 Update GitHub Actions workflow to install the latest npm version before publishing 2025-10-20 14:24:35 -04:00
jake 2f0e784cf7 Run npm pkg fix 2025-10-20 14:20:26 -04:00
jake d87e898a9f Add additional synonyms for WHOIS normalization (fixes #10) 2025-10-20 14:15:23 -04:00
jake 2a1b7529cc Implement WHOIS referral chain collection and merging logic (fixes #11)
- Introduced `collectWhoisReferralChain` to gather WHOIS responses while avoiding contradictory data from registrars.
- Updated `lookupDomain` to utilize the new chain collection method, ensuring TLD responses are prioritized.
- Added `mergeWhoisRecords` function to consolidate WHOIS data from multiple sources.
- Enhanced tests for referral handling and merging behavior, ensuring accurate data retention across scenarios.
2025-10-20 14:08:26 -04:00
jake b00d0bbb0a Fix order of package.json exports 2025-10-20 14:05:33 -04:00
jake 9fcad5438b Add GitHub Actions workflow for publishing to NPM on release 2025-10-20 14:03:35 -04:00
jake 9ca8943e78 Bump dev dependencies 2025-10-20 13:57:58 -04:00
jake dbe63b0b9f 0.8.0 2025-10-17 22:04:57 -04:00
jake b171b5ec75 Update getDomainParts to allow passing options to tldts.parse(). 2025-10-17 22:04:37 -04:00
jake 0cfca2c877 0.7.0 2025-10-14 13:25:26 -04:00
jake 4e9b99a25f Prefer TLD WHOIS over contradictory registrar referral; revert heuristic override and add referral test\n\n- Keep TLD response when registrar says ‘not found’\n- Revert WHOIS isRegistered to simple availability check\n- Add referral contradiction unit test for .io scenario\n- All tests passing 2025-10-14 13:24:51 -04:00
jake c3a68639b6 Update CLI script path to use .js extension 2025-10-14 13:01:03 -04:00
jake 08a5b9a576 Make the (very minimal) CLI official 2025-10-12 17:14:37 -04:00
jake 35c73e2bb2 0.6.0 2025-10-12 13:56:54 -04:00
jake db96e8d933 Lazy load node:net for improved edge runtime compatibility 2025-10-12 13:52:50 -04:00
jake 94a751d9b0 0.5.0 2025-10-10 10:45:10 -04:00
jake 6070d91424 Add toRegistrableDomain function for domain normalization 2025-10-10 10:44:04 -04:00
jake bfcecc5eff Migrate from psl to tldts for public suffix detection 2025-10-10 10:29:29 -04:00
jake a030817d27 0.4.1 2025-10-08 21:43:49 -04:00
jake 33203b2b47 Remove fetchedAt field from DomainRecord interface and related functions 2025-10-08 21:43:32 -04:00
jake 476ead274d 0.4.0 2025-10-08 21:32:04 -04:00
jake 2c9904e5e8 New privacyEnabled field to detect redaction based on keyword heuristics
Updated the DomainRecord interface to include detailed comments for clarity and added a new privacyEnabled field to indicate if the registrant's information is privacy-redacted. Enhanced normalization functions for both RDAP and WHOIS to derive the privacy flag based on registrant keywords. Updated tests to verify the correct functionality of privacy detection in both normalization processes. Additionally, the README was updated to reflect the inclusion of the privacy flag in the normalized output.
2025-10-08 21:31:21 -04:00
jake 57209eae39 0.3.0 2025-10-08 19:43:38 -04:00
jake 15e807f093 Refactor date parsing function and improve test coverage
Renamed the `parseWithRegex` function to `parseDateWithRegex` for clarity and consistency. Added a blank line in the `toISO` test to enhance readability. These changes aim to improve code maintainability and ensure better test organization.
2025-10-08 19:43:01 -04:00
jake 9661db0b46 Enhance date parsing in WHOIS and add tests for registrar expiration dates
Updated the `toISO` function to handle various timezone formats in WHOIS date strings. Added tests to verify parsing of registrar registration expiration dates and EDUCAUSE format dates in the normalization process. This improves the accuracy of date handling in WHOIS responses.
2025-10-08 19:39:56 -04:00
jake f8280508ff Enhance RDAP and WHOIS functionality with referral handling
Added support for following registrar WHOIS referrals with configurable hop limits. Introduced new options in LookupOptions for maximum referral hops and RDAP link handling. Updated README to reflect these changes and improved the lookupDomain function to utilize the new referral logic. Added utility functions for merging RDAP documents and extracting related links.
2025-10-08 19:25:51 -04:00
jake 27b3187d33 0.2.0 2025-09-28 21:31:42 -04:00
jake c76da2bf5c Replaced tsconfig.build.json with tsdown configuration for simplified builds. 2025-09-28 21:30:57 -04:00
jake d09d8e4ffd 0.1.1 2025-09-26 11:51:14 -04:00
jake 174cae8610 Update testing framework to Vitest (#4) 2025-09-26 11:49:44 -04:00
jake 5bc6debe30 Enhance WHOIS fallback error handling and add IANA WHOIS parsing utilities
Updated the error messages in the lookupDomain function to provide clearer guidance when RDAP is unavailable or when no WHOIS server is discovered for a TLD. Introduced new utility functions to parse IANA WHOIS responses, improving the discovery process for WHOIS servers and registration information URLs.
2025-09-26 11:48:02 -04:00
jake e873fb7629 Add link to hoot.sh in README
Updated README to include a link to hoot.sh
2025-09-24 21:29:45 -04:00
jake 863c158e28 0.1.0 2025-09-24 19:57:16 -04:00
jake e1e6d0243a Update project metadata and TypeScript configuration: refine repository details in package.json, simplify tsconfig.build.json, and adjust tsconfig.json for cleaner output settings. 2025-09-24 19:55:48 -04:00
jake aa8d089b6d Update package.json: enhance project metadata with new description, author details, and keywords for better discoverability 2025-09-24 19:52:10 -04:00
jake dc0ff2a00b Refine README examples and API documentation: simplify usage of lookupDomain function and clarify fallback behavior for RDAP and WHOIS. 2025-09-24 19:30:22 -04:00
jake fda6d09096 Add includeRaw option to CLI and API: enable inclusion of raw RDAP/WHOIS data in results 2025-09-24 19:24:57 -04:00
jake 05445ef831 Update repository guidelines and README: enhance project structure documentation, clarify build and test commands, and improve API usage examples for better user understanding. 2025-09-24 19:19:41 -04:00
jake 3429c70bd7 Update WHOIS TLD exceptions: refine server entries, correct outdated references, and enhance documentation for clarity. 2025-09-24 19:09:26 -04:00
jake 6857b0d11b Refactor WHOIS handling: move WHOIS_TLD_EXCEPTIONS to servers.ts, update imports in discovery and index files, and add DEFAULT_TIMEOUT_MS constant to bootstrap and client modules for consistency. 2025-09-24 18:57:55 -04:00
jake e5ec1b488c Update TypeScript configuration and introduce constants: change module resolution to NodeNext, add DEFAULT_TIMEOUT_MS constant for consistent timeout handling across RDAP and WHOIS clients. 2025-09-24 18:53:50 -04:00
jake 67f9bb68fa Implement domain lookup in index.ts: consolidate RDAP and WHOIS logic into a single function, add availability checks, and enhance type definitions. Remove deprecated lookup.ts and introduce smoke tests for comprehensive coverage of lookup scenarios. 2025-09-24 18:47:03 -04:00
jake 4f568ac409 Add smoke tests for domain lookup: implement RDAP and WHOIS scenarios for example domains, including negative cases for RDAP-only lookups. Enhance test coverage for date parsing with non-null assertions in date tests. 2025-09-24 18:35:33 -04:00
jake 36cf6d6b38 Enhance project structure: add AGENTS.md for repository guidelines, update .gitignore to exclude TypeScript build info, and refine package.json scripts for improved build and publish processes. 2025-09-24 18:24:47 -04:00
jake 56e9e23e4b 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. 2025-09-24 17:40:03 -04:00
jake 0a852ff3cd Add CLI script for domain lookup and create package-lock.json; update README and package.json for clarity and dependencies 2025-09-24 17:28:12 -04:00
jake 43fa2a12c7 Update exports in index.ts to include .js extensions, add centralized WHOIS server fallbacks for TLDs in whois-fallbacks.ts, and integrate fallbacks into the ianaWhoisServerForTld function in whois.ts for improved error handling. 2025-09-24 16:53:12 -04:00
jake a788b0147a Refactor lookup and normalization functions to improve type safety and error handling. Updated domain lookup to provide a stable ISO string fallback and enhanced error messaging. Modified RDAP normalization to use stricter types and added utility functions for type assertions. 2025-09-24 14:56:56 -04:00
jake 38cf9c5eaa Update biome configuration and package scripts. Removed unused ignore file option in biome.json and added file includes. Modified build script in package.json to use tsc directly and added a lint script for biome checks. 2025-09-24 14:32:49 -04:00
jake 33a648460b Core functionality for domain lookup using RDAP and WHOIS protocols, along with utility functions and tests. 2025-09-24 14:28:09 -04:00
jake bd4846302d Initial commit 2025-09-24 13:06:40 -04:00