Files
EvoBGP/web/src/lib/api/client.ts
T

48 lines
1.1 KiB
TypeScript

import { browser } from '$app/environment';
export const TOKEN_STORAGE_KEY = 'evobgp_api_token';
export type Problem = {
title?: string;
status?: number;
detail?: string;
};
function mergeHeaders(init?: RequestInit): Headers {
const h = new Headers(init?.headers);
if (!h.has('Accept')) {
h.set('Accept', 'application/json');
}
if (browser) {
const t = localStorage.getItem(TOKEN_STORAGE_KEY);
if (t && !h.has('Authorization')) {
h.set('Authorization', `Bearer ${t}`);
}
}
return h;
}
export async function apiFetch(path: string, init?: RequestInit): Promise<Response> {
if (!browser) {
throw new Error('API is only available in the browser');
}
return fetch(path, { ...init, headers: mergeHeaders(init) });
}
export async function apiJSON<T>(path: string, init?: RequestInit): Promise<T> {
const res = await apiFetch(path, init);
const text = await res.text();
if (!res.ok) {
let detail = text;
try {
const j = JSON.parse(text) as Problem;
if (j?.detail) detail = j.detail;
} catch {
/* plain text */
}
throw new Error(detail || `HTTP ${res.status}`);
}
if (!text) return undefined as T;
return JSON.parse(text) as T;
}