export default class Api { constructor({server, processPage, timezone, csrfToken, errorCode, lang}) { this.server = server; this.processPage = processPage; this.timezone = timezone; this.csrfToken = csrfToken; this.errorCode = errorCode; this.lang = lang; } async get(sAction, asParams = {}) { const oResponse = await this.request(sAction, asParams, 'GET'); return oResponse.data; } async post(sAction, asParams = {}) { const oResponse = await this.request(sAction, asParams, 'POST'); return oResponse.data; } /** * Fire-and-forget POST that survives the page going away. Used for the * close-the-entry call on unload, where a fetch would simply be cancelled. * sendBeacon cannot set headers, so the CSRF token rides in the body - * which the controller accepts as a fallback for exactly this case. */ beacon(sAction, asParams = {}) { if(!navigator.sendBeacon) return false; const oBody = new URLSearchParams({ ...asParams, a: sAction, t: this.timezone, csrf_token: this.csrfToken }); return navigator.sendBeacon( new URL(this.processPage, this.server), new Blob([oBody.toString()], {type: 'application/x-www-form-urlencoded;charset=UTF-8'}) ); } async request(sAction, asParams = {}, sMethod = 'GET') { const oUrl = new URL(this.processPage, this.server); const sUrlParams = new URLSearchParams({ ...asParams, a: sAction, t: this.timezone }).toString(); const asOptions = { method: sMethod, headers: {'Accept': 'application/json'} }; if(sMethod === 'GET') { oUrl.search = sUrlParams; } else { asOptions.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; asOptions.headers['X-CSRF-Token'] = this.csrfToken; asOptions.body = sUrlParams; } const oRequest = await fetch(oUrl, asOptions); if(!oRequest.ok) { throw new Error('Error HTTP ' + oRequest.status + ': ' + oRequest.statusText); } const oResponse = await oRequest.json(); oResponse.desc_lang_text = this.lang.get(oResponse.desc_lang_id, oResponse.desc_lang_params); if(oResponse.result == this.errorCode) { const oError = new Error(oResponse.desc_lang_text || oResponse.desc_lang_id); oError.desc_lang_id = oResponse.desc_lang_id; oError.desc_lang_params = oResponse.desc_lang_params; oError.desc_lang_text = oResponse.desc_lang_text; throw oError; } return oResponse; } }