fix(docker): harden frontend runtime config
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { backendBaseUrl as BASE } from "./runtime-config";
|
||||
import { backendBaseUrl as BASE, joinBackendPath } from "./runtime-config";
|
||||
|
||||
export async function apiFetch<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
// Only declare a JSON content-type when we actually send a body. Body-less
|
||||
@@ -10,7 +10,7 @@ export async function apiFetch<T>(path: string, init?: RequestInit): Promise<T>
|
||||
if (init?.body != null && !("content-type" in headers) && !("Content-Type" in headers)) {
|
||||
headers["content-type"] = "application/json";
|
||||
}
|
||||
const res = await fetch(`${BASE}${path}`, { ...init, headers });
|
||||
const res = await fetch(joinBackendPath(BASE, path), { ...init, headers });
|
||||
if (!res.ok) throw new Error(`${res.status} ${await res.text().catch(() => "")}`);
|
||||
return res.status === 204 ? (undefined as T) : ((await res.json()) as T);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { backendBaseUrl, resolveBackendUrl } from "./runtime-config";
|
||||
import { backendBaseUrl, joinBackendPath, resolveBackendUrl } from "./runtime-config";
|
||||
|
||||
describe("resolveBackendUrl", () => {
|
||||
it("uses the runtime-injected backend URL", () => {
|
||||
@@ -15,3 +15,16 @@ describe("resolveBackendUrl", () => {
|
||||
expect(backendBaseUrl).toBe(import.meta.env.VITE_BACKEND_URL ?? "http://localhost:8787");
|
||||
});
|
||||
});
|
||||
|
||||
describe("joinBackendPath", () => {
|
||||
it.each([
|
||||
["", "/sessions/s1", "/sessions/s1"],
|
||||
["/", "/sessions/s1", "/sessions/s1"],
|
||||
["/api", "/sessions/s1", "/api/sessions/s1"],
|
||||
["/api/", "/sessions/s1", "/api/sessions/s1"],
|
||||
["https://example.test/api", "/sessions/s1", "https://example.test/api/sessions/s1"],
|
||||
["https://example.test/api/", "sessions/s1", "https://example.test/api/sessions/s1"],
|
||||
])("joins base %j and path %j", (base, path, expected) => {
|
||||
expect(joinBackendPath(base, path)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,12 @@ export function resolveBackendUrl(config: RuntimeConfig | undefined): string {
|
||||
return config?.backendBaseUrl ?? import.meta.env.VITE_BACKEND_URL ?? "";
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
Reference in New Issue
Block a user