'use strict'; const PagerAPI = (() => { let apiBase = ''; let on401 = null; const GET_TIMEOUT_MS = 20000; const WRITE_TIMEOUT_MS = 45000; async function request(method, path, body, attempt) { attempt = attempt || 0; const opts = { method, headers: {}, credentials: 'include' }; if (body !== undefined) { opts.headers['Content-Type'] = 'application/json'; opts.body = JSON.stringify(body); } const timeoutMs = method === 'GET' ? GET_TIMEOUT_MS : WRITE_TIMEOUT_MS; const ctl = new AbortController(); const timer = setTimeout(() => ctl.abort(), timeoutMs); opts.signal = ctl.signal; let res; try { res = await fetch(apiBase + path, opts); } catch (e) { clearTimeout(timer); if (method === 'GET' && attempt < 1) { return request(method, path, body, attempt + 1); } const error = new Error((e && e.name === 'AbortError') ? 'Request timed out' : (e && e.message) || 'Network error'); error.status = 0; throw error; } clearTimeout(timer); if (res.status === 401) { if (on401) on401(); throw new Error('unauthorized'); } const ct = res.headers.get('Content-Type') || ''; let data; if (ct.indexOf('json') !== -1) { try { data = await res.json(); } catch (e) { data = null; } } else { data = await res.text(); } if (!res.ok) { const detail = data && typeof data.detail === 'string' ? data.detail : ''; const message = (data && data.error ? data.error : ('HTTP ' + res.status)) + (detail ? ': ' + detail : ''); const error = new Error(message); error.status = res.status; error.data = data; throw error; } return { status: res.status, data }; } return { setBase: (b) => { apiBase = b; }, on401: (fn) => { on401 = fn; }, get: (p) => request('GET', p), post: (p, b) => request('POST', p, b === undefined ? {} : b), del: (p, b) => request('DELETE', p, b === undefined ? {} : b), login: async (username, password) => request('POST', '/api/login', { username, password }) }; })();