2019-11-11 15:58:06 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2019-11-13 10:04:39 +00:00
|
|
|
return doFetchRequest(method, url, headers, data)
|
|
|
|
.then(res => res.status == 204 ? {} : res.json());
|
2019-11-11 15:58:06 +00:00
|
|
|
}
|
|
|
|
|