-
Notifications
You must be signed in to change notification settings - Fork 0
/
fetchapi.js
116 lines (111 loc) · 3.55 KB
/
fetchapi.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
require('isomorphic-fetch');
const { accept, createFetch, createStack, header, init } = require('http-client');
const { find, cloneDeep, omit } = require('lodash');
const queryString = require('query-string');
const noop = () => null;
let log = noop;
const defaultHeaders = {
'Content-Type': 'application/json'
}
function getSHA(file) {
const shasum = crypto.createHash('sha1');
shasum.update(file);
return shasum.digest('hex');
}
const errorCheck = opts => (response) => {
log(`errorCheck = (${response})`);
if (!response.ok) {
const error = new Error(`Unable to fetch. ${response.status} ${response.statusCode}`);
error.status = response.status;
return Promise.reject(error);
}
if (opts.accept === 'application/json') { return response.json(); }
return response.text();
};
/**
* returns fetch promise
* params:
* two strings,
* OR Object with:
* method: 'GET'
* path: '/listAllUsers'
* query: { key: value }
* body: { key: value } || { name: string, content: buffer }
* headers: { key: value }
*/
const api = opts => async (methodOrOpts, path, body) => {
let method
let query;
let headers;
if (typeof methodOrOpts === 'string') {
method = methodOrOpts
} else {
method = methodOrOpts.method
query = methodOrOpts.query
body = methodOrOpts.body
headers = methodOrOpts.headers
path = methodOrOpts.path
}
log(`api`, {method, path, query, body, host: opts.host, url: opts.url});
if (query) {
if (typeof query !== 'string') {
query = queryString.stringify(query);
}
query = `?${query}`
}
const endpoint = opts.url || `${opts.host || ''}/${path || ''}${query || ''}`;
log('endpoint', endpoint)
const fetchOpts = { method };
const createFetchParams = [opts.fetchStack];
const requestHeaders = headers || {};
if (method !== 'GET' && body) {
if (body.hasOwnProperty('name') && body.hasOwnProperty('content')) {
requestHeaders['Content-Type'] = 'application/octet-stream';
requestHeaders['Content-Length'] = body.content.length;
if (opts.nowHeaders) {
requestHeaders['x-now-digest'] = getSHA(body.content);
requestHeaders['x-now-size'] = body.content.length;
}
fetchOpts.body = body.content;
} else {
requestHeaders['Content-Type'] = 'application/json';
fetchOpts.body = JSON.stringify(body);
}
}
for (const key in requestHeaders) {
if (requestHeaders[key]) {
const value = requestHeaders[key];
createFetchParams.push(header(key, value))
}
}
const thisFetch = createFetch.apply(createFetch, createFetchParams)
return thisFetch(endpoint, fetchOpts).then(opts.errorHandler);
};
/**
* returns api (defined above)
* params:
* agent = HttpsProxyAgent config
* accept = 'json' || accept header string
* headers = { key: value }
* host = 'https://example.com/v2'
*/
module.exports = (opts) => {
if (process.env.DEBUG === 'fetchapi') { log = console.log; } else { log = noop }
if (process.env.PROXY_REQUESTS) {
const HttpsProxyAgent = require('https-proxy-agent');
opts.proxyagent = new HttpsProxyAgent(opts.agent);
}
let fetch;
if (!opts.accept || opts.accept === 'json') { opts.accept = 'application/json' };
const headers = Object.assign({}, defaultHeaders, opts.headers)
const fetchOpts = [accept(opts.accept)]
for (const key in headers) {
if (headers[key]) {
const value = headers[key];
fetchOpts.push(header(key, value))
}
}
opts.fetchStack = createStack.apply(createStack, fetchOpts);
opts.errorHandler = errorCheck(opts)
return api(opts)
}