class ApiError extends Error { constructor( message: string, public status: number, ) { super(message); this.name = "ApiError"; } } async function handleResponse(res: Response): Promise { if (!res.ok) { let message = `Request failed with status ${res.status}`; try { const body = await res.json(); if (body.error) message = body.error; } catch { // Use default message } throw new ApiError(message, res.status); } return res.json() as Promise; } export async function apiGet(url: string): Promise { const res = await fetch(url); return handleResponse(res); } export async function apiPost(url: string, body: unknown): Promise { const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); return handleResponse(res); } export async function apiPut(url: string, body: unknown): Promise { const res = await fetch(url, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); return handleResponse(res); } export async function apiDelete(url: string): Promise { const res = await fetch(url, { method: "DELETE" }); return handleResponse(res); } export async function apiUpload(url: string, file: File): Promise { const formData = new FormData(); formData.append("image", file); const res = await fetch(url, { method: "POST", body: formData, }); return handleResponse(res); }