"use client"; import type { ApiError } from "@spinza/shared"; export class ApiClientError extends Error { constructor( public status: number, public code: string, message: string, public details?: unknown, ) { super(message); } } /** Browser fetch wrapper: same-origin `/api/*`, JSON in/out, typed errors. */ export async function api(path: string, init: RequestInit & { json?: unknown } = {}): Promise { const { json, headers, ...rest } = init; const res = await fetch(path, { ...rest, method: rest.method ?? (json !== undefined ? "POST" : "GET"), credentials: "same-origin", headers: { ...(json !== undefined ? { "Content-Type": "application/json" } : {}), ...(headers ?? {}) }, body: json !== undefined ? JSON.stringify(json) : rest.body, }).catch(() => { throw new ApiClientError(0, "NETWORK", "Connection lost. Check your network and try again."); }); const text = await res.text(); let data: unknown = null; try { data = text ? JSON.parse(text) : null; } catch { data = null; } if (!res.ok) { const e = (data ?? {}) as Partial; throw new ApiClientError(res.status, e.error ?? "HTTP_" + res.status, e.message ?? (res.status >= 500 ? "Server unavailable. Please try again shortly." : "Request failed."), e.details); } return data as T; } export const isUnauthorized = (e: unknown) => e instanceof ApiClientError && e.status === 401;