Files
GearBox/src/client/lib/api.ts

62 lines
1.5 KiB
TypeScript

class ApiError extends Error {
constructor(
message: string,
public status: number,
) {
super(message);
this.name = "ApiError";
}
}
async function handleResponse<T>(res: Response): Promise<T> {
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<T>;
}
export async function apiGet<T>(url: string): Promise<T> {
const res = await fetch(url);
return handleResponse<T>(res);
}
export async function apiPost<T>(url: string, body: unknown): Promise<T> {
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
return handleResponse<T>(res);
}
export async function apiPut<T>(url: string, body: unknown): Promise<T> {
const res = await fetch(url, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
return handleResponse<T>(res);
}
export async function apiDelete<T>(url: string): Promise<T> {
const res = await fetch(url, { method: "DELETE" });
return handleResponse<T>(res);
}
export async function apiUpload<T>(url: string, file: File): Promise<T> {
const formData = new FormData();
formData.append("image", file);
const res = await fetch(url, {
method: "POST",
body: formData,
});
return handleResponse<T>(res);
}