@superutils/fetch 1.2.3 → 1.4.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 +97 -100
- package/dist/index.d.ts +275 -157
- package/dist/index.js +188 -172
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -12,9 +12,9 @@ For full API reference check out the [docs page](https://alien45.github.io/super
|
|
|
12
12
|
|
|
13
13
|
## Table of Contents
|
|
14
14
|
|
|
15
|
-
- Features
|
|
16
|
-
- Installation
|
|
17
|
-
- Usage
|
|
15
|
+
- [Features](#features)
|
|
16
|
+
- [Installation](#installation)
|
|
17
|
+
- [Usage](#usage)
|
|
18
18
|
- [`fetch()`](#fetch): drop-in replacement for built-in `fetch()`
|
|
19
19
|
- [`PromisE Features`](#promise-features): status, early finalization etc
|
|
20
20
|
- [`Method Specific Functions`](#methods)
|
|
@@ -67,39 +67,39 @@ All fetch calls return a `PromisE` (`@superutils/promise`) instance which means
|
|
|
67
67
|
|
|
68
68
|
1. Status tracking: all instances come with `.pending`, `.resolved` and `.rejected` attributes that indicate the current state of the promise.
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
```javascript
|
|
71
|
+
import fetch from '@superutils/fetch'
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
const request = fetch('https://dummyjson.com/products/1')
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
console.log(request.pending) // true
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
request.then(() => {
|
|
78
|
+
console.log(request.resolved) // true
|
|
79
|
+
console.log(request.pending) // false
|
|
80
|
+
console.log(request.rejected) // false
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
83
|
|
|
84
84
|
2. Early finalization: all `PromisE` instances expose `.resolve()` and `.reject()` methods that allow early finalization and `.onEarlyFinalize` array that allows adding callbacks to be executed when the promise is finalized externally using these methods. Fetch promises utilize this to abort the request when appropriate.
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
```javascript
|
|
87
|
+
import fetch from '@superutils/fetch'
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
// Request that will take 5 seconds to resolve
|
|
90
|
+
const request = fetch('https://dummyjson.com/products?delay=5000')
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
request.then(result => console.log(result), console.warn)
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
// Add a callback to do stuff whenever request is aborted externally.
|
|
95
|
+
// This will not be invoked if fetch fails or resolves (promise finalized naturally) using the Promise executor.
|
|
96
|
+
request.onEarlyFinalize.push((resolved, valueOrReason) =>
|
|
97
|
+
console.log('Aborted externally:', { resolved, valueOrReason }),
|
|
98
|
+
)
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
// resolve/reject before the promise is finalized
|
|
101
|
+
request.reject(new Error('No longer needed'))
|
|
102
|
+
```
|
|
103
103
|
|
|
104
104
|
<div id="methods"></div>
|
|
105
105
|
|
|
@@ -362,86 +362,82 @@ The following interceptor callbacks allow intercepting and/or transforming at di
|
|
|
362
362
|
- Value returned (transformed) by an interceptor will be carried over to the subsequent interceptor of the same type.
|
|
363
363
|
- There are 2 category of interceptors:
|
|
364
364
|
- Local: interceptors provided when making a request.
|
|
365
|
+
- Global: interceptors that are executed application-wide on every request. Global interceptors can be added/accessed at `fetch.defaults.interceptors`. Global interceptors are always executed before local interceptors.
|
|
365
366
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
```javascript
|
|
369
|
-
import fetch, { FetchError } from '@superutils/fetch'
|
|
370
|
-
|
|
371
|
-
const interceptors = {
|
|
372
|
-
error: [
|
|
373
|
-
(err, url, options) => {
|
|
374
|
-
console.log('Request failed', err, url, options)
|
|
375
|
-
// return nothing/undefined to keep the error unchanged
|
|
376
|
-
// or return modified/new error
|
|
377
|
-
err.message = 'My custom error message!'
|
|
378
|
-
// or create a new FetchError by cloning it (make sure all the required properties are set correctly)
|
|
379
|
-
return err.clone('My custom error message!')
|
|
380
|
-
},
|
|
381
|
-
],
|
|
382
|
-
request: [
|
|
383
|
-
(url, options) => {
|
|
384
|
-
// add extra headers or modify request options here
|
|
385
|
-
options.headers.append('x-custom-header', 'some value')
|
|
386
|
-
|
|
387
|
-
// transform the URL by returning a modified URL
|
|
388
|
-
return url + '?param=value'
|
|
389
|
-
},
|
|
390
|
-
],
|
|
391
|
-
response: [
|
|
392
|
-
(response, url, options) => {
|
|
393
|
-
if (response.ok) return
|
|
394
|
-
console.log('request was successful', { url, options })
|
|
395
|
-
|
|
396
|
-
// You can transform the response by returning different `Response` object or even make a completely new HTTP reuqest.
|
|
397
|
-
// You can transform the response by returning different `Response` object or even make a completely new HTTP request.
|
|
398
|
-
// The subsequent response interceptors will receive the returned response
|
|
399
|
-
return fetch('https://dummyjson.com/products/1') // promise will be resolved automatically
|
|
400
|
-
},
|
|
401
|
-
],
|
|
402
|
-
result: [
|
|
403
|
-
(result, url, options) => {
|
|
404
|
-
const productId = Number(
|
|
405
|
-
new URL(url).pathname.split('/products/')[1],
|
|
406
|
-
)
|
|
407
|
-
if (options.method === 'get' && !Number.isNaN(productId)) {
|
|
408
|
-
result.title ??= 'Unknown title'
|
|
409
|
-
}
|
|
410
|
-
return result
|
|
411
|
-
},
|
|
412
|
-
],
|
|
413
|
-
}
|
|
414
|
-
fetch
|
|
415
|
-
.get('https://dummyjson.com/products/1', { interceptors })
|
|
416
|
-
.then(product => console.log({ product }))
|
|
417
|
-
```
|
|
367
|
+
**Example: Interceptor usage**
|
|
418
368
|
|
|
419
|
-
|
|
369
|
+
```javascript
|
|
370
|
+
import fetch, { FetchError } from '@superutils/fetch'
|
|
371
|
+
|
|
372
|
+
const interceptors = {
|
|
373
|
+
error: [
|
|
374
|
+
(err, url, options) => {
|
|
375
|
+
console.log('Request failed', err, url, options)
|
|
376
|
+
// return nothing/undefined to keep the error unchanged
|
|
377
|
+
// or return modified/new error
|
|
378
|
+
err.message = 'My custom error message!'
|
|
379
|
+
// or create a new FetchError by cloning it (make sure all the required properties are set correctly)
|
|
380
|
+
return err.clone('My custom error message!')
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
request: [
|
|
384
|
+
(url, options) => {
|
|
385
|
+
// add extra headers or modify request options here
|
|
386
|
+
options.headers.append('x-custom-header', 'some value')
|
|
387
|
+
|
|
388
|
+
// transform the URL by returning a modified URL
|
|
389
|
+
return url + '?param=value'
|
|
390
|
+
},
|
|
391
|
+
],
|
|
392
|
+
response: [
|
|
393
|
+
(response, url, options) => {
|
|
394
|
+
if (response.ok) return
|
|
395
|
+
console.log('request was successful', { url, options })
|
|
396
|
+
|
|
397
|
+
// You can transform the response by returning different `Response` object or even make a completely new HTTP reuqest.
|
|
398
|
+
// You can transform the response by returning different `Response` object or even make a completely new HTTP request.
|
|
399
|
+
// The subsequent response interceptors will receive the returned response
|
|
400
|
+
return fetch('https://dummyjson.com/products/1') // promise will be resolved automatically
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
result: [
|
|
404
|
+
(result, url, options) => {
|
|
405
|
+
const productId = Number(
|
|
406
|
+
new URL(url).pathname.split('/products/')[1],
|
|
407
|
+
)
|
|
408
|
+
if (options.method === 'get' && !Number.isNaN(productId)) {
|
|
409
|
+
result.title ??= 'Unknown title'
|
|
410
|
+
}
|
|
411
|
+
return result
|
|
412
|
+
},
|
|
413
|
+
],
|
|
414
|
+
}
|
|
415
|
+
fetch
|
|
416
|
+
.get('https://dummyjson.com/products/1', { interceptors })
|
|
417
|
+
.then(product => console.log({ product }))
|
|
418
|
+
```
|
|
420
419
|
|
|
421
|
-
|
|
420
|
+
**Example: Add global request and error interceptors**
|
|
422
421
|
|
|
423
|
-
|
|
424
|
-
|
|
422
|
+
```javascript
|
|
423
|
+
import fetch from '@superutils/fetch'
|
|
425
424
|
|
|
426
|
-
|
|
425
|
+
const { interceptors } = fetch.defaults
|
|
427
426
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
427
|
+
interceptors.request.push((url, options) => {
|
|
428
|
+
// a headers to all requests make by the application
|
|
429
|
+
// add headers to all requests made by the application
|
|
430
|
+
options.headers.append('x-auth', 'token')
|
|
431
|
+
})
|
|
433
432
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
433
|
+
interceptors.error.push((err, url, options) => {
|
|
434
|
+
// log whenever a request fails
|
|
435
|
+
console.log('Error interceptor', err)
|
|
436
|
+
})
|
|
438
437
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
console.warn,
|
|
443
|
-
)
|
|
444
|
-
```
|
|
438
|
+
// Each time a requst is made using @superutils/fetch, the above interceptors will be executed when appropriate
|
|
439
|
+
fetch('https://dummyjson.com/products/1').then(console.log, console.warn)
|
|
440
|
+
```
|
|
445
441
|
|
|
446
442
|
<div id="retry"></div>
|
|
447
443
|
|
|
@@ -569,7 +565,7 @@ While `createClient()` is versatile enough for any HTTP method, `createPostClien
|
|
|
569
565
|
Similar to `createClient`, the returned function comes equipped with a `.deferred()` method, enabling debounced, throttled, or sequential execution.
|
|
570
566
|
|
|
571
567
|
```javascript
|
|
572
|
-
import { createPostClient
|
|
568
|
+
import { createPostClient } from '@superutils/fetch'
|
|
573
569
|
|
|
574
570
|
// Create a POST client with 10-second as the default timeout
|
|
575
571
|
const postClient = createPostClient(
|
|
@@ -591,8 +587,9 @@ postClient(
|
|
|
591
587
|
const updateProduct = postClient.deferred(
|
|
592
588
|
{
|
|
593
589
|
delayMs: 300, // debounce duration
|
|
590
|
+
onResult: console.log, // prints only successful results
|
|
594
591
|
},
|
|
595
|
-
'https://dummyjson.com/products/
|
|
592
|
+
'https://dummyjson.com/products/add',
|
|
596
593
|
{
|
|
597
594
|
method: 'patch',
|
|
598
595
|
timeout: 3000,
|