import { isApiError, type ApiError } from "@/lib/errors" type JsonRequestInit = Omit & { headers?: HeadersInit body?: BodyInit | null json?: unknown } async function readJsonBody(res: Response): Promise { const text = await res.text() if (!text) return null try { return JSON.parse(text) as unknown } catch { return null } } export async function httpJson(path: string, init?: JsonRequestInit): Promise { if (/^https?:\/\//.test(path)) { throw new Error("Absolute URLs are not allowed") } const { json, headers: headersInit, body: bodyInit, ...rest } = init ?? {} const headers = new Headers(headersInit) headers.set("Accept", "application/json") const body = json === undefined ? bodyInit : JSON.stringify(json) if (json !== undefined && !headers.has("Content-Type")) { headers.set("Content-Type", "application/json") } const res = await fetch(path, { ...rest, headers, body, }) const data = await readJsonBody(res) if (res.ok) { return data as T } const apiError = isApiError(data) ? data : null if (res.status === 401 || apiError?.code === 401) { throw new Error("UNAUTHORIZED") } if (apiError) { throw apiError } throw { code: res.status, msg: res.statusText || "Request failed" } satisfies ApiError }