48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
const GATEWAY_URL = process.env['NEXT_PUBLIC_GATEWAY_URL'] ?? 'http://localhost:14242';
|
|
|
|
export interface ApiRequestInit extends Omit<RequestInit, 'body'> {
|
|
body?: unknown;
|
|
}
|
|
|
|
export interface ApiError {
|
|
statusCode: number;
|
|
message: string;
|
|
}
|
|
|
|
/**
|
|
* Fetch wrapper for the Mosaic gateway API.
|
|
* Sends credentials (cookies) and JSON body automatically.
|
|
*/
|
|
export async function api<T>(path: string, init?: ApiRequestInit): Promise<T> {
|
|
const { body, headers: customHeaders, ...rest } = init ?? {};
|
|
|
|
const headers: Record<string, string> = {
|
|
Accept: 'application/json',
|
|
...(customHeaders as Record<string, string>),
|
|
};
|
|
|
|
if (body !== undefined) {
|
|
headers['Content-Type'] = 'application/json';
|
|
}
|
|
|
|
const res = await fetch(`${GATEWAY_URL}${path}`, {
|
|
credentials: 'include',
|
|
...rest,
|
|
headers,
|
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const errorBody = (await res.json().catch(() => ({
|
|
statusCode: res.status,
|
|
message: res.statusText,
|
|
}))) as ApiError;
|
|
throw Object.assign(new Error(errorBody.message), {
|
|
statusCode: errorBody.statusCode,
|
|
});
|
|
}
|
|
|
|
if (res.status === 204) return undefined as T;
|
|
return (await res.json()) as T;
|
|
}
|