Repository Public
1"use client";23export class ApiClientError extends Error {4 constructor(public status: number, public code: string, message: string, public details?: unknown) { super(message); }5}67let csrf: string | null = null;8export const setCsrf = (t: string | null) => { csrf = t; };910/** JSON fetch against our own API. Network failures surface as code "network". */11export async function api<T = unknown>(path: string, init: { method?: string; body?: unknown; raw?: BodyInit; headers?: Record<string, string> } = {}): Promise<T> {12 let res: Response;13 try {14 res = await fetch(path, {15 method: init.method ?? (init.body !== undefined || init.raw !== undefined ? "POST" : "GET"),16 headers: { ...(init.body !== undefined ? { "Content-Type": "application/json" } : {}), ...(csrf ? { "X-CSRF-Token": csrf } : {}), ...(init.headers ?? {}) },17 body: init.raw ?? (init.body !== undefined ? JSON.stringify(init.body) : undefined),18 credentials: "same-origin", cache: "no-store",19 });20 } catch { throw new ApiClientError(0, "network", "Network error"); }21 const text = await res.text();22 let data: unknown = null;23 try { data = text ? JSON.parse(text) : null; } catch { /* not JSON */ }24 if (!res.ok) {25 const e = (data as { error?: { code?: string; message?: string; details?: unknown } } | null)?.error;26 throw new ApiClientError(res.status, e?.code ?? "http_" + res.status, e?.message ?? `HTTP ${res.status}`, e?.details);27 }28 return data as T;29}30