import { parse } from '@brillout/json-serializer/parse'; /* eslint-disable-line import/extensions */ import events from '#/src/events.js'; const postHeaders = { mode: 'cors', credentials: 'same-origin', headers: { 'Content-Type': 'application/json', }, }; function getQuery(data) { if (!data) { return ''; } const curatedQuery = Object.fromEntries(Object.entries(data).map(([key, value]) => (value === undefined ? null : [key, value])).filter(Boolean)); return `?${encodeURI(decodeURIComponent(new URLSearchParams(curatedQuery).toString()))}`; // recode so commas aren't encoded } function showFeedback(isSuccess, options = {}, errorMessage) { if (!isSuccess && typeof options.errorFeedback) { events.emit('feedback', { type: 'error', message: options.appendErrorMessage && errorMessage ? `${options.errorFeedback}: ${errorMessage}` : options.errorFeedback, }); } if (isSuccess && options.successFeedback) { events.emit('feedback', { type: 'success', message: options.successFeedback, }); } if (isSuccess && options.undoFeedback) { events.emit('feedback', { type: 'undo', message: options.undoFeedback, }); } } export async function get(path, query = {}, options = {}) { try { const res = await fetch(`/api${path}${getQuery(query)}`); const body = parse(await res.text()); if (res.ok) { showFeedback(true, options); return body; } showFeedback(false, options, body.statusMessage); throw new Error(body.statusMessage); } catch (error) { showFeedback(false, options, error.message); throw error; } } export async function post(path, data, options = {}) { try { const res = await fetch(`/api${path}${getQuery(options.query)}`, { method: 'POST', body: JSON.stringify(data), ...postHeaders, }); if (res.status === 204) { showFeedback(true, options); return null; } const body = parse(await res.text()); if (res.ok) { showFeedback(true, options); return body; } showFeedback(false, options, body.statusMessage); throw new Error(body.statusMessage); } catch (error) { showFeedback(false, options, error.message); throw error; } } export async function patch(path, data, options = {}) { try { const res = await fetch(`/api${path}${getQuery(options.query)}`, { method: 'PATCH', body: JSON.stringify(data), ...postHeaders, }); if (res.status === 204) { return null; } const body = parse(await res.text()); if (res.ok) { showFeedback(true, options); return body; } showFeedback(false, options, body.statusMessage); throw new Error(body.statusMessage); } catch (error) { showFeedback(false, options, error.message); throw error; } } export async function del(path, options = {}) { try { const res = await fetch(`/api${path}${getQuery(options.query)}`, { method: 'DELETE', body: JSON.stringify(options.data), ...postHeaders, }); if (res.status === 204) { showFeedback(true, options); return null; } const body = parse(await res.text()); if (res.ok) { showFeedback(true, options); return body; } showFeedback(false, options, body.statusMessage); throw new Error(body.statusMessage); } catch (error) { showFeedback(false, options, error.message); throw error; } }