1.8 KiB
Capability Spec: domain-normalizer
Package: @suaveplan/domain-normalizer
Version: 0.0.0 (genesis)
Status: ADDED
ADDED Requirements
DN-01 — Normalisation contract
normalizeDomain(input) MUST lowercase, trim, strip leading www., strip port, and apply punycode conversion for IDNs. For any valid input, normalizeDomain(normalizeDomain(x)) MUST equal normalizeDomain(x).
DN-02 — Registrable domain via PSL
getRegistrableDomain(input) MUST return the domain at the public-suffix+1 level using the Public Suffix List via tldts. For a.b.co.uk → b.co.uk. Invalid inputs MUST return undefined, not throw.
DN-03 — Alias canonicalisation
getCanonicalDomain(input) MUST resolve built-in aliases (e.g. m.youtube.com, youtu.be → youtube.com) plus any aliases registered via config.customAliases. isKnownAlias MUST return true iff the input matches any alias rule. resetAliasCache MUST clear any memoisation.
DN-04 — Similarity
computeSimilarity(a, b) MUST return a value in [0, 1] combining normalised Levenshtein distance and PSL-level registrable-domain equality. levenshteinDistance MUST be a standard O(|a|·|b|) implementation.
DN-05 — Match result
matchDomains(a, b, config?) MUST return DomainMatch { matched, reason, score }. reason MUST be one of 'exact' | 'alias' | 'registrable-equal' | 'similarity' | 'none'.
DN-06 — URL parsing
normalizeUrl(url) MUST return NormalizedUrl { protocol, host, port?, pathname, search, hash, registrableDomain, subdomain, canonicalDomain }. Malformed URLs MUST surface as DOMAIN_NORMALIZER.INVALID_INPUT.
DN-07 — Observability
Every normalisation MUST emit domain_normalizer.normalize.total{outcome} counter and domain_normalizer.normalize.duration_ms histogram.