traxxx-web/src/api.js

147 lines
3.2 KiB
JavaScript

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 `?${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;
}
}