export class ApiError extends Error { constructor(status, message) { super(message); this.status = status; } } const unauthorizedListeners = new Set(); export function onUnauthorized(listener) { unauthorizedListeners.add(listener); } function parseBody(text) { if (!text) return null; try { return JSON.parse(text); } catch { return null; } } async function request(method, path, body) { const options = { method, credentials: "same-origin", headers: {} }; if (body !== undefined) { options.headers["Content-Type"] = "application/json"; options.body = JSON.stringify(body); } const response = await fetch(path, options); const data = parseBody(await response.text()); if (!response.ok) { if (response.status === 401 && path !== "/api/login") { unauthorizedListeners.forEach((listener) => listener()); } const message = data && data.error ? data.error : `Request failed (${response.status})`; throw new ApiError(response.status, message); } return data; } function jobPath(id, suffix = "") { return `/api/jobs/${encodeURIComponent(id)}${suffix}`; } export const api = { session: () => request("GET", "/api/session"), login: (username, password) => request("POST", "/api/login", { username, password }), logout: () => request("POST", "/api/logout", {}), libraries: () => request("GET", "/api/libraries"), disk: () => request("GET", "/api/disk"), settings: () => request("GET", "/api/settings"), saveSettings: (settings) => request("POST", "/api/settings", settings), jobs: () => request("GET", "/api/jobs"), createJob: (payload) => request("POST", "/api/jobs", payload), files: (id) => request("GET", jobPath(id, "/files")), extract: (id, path) => request("POST", jobPath(id, "/extract"), { path }), move: (id, payload) => request("POST", jobPath(id, "/move"), payload), pause: (id) => request("POST", jobPath(id, "/pause"), {}), resume: (id) => request("POST", jobPath(id, "/resume"), {}), reorder: (id, direction) => request("POST", jobPath(id, "/queue"), { direction }), remove: (id) => request("DELETE", jobPath(id)), history: () => request("GET", "/api/history"), clearHistory: () => request("DELETE", "/api/history"), };