-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasync-fetch.js
55 lines (51 loc) · 1.37 KB
/
async-fetch.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
import { base64Encode, crocks, R } from './deps.js'
import { toEsErr } from './utils.js'
const { Async } = crocks
const {
ifElse,
assoc,
pipe,
identity,
propOr,
compose,
tap,
} = R
// TODO: Tyler. wrap with opionated approach like before with https://github.com/vercel/fetch
export const asyncFetch = (fetch) => Async.fromPromise(fetch)
export const createHeaders = (username, password) =>
pipe(
assoc('Content-Type', 'application/json'),
assoc('Accept', 'application/json'),
ifElse(
() => username && password,
assoc(
'authorization',
`Basic ${base64Encode(new TextEncoder().encode(username + ':' + password))}`,
),
identity,
),
)({})
export const handleResponse = (pred) =>
ifElse(
(res) => pred(res),
(res) =>
Async.of(res)
.chain(Async.fromPromise((res) => res.json())),
(res) =>
Async.of(res)
.chain(Async.fromPromise((res) => res.json()))
.map(tap(console.log))
/**
* Elasticsearch errors have the format:
* { error: { reason: string }, status: number }
* IF defined
*/
.map((body = { status: res.status }) =>
compose(
(err) => toEsErr(err, res.status),
assoc('status', body.status),
propOr(body, 'error'),
)(body)
)
.chain(Async.Rejected),
)