Files
byre/web/dist/api.js
T

52 lines
1.8 KiB
JavaScript
Raw Normal View History

export class ApiError extends Error {
status;
constructor(status, message) {
super(message);
this.status = status;
}
}
export async function request(method, path, opts = {}) {
const pathParams = (opts.path ?? {});
let url = path.replace(/\{(\w+)\}/g, (_, key) => {
const value = pathParams[key];
if (value === undefined) {
throw new Error(`missing path parameter ${key} for ${path}`);
}
return encodeURIComponent(String(value));
});
const query = new URLSearchParams();
for (const [key, value] of Object.entries((opts.query ?? {}))) {
if (value !== undefined) {
query.set(key, String(value));
}
}
if (query.size > 0) {
url += `?${query}`;
}
const init = { method: method.toUpperCase() };
2026-10-14 20:07:26 -07:00
if (opts.body instanceof Blob) {
init.headers = { "Content-Type": opts.body.type || "application/octet-stream" };
init.body = opts.body;
}
else if (opts.body !== undefined) {
init.headers = { "Content-Type": "application/json" };
init.body = JSON.stringify(opts.body);
}
const res = await fetch(url, init);
const data = await res.json();
if (!res.ok) {
throw new ApiError(res.status, data.message);
}
return data;
}
export const get = (path, opts) => request("get", path, opts);
export const post = (path, opts) => request("post", path, opts);
export const put = (path, opts) => request("put", path, opts);
export function subscribe(after, onEvent, onState) {
const source = new EventSource(`/api/events?after=${after}`);
source.onopen = () => onState(true);
source.onerror = () => onState(false);
source.onmessage = (msg) => onEvent(JSON.parse(msg.data));
return source;
}
//# sourceMappingURL=api.js.map