33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
export type ApiError = { code: string; message: string };
|
|
export type ApiResult<T> = { data: T } | { error: ApiError };
|
|
|
|
export async function fetchJson<T>(input: RequestInfo, init?: RequestInit): Promise<ApiResult<T>> {
|
|
const res = await fetch(input, {
|
|
...init,
|
|
credentials: "include",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
...(init?.headers || {})
|
|
}
|
|
});
|
|
|
|
const payload = await res.json().catch(() => ({}));
|
|
if (!res.ok) {
|
|
const errorPayload = payload?.error;
|
|
let code = String(res.status);
|
|
let message = res.statusText || "Request failed";
|
|
|
|
if (typeof errorPayload === "string") {
|
|
message = errorPayload;
|
|
} else if (errorPayload && typeof errorPayload === "object") {
|
|
if (typeof errorPayload.code === "string") code = errorPayload.code;
|
|
if (typeof errorPayload.message === "string") message = errorPayload.message;
|
|
} else if (typeof payload?.message === "string") {
|
|
message = payload.message;
|
|
}
|
|
|
|
return { error: { code, message } };
|
|
}
|
|
return { data: payload as T };
|
|
}
|