46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
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());
|
|
}
|