62 lines
1.5 KiB
TypeScript
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);
|
|
}
|