import { configuredBackendUrl } from "@/lib/backend-url" export class ApiClientError extends Error { constructor( message: string, public readonly status: number, public readonly payload?: unknown, ) { super(message) this.name = "ApiClientError" } } function trimBaseUrl(baseUrl: string): string { return baseUrl.replace(/\/$/, "") } function resolveRequestUrl(baseUrl: string, path: string): string { if (path.startsWith("/") && configuredBackendUrl().kind === "same-origin") { return path } return trimBaseUrl(baseUrl) + path } export async function requestJson( baseUrl: string, path: string, init?: RequestInit, ): Promise { const hasBody = init?.body != null const res = await fetch(resolveRequestUrl(baseUrl, path), { ...init, headers: { ...(hasBody ? { "Content-Type": "application/json" } : {}), ...(init?.headers ?? {}), }, }) if (res.status === 204) return undefined as T const payload = await res.json().catch(() => undefined) if (!res.ok) { const msg = typeof payload === "object" && payload !== null && "error" in payload && typeof (payload as { error?: unknown }).error === "string" ? (payload as { error: string }).error : res.statusText throw new ApiClientError(msg, res.status, payload) } return payload as T }