export const RESERVED_SUBDOMAINS = new Set([ 'app', 'api', 'www', 'admin', 'auth', 'mail', 'static', ]); const SUBDOMAIN_RE = /^[a-z0-9-]{3,32}$/; export function validateSubdomain(input: unknown): | { ok: true; value: string } | { ok: false; error: string } { if (typeof input !== 'string') { return { ok: false, error: 'subdomain must be a string' }; } const value = input.trim().toLowerCase(); if (!SUBDOMAIN_RE.test(value)) { return { ok: false, error: 'subdomain must be 3–32 chars, lowercase a–z, 0–9, hyphen', }; } if (RESERVED_SUBDOMAINS.has(value)) { return { ok: false, error: `'${value}' is reserved` }; } return { ok: true, value }; }