function trimTrailingSlash(value: string) { return value.endsWith('/') ? value.slice(0, -1) : value; } function isInternalHost(hostname: string) { return hostname === 'backend' || hostname === 'localhost' || hostname === '127.0.0.1' || hostname.endsWith('.internal'); } function parseUrl(url: string) { try { return new URL(url); } catch { return null; } } export function resolveApiBaseURL(configuredBaseURL: string | undefined) { const fallbackLocal = 'http://localhost:3001'; const candidate = configuredBaseURL?.trim() || fallbackLocal; if (typeof window === 'undefined') { return trimTrailingSlash(candidate); } const parsed = parseUrl(candidate); if (!parsed) { return `${window.location.origin}`; } const browserHost = window.location.hostname; const browserIsLocal = browserHost === 'localhost' || browserHost === '127.0.0.1'; if (!browserIsLocal && isInternalHost(parsed.hostname)) { console.warn( `[fiscal] NEXT_PUBLIC_API_URL is internal (${parsed.hostname}); falling back to https://api.${browserHost}` ); return trimTrailingSlash(`https://api.${browserHost}`); } return trimTrailingSlash(parsed.toString()); }