-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfetch-interpreter.js
96 lines (87 loc) · 2.77 KB
/
fetch-interpreter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
require('isomorphic-fetch');
require('es6-promise').polyfill();
var utils = require('./libs/interpreter-utils');
var btoa = require('btoa');
var formurlencoded = require('form-urlencoded');
function buildAuthHeader(auth) {
if (typeof auth === 'object') {
if (typeof auth.user !== 'undefined') return 'Basic '+ btoa(auth.user +':' + auth.pass);
else if (typeof auth.bearer !== 'undefined') return 'Bearer ' + auth.bearer
}
return auth;
}
function attachAuth(auth, req) {
if (typeof auth === 'function') {
return auth().then(function(a){
req.headers.set('Authorization', buildAuthHeader(a));
return req
});
} else {
return new Promise(function(resolve){
if (auth) {
req.headers.set('Authorization', buildAuthHeader(auth))
}
resolve(req);
});
}
}
function mapMethod(method) {
return {
'get': 'GET',
'post': 'POST',
'put': 'PUT',
'del': 'DELETE'
}[method];
}
/** Execute the request. This just collapses the list of partial requests into a single Object,
* attaches and auth, builds the object used by fetch. Notice that I'm also executing
* any mapping functions on the result. This is a bit nasty, but pretty useful */
exports.run = function(des) {
var render = des.reduce();
var req = {
headers: new Headers(),
method: mapMethod(render.METHOD)
};
var url = utils.url([render.HOST, render.PATH]);
if (render.FORM){
req.headers.set('Content-Type', 'application/x-www-form-urlencoded');
render.BODY = formurlencoded(render.FORM);
}
if (render.JSON){
req.headers.set('Content-Type', 'application/json');
if (render.BODY && typeof render.BODY === 'object') {
render.BODY = JSON.stringify(render.BODY);
}
}
if (render.BODY) {
req.body = render.BODY;
req.headers['Content-Length'] = req.body.length.toString();
}
if (render.QUERY) url = url + utils.buildQueryString(render.QUERY);
return attachAuth(render.AUTH, req).then(function(req){
return fetch(new Request(url, req), {credentials: 'same-origin'}).then(function(result){
var body;
var contentType = result.headers.get("content-type");
if (contentType && contentType.indexOf("application/json") !== -1) {
body = result.json();
} else {
body = result.text();
}
if (!utils.httpSuccess(result.status)) {
return body.then(function (body) {
return Promise.reject({
err: 'http request failed',
statusCode: result.status,
body: body,
headers: JSON.stringify(result.headers),
reqHeaders: JSON.stringify(req.headers),
url: result.url,
reqBody: req.body
});
});
} else {
return body;
}
}).then(utils.applyMap(render));
});
};