fch 4.0.0 → 4.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/package.json +25 -12
- package/readme.md +38 -11
- package/fetch.min.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fch",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "Fetch interface with better promises, deduplication, defaults, etc.",
|
|
5
5
|
"homepage": "https://github.com/franciscop/fetch",
|
|
6
6
|
"repository": "https://github.com/franciscop/fetch.git",
|
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
"author": "Francisco Presencia <public@francisco.io> (https://francisco.io/)",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "
|
|
13
|
-
"size": "echo $(gzip -c
|
|
14
|
-
"start": "
|
|
15
|
-
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --detectOpenHandles"
|
|
16
|
-
"watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch --coverage --detectOpenHandles"
|
|
12
|
+
"build": "rollup -c",
|
|
13
|
+
"size": "echo $(gzip -c index.min.js | wc -c) bytes",
|
|
14
|
+
"start": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch --coverage --detectOpenHandles",
|
|
15
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --detectOpenHandles"
|
|
17
16
|
},
|
|
18
17
|
"keywords": [
|
|
19
18
|
"fetch",
|
|
@@ -23,21 +22,35 @@
|
|
|
23
22
|
"async",
|
|
24
23
|
"ajax"
|
|
25
24
|
],
|
|
26
|
-
"main": "./
|
|
27
|
-
"files": [
|
|
28
|
-
"fetch.min.js"
|
|
29
|
-
],
|
|
25
|
+
"main": "./index.min.js",
|
|
26
|
+
"files": [],
|
|
30
27
|
"type": "module",
|
|
31
28
|
"engines": {
|
|
32
29
|
"node": ">=18.0.0"
|
|
33
30
|
},
|
|
34
31
|
"devDependencies": {
|
|
35
|
-
"
|
|
32
|
+
"@babel/core": "^7.15.0",
|
|
33
|
+
"@babel/preset-env": "^7.15.0",
|
|
34
|
+
"@babel/preset-react": "^7.14.5",
|
|
35
|
+
"babel-loader": "^8.2.2",
|
|
36
|
+
"babel-polyfill": "^6.26.0",
|
|
37
|
+
"jest": "^28.1.0",
|
|
38
|
+
"jest-environment-jsdom": "^28.1.0",
|
|
36
39
|
"jest-fetch-mock": "^3.0.3",
|
|
37
|
-
"
|
|
40
|
+
"rollup": "^1.32.1",
|
|
41
|
+
"rollup-plugin-babel": "^4.4.0",
|
|
42
|
+
"rollup-plugin-node-resolve": "^5.2.0",
|
|
43
|
+
"rollup-plugin-terser": "^5.2.0",
|
|
44
|
+
"swear": "^1.1.2"
|
|
38
45
|
},
|
|
39
46
|
"jest": {
|
|
40
47
|
"testEnvironment": "jest-environment-node",
|
|
41
48
|
"transform": {}
|
|
49
|
+
},
|
|
50
|
+
"babel": {
|
|
51
|
+
"presets": [
|
|
52
|
+
"@babel/preset-env",
|
|
53
|
+
"@babel/preset-react"
|
|
54
|
+
]
|
|
42
55
|
}
|
|
43
56
|
}
|
package/readme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Fch [](https://www.npmjs.com/package/fch) [](https://www.npmjs.com/package/fch) [](https://github.com/franciscop/fetch/blob/master/.github/workflows/tests.yml) [](https://github.com/franciscop/fetch/blob/master/index.min.js)
|
|
2
2
|
|
|
3
3
|
A tiny library to make API calls easier. Similar to Axios, but tiny size and simpler API:
|
|
4
4
|
|
|
@@ -32,6 +32,7 @@ api.head(url, { headers, ...options });
|
|
|
32
32
|
api.post(url, { body, headers, ...options });
|
|
33
33
|
api.patch(url, { body, headers, ...options });
|
|
34
34
|
api.put(url, { body, headers, ...options });
|
|
35
|
+
api.del(url, { body, headers, ...options });
|
|
35
36
|
api.delete(url, { body, headers, ...options });
|
|
36
37
|
|
|
37
38
|
api.create({ url, body, headers, ...options });
|
|
@@ -256,6 +257,21 @@ When to use each?
|
|
|
256
257
|
|
|
257
258
|
### Output
|
|
258
259
|
|
|
260
|
+
The default output manipulation is to expect either plain `TEXT` as `plain/text` or `JSON` as `application/json` from the `Content-Type`. If your API works with these (the vast majority of APIs do) then you should be fine out of the box!
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
const cats = await api.get("/cats");
|
|
264
|
+
console.log(cats); // [{ id: 1, name: 'Whiskers', ... }, ...]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
For more expressive control, you can use the **`output` option** (either as a default when [creating an instance](#create-an-instance) or with each call), or using a method:
|
|
268
|
+
|
|
269
|
+
```js
|
|
270
|
+
const api = fch.create({ output: "json" }); // JSON by default
|
|
271
|
+
const streamImg = await api.get("/cats/123/image", { output: "stream" }); // Stream the image
|
|
272
|
+
const streamImg2 = await api.get("/cats/123/image").stream(); // Shortcut for the one above
|
|
273
|
+
```
|
|
274
|
+
|
|
259
275
|
This controls whether the call returns just the body (default), or the whole response. It can be controlled globally or on a per-request basis:
|
|
260
276
|
|
|
261
277
|
```js
|
|
@@ -276,16 +292,27 @@ const blob = await api.get("/data", { output: "blob" });
|
|
|
276
292
|
There are few options that can be specified:
|
|
277
293
|
|
|
278
294
|
- `output: "body"` (default): returns the body, parsed as JSON or plain TEXT depending on the headers.
|
|
279
|
-
- `output: "response"`: return the full response with the properties `body`, `headers`, `status
|
|
295
|
+
- `output: "response"`: return the full response with the properties `body`, `headers`, `status`. The body will be parsed as JSON or plain TEXT depending on the headers. If you want the raw `response`, use `raw` or `clone` instead (see below in "raw" or "clone").
|
|
280
296
|
- `output: "stream"`: return a [web ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) of the body as the result of the promise.
|
|
281
|
-
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
297
|
+
- `output: "arrayBuffer"`\*: returns an arrayBuffer of the response body.
|
|
298
|
+
- `output: "blob"`\*: returns an arrayBuffer of the response body.
|
|
299
|
+
- `output: "clone"`\*: returns the raw Response, with the raw body. See also `raw` below.
|
|
300
|
+
- `output: "formData"`\* (might be unavailable): returns an instance of FormData with all the parsed data.
|
|
301
|
+
- `output: "json"`\*: attempts to parse the response as JSON.
|
|
302
|
+
- `output: "text"`\*: puts the response body as plain text.
|
|
303
|
+
- `output: "raw"`\*: an alias for `clone`, returning the raw response (after passing through `after`).
|
|
304
|
+
|
|
305
|
+
\* Standard [MDN methods](https://developer.mozilla.org/en-US/docs/Web/API/Response#methods)
|
|
306
|
+
|
|
307
|
+
The `output` values can all be used as a method as well. So all of these are equivalent:
|
|
308
|
+
|
|
309
|
+
```js
|
|
310
|
+
const text = await api.get("/cats", { output: "text" });
|
|
311
|
+
const text = await api.get("/cats").text();
|
|
312
|
+
|
|
313
|
+
const raw = await api.get("/cats", { output: "raw" });
|
|
314
|
+
const raw = await api.get("/cats").raw();
|
|
315
|
+
```
|
|
289
316
|
|
|
290
317
|
For example, return the raw body as a `ReadableStream` with the option `stream`:
|
|
291
318
|
|
|
@@ -341,7 +368,7 @@ it("can opt out locally", async () => {
|
|
|
341
368
|
You can also easily add the interceptors `before`, `after` and `error`:
|
|
342
369
|
|
|
343
370
|
- `before`: Called when the request is fully formed, but before actually launching it.
|
|
344
|
-
- `
|
|
371
|
+
- `after`: Called just after the response is created and if there was no error, but before parsing anything else.
|
|
345
372
|
- `error`: When the response is not okay, if possible it'll include the `response` object.
|
|
346
373
|
|
|
347
374
|
> Note: interceptors are never deduped/cached and always execute once per call, even if the main async fetch() has been deduped.
|
package/fetch.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e=(e,{after:t,cache:r,error:o,output:a})=>fetch(e.url,e).then((async e=>{r&&r.clear();let s={status:e.status,statusText:e.statusText,headers:{}};for(let t of e.headers.keys())s.headers[t.toLowerCase()]=e.headers.get(t);if(!e.ok){const t=new Error(e.statusText);return t.response=s,o(t)}if(s=t(s),"stream"===a)return e.body;if(e[a]&&"function"==typeof e[a])return e[a]();const n=e.headers.get("content-type"),u=n&&n.includes("application/json");if(s.body=s.body||await(u?e.json():e.text()),"body"===a)return s.body;if("response"===a)return s;throw new Error(`Invalid option output="${a}"`)})),t=(r={})=>{const o=(()=>{const e=new Map;return t=>({save:r=>(e.set(t,r),r),get:()=>e.get(t),clear:()=>e.delete(t)})})(),a=async(t="/",r={})=>{"object"!=typeof r&&(r={}),r="string"==typeof t?{url:t,...r}:t;let{dedupe:s,output:n,before:u,after:d,error:c,...f}={...a,...r};f.url=((e,t,r)=>{let[o,a={}]=e.split("?");const s=new URLSearchParams({...Object.fromEntries(new URLSearchParams(t)),...Object.fromEntries(new URLSearchParams(a))}).toString();return s&&(o=o+"?"+s),r?new URL(o,r).href:o})(f.url,{...a.query,...r.query},f.baseUrl??f.baseURL),f.method=f.method.toLowerCase(),f.headers=(e=>{const t={};for(let[r,o]of Object.entries(e))t[r.toLowerCase()]=o;return t})({...a.headers,...r.headers});const p=!(!s||"get"!==f.method)&&o(f.url);var i;return"object"!=typeof(i=f.body)||i instanceof FormData||i.pipe||(f.body=JSON.stringify(f.body),f.headers["content-type"]="application/json"),f=u(f),p&&!f.signal?p.get()?p.get():p.save(e(f,{cache:p,output:n,error:c,after:d})):e(f,{output:n,error:c,after:d})};return a.url=r.url??"/",a.method=r.method??"get",a.query=r.query??{},a.headers=r.headers??{},a.baseUrl=r.baseUrl??r.baseURL??null,a.dedupe=r.dedupe??!0,a.output=r.output??"body",a.credentials=r.credentials??"include",a.before=r.before??(e=>e),a.after=r.after??(e=>e),a.error=r.error??(e=>{throw e}),["get","head","post","patch","put","delete"].map((e=>{a[e]=(t,r={})=>a(t,{...r,method:e})})),a.create=t,a};"undefined"!=typeof window&&(window.fch=t());export default t();
|