@superutils/fetch 1.1.8 → 1.2.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 +179 -10
- package/dist/index.d.ts +220 -148
- package/dist/index.js +83 -52
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -13,7 +13,10 @@ This package enhances the native `fetch` API by providing a streamlined interfac
|
|
|
13
13
|
- [`Method Specific Functions`](#methods)
|
|
14
14
|
- [`fetch.get.deferred()`](#fetch-deferred): cancellable and debounced or throttled `fetch()`
|
|
15
15
|
- [`fetch.post()`](#post): make post requests
|
|
16
|
-
- [`fetch.post.deferred()`](#post-deferred) cancellable and debounced or throttled `post()`
|
|
16
|
+
- [`fetch.post.deferred()`](#post-deferred): cancellable and debounced or throttled `post()`
|
|
17
|
+
- [`Retry`](#retry) Retry on request failure
|
|
18
|
+
- [`Timeout`](#timeout) Abort request on timeout
|
|
19
|
+
- [`Interceptors/Transformers`](#interceptors)
|
|
17
20
|
|
|
18
21
|
## Features
|
|
19
22
|
|
|
@@ -37,18 +40,14 @@ npm install @superutils/fetch
|
|
|
37
40
|
|
|
38
41
|
### `fetch(url, options)`
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
Use as a drop-in replacement to the built-in `fetch()`.
|
|
41
44
|
|
|
42
|
-
```
|
|
45
|
+
```javascript
|
|
43
46
|
import fetch from '@superutils/fetch'
|
|
44
47
|
|
|
45
|
-
fetch('https://dummyjson.com/products/1'
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// Alternative:
|
|
49
|
-
fetch
|
|
50
|
-
.get('https://dummyjson.com/products/1')
|
|
51
|
-
.then(theActualData => console.log(theActualData))
|
|
48
|
+
fetch('https://dummyjson.com/products/1')
|
|
49
|
+
.then(response => response.json())
|
|
50
|
+
.then(console.log)
|
|
52
51
|
```
|
|
53
52
|
|
|
54
53
|
<div id="methods"></div>
|
|
@@ -75,6 +74,16 @@ While `fetch()` provides access to all HTTP request methods by specifying it in
|
|
|
75
74
|
- `fetch.post.deferred(...)`
|
|
76
75
|
- `fetch.put.deferred(...)`
|
|
77
76
|
|
|
77
|
+
All method specific functions by default return result parsed as JSON. No need for `response.json()` or `result.data.data` drilling.
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
import fetch from '@superutils/fetch'
|
|
81
|
+
|
|
82
|
+
fetch
|
|
83
|
+
.get('https://dummyjson.com/products/1')
|
|
84
|
+
.then(product => console.log({ product }))
|
|
85
|
+
```
|
|
86
|
+
|
|
78
87
|
<div id="fetch-deferred"></div>
|
|
79
88
|
|
|
80
89
|
### `fetch.get.deferred(deferOptions, defaultUrl, defaultOptions)`
|
|
@@ -268,3 +277,163 @@ fetch
|
|
|
268
277
|
// Only the final call executes, 300ms after it was made (at the 400ms mark).
|
|
269
278
|
// The token is refreshed only once, preventing redundant network requests.
|
|
270
279
|
```
|
|
280
|
+
|
|
281
|
+
<div id="interceptors"></div>
|
|
282
|
+
|
|
283
|
+
### Interceptors: intercept and/or transform request & result
|
|
284
|
+
|
|
285
|
+
The following interceptor callbacks allow intercepting and/or transforming at different stages of the request.
|
|
286
|
+
|
|
287
|
+
#### Interceptor types (executed in sequence):
|
|
288
|
+
|
|
289
|
+
1. `request`: Request interceptors are executed before a HTTP request is made.
|
|
290
|
+
- To transform the URL simply return a new or modified URL.
|
|
291
|
+
- To transform `fetch` options simply modify the options parameter
|
|
292
|
+
2. `response`: Response interceptors are executed after receiving a `fetch` Response regardless of the HTTP status code.
|
|
293
|
+
3. `result`: Result interceptors are executed before returning the result. To transform the result simply return a new value.
|
|
294
|
+
PS: if the value of `options.as` is `FetchAs.response` (`"response"`), the value received in result will be a `Response` object.
|
|
295
|
+
4. `error`: Error interceptors are executed when the request fails. Error can be transformed by returning a modified/new `FetchError`.
|
|
296
|
+
|
|
297
|
+
#### Notes:
|
|
298
|
+
|
|
299
|
+
- All interceptors can be either asynchronous or synchronous functions.
|
|
300
|
+
- If an exception is raised while executing the interceptors, it will be gracefully ignored.
|
|
301
|
+
- Value returned (transformed) by an interceptor will be carried over to the subsequent interceptor of the same type.
|
|
302
|
+
- There are 2 category of interceptors:
|
|
303
|
+
- Local: interceptors provided when making a request.
|
|
304
|
+
- Global: intereptors 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.
|
|
305
|
+
|
|
306
|
+
**Example: Add global request and error interceptors**
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
import fetch from '@superutils/fetch'
|
|
310
|
+
|
|
311
|
+
const { interceptors } = fetch.defaults
|
|
312
|
+
interceptors.request.push((url, options) => {
|
|
313
|
+
// a headers to all requests make by the application
|
|
314
|
+
options.headers.append('x-auth', 'token')
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
interceptors.error.push((err, url, options) => {
|
|
318
|
+
// log whenever a request fails
|
|
319
|
+
console.log('Error interceptor', err)
|
|
320
|
+
})
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
```javascript
|
|
324
|
+
import fetch, { FetchError } from '@superutils/fetch'
|
|
325
|
+
|
|
326
|
+
const interceptors = {
|
|
327
|
+
error: [
|
|
328
|
+
(err, url, options) => {
|
|
329
|
+
console.log('Request failed', err, url, options)
|
|
330
|
+
// return nothing/undefined to keep the error unchanged
|
|
331
|
+
// or return modified/new error
|
|
332
|
+
err.message = 'My custom error message!'
|
|
333
|
+
// or create a new FetchError by cloning it (make sure all the required properties are set correctly)
|
|
334
|
+
return err.clone('My custom error message!')
|
|
335
|
+
},
|
|
336
|
+
],
|
|
337
|
+
request: [
|
|
338
|
+
(url, options) => {
|
|
339
|
+
// add extra headers or modify request options here
|
|
340
|
+
options.headers.append('x-custom-header', 'some value')
|
|
341
|
+
|
|
342
|
+
// transform the URL by returning a modified URL
|
|
343
|
+
return url + '?param=value'
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
response: [
|
|
347
|
+
(response, url, options) => {
|
|
348
|
+
if (response.ok) return
|
|
349
|
+
console.log('request was successful', { url, options })
|
|
350
|
+
|
|
351
|
+
// You can transform the response by returning different `Response` object or even make a completely new HTTP reuqest.
|
|
352
|
+
// The subsequent response interceptors will receive the returned response
|
|
353
|
+
return fetch('https://dummyjson.com/products/1') // promise will be resolved automatically
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
result: [
|
|
357
|
+
(result, url, options) => {
|
|
358
|
+
const productId = Number(
|
|
359
|
+
new URL(url).pathname.split('/products/')[1],
|
|
360
|
+
)
|
|
361
|
+
if (options.method === 'get' && !Number.isNaN(productId)) {
|
|
362
|
+
result.title ??= 'Unknown title'
|
|
363
|
+
}
|
|
364
|
+
return result
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
}
|
|
368
|
+
fetch
|
|
369
|
+
.get('https://dummyjson.com/products/1', { interceptors })
|
|
370
|
+
.then(product => console.log({ product }))
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
<div id="retry"></div>
|
|
374
|
+
|
|
375
|
+
### Retry
|
|
376
|
+
|
|
377
|
+
The `retry` option provides a robust mechanism to automatically re-attempt failed requests, with support for both linear and exponential backoff strategies to gracefully handle transient network issues.
|
|
378
|
+
|
|
379
|
+
```javascript
|
|
380
|
+
import fetch from '@superutils/fetch'
|
|
381
|
+
|
|
382
|
+
fetch.get('https://dummyjson.com/products/1', {
|
|
383
|
+
retry: 3, // Max number of retries.
|
|
384
|
+
retryBackOff: 'linear', // Backoff strategy: 'linear' or 'exponential'.
|
|
385
|
+
// Delay in milliseconds.
|
|
386
|
+
// - 'linear': Constant delay between each attempt.
|
|
387
|
+
// - 'exponential': Initial delay that doubles with each retry.
|
|
388
|
+
retryDelay: 300,
|
|
389
|
+
retryDelayJitter: true, // Add random delay to avoid thundering herd.
|
|
390
|
+
retryDelayJitterMax: 100, // Max jitter delay (ms).
|
|
391
|
+
retryIf: (response, retryCount, error) => {
|
|
392
|
+
console.log('Attempt #', retryCount + 1)
|
|
393
|
+
// re-attempt if status code not 200
|
|
394
|
+
return response.status !== 200
|
|
395
|
+
},
|
|
396
|
+
})
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
<div id="timeout"></div>
|
|
400
|
+
|
|
401
|
+
### Request Timeout
|
|
402
|
+
|
|
403
|
+
A request can be automatically cancelled by simply providing a `timeout` duration in milliseconds. Internally, `fetch` uses an `AbortController` to cancel the request if it does not complete within the specified time.
|
|
404
|
+
|
|
405
|
+
```javascript
|
|
406
|
+
import fetch from '@superutils/fetch'
|
|
407
|
+
|
|
408
|
+
fetch.get('https://dummyjson.com/products/1', {
|
|
409
|
+
timeout: 5000,
|
|
410
|
+
})
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
<div id="fetch-as"></div>
|
|
414
|
+
|
|
415
|
+
### Response Parsing
|
|
416
|
+
|
|
417
|
+
By default, `fetch()` returns a `Response` object, making it a drop-in replacement for the built-in `fetch`.
|
|
418
|
+
|
|
419
|
+
However, all method-specific functions (e.g., `fetch.get`, `fetch.post`, `fetch.get.deferred`) automatically parse and return the result as JSON.
|
|
420
|
+
|
|
421
|
+
To retrieve the response in a different format (e.g., as text, a blob, or the raw `Response` object), set the `as` option to one of the following `FetchAs` values:
|
|
422
|
+
|
|
423
|
+
- `FetchAs.json`
|
|
424
|
+
- `FetchAs.text`
|
|
425
|
+
- `FetchAs.blob`
|
|
426
|
+
- `FetchAs.arrayBuffer`
|
|
427
|
+
- `FetchAs.formData`
|
|
428
|
+
- `FetchAs.bytes`
|
|
429
|
+
- `FetchAs.response`
|
|
430
|
+
|
|
431
|
+
> **Note:** When not using TypeScript, you can simply pass the string value (e.g., `'text'`, `'blob'`, `'response'`).
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
import fetch, { FetchAs } from '@superutils/fetch'
|
|
435
|
+
|
|
436
|
+
fetch.get('https://dummyjson.com/products/1', {
|
|
437
|
+
as: FetchAs.text,
|
|
438
|
+
})
|
|
439
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ValueOrPromise } from '@superutils/core';
|
|
2
1
|
import * as _superutils_promise from '@superutils/promise';
|
|
3
2
|
import { RetryOptions, IPromisE, DeferredAsyncOptions } from '@superutils/promise';
|
|
4
3
|
export { DeferredAsyncOptions, ResolveError, ResolveIgnored } from '@superutils/promise';
|
|
4
|
+
import { ValueOrPromise } from '@superutils/core';
|
|
5
5
|
|
|
6
6
|
type FetchArgs<OmitMethod extends boolean = false> = [
|
|
7
7
|
url: string | URL,
|
|
@@ -46,7 +46,7 @@ type FetchErrMsgs = {
|
|
|
46
46
|
};
|
|
47
47
|
/** Custom error message for fetch requests with more detailed info about the request URL, fetch options and response */
|
|
48
48
|
declare class FetchError extends Error {
|
|
49
|
-
options
|
|
49
|
+
options: FetchOptions;
|
|
50
50
|
response?: Response;
|
|
51
51
|
url: string | URL;
|
|
52
52
|
constructor(message: string, options: {
|
|
@@ -55,6 +55,7 @@ declare class FetchError extends Error {
|
|
|
55
55
|
response?: Response;
|
|
56
56
|
url: string | URL;
|
|
57
57
|
});
|
|
58
|
+
clone: (newMessage: string) => FetchError;
|
|
58
59
|
}
|
|
59
60
|
/**
|
|
60
61
|
* Fetch error interceptor to be invoked whenever an exception occurs.
|
|
@@ -97,11 +98,10 @@ declare class FetchError extends Error {
|
|
|
97
98
|
*/
|
|
98
99
|
type FetchInterceptorError = Interceptor<FetchError, FetchArgsInterceptor>;
|
|
99
100
|
/**
|
|
100
|
-
*
|
|
101
101
|
* Fetch request interceptor to be invoked before making a fetch request.
|
|
102
102
|
* This interceptor can also be used as a transformer:
|
|
103
103
|
* 1. by returning an API URL (string/URL)
|
|
104
|
-
* 2. by modifying the properties of the options
|
|
104
|
+
* 2. by modifying the properties of the options parameter to be used before making the fetch request
|
|
105
105
|
*
|
|
106
106
|
* @example intercept and transform fetch request
|
|
107
107
|
* ```typescript
|
|
@@ -119,7 +119,9 @@ type FetchInterceptorError = Interceptor<FetchError, FetchArgsInterceptor>;
|
|
|
119
119
|
* })
|
|
120
120
|
* ```
|
|
121
121
|
*/
|
|
122
|
-
type FetchInterceptorRequest = Interceptor<FetchArgs[0],
|
|
122
|
+
type FetchInterceptorRequest = Interceptor<FetchArgs[0], [
|
|
123
|
+
FetchArgsInterceptor[1]
|
|
124
|
+
]>;
|
|
123
125
|
/**
|
|
124
126
|
* Fetch response interceptor to be invoked before making a fetch request.
|
|
125
127
|
*
|
|
@@ -187,7 +189,7 @@ type FetchInterceptorResponse = Interceptor<Response, FetchArgsInterceptor>;
|
|
|
187
189
|
* })
|
|
188
190
|
* ```
|
|
189
191
|
*/
|
|
190
|
-
type FetchInterceptorResult = Interceptor<unknown,
|
|
192
|
+
type FetchInterceptorResult<Args extends unknown[] = FetchArgsInterceptor> = Interceptor<unknown, Args>;
|
|
191
193
|
/**
|
|
192
194
|
* All valid interceptors for fetch requests are:
|
|
193
195
|
* ---
|
|
@@ -235,7 +237,7 @@ type FetchInterceptors = {
|
|
|
235
237
|
* Fetch request options
|
|
236
238
|
*/
|
|
237
239
|
type FetchOptions = RequestInit & FetchCustomOptions;
|
|
238
|
-
type FetchOptionsDefaults = Omit<FetchOptionsInterceptor, 'method' | 'retryIf'>;
|
|
240
|
+
type FetchOptionsDefaults = Omit<FetchOptionsInterceptor, 'as' | 'method' | 'retryIf'>;
|
|
239
241
|
/**
|
|
240
242
|
* Fetch options available to interceptors
|
|
241
243
|
*/
|
|
@@ -248,7 +250,7 @@ type FetchOptionsInterceptor = Omit<FetchOptions, 'as' | 'errMsgs' | 'intercepto
|
|
|
248
250
|
/**
|
|
249
251
|
* Result types for specific parsers ("as": FetchAs)
|
|
250
252
|
*/
|
|
251
|
-
|
|
253
|
+
type FetchResult<T> = {
|
|
252
254
|
arrayBuffer: ArrayBuffer;
|
|
253
255
|
blob: Blob;
|
|
254
256
|
bytes: Uint8Array<ArrayBuffer>;
|
|
@@ -256,7 +258,7 @@ interface FetchResult<T> {
|
|
|
256
258
|
json: T;
|
|
257
259
|
text: string;
|
|
258
260
|
response: Response;
|
|
259
|
-
}
|
|
261
|
+
};
|
|
260
262
|
/**
|
|
261
263
|
* Fetch retry options
|
|
262
264
|
*/
|
|
@@ -318,12 +320,218 @@ type PostOptions = Omit<FetchOptions, 'method'> & {
|
|
|
318
320
|
method?: 'post' | 'put' | 'patch' | 'delete' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
319
321
|
};
|
|
320
322
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
+
/** Create a method-specific fetch function attached with a `.deferred()` function */
|
|
324
|
+
declare const createFetchMethodFunc: (method?: Pick<FetchOptions, "method">["method"]) => {
|
|
325
|
+
<T, TOptions extends FetchOptions = FetchOptions, TAs extends FetchAs = TOptions["as"] extends FetchAs ? TOptions["as"] : FetchAs.json, TReturn = FetchResult<T>[TAs]>(url: string | URL, options?: TOptions | undefined): _superutils_promise.IPromisE<T>;
|
|
326
|
+
deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Create a method-specific function for POST-like methods that automatically stringifies `data`
|
|
331
|
+
* and attached with a `.deferred()` function
|
|
332
|
+
*/
|
|
333
|
+
declare const createPostMethodFunc: (method?: Pick<PostOptions, "method">["method"]) => {
|
|
334
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
335
|
+
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Extended `fetch` with timeout, retry, and other options. Automatically parses as JSON by default on success.
|
|
340
|
+
*
|
|
341
|
+
* @param url request URL
|
|
342
|
+
* @param options (optional) Standard `fetch` options extended with {@link FetchCustomOptions}.
|
|
343
|
+
* Default content type is 'application/json'
|
|
344
|
+
* @param options.as (optional) determines who to parse the result. Default: {@link FetchAs.json}
|
|
345
|
+
* @param options.method (optional) fetch method. Default: `'get'`
|
|
346
|
+
*
|
|
347
|
+
* @example Make a simple HTTP requests
|
|
348
|
+
* ```typescript
|
|
349
|
+
* import { fetch } from '@superutils/fetch'
|
|
350
|
+
*
|
|
351
|
+
* // no need for `response.json()` or `result.data.data` drilling
|
|
352
|
+
* fetch('https://dummyjson.com/products/1')
|
|
353
|
+
* .then(product => console.log(product))
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
declare const fetch: {
|
|
357
|
+
<T, TOptions extends FetchOptions = FetchOptions, TAs extends FetchAs = TOptions["as"] extends FetchAs ? TOptions["as"] : FetchAs.json, TReturn = FetchResult<T>[TAs]>(url: string | URL, options?: TOptions): IPromisE<TReturn>;
|
|
323
358
|
/** Default fetch options */
|
|
324
359
|
defaults: FetchOptionsDefaults;
|
|
325
360
|
};
|
|
326
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Drop-in replacement for built-in `fetch()` with with timeout, retry etc options and Response as default return type.
|
|
364
|
+
*
|
|
365
|
+
* @param url request URL
|
|
366
|
+
* @param options (optional) Standard `fetch` options extended with {@link FetchCustomOptions}
|
|
367
|
+
* @param options.as (optional) determines who to parse the result. Default: {@link FetchAs.response}
|
|
368
|
+
* @param options.method (optional) fetch method. Default: `'get'`
|
|
369
|
+
*
|
|
370
|
+
* @example Make a simple HTTP requests
|
|
371
|
+
* ```typescript
|
|
372
|
+
* import { fetchResponse } from '@superutils/fetch'
|
|
373
|
+
*
|
|
374
|
+
* fetchResponse('https://dummyjson.com/products/1')
|
|
375
|
+
* .then(response => response.json())
|
|
376
|
+
* .then(console.log, console.error)
|
|
377
|
+
* ```
|
|
378
|
+
*/
|
|
379
|
+
declare const fetchResponse: <T = Response, TOptions extends FetchOptions = FetchOptions, TAs extends FetchAs = TOptions["as"] extends FetchAs ? TOptions["as"] : FetchAs.response, TReturn = FetchResult<T>[TAs]>(...args: Parameters<typeof fetch<T, TOptions, TAs, TReturn>>) => IPromisE<TReturn>;
|
|
380
|
+
|
|
381
|
+
declare const _get: {
|
|
382
|
+
<T, TOptions extends FetchOptions = FetchOptions, TAs extends FetchAs = TOptions["as"] extends FetchAs ? TOptions["as"] : FetchAs.json, TReturn = FetchResult<T>[TAs]>(url: string | URL, options?: TOptions | undefined): _superutils_promise.IPromisE<T>;
|
|
383
|
+
deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
384
|
+
};
|
|
385
|
+
declare const _head: {
|
|
386
|
+
<T, TOptions extends FetchOptions = FetchOptions, TAs extends FetchAs = TOptions["as"] extends FetchAs ? TOptions["as"] : FetchAs.json, TReturn = FetchResult<T>[TAs]>(url: string | URL, options?: TOptions | undefined): _superutils_promise.IPromisE<T>;
|
|
387
|
+
deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
388
|
+
};
|
|
389
|
+
declare const _options: {
|
|
390
|
+
<T, TOptions extends FetchOptions = FetchOptions, TAs extends FetchAs = TOptions["as"] extends FetchAs ? TOptions["as"] : FetchAs.json, TReturn = FetchResult<T>[TAs]>(url: string | URL, options?: TOptions | undefined): _superutils_promise.IPromisE<T>;
|
|
391
|
+
deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
392
|
+
};
|
|
393
|
+
declare const _delete: {
|
|
394
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
395
|
+
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
396
|
+
};
|
|
397
|
+
declare const _patch: {
|
|
398
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
399
|
+
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
400
|
+
};
|
|
401
|
+
declare const _post: {
|
|
402
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
403
|
+
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
404
|
+
};
|
|
405
|
+
declare const _put: {
|
|
406
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
407
|
+
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
408
|
+
};
|
|
409
|
+
type FetchWithMethods = typeof fetchResponse & {
|
|
410
|
+
/** Default options */
|
|
411
|
+
defaults: typeof fetch.defaults;
|
|
412
|
+
/** Make HTTP `DELETE` request, result automatically parsed as JSON */
|
|
413
|
+
delete: typeof _delete;
|
|
414
|
+
/** Make HTTP `GET` request, result automatically parsed as JSON */
|
|
415
|
+
get: typeof _get;
|
|
416
|
+
/** Make HTTP `HEAD` request, result automatically parsed as JSON */
|
|
417
|
+
head: typeof _head;
|
|
418
|
+
/** Make HTTP `OPTIONS` request, result automatically parsed as JSON */
|
|
419
|
+
options: typeof _options;
|
|
420
|
+
/** Make HTTP `PATCH` request, result automatically parsed as JSON */
|
|
421
|
+
patch: typeof _patch;
|
|
422
|
+
/** Make HTTP `POST` request, result automatically parsed as JSON */
|
|
423
|
+
post: typeof _post;
|
|
424
|
+
/** Make HTTP `PUT` request, result automatically parsed as JSON */
|
|
425
|
+
put: typeof _put;
|
|
426
|
+
};
|
|
427
|
+
/**
|
|
428
|
+
* A `fetch()` replacement that simplifies data fetching with automatic JSON parsing, request timeouts, retries,
|
|
429
|
+
* and handy interceptors that also work as transformers. It also includes deferred and throttled request
|
|
430
|
+
* capabilities for complex asynchronous control flows.
|
|
431
|
+
*
|
|
432
|
+
* Will reject promise if response status code is not 2xx (200 <= status < 300).
|
|
433
|
+
*
|
|
434
|
+
* ## Method Specific Functions
|
|
435
|
+
*
|
|
436
|
+
* While `fetch()` provides access to all HTTP request methods by specifying it in options (eg: `{ method: 'get' }`),
|
|
437
|
+
* for ease of use you can also use the following:
|
|
438
|
+
*
|
|
439
|
+
* - `fetch.delete(...)`
|
|
440
|
+
* - `fetch.get(...)`
|
|
441
|
+
* - `fetch.head(...)`
|
|
442
|
+
* - `fetch.options(...)`
|
|
443
|
+
* - `fetch.patch(...)`
|
|
444
|
+
* - `fetch.post(...)`
|
|
445
|
+
* - `fetch.put(...)`
|
|
446
|
+
*
|
|
447
|
+
* **Deferred variants:** To debounce/throttle requests.
|
|
448
|
+
*
|
|
449
|
+
* - `fetch.delete.deferred(...)`
|
|
450
|
+
* - `fetch.get.deferred(...)`
|
|
451
|
+
* - `fetch.head.deferred(...)`
|
|
452
|
+
* - `fetch.options.deferred(...)`
|
|
453
|
+
* - `fetch.patch.deferred(...)`
|
|
454
|
+
* - `fetch.post.deferred(...)`
|
|
455
|
+
* - `fetch.put.deferred(...)`
|
|
456
|
+
*
|
|
457
|
+
* @template T The type of the value that the `fetch` resolves to.
|
|
458
|
+
* @template TReturn Return value type.
|
|
459
|
+
*
|
|
460
|
+
* If `T` is not specified defaults to the following based on the value of `options.as`:
|
|
461
|
+
* - FetchAs.arrayBuffer: `ArrayBuffer`
|
|
462
|
+
* - FetchAs.blob: `Blob`
|
|
463
|
+
* - FetchAs.bytes: `Uint8Array<ArrayBuffer>`
|
|
464
|
+
* - FetchAs.formData: `FormData`
|
|
465
|
+
* - FetchAs.json: `unknown`
|
|
466
|
+
* - FetchAs.text: `string`
|
|
467
|
+
* - FetchAs.response: `Response`
|
|
468
|
+
* @param url
|
|
469
|
+
* @param options (optional) Standard `fetch` options extended with {@link FetchCustomOptions}
|
|
470
|
+
* @param options.as (optional) determines who to parse the result. Default: {@link FetchAs.response}
|
|
471
|
+
* @param options.headers (optional) request headers
|
|
472
|
+
* Default: `{ 'content-type': `'application/json' }` (unless changed in the fetch.defaults).
|
|
473
|
+
* @param options.method (optional) fetch method. Default: `'get'`
|
|
474
|
+
*
|
|
475
|
+
* Options' default values (excluding `as`, `method` and `retryIf`) can be configured to be EFFECTIVE GLOBALLY.
|
|
476
|
+
*
|
|
477
|
+
* ```typescript
|
|
478
|
+
* import fetch from '@superutils/fetch'
|
|
479
|
+
*
|
|
480
|
+
* fetch.defaults = {
|
|
481
|
+
* errMsgs: {
|
|
482
|
+
* invalidUrl: 'Invalid URL',
|
|
483
|
+
* parseFailed: 'Failed to parse response as',
|
|
484
|
+
* reqTimedout: 'Request timed out',
|
|
485
|
+
* requestFailed: 'Request failed with status code:',
|
|
486
|
+
* },
|
|
487
|
+
* headers: new Headers([['content-type', 'application/json']]),
|
|
488
|
+
* // Global/application-wide Interceptor & Transfermers
|
|
489
|
+
* interceptors: {
|
|
490
|
+
* error: [],
|
|
491
|
+
* request: [],
|
|
492
|
+
* response: [],
|
|
493
|
+
* result: [],
|
|
494
|
+
* },
|
|
495
|
+
* timeout: 0,
|
|
496
|
+
* //........
|
|
497
|
+
* }
|
|
498
|
+
* ```
|
|
499
|
+
*
|
|
500
|
+
* @property options.abortCtrl (optional) if not provided `AbortController` will be instantiated when `timeout` used.
|
|
501
|
+
* @property options.headers (optional) request headers. Default: `{ 'content-type' : 'application/json'}`
|
|
502
|
+
* @property options.interceptors (optional) request interceptor callbacks. See {@link FetchInterceptors} for details.
|
|
503
|
+
* @property options.method (optional) Default: `"get"`
|
|
504
|
+
* @property options.timeout (optional) duration in milliseconds to abort the request if it takes longer.
|
|
505
|
+
* @property options.parse (optional) specify how to parse the result.
|
|
506
|
+
* Default: {@link FetchAs.json}
|
|
507
|
+
* For raw `Response` use {@link FetchAs.response}
|
|
508
|
+
*
|
|
509
|
+
* @example Drop-in replacement for built-in `fetch`
|
|
510
|
+
* ```typescript
|
|
511
|
+
* import fetch from '@superutils/fetch'
|
|
512
|
+
*
|
|
513
|
+
* fetch('https://dummyjson.com/products/1')
|
|
514
|
+
* .then(response => response.json())
|
|
515
|
+
* .then(console.log, console.error)
|
|
516
|
+
* ```
|
|
517
|
+
*
|
|
518
|
+
* @example Method specific function with JSON parsing by default
|
|
519
|
+
* ```typescript
|
|
520
|
+
* import fetch from '@superutils/fetch'
|
|
521
|
+
*
|
|
522
|
+
* // no need for `response.json()` or `result.data.data` drilling
|
|
523
|
+
* fetch.get('https://dummyjson.com/products/1')
|
|
524
|
+
* .then(product => console.log(product))
|
|
525
|
+
* fetch.get('https://dummyjson.com/products/1')
|
|
526
|
+
* .then(product => console.log(product))
|
|
527
|
+
*
|
|
528
|
+
*
|
|
529
|
+
* fetch.post('https://dummyjson.com/products/add', { title: 'Product title' })
|
|
530
|
+
* .then(product => console.log(product))
|
|
531
|
+
* ```
|
|
532
|
+
*/
|
|
533
|
+
declare const fetchDefault: FetchWithMethods;
|
|
534
|
+
|
|
327
535
|
/**
|
|
328
536
|
* Creates a deferred/throttled version of {@link fetch}, powered by {@link PromisE.deferred}.
|
|
329
537
|
* This is ideal for scenarios requiring advanced control over HTTP requests, such as debouncing search inputs,
|
|
@@ -521,140 +729,4 @@ declare function postDeferred<ThisArg, Delay = unknown, DefaultUrl extends PostA
|
|
|
521
729
|
*/
|
|
522
730
|
declare const mergeFetchOptions: (...allOptions: FetchOptions[]) => FetchOptionsInterceptor;
|
|
523
731
|
|
|
524
|
-
|
|
525
|
-
declare const createFetchMethodFunc: (method?: string) => {
|
|
526
|
-
<T>(url: string | URL, options?: Omit<FetchOptions, "method">): _superutils_promise.IPromisE<T>;
|
|
527
|
-
deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
528
|
-
};
|
|
529
|
-
/** Create a method-specific function for POST-like methods and with a `.deferred()` function */
|
|
530
|
-
declare const createPostMethodFunc: (method?: Pick<PostOptions, "method">["method"]) => {
|
|
531
|
-
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
532
|
-
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
533
|
-
};
|
|
534
|
-
declare const _get: {
|
|
535
|
-
<T>(url: string | URL, options?: Omit<FetchOptions, "method">): _superutils_promise.IPromisE<T>;
|
|
536
|
-
deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
537
|
-
};
|
|
538
|
-
declare const _head: {
|
|
539
|
-
<T>(url: string | URL, options?: Omit<FetchOptions, "method">): _superutils_promise.IPromisE<T>;
|
|
540
|
-
deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
541
|
-
};
|
|
542
|
-
declare const _options: {
|
|
543
|
-
<T>(url: string | URL, options?: Omit<FetchOptions, "method">): _superutils_promise.IPromisE<T>;
|
|
544
|
-
deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
545
|
-
};
|
|
546
|
-
declare const _delete: {
|
|
547
|
-
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
548
|
-
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
549
|
-
};
|
|
550
|
-
declare const _patch: {
|
|
551
|
-
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
552
|
-
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
553
|
-
};
|
|
554
|
-
declare const _post: {
|
|
555
|
-
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
556
|
-
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
557
|
-
};
|
|
558
|
-
declare const _put: {
|
|
559
|
-
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
560
|
-
deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
|
|
561
|
-
};
|
|
562
|
-
/**
|
|
563
|
-
* @function fetch
|
|
564
|
-
*
|
|
565
|
-
* A `fetch()` replacement that simplifies data fetching with automatic JSON parsing, request timeouts, retries,
|
|
566
|
-
* and handy interceptors that also work as transformers. It also includes deferred and throttled request
|
|
567
|
-
* capabilities for complex asynchronous control flows.
|
|
568
|
-
*
|
|
569
|
-
* Will reject promise if response status code is not 2xx (200 <= status < 300).
|
|
570
|
-
*
|
|
571
|
-
* ## Method Specific Functions
|
|
572
|
-
*
|
|
573
|
-
* While `fetch()` provides access to all HTTP request methods by specifying it in options (eg: `{ method: 'get' }`),
|
|
574
|
-
* for ease of use you can also use the following:
|
|
575
|
-
*
|
|
576
|
-
* - `fetch.delete(...)`
|
|
577
|
-
* - `fetch.get(...)`
|
|
578
|
-
* - `fetch.head(...)`
|
|
579
|
-
* - `fetch.options(...)`
|
|
580
|
-
* - `fetch.patch(...)`
|
|
581
|
-
* - `fetch.post(...)`
|
|
582
|
-
* - `fetch.put(...)`
|
|
583
|
-
*
|
|
584
|
-
* **Deferred variants:** To debounce/throttle requests.
|
|
585
|
-
*
|
|
586
|
-
* - `fetch.delete.deferred(...)`
|
|
587
|
-
* - `fetch.get.deferred(...)`
|
|
588
|
-
* - `fetch.head.deferred(...)`
|
|
589
|
-
* - `fetch.options.deferred(...)`
|
|
590
|
-
* - `fetch.patch.deferred(...)`
|
|
591
|
-
* - `fetch.post.deferred(...)`
|
|
592
|
-
* - `fetch.put.deferred(...)`
|
|
593
|
-
*
|
|
594
|
-
* @template T The type of the value that the `fetch` resolves to.
|
|
595
|
-
* @template TReturn Return value type.
|
|
596
|
-
*
|
|
597
|
-
* If `T` is not specified defaults to the following based on the value of `options.as`:
|
|
598
|
-
* - FetchAs.arrayBuffer: `ArrayBuffer`
|
|
599
|
-
* - FetchAs.blob: `Blob`
|
|
600
|
-
* - FetchAs.bytes: `Uint8Array<ArrayBuffer>`
|
|
601
|
-
* - FetchAs.formData: `FormData`
|
|
602
|
-
* - FetchAs.json: `unknown`
|
|
603
|
-
* - FetchAs.text: `string`
|
|
604
|
-
* - FetchAs.response: `Response`
|
|
605
|
-
* @param url
|
|
606
|
-
* @param options (optional) all built-in `fetch()` options such as "method", "headers" and the additionals below.
|
|
607
|
-
*
|
|
608
|
-
* Options' default values (excluding `method` and `retryIf`) can be configured to be EFFECTIVE GLOBALLY.
|
|
609
|
-
*
|
|
610
|
-
* ```typescript
|
|
611
|
-
* import fetch from '@superutils/fetch'
|
|
612
|
-
*
|
|
613
|
-
* fetch.defaults = {
|
|
614
|
-
* as: FetchAs.json,
|
|
615
|
-
* errMsgs: {
|
|
616
|
-
* invalidUrl: 'Invalid URL',
|
|
617
|
-
* parseFailed: 'Failed to parse response as',
|
|
618
|
-
* reqTimedout: 'Request timed out',
|
|
619
|
-
* requestFailed: 'Request failed with status code:',
|
|
620
|
-
* },
|
|
621
|
-
* headers: new Headers([['content-type', 'application/json']]),
|
|
622
|
-
* interceptors: {
|
|
623
|
-
* error: [],
|
|
624
|
-
* request: [],
|
|
625
|
-
* response: [],
|
|
626
|
-
* result: [],
|
|
627
|
-
* },
|
|
628
|
-
* timeout: 0,
|
|
629
|
-
* //........
|
|
630
|
-
* }
|
|
631
|
-
* ```
|
|
632
|
-
*
|
|
633
|
-
* @property options.abortCtrl (optional) if not provided `AbortController` will be instantiated when `timeout` used.
|
|
634
|
-
* @property options.headers (optional) request headers. Default: `{ 'content-type' : 'application/json'}`
|
|
635
|
-
* @property options.interceptors (optional) request interceptor callbacks. See {@link FetchInterceptors} for details.
|
|
636
|
-
* @property options.method (optional) Default: `"get"`
|
|
637
|
-
* @property options.timeout (optional) duration in milliseconds to abort the request if it takes longer.
|
|
638
|
-
* @property options.parse (optional) specify how to parse the result.
|
|
639
|
-
* Default: {@link FetchAs.json}
|
|
640
|
-
* For raw `Response` use {@link FetchAs.response}
|
|
641
|
-
*
|
|
642
|
-
* @example Make a simple HTTP requests
|
|
643
|
-
* ```typescript
|
|
644
|
-
* import { fetch } from '@superutils/fetch'
|
|
645
|
-
*
|
|
646
|
-
* // no need for `response.json()` or `result.data.theActualData` drilling
|
|
647
|
-
* fetch('https://dummyjson.com/products/1').then(theActualData => console.log(theActualData))
|
|
648
|
-
* ```
|
|
649
|
-
*/
|
|
650
|
-
declare const fetch: typeof fetch$1 & {
|
|
651
|
-
delete: typeof _delete;
|
|
652
|
-
get: typeof _get;
|
|
653
|
-
head: typeof _head;
|
|
654
|
-
options: typeof _options;
|
|
655
|
-
patch: typeof _patch;
|
|
656
|
-
post: typeof _post;
|
|
657
|
-
put: typeof _put;
|
|
658
|
-
};
|
|
659
|
-
|
|
660
|
-
export { type FetchArgs, type FetchArgsInterceptor, FetchAs, type FetchCustomOptions, type FetchDeferredArgs, type FetchErrMsgs, FetchError, type FetchInterceptorError, type FetchInterceptorRequest, type FetchInterceptorResponse, type FetchInterceptorResult, type FetchInterceptors, type FetchOptions, type FetchOptionsDefaults, type FetchOptionsInterceptor, type FetchResult, type FetchRetryOptions, type Interceptor, type PostArgs, type PostBody, type PostDeferredCbArgs, type PostOptions, createFetchMethodFunc, createPostMethodFunc, fetch as default, fetch, fetchDeferred, mergeFetchOptions, postDeferred };
|
|
732
|
+
export { type FetchArgs, type FetchArgsInterceptor, FetchAs, type FetchCustomOptions, type FetchDeferredArgs, type FetchErrMsgs, FetchError, type FetchInterceptorError, type FetchInterceptorRequest, type FetchInterceptorResponse, type FetchInterceptorResult, type FetchInterceptors, type FetchOptions, type FetchOptionsDefaults, type FetchOptionsInterceptor, type FetchResult, type FetchRetryOptions, type FetchWithMethods, type Interceptor, type PostArgs, type PostBody, type PostDeferredCbArgs, type PostOptions, createFetchMethodFunc, createPostMethodFunc, fetchDefault as default, fetch, fetchDeferred, fetchResponse, mergeFetchOptions, postDeferred };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// src/fetch.ts
|
|
2
2
|
import {
|
|
3
3
|
fallbackIfFails as fallbackIfFails2,
|
|
4
|
-
isEmpty as isEmpty2,
|
|
5
4
|
isFn as isFn2,
|
|
6
5
|
isPositiveNumber,
|
|
7
6
|
isPromise,
|
|
@@ -109,9 +108,15 @@ var FetchAs = /* @__PURE__ */ ((FetchAs2) => {
|
|
|
109
108
|
FetchAs2["text"] = "text";
|
|
110
109
|
return FetchAs2;
|
|
111
110
|
})(FetchAs || {});
|
|
112
|
-
var FetchError = class extends Error {
|
|
111
|
+
var FetchError = class _FetchError extends Error {
|
|
113
112
|
constructor(message, options) {
|
|
114
113
|
super(message, { cause: options.cause });
|
|
114
|
+
this.clone = (newMessage) => new _FetchError(newMessage, {
|
|
115
|
+
cause: this.cause,
|
|
116
|
+
options: this.options,
|
|
117
|
+
response: this.response,
|
|
118
|
+
url: this.url
|
|
119
|
+
});
|
|
115
120
|
this.name = "FetchError";
|
|
116
121
|
this.options = options.options;
|
|
117
122
|
this.response = options.response;
|
|
@@ -124,17 +129,18 @@ var fetch = (url, options = {}) => {
|
|
|
124
129
|
let abortCtrl;
|
|
125
130
|
let timeoutId;
|
|
126
131
|
const promise = new PromisE2(async (resolve, reject) => {
|
|
127
|
-
var _a, _b;
|
|
132
|
+
var _a, _b, _c, _d;
|
|
128
133
|
const _options2 = mergeFetchOptions_default(fetch.defaults, options);
|
|
129
|
-
|
|
134
|
+
(_a = _options2.as) != null ? _a : _options2.as = "json" /* json */;
|
|
135
|
+
(_b = _options2.method) != null ? _b : _options2.method = "get";
|
|
130
136
|
const errorInterceptors = [..._options2.interceptors.error];
|
|
131
137
|
const requestInterceptors = [..._options2.interceptors.request];
|
|
132
138
|
const responseInterceptors = [..._options2.interceptors.response];
|
|
133
139
|
const resultInterceptors = [..._options2.interceptors.result];
|
|
134
|
-
url = await executeInterceptors_default(url, requestInterceptors,
|
|
140
|
+
url = await executeInterceptors_default(url, requestInterceptors, _options2);
|
|
135
141
|
const { as: parseAs, errMsgs, timeout } = _options2;
|
|
136
142
|
if (isPositiveNumber(timeout)) {
|
|
137
|
-
(
|
|
143
|
+
(_c = _options2.abortCtrl) != null ? _c : _options2.abortCtrl = new AbortController();
|
|
138
144
|
timeoutId = setTimeout(() => {
|
|
139
145
|
var _a2;
|
|
140
146
|
return (_a2 = _options2.abortCtrl) == null ? void 0 : _a2.abort();
|
|
@@ -156,14 +162,14 @@ var fetch = (url, options = {}) => {
|
|
|
156
162
|
const { status = 0 } = response;
|
|
157
163
|
const isSuccess = status >= 200 && status < 300;
|
|
158
164
|
if (!isSuccess) {
|
|
165
|
+
const fallbackMsg = `${errMsgs.requestFailed} ${status}`;
|
|
159
166
|
const jsonError = await fallbackIfFails2(
|
|
160
167
|
// try to parse error response as json first
|
|
161
168
|
() => response.json(),
|
|
162
169
|
[],
|
|
163
|
-
|
|
164
|
-
`Request failed with status code: ${status}`
|
|
170
|
+
void 0
|
|
165
171
|
);
|
|
166
|
-
const message = (jsonError == null ? void 0 : jsonError.message) ||
|
|
172
|
+
const message = (jsonError == null ? void 0 : jsonError.message) || fallbackMsg;
|
|
167
173
|
throw new Error(`${message}`.replace("Error: ", ""), {
|
|
168
174
|
cause: jsonError
|
|
169
175
|
});
|
|
@@ -176,23 +182,23 @@ var fetch = (url, options = {}) => {
|
|
|
176
182
|
`${errMsgs.parseFailed} ${parseAs}. ${err == null ? void 0 : err.message}`,
|
|
177
183
|
{ cause: err }
|
|
178
184
|
);
|
|
179
|
-
return
|
|
185
|
+
return Promise.reject(err);
|
|
180
186
|
};
|
|
181
187
|
result = parseFunc.bind(response)();
|
|
182
188
|
if (isPromise(result)) result = result.catch(handleErr);
|
|
183
|
-
result = await executeInterceptors_default(
|
|
184
|
-
result,
|
|
185
|
-
resultInterceptors,
|
|
186
|
-
url,
|
|
187
|
-
_options2
|
|
188
|
-
);
|
|
189
189
|
}
|
|
190
|
+
result = await executeInterceptors_default(
|
|
191
|
+
result,
|
|
192
|
+
resultInterceptors,
|
|
193
|
+
url,
|
|
194
|
+
_options2
|
|
195
|
+
);
|
|
190
196
|
resolve(result);
|
|
191
197
|
} catch (err) {
|
|
192
198
|
const errX = err;
|
|
193
199
|
const msg = (errX == null ? void 0 : errX.name) === "AbortError" ? errMsgs.reqTimedout : err == null ? void 0 : err.message;
|
|
194
200
|
let error = new FetchError(msg, {
|
|
195
|
-
cause: (
|
|
201
|
+
cause: (_d = errX == null ? void 0 : errX.cause) != null ? _d : err,
|
|
196
202
|
response: errResponse,
|
|
197
203
|
options: _options2,
|
|
198
204
|
url
|
|
@@ -211,7 +217,6 @@ var fetch = (url, options = {}) => {
|
|
|
211
217
|
return promise;
|
|
212
218
|
};
|
|
213
219
|
fetch.defaults = {
|
|
214
|
-
as: "json" /* json */,
|
|
215
220
|
errMsgs: {
|
|
216
221
|
invalidUrl: "Invalid URL",
|
|
217
222
|
parseFailed: "Failed to parse response as",
|
|
@@ -259,8 +264,23 @@ function fetchDeferred(deferOptions = {}, defaultUrl, defaultOptions) {
|
|
|
259
264
|
}
|
|
260
265
|
var fetchDeferred_default = fetchDeferred;
|
|
261
266
|
|
|
262
|
-
// src/
|
|
263
|
-
|
|
267
|
+
// src/createFetchMethodFunc.ts
|
|
268
|
+
var createFetchMethodFunc = (method = "get") => {
|
|
269
|
+
const methodFunc = (...args) => {
|
|
270
|
+
var _a;
|
|
271
|
+
(_a = args[1]) != null ? _a : args[1] = {};
|
|
272
|
+
args[1].method = method;
|
|
273
|
+
return fetch_default(...args);
|
|
274
|
+
};
|
|
275
|
+
methodFunc.deferred = (...args) => {
|
|
276
|
+
var _a;
|
|
277
|
+
(_a = args[2]) != null ? _a : args[2] = {};
|
|
278
|
+
args[2].method = method;
|
|
279
|
+
return fetchDeferred_default(...args);
|
|
280
|
+
};
|
|
281
|
+
return methodFunc;
|
|
282
|
+
};
|
|
283
|
+
var createFetchMethodFunc_default = createFetchMethodFunc;
|
|
264
284
|
|
|
265
285
|
// src/post.ts
|
|
266
286
|
import { isFn as isFn3, isStr } from "@superutils/core";
|
|
@@ -274,6 +294,7 @@ function post(...[url = "", data, options = {}]) {
|
|
|
274
294
|
}
|
|
275
295
|
|
|
276
296
|
// src/postDeferred.ts
|
|
297
|
+
import PromisE4 from "@superutils/promise";
|
|
277
298
|
function postDeferred(deferOptions = {}, defaultUrl, defaultData, defaultOptions) {
|
|
278
299
|
let _abortCtrl;
|
|
279
300
|
const doPost = (...args) => {
|
|
@@ -296,21 +317,7 @@ function postDeferred(deferOptions = {}, defaultUrl, defaultData, defaultOptions
|
|
|
296
317
|
}
|
|
297
318
|
var postDeferred_default = postDeferred;
|
|
298
319
|
|
|
299
|
-
// src/
|
|
300
|
-
var createFetchMethodFunc = (method = "get") => {
|
|
301
|
-
const methodFunc = (url, options) => {
|
|
302
|
-
options != null ? options : options = {};
|
|
303
|
-
options.method = method;
|
|
304
|
-
return fetch_default(url, options);
|
|
305
|
-
};
|
|
306
|
-
methodFunc.deferred = (...args) => {
|
|
307
|
-
var _a;
|
|
308
|
-
(_a = args[2]) != null ? _a : args[2] = {};
|
|
309
|
-
args[2].method = method;
|
|
310
|
-
return fetchDeferred_default(...args);
|
|
311
|
-
};
|
|
312
|
-
return methodFunc;
|
|
313
|
-
};
|
|
320
|
+
// src/createPostMethodFunc.ts
|
|
314
321
|
var createPostMethodFunc = (method = "post") => {
|
|
315
322
|
const methodFunc = (url, data, options) => {
|
|
316
323
|
options != null ? options : options = {};
|
|
@@ -325,22 +332,45 @@ var createPostMethodFunc = (method = "post") => {
|
|
|
325
332
|
};
|
|
326
333
|
return methodFunc;
|
|
327
334
|
};
|
|
328
|
-
var
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
var
|
|
332
|
-
var
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
var
|
|
335
|
+
var createPostMethodFunc_default = createPostMethodFunc;
|
|
336
|
+
|
|
337
|
+
// src/fetchResponse.ts
|
|
338
|
+
var fetchResponse = (...args) => {
|
|
339
|
+
var _a, _b, _c;
|
|
340
|
+
(_a = args[1]) != null ? _a : args[1] = {};
|
|
341
|
+
(_c = (_b = args[1]).as) != null ? _c : _b.as = "response" /* response */;
|
|
342
|
+
return fetch_default(...args);
|
|
343
|
+
};
|
|
344
|
+
var fetchResponse_default = fetchResponse;
|
|
345
|
+
|
|
346
|
+
// src/fetchDefault.ts
|
|
347
|
+
var _get = createFetchMethodFunc_default("get");
|
|
348
|
+
var _head = createFetchMethodFunc_default("head");
|
|
349
|
+
var _options = createFetchMethodFunc_default("options");
|
|
350
|
+
var _delete = createPostMethodFunc_default("delete");
|
|
351
|
+
var _patch = createPostMethodFunc_default("patch");
|
|
352
|
+
var _post = createPostMethodFunc_default("post");
|
|
353
|
+
var _put = createPostMethodFunc_default("put");
|
|
354
|
+
var fetchDefault = fetchResponse_default;
|
|
355
|
+
Object.defineProperty(fetchDefault, "defaults", {
|
|
356
|
+
get() {
|
|
357
|
+
return fetch_default.defaults;
|
|
358
|
+
},
|
|
359
|
+
set(newDefaults) {
|
|
360
|
+
fetch_default.defaults = newDefaults;
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
fetchDefault.delete = _delete;
|
|
364
|
+
fetchDefault.get = _get;
|
|
365
|
+
fetchDefault.head = _head;
|
|
366
|
+
fetchDefault.options = _options;
|
|
367
|
+
fetchDefault.patch = _patch;
|
|
368
|
+
fetchDefault.post = _post;
|
|
369
|
+
fetchDefault.put = _put;
|
|
370
|
+
var fetchDefault_default = fetchDefault;
|
|
371
|
+
|
|
372
|
+
// src/index.ts
|
|
373
|
+
var index_default = fetchDefault_default;
|
|
344
374
|
export {
|
|
345
375
|
FetchAs,
|
|
346
376
|
FetchError,
|
|
@@ -349,8 +379,9 @@ export {
|
|
|
349
379
|
createFetchMethodFunc,
|
|
350
380
|
createPostMethodFunc,
|
|
351
381
|
index_default as default,
|
|
352
|
-
|
|
382
|
+
fetch,
|
|
353
383
|
fetchDeferred,
|
|
384
|
+
fetchResponse,
|
|
354
385
|
mergeFetchOptions,
|
|
355
386
|
postDeferred
|
|
356
387
|
};
|
package/package.json
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
},
|
|
6
6
|
"description": "A lightweight `fetch` wrapper for browsers and Node.js, designed to simplify data fetching and reduce boilerplate.",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@superutils/core": "^1.1.
|
|
9
|
-
"@superutils/promise": "^1.1.
|
|
8
|
+
"@superutils/core": "^1.1.5",
|
|
9
|
+
"@superutils/promise": "^1.1.5"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"main": "dist/index.js",
|
|
25
25
|
"name": "@superutils/fetch",
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@superutils/core": "^1.1.
|
|
28
|
-
"@superutils/promise": "^1.1.
|
|
27
|
+
"@superutils/core": "^1.1.5",
|
|
28
|
+
"@superutils/promise": "^1.1.5"
|
|
29
29
|
},
|
|
30
30
|
"publishConfig": {
|
|
31
31
|
"access": "public"
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"sideEffects": false,
|
|
46
46
|
"type": "module",
|
|
47
47
|
"types": "dist/index.d.ts",
|
|
48
|
-
"version": "1.1
|
|
48
|
+
"version": "1.2.1"
|
|
49
49
|
}
|