* Normalize a raw domain input to its canonical form. * Returns the canonical form and the reason code if the input was changed.
(raw: string)
| 53 | * Returns the canonical form and the reason code if the input was changed. |
| 54 | */ |
| 55 | function normalizeDomain(raw: string): NormalizeResult { |
| 56 | const trimmed = raw.trim(); |
| 57 | |
| 58 | // Strip protocol, path, query, fragment, trailing slash |
| 59 | let canonical = trimmed |
| 60 | .replace(/^https?:\/\//i, '') |
| 61 | .replace(/[/?#].*$/, '') |
| 62 | .replace(/\.$/, '') // trailing FQDN dot |
| 63 | .replace(/\/$/, '') |
| 64 | .toLowerCase(); |
| 65 | |
| 66 | let reason: string | null = null; |
| 67 | |
| 68 | if (canonical.startsWith('www.')) { |
| 69 | canonical = canonical.slice(4); |
| 70 | reason = 'www_stripped'; |
| 71 | } else if (canonical.startsWith('m.')) { |
| 72 | canonical = canonical.slice(2); |
| 73 | reason = 'm_stripped'; |
| 74 | } else if (canonical !== trimmed.replace(/^https?:\/\//i, '').replace(/[/?#].*$/, '').replace(/\.$/, '').replace(/\/$/, '').toLowerCase()) { |
| 75 | reason = 'normalized'; |
| 76 | } |
| 77 | |
| 78 | return { canonical, reason }; |
| 79 | } |
| 80 | |
| 81 | export class PropertyCheckService { |
| 82 | async check(domains: string[]): Promise<CheckResult> { |