Files
nuzlocke-tracker/frontend/src/api/client.ts

54 lines
1.2 KiB
TypeScript
Raw Normal View History

const API_BASE = import.meta.env['VITE_API_URL'] ?? ''
export class ApiError extends Error {
status: number
constructor(status: number, message: string) {
super(message)
this.name = 'ApiError'
this.status = status
}
}
async function request<T>(path: string, options?: RequestInit): Promise<T> {
const res = await fetch(`${API_BASE}/api/v1${path}`, {
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
})
if (!res.ok) {
const body = await res.json().catch(() => ({}))
throw new ApiError(res.status, body.detail ?? res.statusText)
}
if (res.status === 204) return undefined as T
return res.json()
}
export const api = {
get: <T>(path: string) => request<T>(path),
post: <T>(path: string, body: unknown) =>
request<T>(path, {
method: 'POST',
body: JSON.stringify(body),
}),
patch: <T>(path: string, body: unknown) =>
request<T>(path, {
method: 'PATCH',
body: JSON.stringify(body),
}),
put: <T>(path: string, body: unknown) =>
request<T>(path, {
method: 'PUT',
body: JSON.stringify(body),
}),
del: <T = void>(path: string) => request<T>(path, { method: 'DELETE' }),
}