const WILDCARD_IPS = new Set(["", "0.0.0.0", "::"]); /** IPv6 literals need brackets in a URL; location.hostname already has them. */ export function urlHost(host: string): string { return host.includes(":") && !host.startsWith("[") ? `[${host}]` : host; } function isIpLiteral(host: string): boolean { return /^\d{1,3}(\.\d{1,3}){3}$/.test(host) || host.startsWith("["); } /** Where a port bound to all interfaces is reached. The page's own hostname * only works when it *is* the Docker host — behind a reverse proxy it is the * proxy's domain, and domain:8080 lands on the proxy. So: the configured * host, else the page's hostname when that is an IP (or localhost), else the * host address the backend detected, else the page's hostname after all. */ export function defaultLinkHost( page: string, settings?: { port_link_host: string; detected_host_ip: string | null } ): string { if (settings?.port_link_host) return settings.port_link_host; if (isIpLiteral(page) || page === "localhost") return page; return settings?.detected_host_ip || page; } /** Pick the host to link to: an explicit override, the bound * host IP if it's a concrete address, otherwise the default above. */ export function linkHost(hostIp: string | undefined, fallback: string, override?: string): string { if (override) return override; if (hostIp && !WILDCARD_IPS.has(hostIp)) return hostIp; return fallback; }