import { HttpError, ReferenceError, UnauthorizedError } from './errors'; export const serverPath = (document.documentElement.dataset.apiDomain || '') + '/api'; interface FetchParams { [key: string]: string | number | boolean; } export const handleFetch = async (path: string, init: RequestInit = {}, isJson = true): Promise => { const headers: Headers = new Headers(init.headers); if (isJson) { headers.append('Accept', 'application/json'); headers.append('Content-Type', 'application/json'); } const response = await fetch(`${serverPath}${path}`, { ...init, ...(init && init.body) && { body: init.body, }, headers, credentials: 'include', }); return handleResponse(response); }; export const handleDelete = (path: string): Promise => { return handleFetch(path, { method: 'delete' }, false) .catch((error: HttpError) => { // Error code 3001 indicates the item is still referenced somewhere else if (error.errorCode === 3001) { throw new ReferenceError( 'Er zijn nog bestaande verwijzingen naar dit item, verwijder deze eerst.', true, error, ); } throw error; }); }; export const stringifyQuery = (path: string, params: FetchParams): string => { const qsParams = Object.keys(params).map((key) => key + '=' + encodeURIComponent(params[key])).join('&'); return `${path}?${qsParams}`; }; const handleResponse = async (response: Response): Promise => { // TODO: singletonFactory can return a 204 on /{itemName}/latest, we have to take that response into account if (!response.ok) { let errorCode; let message; if (response.body) { const res = await response.json(); message = res.message; errorCode = res.errorCode; } if (response.status === 401) { throw new UnauthorizedError(`Deze gebruiker heeft geen toegang tot ${response.url}`, errorCode); } throw new HttpError( `De server geeft een fout terug. ${response.status}: ${message || response.statusText}`, response.status, errorCode, ); } return response; };