Files
2026-04-21 08:56:51 -05:00

30 lines
894 B
TypeScript

export interface ApiFailure {
error: string;
code?: string;
issues?: Array<{ path: unknown; message: string }>;
}
export class ApiClientError extends Error {
constructor(public status: number, public code: string | undefined, message: string) {
super(message);
}
}
export async function apiFetch<T>(
input: string,
init: RequestInit = {},
): Promise<T> {
const headers = new Headers(init.headers);
if (init.body && !headers.has("content-type") && !(init.body instanceof FormData)) {
headers.set("content-type", "application/json");
}
const res = await fetch(input, { ...init, headers });
const text = await res.text();
const data = text ? (JSON.parse(text) as unknown) : undefined;
if (!res.ok) {
const fail = (data ?? { error: res.statusText }) as ApiFailure;
throw new ApiClientError(res.status, fail.code, fail.error);
}
return data as T;
}