export type UrlValidation = | { ok: true; url: string } | { ok: false; error: string }; const ALLOWED_PROTOCOLS = new Set(["http:", "https:"]); export function normalizeUrl(raw: string): string { const trimmed = raw.trim(); if (trimmed === "") return trimmed; if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)) return trimmed; return `https://${trimmed}`; } export function validateUrl(raw: string): UrlValidation { const trimmed = raw.trim(); if (trimmed === "") return { ok: false, error: "Enter a URL" }; const candidate = normalizeUrl(trimmed); let parsed: URL; try { parsed = new URL(candidate); } catch { return { ok: false, error: "That doesn't look like a URL" }; } if (!ALLOWED_PROTOCOLS.has(parsed.protocol)) { return { ok: false, error: "Only http and https URLs are allowed" }; } if (!parsed.hostname) { return { ok: false, error: "That doesn't look like a URL" }; } return { ok: true, url: parsed.toString() }; }