// http.ts - Base HTTP client class HTTPError extends Error { status: number statusText: string constructor(status: number, statusText: string, message?: string) { super(message || statusText) this.status = status this.statusText = statusText } } async function request(url: string, options: RequestInit = {}): Promise { const defaultOptions: RequestInit = { credentials: 'include', } const response = await fetch(url, { ...defaultOptions, ...options }) if (!response.ok) { throw new HTTPError( response.status, response.statusText, `HTTP ${response.status}`, ) } // Handle empty response (e.g. 204 No Content) if (response.status === 204) { return {} as T } return response.json() } export const http = { get: (url: string, options?: RequestInit) => request(url, { ...options, method: 'GET' }), post: (url: string, body?: any, options?: RequestInit) => request(url, { ...options, method: 'POST', headers: { 'Content-Type': 'application/json', ...options?.headers }, body: JSON.stringify(body), }), put: (url: string, body?: any, options?: RequestInit) => request(url, { ...options, method: 'PUT', headers: { 'Content-Type': 'application/json', ...options?.headers }, body: JSON.stringify(body), }), delete: (url: string, options?: RequestInit) => request(url, { ...options, method: 'DELETE' }), }