-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate-fetchival.js
62 lines (51 loc) · 1.79 KB
/
create-fetchival.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
// Based on https://github.com/typicode/fetchival and aims to keep most of the same API
// Unlike fetchival, we also encode the keys
function query(params) {
if (!params) return ''
return `?${Object.entries(params)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&')}`
}
function createFetchival({ fetch }) {
async function _fetch(method, url, opts, data) {
// Unlike fetchival, don't silently ignore and override
if (opts.body) throw new Error('unexpected pre-set body option')
// Unlike fetchival, don't pollute the opts object we were given
const res = await fetchival.fetch(url, {
...opts,
method,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...opts.headers,
},
...(data ? { body: JSON.stringify(data) } : {}),
})
if (res.status >= 200 && res.status < 300) {
if (opts.responseAs === 'response') return res
if (res.status === 204) return null
if (opts.responseAs === 'text') return res.text()
return res.json()
}
const err = new Error(res.statusText)
err.response = res
throw err
}
function fetchival(url, opts = {}) {
const _ = (sub, o = {}) => {
// TODO: validate subpath here
const str = `${url}`
const joined = str.endsWith('/') ? `${url}${sub}` : `${url}/${sub}`
return fetchival(joined, { ...opts, ...o })
}
_.get = (params) => _fetch('GET', url + query(params), opts)
_.post = (data) => _fetch('POST', url, opts, data)
_.put = (data) => _fetch('PUT', url, opts, data)
_.patch = (data) => _fetch('PATCH', url, opts, data)
_.delete = () => _fetch('DELETE', url, opts)
return _
}
fetchival.fetch = fetch
return fetchival
}
module.exports = createFetchival