46 lines
2.1 KiB
JavaScript
46 lines
2.1 KiB
JavaScript
|
|
export const base = '/api/v1/remote';
|
||
|
|
let csrf = '';
|
||
|
|
export async function api(path, data, method = data === undefined ? 'GET' : 'POST') {
|
||
|
|
const controller = new AbortController();
|
||
|
|
const timeout = setTimeout(() => controller.abort(), 15000);
|
||
|
|
try {
|
||
|
|
const response = await fetch(base + path, {method, credentials: 'same-origin', cache: 'no-store', signal: controller.signal,
|
||
|
|
headers: data === undefined ? {} : {'Content-Type': 'application/json', 'X-Remote-CSRF': csrf},
|
||
|
|
body: data === undefined ? undefined : JSON.stringify(data)});
|
||
|
|
if (response.redirected || (response.ok && !response.headers.get('Content-Type')?.includes('application/json'))) {
|
||
|
|
throw new Error('Hub sendte ikke det forventede svar. Prøver igen…');
|
||
|
|
}
|
||
|
|
const result = await response.json();
|
||
|
|
if (!response.ok) {
|
||
|
|
const error = new Error(typeof result.detail === 'string' ? result.detail : 'Kontrollér oplysningerne og prøv igen');
|
||
|
|
error.status = response.status;
|
||
|
|
error.retry = Number(response.headers.get('Retry-After') || 0);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
} catch (error) {
|
||
|
|
if (error.status || error.message?.includes('forventede svar')) throw error;
|
||
|
|
throw new Error('Forbindelsen til Hub er afbrudt. Prøver igen…');
|
||
|
|
} finally { clearTimeout(timeout); }
|
||
|
|
}
|
||
|
|
export async function bootstrap() {
|
||
|
|
const result = await api('/bootstrap');
|
||
|
|
csrf = result.csrf;
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
export function element(tag, text, className) {
|
||
|
|
const node = document.createElement(tag);
|
||
|
|
node.textContent = text;
|
||
|
|
if (className) node.className = className;
|
||
|
|
return node;
|
||
|
|
}
|
||
|
|
|
||
|
|
// getRandomValues also works on HTTP local-network origins.
|
||
|
|
export function requestId() {
|
||
|
|
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
||
|
|
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
||
|
|
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||
|
|
const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
|
||
|
|
return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`;
|
||
|
|
}
|