fetchbasequery 0.0.2 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -2
- package/package.json +1 -1
- package/src/baseQuery.js +8 -11
- package/src/helpers/mergeHeaders.js +7 -0
- package/src/helpers/purge.js +13 -1
- package/src/middlewares/accessToken.js +9 -6
- package/src/middlewares/commonReply.js +1 -1
- package/src/middlewares/encodeBody.js +10 -7
- package/src/middlewares/jsonReply.js +1 -1
- package/types/index.d.ts +1 -1
package/README.md
CHANGED
|
@@ -2,8 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Library for easily make HTTP queries without mass of boilerplate code.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
NPM:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install fetchbasequery
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
PNPM:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
pnpm add fetchbasequery
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
7
20
|
|
|
8
21
|
Build base query function:
|
|
9
22
|
|
|
@@ -11,14 +24,21 @@ Build base query function:
|
|
|
11
24
|
import fetchBaseQuery, { baseQuery, encodeBody, accessToken, jsonReply, commonReply } from 'fetchbasequery'
|
|
12
25
|
|
|
13
26
|
const query = fetchBaseQuery({
|
|
27
|
+
// main options ...
|
|
14
28
|
baseUrl: 'https://api.example.org/v1'
|
|
15
29
|
baseQuery,
|
|
16
30
|
logErrors: true,
|
|
31
|
+
// add some defaults for `fetch()` ...
|
|
32
|
+
mode: 'cors',
|
|
33
|
+
credentials: 'include',
|
|
34
|
+
cache: 'reload',
|
|
35
|
+
// middlewares
|
|
17
36
|
middleware: [
|
|
18
37
|
encodeBody(),
|
|
19
38
|
accessToken({
|
|
20
39
|
getAccessToken: () => localStorage.getItem('access_token'),
|
|
21
40
|
setAccessToken: (token) => localStorage.setItem('access_token', token),
|
|
41
|
+
removeAccessToken: (token) => localStorage.removeItem('access_token'),
|
|
22
42
|
getUpdatedAccessToken: async (response) => response.headers.get('X-Access-Token')
|
|
23
43
|
}),
|
|
24
44
|
jsonReply(),
|
|
@@ -54,3 +74,7 @@ addEventListener('fetch', evt => {
|
|
|
54
74
|
It works fine both on frontend and backend sides. For backend side usage Node.js v18+ is required,
|
|
55
75
|
because the middleware `baseQuery` based on `Fetch API`. But it can be replaced with your own
|
|
56
76
|
implementation based on another API (e.g. based on `axios` etc).
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
MIT
|
package/package.json
CHANGED
package/src/baseQuery.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import responseFromError from './helpers/responseFromError.js'
|
|
2
2
|
import purge from './helpers/purge.js'
|
|
3
|
+
import mergeHeaders from './helpers/mergeHeaders.js'
|
|
3
4
|
|
|
4
5
|
const moduleName = 'fetchBaseQuery/baseQuery'
|
|
5
6
|
|
|
@@ -16,12 +17,6 @@ export default async ({ url: endpoint, request: subject, ...options } = {}) => {
|
|
|
16
17
|
: undefined,
|
|
17
18
|
...options
|
|
18
19
|
}
|
|
19
|
-
// default options for `fetch()`
|
|
20
|
-
const defaultFetchOptions = {
|
|
21
|
-
method: 'GET',
|
|
22
|
-
cache: 'reload',
|
|
23
|
-
credentials: 'include',
|
|
24
|
-
}
|
|
25
20
|
// extract options which are known by `fetch()`
|
|
26
21
|
const { method, headers, body, mode, credentials, cache, redirect,
|
|
27
22
|
referrer, referrerPolicy, integrity, keepalive, signal } = restOptions
|
|
@@ -50,11 +45,13 @@ export default async ({ url: endpoint, request: subject, ...options } = {}) => {
|
|
|
50
45
|
)
|
|
51
46
|
}
|
|
52
47
|
subject = url
|
|
48
|
+
} else if (fetchOptions.headers) {
|
|
49
|
+
fetchOptions.headers = mergeHeaders(subject.headers, fetchOptions.headers)
|
|
50
|
+
}
|
|
51
|
+
request = new Request(subject, fetchOptions)
|
|
52
|
+
if (debug?.baseQuery) {
|
|
53
|
+
console.log(moduleName, { request })
|
|
53
54
|
}
|
|
54
|
-
request = new Request(subject, {
|
|
55
|
-
...defaultFetchOptions,
|
|
56
|
-
...fetchOptions
|
|
57
|
-
})
|
|
58
55
|
response = await fetch(request)
|
|
59
56
|
} catch (error) {
|
|
60
57
|
if (logErrors) {
|
|
@@ -63,7 +60,7 @@ export default async ({ url: endpoint, request: subject, ...options } = {}) => {
|
|
|
63
60
|
response = responseFromError(error)
|
|
64
61
|
}
|
|
65
62
|
if (debug?.baseQuery) {
|
|
66
|
-
console.log(moduleName, response)
|
|
63
|
+
console.log(moduleName, { response })
|
|
67
64
|
}
|
|
68
65
|
return response
|
|
69
66
|
}
|
package/src/helpers/purge.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
const purgeObject = object => Object.fromEntries(
|
|
2
2
|
Object.entries(object)
|
|
3
3
|
.filter(entry => entry[1] !== undefined)
|
|
4
4
|
)
|
|
5
|
+
|
|
6
|
+
const purgeHeaders = headers => {
|
|
7
|
+
headers.entities().forEach(([ name, value ]) => {
|
|
8
|
+
if (value === '')
|
|
9
|
+
headers.delete(name)
|
|
10
|
+
})
|
|
11
|
+
return headers
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default object => object instanceof Headers
|
|
15
|
+
? purgeHeaders(object)
|
|
16
|
+
: purgeObject(object)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import responseFromError from '../helpers/responseFromError.js'
|
|
2
2
|
import purge from '../helpers/purge.js'
|
|
3
|
+
import mergeHeaders from '../helpers/mergeHeaders.js'
|
|
3
4
|
|
|
4
5
|
const moduleName = 'fetchBaseQuery/middlewares/accessToken'
|
|
5
6
|
|
|
@@ -7,12 +8,14 @@ export default (settings = {}) => query => async ({ payload, headers, ...options
|
|
|
7
8
|
const {
|
|
8
9
|
getAccessToken,
|
|
9
10
|
setAccessToken,
|
|
11
|
+
removeAccessToken,
|
|
10
12
|
isUnauthorized,
|
|
11
13
|
getUpdatedAccessToken,
|
|
12
14
|
getAuthorizationHeaders
|
|
13
15
|
} = {
|
|
14
16
|
getAccessToken: (payload) => undefined,
|
|
15
17
|
setAccessToken: (token) => {},
|
|
18
|
+
removeAccessToken: () => {},
|
|
16
19
|
isUnauthorized: (response) => response.status === 401,
|
|
17
20
|
getUpdatedAccessToken: async (response) => undefined,
|
|
18
21
|
getAuthorizationHeaders: (accessToken) => (
|
|
@@ -26,10 +29,10 @@ export default (settings = {}) => query => async ({ payload, headers, ...options
|
|
|
26
29
|
try {
|
|
27
30
|
response = await query({
|
|
28
31
|
...options,
|
|
29
|
-
headers:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
headers: mergeHeaders(
|
|
33
|
+
purge(getAuthorizationHeaders(getAccessToken(payload))),
|
|
34
|
+
headers || {}
|
|
35
|
+
)
|
|
33
36
|
})
|
|
34
37
|
} catch (error) {
|
|
35
38
|
if (options.logErrors) {
|
|
@@ -39,7 +42,7 @@ export default (settings = {}) => query => async ({ payload, headers, ...options
|
|
|
39
42
|
}
|
|
40
43
|
try {
|
|
41
44
|
if (isUnauthorized(response)) {
|
|
42
|
-
|
|
45
|
+
removeAccessToken()
|
|
43
46
|
} else {
|
|
44
47
|
const updatedAccessToken = await getUpdatedAccessToken(response)
|
|
45
48
|
if (updatedAccessToken) {
|
|
@@ -53,7 +56,7 @@ export default (settings = {}) => query => async ({ payload, headers, ...options
|
|
|
53
56
|
response = responseFromError(error)
|
|
54
57
|
}
|
|
55
58
|
if (options.debug?.accessToken) {
|
|
56
|
-
console.log(moduleName, response)
|
|
59
|
+
console.log(moduleName, { response })
|
|
57
60
|
}
|
|
58
61
|
return response
|
|
59
62
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import purge from '../helpers/purge.js'
|
|
2
2
|
import encodeJson from '../helpers/encodeJson.js'
|
|
3
3
|
import responseFromError from '../helpers/responseFromError.js'
|
|
4
|
+
import mergeHeaders from '../helpers/mergeHeaders.js'
|
|
4
5
|
|
|
5
6
|
const moduleName = 'fetchBaseQuery/middlewares/accessToken'
|
|
6
7
|
|
|
@@ -61,12 +62,14 @@ export default (settings = {}) => (query) => async ({ body, headers, ...options
|
|
|
61
62
|
try {
|
|
62
63
|
response = await query({
|
|
63
64
|
...options,
|
|
64
|
-
headers:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
headers: mergeHeaders(
|
|
66
|
+
purge({
|
|
67
|
+
'Content-Type': contentType instanceof Function
|
|
68
|
+
? contentType({ body })
|
|
69
|
+
: contentType
|
|
70
|
+
}),
|
|
71
|
+
headers || {}
|
|
72
|
+
),
|
|
70
73
|
body: encodeBody(body)
|
|
71
74
|
})
|
|
72
75
|
} catch (error) {
|
|
@@ -76,7 +79,7 @@ export default (settings = {}) => (query) => async ({ body, headers, ...options
|
|
|
76
79
|
response = responseFromError(error)
|
|
77
80
|
}
|
|
78
81
|
if (options.debug?.encodeBody) {
|
|
79
|
-
console.log(moduleName, response)
|
|
82
|
+
console.log(moduleName, { response })
|
|
80
83
|
}
|
|
81
84
|
return response
|
|
82
85
|
}
|
package/types/index.d.ts
CHANGED