/* Fetch */ // vim: set ts=2 sw=2 et tw=80: const BODY_METHODS = ['PUT', 'POST', 'PATCH']; const NON_BODY_METHODS = ['GET', 'OPTIONS', 'HEAD', 'DELETE']; const METHODS = BODY_METHODS + NON_BODY_METHODS; /** * @function doFetchRequest * @param {String} method The method of the Fetch request. One of: 'GET', * 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD' * @param {String} url The url of the API to call, optionally with parameters. * @param {Object} headers The Associative Array containing the Request Headers. * It must be undefined if there are no headers. * @param {String} body The body String to be sent to the server. It must be * undefined if there is no body. * @returns {Promise} which receives the HTTP response. */ function doFetchRequest(method, url, headers, body) { if (METHODS.indexOf(method) == -1) { throw new Error(`${method} is not a method`); return; } if (BODY_METHODS.indexOf(method) != -1 && typeof body != 'string') { throw new Error(`body must be a string with ${BODY_METHODS}`); return; } else if (NON_BODY_METHODS.indexOf(method) != -1 && body !== undefined) { throw new Error(`body must be undefined with ${NON_BODY_METHODS}`); return; } return fetch(url, { method: method, headers: headers, body: body }); } /** @function doJSONRequest * @param {String} method The method of the Fetch request. One of: 'GET', * 'POST', 'PUT', 'DELETE'. * @param {String} url The url of the API to call, optionally with parameters. * @param {Object} headers The Associative Array containing the Request Headers. * It must be undefined if there are no headers. * @param {Object} data The object to be sent as JSON body to the server. * It must be undefined if there is no body. * @returns {Promise} which receives directly the object parsed from the * response JSON. */ function doJSONRequest(method, url, headers, data){ const JSON_MIME = 'application/json'; headers = Object.assign({}, headers); if (('Content-Type' in headers && headers['Content-Type'] !== JSON_MIME) || ('Accept' in headers && headers['Accept'] !== JSON_MIME)) { throw new Error(`headers object contains Content-Type or Accept`); return; } headers['Accept'] = JSON_MIME; if (NON_BODY_METHODS.indexOf(method) != -1 && data !== undefined) { throw new Error(`data must be undefined with ${NON_BODY_METHODS}`); return; } else if (BODY_METHODS.indexOf(method) != -1) { if (typeof data != 'object' || data === null) { throw new Error(`data must be a non-null object with ${BODY_METHODS}`); return; } try { data = JSON.stringify(data); } catch (e) { throw new Error('data cannot be converted into JSON: ' + e); return; } headers['Content-Type'] = JSON_MIME; } return doFetchRequest(method, url, headers, data) .then(res => res.status == 204 ? {} : res.json()); }