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