sgmp/frontend/lib/api/client.ts

59 lines
1.5 KiB
TypeScript

"use client";
export class ApiError extends Error {
status: number;
payload: unknown;
constructor(message: string, status: number, payload: unknown = null) {
super(message);
this.status = status;
this.payload = payload;
}
}
async function parseResponse<T>(res: Response): Promise<T> {
const contentType = res.headers.get("content-type") || "";
const isJson = contentType.includes("application/json");
const payload = isJson ? await res.json() : await res.text();
if (!res.ok) {
const message =
(typeof payload === "object" &&
payload &&
"error" in payload &&
typeof (payload as { error?: unknown }).error === "string" &&
(payload as { error: string }).error) ||
`Erro HTTP ${res.status}`;
throw new ApiError(message, res.status, payload);
}
return payload as T;
}
export async function apiGet<T>(url: string): Promise<T> {
const res = await fetch(url, {
method: "GET",
credentials: "include",
cache: "no-store",
});
return parseResponse<T>(res);
}
export async function apiPostJson<T>(url: string, body: unknown): Promise<T> {
const res = await fetch(url, {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
return parseResponse<T>(res);
}
export async function apiPostFormData<T>(url: string, body: FormData): Promise<T> {
const res = await fetch(url, {
method: "POST",
credentials: "include",
body,
});
return parseResponse<T>(res);
}