import policy from "./backend-url-policy.json"; export interface RuntimeConfig { backendBaseUrl?: string; } declare global { interface Window { __THOTHII_CONFIG__?: RuntimeConfig; } } export function resolveBackendUrl(config: RuntimeConfig | undefined): string { const value = config?.backendBaseUrl ?? import.meta.env.VITE_BACKEND_URL ?? ""; if (policy.relativeBases.includes(value)) return value; try { if (!new RegExp(policy.absolutePattern).test(value)) throw new Error("syntax"); const authority = value.replace(/^https?:\/\//, "").split("/", 1)[0]; const suffix = authority.startsWith("[") ? authority.slice(authority.indexOf("]") + 1) : authority.slice(authority.lastIndexOf(":")); const port = suffix.startsWith(":") ? suffix.slice(1) : ""; if (port && (port.length > 5 || Number(port) > policy.maxPort)) throw new Error("port"); return value; } catch { // Fall through to the single actionable runtime error below. } throw new Error( "Invalid BACKEND_BASE_URL: use empty/root, /api, or a valid http(s) base without credentials, query, or fragment", ); } export function joinBackendPath(base: string, path: string): string { const normalizedBase = base === "/" ? "" : base.replace(/\/+$/, ""); const normalizedPath = path.replace(/^\/+/, ""); return `${normalizedBase}/${normalizedPath}`; } export const backendBaseUrl = resolveBackendUrl(typeof window === "undefined" ? undefined : window.__THOTHII_CONFIG__) || "http://localhost:8787";