1
0
mirror of https://github.com/ascribe/onion.git synced 2024-09-28 12:08:55 +02:00
onion/js/utils/requests.js

140 lines
3.7 KiB
JavaScript
Raw Normal View History

'use strict';
2015-06-16 14:01:53 +02:00
import { argsToQueryParams, getCookie } from '../utils/fetch_api_utils';
2015-06-01 14:22:04 +02:00
class UrlMapError extends Error {}
class ServerError extends Error {}
class APIError extends Error {}
2015-06-01 14:22:04 +02:00
class Requests {
2015-06-01 14:22:04 +02:00
_merge(defaults, options) {
let merged = {};
for (let key in defaults) {
merged[key] = defaults[key];
}
for (let key in options) {
merged[key] = options[key];
}
return merged;
}
unpackResponse(response) {
if (response.status >= 500) {
throw new ServerError();
}
return response.text();
}
2015-06-30 17:57:20 +02:00
customJSONparse(responseText) {
// If the responses' body does not contain any data,
// fetch will resolve responseText to the string 'None'.
// If this is the case, we can not try to parse it as JSON.
if(responseText !== 'None') {
return JSON.parse(responseText);
} else {
return {};
}
}
2015-06-01 14:22:04 +02:00
handleFatalError(err) {
this.fatalErrorHandler(err);
throw new ServerError(err);
}
handleAPIError(json) {
if (!json.success) {
2015-06-01 14:22:04 +02:00
let error = new APIError();
error.json = json;
2015-06-30 17:57:20 +02:00
console.error(new Error('The \'success\' property is missing in the server\'s response.'));
2015-06-01 14:22:04 +02:00
throw error;
}
return json;
}
getUrl(url) {
let name = url;
if (!url.match(/^http/)) {
url = this.urlMap[url];
if (!url) {
throw new UrlMapError(`Cannot find a mapping for "${name}"`);
}
}
return url;
}
2015-06-01 16:45:09 +02:00
prepareUrl(url, params, attachParamsToQuery) {
2015-06-01 14:22:04 +02:00
let newUrl = this.getUrl(url);
let re = /\${(\w+)}/g;
2015-06-02 16:47:25 +02:00
2015-06-01 14:22:04 +02:00
newUrl = newUrl.replace(re, (match, key) => {
let val = params[key];
2015-06-01 14:22:04 +02:00
if (!val) {
throw new Error(`Cannot find param ${key}`);
}
delete params[key];
return val;
});
2015-06-01 16:45:09 +02:00
if (attachParamsToQuery && params && Object.keys(params).length > 0) {
newUrl += argsToQueryParams(params);
2015-06-01 14:22:04 +02:00
}
return newUrl;
}
request(verb, url, options) {
options = options || {};
let merged = this._merge(this.httpOptions, options);
2015-06-16 19:28:21 +02:00
let csrftoken = getCookie('csrftoken');
if (csrftoken) {
merged.headers['X-CSRFToken'] = csrftoken;
}
merged.method = verb;
return fetch(url, merged)
2015-06-01 16:45:09 +02:00
.then(this.unpackResponse)
2015-06-30 17:57:20 +02:00
.then(this.customJSONparse)
2015-06-01 16:45:09 +02:00
.catch(this.handleFatalError.bind(this))
.then(this.handleAPIError);
2015-06-01 14:22:04 +02:00
}
2015-06-01 16:45:09 +02:00
get(url, params) {
2015-06-20 16:43:18 +02:00
if (url === undefined){
throw new Error('Url undefined');
}
2015-06-01 16:45:09 +02:00
let paramsCopy = this._merge(params);
2015-06-09 17:24:06 +02:00
let newUrl = this.prepareUrl(url, paramsCopy, true);
2015-06-02 14:33:00 +02:00
return this.request('get', newUrl);
2015-06-01 14:22:04 +02:00
}
2015-06-10 15:49:46 +02:00
delete(url, params) {
let paramsCopy = this._merge(params);
let newUrl = this.prepareUrl(url, paramsCopy, true);
return this.request('delete', newUrl);
}
2015-06-01 16:45:09 +02:00
post(url, params) {
let paramsCopy = this._merge(params);
2015-06-09 17:24:06 +02:00
let newUrl = this.prepareUrl(url, paramsCopy);
2015-06-01 17:43:38 +02:00
let body = null;
2015-06-09 17:24:06 +02:00
if (paramsCopy && paramsCopy.body) {
body = JSON.stringify(paramsCopy.body);
2015-06-01 17:43:38 +02:00
}
2015-06-09 17:24:06 +02:00
return this.request('post', newUrl, { body });
2015-06-01 14:22:04 +02:00
}
defaults(options) {
this.httpOptions = options.http || {};
this.urlMap = options.urlMap || {};
this.fatalErrorHandler = options.fatalErrorHandler || (() => {});
}
}
let requests = new Requests();
2015-06-01 14:22:04 +02:00
export default requests;