@superutils/fetch 1.0.0 → 1.0.2
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 +141 -13
- package/dist/index.d.ts +183 -98
- package/dist/index.js +70 -64
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -10,9 +10,10 @@ This package enhances the native `fetch` API by providing a streamlined interfac
|
|
|
10
10
|
- Installation
|
|
11
11
|
- Usage
|
|
12
12
|
- [`fetch()`](#fetch): make HTTP requests just like built-in `fetch()`
|
|
13
|
-
- [`
|
|
14
|
-
- [`
|
|
15
|
-
- [`
|
|
13
|
+
- [`Method Specific Functions`](#methods)
|
|
14
|
+
- [`fetch.get.deferred()`](#fetch-deferred): cancellable and debounced or throttled `fetch()`
|
|
15
|
+
- [`fetch.post()`](#post): make post requests
|
|
16
|
+
- [`fetch.post.deferred()`](#post-deferred) cancellable and debounced or throttled `post()`
|
|
16
17
|
|
|
17
18
|
## Features
|
|
18
19
|
|
|
@@ -39,25 +40,49 @@ npm install @superutils/fetch
|
|
|
39
40
|
Make a simple GET request. No need for `response.json()` or `result.data.theActualData` drilling.
|
|
40
41
|
|
|
41
42
|
```typescript
|
|
42
|
-
import
|
|
43
|
+
import fetch from '@superutils/fetch'
|
|
43
44
|
|
|
44
45
|
const theActualData = await fetch('https://dummyjson.com/products/1', {
|
|
45
46
|
method: 'get', // default
|
|
46
47
|
})
|
|
47
48
|
console.log(theActualData)
|
|
48
49
|
// Alternative:
|
|
49
|
-
const
|
|
50
|
-
console.log(
|
|
50
|
+
const theActualData2 = await fetch.get('https://dummyjson.com/products/1')
|
|
51
|
+
console.log(theActualData2)
|
|
51
52
|
```
|
|
52
53
|
|
|
54
|
+
<div id="methods"></div>
|
|
55
|
+
|
|
56
|
+
### Method Specific Functions
|
|
57
|
+
|
|
58
|
+
While `fetch()` provides access to all HTTP request methods by specifying it in options (eg: `{ method: 'get' }`), for ease of use you can also use the following:
|
|
59
|
+
|
|
60
|
+
- `fetch.delete(...)`
|
|
61
|
+
- `fetch.get(...)`
|
|
62
|
+
- `fetch.head(...)`
|
|
63
|
+
- `fetch.options(...)`
|
|
64
|
+
- `fetch.patch(...)`
|
|
65
|
+
- `fetch.post(...)`
|
|
66
|
+
- `fetch.put(...)`
|
|
67
|
+
|
|
68
|
+
**Deferred variants:** To debounce/throttle requests.
|
|
69
|
+
|
|
70
|
+
- `fetch.delete.deferred(...)`
|
|
71
|
+
- `fetch.get.deferred(...)`
|
|
72
|
+
- `fetch.head.deferred(...)`
|
|
73
|
+
- `fetch.options.deferred(...)`
|
|
74
|
+
- `fetch.patch.deferred(...)`
|
|
75
|
+
- `fetch.post.deferred(...)`
|
|
76
|
+
- `fetch.put.deferred(...)`
|
|
77
|
+
|
|
53
78
|
<div id="fetch-deferred"></div>
|
|
54
79
|
|
|
55
|
-
### `fetch.get.deferred(deferOptions,
|
|
80
|
+
### `fetch.get.deferred(deferOptions, defaultUrl, defaultOptions)`
|
|
56
81
|
|
|
57
82
|
A practical utility that combines `PromisE.deferred()` from the `@superutils/promise` package with `fetch()`. It's perfect for implementing cancellable, debounced, or throttled search inputs.
|
|
58
83
|
|
|
59
84
|
```typescript
|
|
60
|
-
import { fetchDeferred, ResolveIgnored } from '@superutils/fetch'
|
|
85
|
+
import fetch, { fetchDeferred, ResolveIgnored } from '@superutils/fetch'
|
|
61
86
|
|
|
62
87
|
// Create a debounced search function with a 300ms delay.
|
|
63
88
|
const searchProducts = fetch.get.deferred({
|
|
@@ -99,16 +124,20 @@ setTimeout(() => {
|
|
|
99
124
|
of the final "iphone 9" request. Both promises resolve to the same value.
|
|
100
125
|
3. `ResolveIgnored.NEVER`: The promise for the aborted "iphone" request is neither resolved nor rejected.
|
|
101
126
|
It will remain pending indefinitely.
|
|
102
|
-
|
|
127
|
+
- **`resolveError`**: Controls how failed requests are handled.
|
|
128
|
+
1. `ResolveError.NEVER`: Never resolve ignored promises. Caution: make sure this doesn't cause any memory leaks.
|
|
129
|
+
2. `ResolveError.WITH_LAST`: (default) resolve with active promise result, the one that caused the current promise/callback to be ignored.
|
|
130
|
+
3. `ResolveError.WITH_UNDEFINED`: resolve failed requests with `undefined` value
|
|
131
|
+
4. `ResolveError.WITH_ERROR`: The promise for the aborted "iphone" request is rejected with a `FetchError`.
|
|
103
132
|
|
|
104
133
|
#### Using defaults to reduce redundancy
|
|
105
134
|
|
|
106
135
|
```typescript
|
|
107
|
-
import {
|
|
136
|
+
import fetch, { ResolveIgnored } from '@superutils/fetch'
|
|
108
137
|
|
|
109
138
|
// Create a throttled function to fetch a random quote.
|
|
110
139
|
// The URL and a 3-second timeout are set as defaults, creating a reusable client.
|
|
111
|
-
const getRandomQuote =
|
|
140
|
+
const getRandomQuote = fetch.get.deferred(
|
|
112
141
|
{
|
|
113
142
|
delayMs: 300, // Throttle window
|
|
114
143
|
throttle: true,
|
|
@@ -135,8 +164,107 @@ getRandomQuote().then(quote => console.log('Call 3 resolved:', quote.id))
|
|
|
135
164
|
|
|
136
165
|
### `fetch.post(url, options)`
|
|
137
166
|
|
|
167
|
+
Send a POST request to create a new product and receive the parsed JSON response.
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
import fetch from '@superutils/fetch'
|
|
171
|
+
|
|
172
|
+
const newProduct = { title: 'Perfume Oil' }
|
|
173
|
+
|
|
174
|
+
fetch.post('https://dummyjson.com/products/add', newProduct).then(
|
|
175
|
+
createdProduct => console.log('Product created:', createdProduct),
|
|
176
|
+
error => console.error('Failed to create product:', error),
|
|
177
|
+
)
|
|
178
|
+
```
|
|
179
|
+
|
|
138
180
|
<div id="post-deferred"></div>
|
|
139
181
|
|
|
140
|
-
### `fetch.post.deferred(deferOptions, url,
|
|
182
|
+
### `fetch.post.deferred(deferOptions, url, data, options)`
|
|
183
|
+
|
|
184
|
+
HTTP POST request with debounce/throttle.
|
|
185
|
+
|
|
186
|
+
#### Example 1: Auto-saving form data with throttling
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import fetch from '@superutils/fetch'
|
|
190
|
+
import PromisE from '@superutils/promise'
|
|
191
|
+
|
|
192
|
+
// Create a throttled function to auto-save product updates.
|
|
193
|
+
const saveProductThrottled = fetch.post.deferred(
|
|
194
|
+
{
|
|
195
|
+
delayMs: 1000, // Throttle window of 1 second
|
|
196
|
+
throttle: true,
|
|
197
|
+
trailing: true, // Ensures the very last update is always saved
|
|
198
|
+
onResult: product => console.log(`[Saved] Product: ${product.title}`),
|
|
199
|
+
},
|
|
200
|
+
'https://dummyjson.com/products/1', // Default URL
|
|
201
|
+
undefined, // No default data
|
|
202
|
+
{ method: 'put' }, // Default method
|
|
203
|
+
)
|
|
204
|
+
// Simulate a user typing quickly, triggering multiple saves.
|
|
205
|
+
console.log('User starts typing...')
|
|
206
|
+
saveProductThrottled({ title: 'iPhone' }) // Executed immediately (leading edge)
|
|
207
|
+
await PromisE.delay(200)
|
|
208
|
+
saveProductThrottled({ title: 'iPhone 15' }) // Ignored (within 1000ms throttle window)
|
|
209
|
+
await PromisE.delay(300)
|
|
210
|
+
saveProductThrottled({ title: 'iPhone 15 Pro' }) // Ignored
|
|
211
|
+
await PromisE.delay(400)
|
|
212
|
+
saveProductThrottled({ title: 'iPhone 15 Pro Max' }) // Queued to execute on the trailing edge
|
|
213
|
+
// Outcome:
|
|
214
|
+
// The first call ('iPhone') is executed immediately.
|
|
215
|
+
// The next two calls are ignored by the throttle.
|
|
216
|
+
// The final call ('iPhone 15 Pro Max') is executed after the 1000ms throttle window closes,
|
|
217
|
+
// thanks to `trailing: true`.
|
|
218
|
+
// This results in only two network requests instead of four.
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### Example 2: debouncing an authentication token refresh
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
import fetch from '@superutils/fetch'
|
|
225
|
+
import PromisE from '@superutils/promise'
|
|
226
|
+
|
|
227
|
+
// Mock a simple token store
|
|
228
|
+
let currentRefreshToken = ''
|
|
229
|
+
// Create a debounced function to refresh the auth token.
|
|
230
|
+
// It waits 300ms after the last call before executing.
|
|
231
|
+
const requestNewToken = fetch.post.deferred(
|
|
232
|
+
{
|
|
233
|
+
delayMs: 300, // debounce delay
|
|
234
|
+
onResult: ({ token = '' }) => {
|
|
235
|
+
console.log(
|
|
236
|
+
`Auth token successfully refreshed at ${new Date().toISOString()}`,
|
|
237
|
+
)
|
|
238
|
+
currentRefreshToken = token
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
'https://dummyjson.com/auth/refresh', // Default URL
|
|
242
|
+
() => ({
|
|
243
|
+
refreshToken: currentRefreshToken,
|
|
244
|
+
expiresInMins: 30,
|
|
245
|
+
}),
|
|
246
|
+
)
|
|
141
247
|
|
|
142
|
-
|
|
248
|
+
// First authenticate user to get the initial refresh token and then request new referesh tokens
|
|
249
|
+
fetch
|
|
250
|
+
.post<{ refreshToken: string }>(
|
|
251
|
+
'https://dummyjson.com/auth/login',
|
|
252
|
+
{
|
|
253
|
+
username: 'emilys',
|
|
254
|
+
password: 'emilyspass',
|
|
255
|
+
expiresInMins: 30,
|
|
256
|
+
},
|
|
257
|
+
{ credentials: 'include' },
|
|
258
|
+
)
|
|
259
|
+
.then(result => {
|
|
260
|
+
currentRefreshToken = result?.refreshToken
|
|
261
|
+
|
|
262
|
+
requestNewToken() // Called at 0ms
|
|
263
|
+
PromisE.delay(50, requestNewToken) // Called at 50ms
|
|
264
|
+
PromisE.delay(100, requestNewToken) // Called at 100ms
|
|
265
|
+
}, console.error)
|
|
266
|
+
// Outcome:
|
|
267
|
+
// The first two calls are aborted by the debounce mechanism.
|
|
268
|
+
// Only the final call executes, 300ms after it was made (at the 400ms mark).
|
|
269
|
+
// The token is refreshed only once, preventing redundant network requests.
|
|
270
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { ValueOrPromise } from '@superutils/core';
|
|
1
2
|
import * as _superutils_promise from '@superutils/promise';
|
|
2
3
|
import { RetryOptions, IPromisE, DeferredAsyncOptions } from '@superutils/promise';
|
|
3
4
|
export { DeferredAsyncOptions, ResolveError, ResolveIgnored } from '@superutils/promise';
|
|
4
|
-
import { ValueOrPromise } from '@superutils/core';
|
|
5
5
|
|
|
6
|
-
type FetchArgs
|
|
6
|
+
type FetchArgs<OmitMethod extends boolean = false> = [
|
|
7
|
+
url: string | URL,
|
|
8
|
+
options?: OmitMethod extends true ? Omit<FetchOptions, 'method'> : FetchOptions
|
|
9
|
+
];
|
|
7
10
|
type FetchArgsInterceptor = [
|
|
8
11
|
url: string | URL,
|
|
9
12
|
options: FetchOptionsInterceptor
|
|
@@ -17,7 +20,8 @@ declare enum FetchAs {
|
|
|
17
20
|
response = "response",
|
|
18
21
|
text = "text"
|
|
19
22
|
}
|
|
20
|
-
|
|
23
|
+
/** Custom fetch options (not used by built-in `fetch()`*/
|
|
24
|
+
type FetchCustomOptions = {
|
|
21
25
|
/**
|
|
22
26
|
* Specify how the parse the result. To get raw response use {@link FetchAs.response}.
|
|
23
27
|
* Default: 'json'
|
|
@@ -28,11 +32,11 @@ type FetchConf = {
|
|
|
28
32
|
interceptors?: FetchInterceptors;
|
|
29
33
|
/** Request timeout in milliseconds. */
|
|
30
34
|
timeout?: number;
|
|
31
|
-
};
|
|
35
|
+
} & FetchRetryOptions;
|
|
32
36
|
/** Default args */
|
|
33
|
-
type FetchDeferredArgs = [
|
|
37
|
+
type FetchDeferredArgs<OmitMethod extends boolean = false> = [
|
|
34
38
|
url?: string | URL,
|
|
35
|
-
options?: Omit<FetchOptions, 'abortCtrl'>
|
|
39
|
+
options?: Omit<FetchOptions, 'abortCtrl' | (OmitMethod extends true ? 'method' : never)>
|
|
36
40
|
];
|
|
37
41
|
type FetchErrMsgs = {
|
|
38
42
|
invalidUrl?: string;
|
|
@@ -230,7 +234,8 @@ type FetchInterceptors = {
|
|
|
230
234
|
/**
|
|
231
235
|
* Fetch request options
|
|
232
236
|
*/
|
|
233
|
-
type FetchOptions = RequestInit &
|
|
237
|
+
type FetchOptions = RequestInit & FetchCustomOptions;
|
|
238
|
+
type FetchOptionsDefaults = Omit<FetchOptionsInterceptor, 'method' | 'retryIf'>;
|
|
234
239
|
/**
|
|
235
240
|
* Fetch options available to interceptors
|
|
236
241
|
*/
|
|
@@ -271,10 +276,10 @@ type FetchRetryOptions = Omit<Partial<RetryOptions>, 'retry' | 'retryIf'> & {
|
|
|
271
276
|
*/
|
|
272
277
|
type Interceptor<T, TArgs extends unknown[], TArgsCb extends unknown[] = [value: T, ...TArgs]> = (...args: TArgsCb) => ValueOrPromise<void> | ValueOrPromise<T>;
|
|
273
278
|
type PostBody = Record<string, unknown> | BodyInit | null;
|
|
274
|
-
type PostArgs = [
|
|
279
|
+
type PostArgs<OmitMethod = false> = [
|
|
275
280
|
url: string | URL,
|
|
276
|
-
data?: PostBody,
|
|
277
|
-
options?: PostOptions
|
|
281
|
+
data?: PostBody | (() => PostBody),
|
|
282
|
+
options?: OmitMethod extends true ? Omit<FetchOptions, 'method'> : PostOptions
|
|
278
283
|
];
|
|
279
284
|
/**
|
|
280
285
|
*
|
|
@@ -306,15 +311,16 @@ type PostArgs = [
|
|
|
306
311
|
* f4().then(console.log, console.warn)
|
|
307
312
|
* ```
|
|
308
313
|
*/
|
|
309
|
-
type PostDeferredCallbackArgs<TUrl = undefined, TData = undefined, RPA extends unknown[] = Required<
|
|
314
|
+
type PostDeferredCallbackArgs<TUrl = undefined, TData = undefined, OmitMethod extends boolean = true, CbArgs extends PostArgs<OmitMethod> = PostArgs<OmitMethod>, Options = CbArgs[2], RPA extends unknown[] = Required<CbArgs>> = [TUrl, TData] extends [RPA[0], undefined] ? [data?: CbArgs[1], options?: Options] : [TUrl, TData] extends [undefined, RPA[1]] ? [url: CbArgs[0], options?: Options] : [TUrl, TData] extends [RPA[0], RPA[1]] ? [options?: Options] : CbArgs;
|
|
310
315
|
type PostOptions = Omit<FetchOptions, 'method'> & {
|
|
311
316
|
/** Default: `'post'` */
|
|
312
|
-
method?: 'post' | 'put' | 'patch' | 'delete';
|
|
317
|
+
method?: 'post' | 'put' | 'patch' | 'delete' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
313
318
|
};
|
|
314
319
|
|
|
315
320
|
declare const fetch$1: {
|
|
316
|
-
<
|
|
317
|
-
|
|
321
|
+
<T, TOptions extends FetchOptions = FetchOptions, TReturn = TOptions["as"] extends FetchAs ? FetchResult<T>[TOptions["as"]] : T>(url: string | URL, options?: TOptions): IPromisE<TReturn>;
|
|
322
|
+
/** Default fetch options */
|
|
323
|
+
defaults: FetchOptionsDefaults;
|
|
318
324
|
};
|
|
319
325
|
|
|
320
326
|
/**
|
|
@@ -403,18 +409,18 @@ declare const fetch$1: {
|
|
|
403
409
|
* // Console output will show the same quote ID for all three calls.
|
|
404
410
|
* ```
|
|
405
411
|
*/
|
|
406
|
-
declare function fetchDeferred<ThisArg = unknown, Delay extends number = number, GlobalUrl
|
|
412
|
+
declare function fetchDeferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = FetchArgs[0] | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: FetchArgs<true>[1]]>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, globalUrl?: GlobalUrl, defaultOptions?: FetchArgs[1]): <TResult = unknown>(...args: CbArgs) => _superutils_promise.IPromisE<TResult>;
|
|
407
413
|
|
|
408
414
|
/**
|
|
409
|
-
* Creates a deferred/throttled function for making `POST`, `PUT`, or `PATCH` requests, powered by
|
|
415
|
+
* Creates a deferred/throttled function for making `DELETE`, `POST`, `PUT`, or `PATCH` requests, powered by
|
|
410
416
|
* {@link PromisE.deferred}.
|
|
417
|
+
*
|
|
411
418
|
* This is ideal for scenarios like auto-saving form data, preventing duplicate submissions on button clicks,
|
|
412
419
|
* or throttling API updates.
|
|
413
420
|
*
|
|
414
421
|
* Like `fetchDeferred`, it automatically aborts pending requests when a new one is initiated, ensuring only
|
|
415
422
|
* the most recent or relevant action is executed.
|
|
416
423
|
*
|
|
417
|
-
*
|
|
418
424
|
* @param deferOptions Configuration for the deferred execution behavior (e.g., `delayMs`, `throttle`).
|
|
419
425
|
* See {@link DeferredAsyncOptions} for details.
|
|
420
426
|
* @param globalUrl (optional) If global URL is `undefined`, returned callback will always require an URL.
|
|
@@ -424,86 +430,87 @@ declare function fetchDeferred<ThisArg = unknown, Delay extends number = number,
|
|
|
424
430
|
* If the same property is provided in both cases, defaults will be overriden by the callback.
|
|
425
431
|
*
|
|
426
432
|
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
433
|
+
*
|
|
434
|
+
* @example Auto-saving form data with throttling
|
|
435
|
+
* ```javascript
|
|
429
436
|
* import { postDeferred } from '@superutils/fetch'
|
|
430
437
|
* import PromisE from '@superutils/promise'
|
|
431
438
|
*
|
|
432
|
-
* //
|
|
433
|
-
*
|
|
439
|
+
* // Create a throttled function to auto-save product updates.
|
|
440
|
+
* const saveProductThrottled = fetch.post.deferred(
|
|
441
|
+
* {
|
|
442
|
+
* delayMs: 1000, // Throttle window of 1 second
|
|
443
|
+
* throttle: true,
|
|
444
|
+
* trailing: true, // Ensures the very last update is always saved
|
|
445
|
+
* onResult: product => console.log(`[Saved] Product: ${product.title}`),
|
|
446
|
+
* },
|
|
447
|
+
* 'https://dummyjson.com/products/1', // Default URL
|
|
448
|
+
* undefined, // No default data
|
|
449
|
+
* { method: 'put' }, // Default method
|
|
450
|
+
* )
|
|
451
|
+
* // Simulate a user typing quickly, triggering multiple saves.
|
|
452
|
+
* console.log('User starts typing...')
|
|
453
|
+
* // First call
|
|
454
|
+
* saveProductThrottled({ title: 'iPhone' }) // Executed immediately (leading edge)
|
|
455
|
+
* // Second call after 200ms => Ignored (within 1000ms throttle window)
|
|
456
|
+
* PromisE.delay(200, () => saveProductThrottled({ title: 'iPhone 15' }))
|
|
457
|
+
* // Third call 300ms after second call => Ignored
|
|
458
|
+
* PromisE.delay(500, () => saveProductThrottled({ title: 'iPhone 15 Pro' }))
|
|
459
|
+
* // Fourth call 400ms after third call => Queued to execute on the trailing edge
|
|
460
|
+
* PromisE.delay(900, () => saveProductThrottled({ title: 'iPhone 15 Pro Max' }))
|
|
461
|
+
* ```
|
|
462
|
+
*
|
|
463
|
+
* @example Advanced example: debouncing an authentication token refresh
|
|
464
|
+
* ```typescript
|
|
465
|
+
* import fetch from '@superutils/fetch'
|
|
466
|
+
* import PromisE from '@superutils/promise'
|
|
434
467
|
*
|
|
468
|
+
* // Mock a simple token store
|
|
469
|
+
* let currentRefreshToken = ''
|
|
435
470
|
* // Create a debounced function to refresh the auth token.
|
|
436
471
|
* // It waits 300ms after the last call before executing.
|
|
437
|
-
* const
|
|
472
|
+
* const requestNewToken = fetch.post.deferred(
|
|
438
473
|
* {
|
|
439
474
|
* delayMs: 300, // debounce delay
|
|
440
|
-
* onResult: (
|
|
441
|
-
* console.log(
|
|
442
|
-
*
|
|
443
|
-
*
|
|
475
|
+
* onResult: ({ token = '' }) => {
|
|
476
|
+
* console.log(
|
|
477
|
+
* `Auth token successfully refreshed at ${new Date().toISOString()}`,
|
|
478
|
+
* )
|
|
479
|
+
* currentRefreshToken = token
|
|
480
|
+
* },
|
|
444
481
|
* },
|
|
445
482
|
* 'https://dummyjson.com/auth/refresh', // Default URL
|
|
483
|
+
* () => ({
|
|
484
|
+
* refreshToken: currentRefreshToken,
|
|
485
|
+
* expiresInMins: 30,
|
|
486
|
+
* }),
|
|
446
487
|
* )
|
|
447
488
|
*
|
|
448
|
-
* //
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
489
|
+
* // First authenticate user to get the initial refresh token and then request new referesh tokens
|
|
490
|
+
* fetch
|
|
491
|
+
* .post<{ refreshToken: string }>(
|
|
492
|
+
* 'https://dummyjson.com/auth/login',
|
|
493
|
+
* {
|
|
494
|
+
* username: 'emilys',
|
|
495
|
+
* password: 'emilyspass',
|
|
496
|
+
* expiresInMins: 30,
|
|
497
|
+
* },
|
|
498
|
+
* { credentials: 'include' },
|
|
499
|
+
* )
|
|
500
|
+
* .then(result => {
|
|
501
|
+
* currentRefreshToken = result?.refreshToken
|
|
502
|
+
*
|
|
503
|
+
* requestNewToken() // Called at 0ms
|
|
504
|
+
* PromisE.delay(50, requestNewToken) // Called at 50ms
|
|
505
|
+
* PromisE.delay(100, requestNewToken) // Called at 100ms
|
|
506
|
+
* }, console.error)
|
|
462
507
|
* // Outcome:
|
|
463
508
|
* // The first two calls are aborted by the debounce mechanism.
|
|
464
509
|
* // Only the final call executes, 300ms after it was made (at the 400ms mark).
|
|
465
510
|
* // The token is refreshed only once, preventing redundant network requests.
|
|
466
511
|
* ```
|
|
467
|
-
*
|
|
468
|
-
* @example Auto-saving form data with throttling
|
|
469
|
-
* ```typescript
|
|
470
|
-
* import { postDeferred } from '@superutils/fetch'
|
|
471
|
-
* import PromisE from '@superutils/promise'
|
|
472
|
-
*
|
|
473
|
-
* // Create a throttled function to auto-save product updates.
|
|
474
|
-
* const saveProductThrottled = postDeferred(
|
|
475
|
-
* {
|
|
476
|
-
* delayMs: 1000, // Throttle window of 1 second
|
|
477
|
-
* throttle: true,
|
|
478
|
-
* trailing: true, // Ensures the very last update is always saved
|
|
479
|
-
* onResult: (product) => console.log(`[Saved] Product: ${product.title}`),
|
|
480
|
-
* },
|
|
481
|
-
* 'https://dummyjson.com/products/1', // Default URL
|
|
482
|
-
* undefined, // No default data
|
|
483
|
-
* { method: 'put' }, // Default method
|
|
484
|
-
* )
|
|
485
|
-
*
|
|
486
|
-
* // Simulate a user typing quickly, triggering multiple saves.
|
|
487
|
-
* console.log('User starts typing...');
|
|
488
|
-
* saveProductThrottled({ title: 'iPhone' }); // Executed immediately (leading edge)
|
|
489
|
-
* await PromisE.delay(200);
|
|
490
|
-
* saveProductThrottled({ title: 'iPhone 15' }); // Ignored (within 1000ms throttle window)
|
|
491
|
-
* await PromisE.delay(300);
|
|
492
|
-
* saveProductThrottled({ title: 'iPhone 15 Pro' }); // Ignored
|
|
493
|
-
* await PromisE.delay(400);
|
|
494
|
-
* saveProductThrottled({ title: 'iPhone 15 Pro Max' }); // Queued to execute on the trailing edge
|
|
495
|
-
*
|
|
496
|
-
* // Outcome:
|
|
497
|
-
* // The first call ('iPhone') is executed immediately.
|
|
498
|
-
* // The next two calls are ignored by the throttle.
|
|
499
|
-
* // The final call ('iPhone 15 Pro Max') is executed after the 1000ms throttle window closes,
|
|
500
|
-
* // thanks to `trailing: true`.
|
|
501
|
-
* // This results in only two network requests instead of four.
|
|
502
|
-
* ```
|
|
503
512
|
*/
|
|
504
|
-
declare function postDeferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, Args extends unknown[] = PostDeferredCallbackArgs<GlobalUrl, GlobalData>>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, globalUrl?: GlobalUrl,
|
|
505
|
-
globalData?: GlobalData, // The default data for all calls
|
|
506
|
-
defaultOptions?: PostOptions): <TResult = unknown>(...args: Args) => _superutils_promise.IPromisE<TResult>;
|
|
513
|
+
declare function postDeferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, Args extends unknown[] = PostDeferredCallbackArgs<GlobalUrl, GlobalData, true>>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, globalUrl?: GlobalUrl, globalData?: GlobalData, defaultOptions?: PostArgs[2]): <TResult = unknown>(...args: Args) => _superutils_promise.IPromisE<TResult>;
|
|
507
514
|
|
|
508
515
|
/**
|
|
509
516
|
* Merge one or more {@link FetchOptions}
|
|
@@ -522,32 +529,102 @@ defaultOptions?: PostOptions): <TResult = unknown>(...args: Args) => _superutils
|
|
|
522
529
|
declare const mergeFetchOptions: (...allOptions: FetchOptions[]) => FetchOptionsInterceptor;
|
|
523
530
|
|
|
524
531
|
type FetchWithoutMethods = typeof fetch$1;
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
deferred:
|
|
532
|
+
declare const _get: {
|
|
533
|
+
<T>(url: string | URL, options?: Omit<FetchOptions, "method">): _superutils_promise.IPromisE<T>;
|
|
534
|
+
deferred: <ThisArg, Delay extends number, GlobalUrl extends string | URL>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay> | undefined, globalUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined) => <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
528
535
|
};
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
deferred:
|
|
536
|
+
declare const _head: {
|
|
537
|
+
<T>(url: string | URL, options?: Omit<FetchOptions, "method">): _superutils_promise.IPromisE<T>;
|
|
538
|
+
deferred: <ThisArg, Delay extends number, GlobalUrl extends string | URL>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay> | undefined, globalUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined) => <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
539
|
+
};
|
|
540
|
+
declare const _options: {
|
|
541
|
+
<T>(url: string | URL, options?: Omit<FetchOptions, "method">): _superutils_promise.IPromisE<T>;
|
|
542
|
+
deferred: <ThisArg, Delay extends number, GlobalUrl extends string | URL>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay> | undefined, globalUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined) => <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]) => _superutils_promise.IPromisE<TResult>;
|
|
543
|
+
};
|
|
544
|
+
declare const _delete: {
|
|
545
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
546
|
+
deferred: <ThisArg, Delay extends number = number, Args extends PostArgs<true> = PostArgs<true>, GlobalUrl extends Args[0] | undefined = undefined, GlobalData extends Args[1] | undefined = undefined>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, globalUrl?: GlobalUrl, globalData?: GlobalData, defaultOptions?: Args[2]) => <TResult = unknown>(...args: PostDeferredCallbackArgs<GlobalUrl, GlobalData, true, PostArgs<true>, Omit<FetchOptions, "method"> | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: Omit<FetchOptions, "method">]>) => _superutils_promise.IPromisE<TResult>;
|
|
547
|
+
};
|
|
548
|
+
declare const _patch: {
|
|
549
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
550
|
+
deferred: <ThisArg, Delay extends number = number, Args extends PostArgs<true> = PostArgs<true>, GlobalUrl extends Args[0] | undefined = undefined, GlobalData extends Args[1] | undefined = undefined>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, globalUrl?: GlobalUrl, globalData?: GlobalData, defaultOptions?: Args[2]) => <TResult = unknown>(...args: PostDeferredCallbackArgs<GlobalUrl, GlobalData, true, PostArgs<true>, Omit<FetchOptions, "method"> | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: Omit<FetchOptions, "method">]>) => _superutils_promise.IPromisE<TResult>;
|
|
551
|
+
};
|
|
552
|
+
declare const _post: {
|
|
553
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
554
|
+
deferred: <ThisArg, Delay extends number = number, Args extends PostArgs<true> = PostArgs<true>, GlobalUrl extends Args[0] | undefined = undefined, GlobalData extends Args[1] | undefined = undefined>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, globalUrl?: GlobalUrl, globalData?: GlobalData, defaultOptions?: Args[2]) => <TResult = unknown>(...args: PostDeferredCallbackArgs<GlobalUrl, GlobalData, true, PostArgs<true>, Omit<FetchOptions, "method"> | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: Omit<FetchOptions, "method">]>) => _superutils_promise.IPromisE<TResult>;
|
|
555
|
+
};
|
|
556
|
+
declare const _put: {
|
|
557
|
+
<T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
|
|
558
|
+
deferred: <ThisArg, Delay extends number = number, Args extends PostArgs<true> = PostArgs<true>, GlobalUrl extends Args[0] | undefined = undefined, GlobalData extends Args[1] | undefined = undefined>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, globalUrl?: GlobalUrl, globalData?: GlobalData, defaultOptions?: Args[2]) => <TResult = unknown>(...args: PostDeferredCallbackArgs<GlobalUrl, GlobalData, true, PostArgs<true>, Omit<FetchOptions, "method"> | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: Omit<FetchOptions, "method">]>) => _superutils_promise.IPromisE<TResult>;
|
|
532
559
|
};
|
|
533
|
-
interface FetchWithMethods extends FetchWithoutMethods {
|
|
534
|
-
get: FetchMethodFunc;
|
|
535
|
-
head: FetchMethodFunc;
|
|
536
|
-
options: FetchMethodFunc;
|
|
537
|
-
delete: PostMethodFunc;
|
|
538
|
-
patch: PostMethodFunc;
|
|
539
|
-
post: PostMethodFunc;
|
|
540
|
-
put: PostMethodFunc;
|
|
541
|
-
}
|
|
542
560
|
/**
|
|
561
|
+
* @function fetch
|
|
562
|
+
*
|
|
543
563
|
* A `fetch()` replacement that simplifies data fetching with automatic JSON parsing, request timeouts, retries,
|
|
544
|
-
* and
|
|
545
|
-
* control flows.
|
|
564
|
+
* and handy interceptors that also work as transformers. It also includes deferred and throttled request
|
|
565
|
+
* capabilities for complex asynchronous control flows.
|
|
546
566
|
*
|
|
547
567
|
* Will reject promise if response status code is not 2xx (200 <= status < 300).
|
|
548
568
|
*
|
|
569
|
+
* ## Method Specific Functions
|
|
570
|
+
*
|
|
571
|
+
* While `fetch()` provides access to all HTTP request methods by specifying it in options (eg: `{ method: 'get' }`),
|
|
572
|
+
* for ease of use you can also use the following:
|
|
573
|
+
*
|
|
574
|
+
* - `fetch.delete(...)`
|
|
575
|
+
* - `fetch.get(...)`
|
|
576
|
+
* - `fetch.head(...)`
|
|
577
|
+
* - `fetch.options(...)`
|
|
578
|
+
* - `fetch.patch(...)`
|
|
579
|
+
* - `fetch.post(...)`
|
|
580
|
+
* - `fetch.put(...)`
|
|
581
|
+
*
|
|
582
|
+
* **Deferred variants:** To debounce/throttle requests.
|
|
583
|
+
*
|
|
584
|
+
* - `fetch.delete.deferred(...)`
|
|
585
|
+
* - `fetch.get.deferred(...)`
|
|
586
|
+
* - `fetch.head.deferred(...)`
|
|
587
|
+
* - `fetch.options.deferred(...)`
|
|
588
|
+
* - `fetch.patch.deferred(...)`
|
|
589
|
+
* - `fetch.post.deferred(...)`
|
|
590
|
+
* - `fetch.put.deferred(...)`
|
|
591
|
+
*
|
|
592
|
+
* @template T The type of the value that the `fetch` resolves to.
|
|
593
|
+
* @template TReturn Return value type.
|
|
594
|
+
*
|
|
595
|
+
* If `T` is not specified defaults to the following based on the value of `options.as`:
|
|
596
|
+
* - FetchAs.arrayBuffer: `ArrayBuffer`
|
|
597
|
+
* - FetchAs.blob: `Blob`
|
|
598
|
+
* - FetchAs.bytes: `Uint8Array<ArrayBuffer>`
|
|
599
|
+
* - FetchAs.formData: `FormData`
|
|
600
|
+
* - FetchAs.json: `unknown`
|
|
601
|
+
* - FetchAs.text: `string`
|
|
602
|
+
* - FetchAs.response: `Response`
|
|
549
603
|
* @param url
|
|
550
604
|
* @param options (optional) all built-in `fetch()` options such as "method", "headers" and the additionals below.
|
|
605
|
+
*
|
|
606
|
+
* Options' default values (excluding `method` and `retryIf`) can be configured to be EFFECTIVE GLOBALLY.
|
|
607
|
+
*
|
|
608
|
+
* ```typescript
|
|
609
|
+
* fetch.defaults = {
|
|
610
|
+
* as: FetchAs.json,
|
|
611
|
+
* errMsgs: {
|
|
612
|
+
* invalidUrl: 'Invalid URL',
|
|
613
|
+
* parseFailed: 'Failed to parse response as',
|
|
614
|
+
* reqTimedout: 'Request timed out',
|
|
615
|
+
* requestFailed: 'Request failed with status code:',
|
|
616
|
+
* },
|
|
617
|
+
* headers: new Headers([['content-type', 'application/json']]),
|
|
618
|
+
* interceptors: {
|
|
619
|
+
* error: [],
|
|
620
|
+
* request: [],
|
|
621
|
+
* response: [],
|
|
622
|
+
* result: [],
|
|
623
|
+
* },
|
|
624
|
+
* timeout: 0,
|
|
625
|
+
* ........
|
|
626
|
+
* }
|
|
627
|
+
* ```
|
|
551
628
|
* @param options.abortCtrl (optional) if not provided `AbortController` will be instantiated when `timeout` used.
|
|
552
629
|
* @param options.headers (optional) request headers. Default: `{ 'content-type' : 'application/json'}`
|
|
553
630
|
* @param options.interceptors (optional) request interceptor callbacks. See {@link FetchInterceptors} for details.
|
|
@@ -565,6 +642,14 @@ interface FetchWithMethods extends FetchWithoutMethods {
|
|
|
565
642
|
* fetch('https://dummyjson.com/products/1').then(theActualData => console.log(theActualData))
|
|
566
643
|
* ```
|
|
567
644
|
*/
|
|
568
|
-
declare const fetch:
|
|
645
|
+
declare const fetch: typeof fetch$1 & {
|
|
646
|
+
get: typeof _get;
|
|
647
|
+
head: typeof _head;
|
|
648
|
+
options: typeof _options;
|
|
649
|
+
delete: typeof _delete;
|
|
650
|
+
patch: typeof _patch;
|
|
651
|
+
post: typeof _post;
|
|
652
|
+
put: typeof _put;
|
|
653
|
+
};
|
|
569
654
|
|
|
570
|
-
export { type FetchArgs, type FetchArgsInterceptor, FetchAs, type
|
|
655
|
+
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 FetchWithoutMethods, type Interceptor, type PostArgs, type PostBody, type PostDeferredCallbackArgs, type PostOptions, fetch as default, fetch, fetchDeferred, mergeFetchOptions, postDeferred };
|
package/dist/index.js
CHANGED
|
@@ -43,9 +43,9 @@ var getResponse = async (...[url, options = {}]) => {
|
|
|
43
43
|
if (!isPositiveInteger(options.retry)) return doFetch();
|
|
44
44
|
const response = PromisE.retry(doFetch, {
|
|
45
45
|
...options,
|
|
46
|
-
retryIf: async (res, count
|
|
46
|
+
retryIf: async (res, count) => {
|
|
47
47
|
var _a;
|
|
48
|
-
return (res == null ? void 0 : res.ok) === false || await ((_a = options == null ? void 0 : options.retryIf) == null ? void 0 : _a.call(options, res, count
|
|
48
|
+
return (res == null ? void 0 : res.ok) === false || await ((_a = options == null ? void 0 : options.retryIf) == null ? void 0 : _a.call(options, res, count)) === true;
|
|
49
49
|
}
|
|
50
50
|
}).catch(
|
|
51
51
|
(err) => Promise.reject(
|
|
@@ -116,32 +116,32 @@ var fetch = (url, options = {}) => {
|
|
|
116
116
|
let timeoutId;
|
|
117
117
|
const promise = new PromisE2(async (resolve, reject) => {
|
|
118
118
|
var _a, _b;
|
|
119
|
-
const
|
|
120
|
-
if (isEmpty2(
|
|
121
|
-
const errorInterceptors = [...
|
|
122
|
-
const requestInterceptors = [...
|
|
123
|
-
const responseInterceptors = [...
|
|
124
|
-
const resultInterceptors = [...
|
|
125
|
-
url = await executeInterceptors_default(url, requestInterceptors, url,
|
|
126
|
-
const { as: parseAs, errMsgs, timeout } =
|
|
119
|
+
const _options2 = mergeFetchOptions_default(fetch.defaults, options);
|
|
120
|
+
if (isEmpty2(_options2.method)) _options2.method = "get";
|
|
121
|
+
const errorInterceptors = [..._options2.interceptors.error];
|
|
122
|
+
const requestInterceptors = [..._options2.interceptors.request];
|
|
123
|
+
const responseInterceptors = [..._options2.interceptors.response];
|
|
124
|
+
const resultInterceptors = [..._options2.interceptors.result];
|
|
125
|
+
url = await executeInterceptors_default(url, requestInterceptors, url, _options2);
|
|
126
|
+
const { as: parseAs, errMsgs, timeout } = _options2;
|
|
127
127
|
if (isPositiveNumber(timeout)) {
|
|
128
|
-
(_a =
|
|
128
|
+
(_a = _options2.abortCtrl) != null ? _a : _options2.abortCtrl = new AbortController();
|
|
129
129
|
timeoutId = setTimeout(() => {
|
|
130
130
|
var _a2;
|
|
131
|
-
return (_a2 =
|
|
131
|
+
return (_a2 = _options2.abortCtrl) == null ? void 0 : _a2.abort();
|
|
132
132
|
}, timeout);
|
|
133
133
|
}
|
|
134
|
-
abortCtrl =
|
|
135
|
-
if (
|
|
134
|
+
abortCtrl = _options2.abortCtrl;
|
|
135
|
+
if (_options2.abortCtrl) _options2.signal = _options2.abortCtrl.signal;
|
|
136
136
|
let errResponse;
|
|
137
137
|
try {
|
|
138
|
-
if (!isUrlValid(url, false)) throw errMsgs.invalidUrl;
|
|
139
|
-
let response = await getResponse_default(url,
|
|
138
|
+
if (!isUrlValid(url, false)) throw new Error(errMsgs.invalidUrl);
|
|
139
|
+
let response = await getResponse_default(url, _options2);
|
|
140
140
|
response = await executeInterceptors_default(
|
|
141
141
|
response,
|
|
142
142
|
responseInterceptors,
|
|
143
143
|
url,
|
|
144
|
-
|
|
144
|
+
_options2
|
|
145
145
|
);
|
|
146
146
|
errResponse = response;
|
|
147
147
|
const { status = 0 } = response;
|
|
@@ -157,43 +157,36 @@ var fetch = (url, options = {}) => {
|
|
|
157
157
|
const parseFunc = response[parseAs];
|
|
158
158
|
if (isFn2(parseFunc)) {
|
|
159
159
|
const handleErr = (err) => {
|
|
160
|
-
var _a2, _b2;
|
|
161
160
|
err = new Error(
|
|
162
|
-
|
|
163
|
-
errMsgs.parseFailed,
|
|
164
|
-
parseAs + ".",
|
|
165
|
-
(_b2 = `${(_a2 = err == null ? void 0 : err.message) != null ? _a2 : err}`) == null ? void 0 : _b2.replace("Error: ", "")
|
|
166
|
-
].join(" "),
|
|
161
|
+
`${errMsgs.parseFailed} ${parseAs}. ${err == null ? void 0 : err.message}`,
|
|
167
162
|
{ cause: err }
|
|
168
163
|
);
|
|
169
164
|
return globalThis.Promise.reject(err);
|
|
170
165
|
};
|
|
171
|
-
result = parseFunc();
|
|
166
|
+
result = parseFunc.bind(response)();
|
|
172
167
|
if (isPromise(result)) result = result.catch(handleErr);
|
|
173
168
|
result = await executeInterceptors_default(
|
|
174
169
|
result,
|
|
175
170
|
resultInterceptors,
|
|
176
171
|
url,
|
|
177
|
-
|
|
172
|
+
_options2
|
|
178
173
|
);
|
|
179
174
|
}
|
|
180
|
-
resolve(
|
|
175
|
+
resolve(result);
|
|
181
176
|
} catch (err) {
|
|
182
177
|
const errX = err;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
);
|
|
178
|
+
const msg = (errX == null ? void 0 : errX.name) === "AbortError" ? errMsgs.reqTimedout : err == null ? void 0 : err.message;
|
|
179
|
+
let error = new FetchError(msg, {
|
|
180
|
+
cause: (_b = errX == null ? void 0 : errX.cause) != null ? _b : err,
|
|
181
|
+
response: errResponse,
|
|
182
|
+
options: _options2,
|
|
183
|
+
url
|
|
184
|
+
});
|
|
192
185
|
error = await executeInterceptors_default(
|
|
193
186
|
error,
|
|
194
187
|
errorInterceptors,
|
|
195
188
|
url,
|
|
196
|
-
|
|
189
|
+
_options2
|
|
197
190
|
);
|
|
198
191
|
reject(error);
|
|
199
192
|
}
|
|
@@ -202,7 +195,7 @@ var fetch = (url, options = {}) => {
|
|
|
202
195
|
promise.onEarlyFinalize.push(() => abortCtrl == null ? void 0 : abortCtrl.abort());
|
|
203
196
|
return promise;
|
|
204
197
|
};
|
|
205
|
-
|
|
198
|
+
fetch.defaults = {
|
|
206
199
|
as: "json" /* json */,
|
|
207
200
|
errMsgs: {
|
|
208
201
|
invalidUrl: "Invalid URL",
|
|
@@ -226,7 +219,6 @@ var defaults = {
|
|
|
226
219
|
},
|
|
227
220
|
timeout: 0
|
|
228
221
|
};
|
|
229
|
-
fetch.defaults = defaults;
|
|
230
222
|
var fetch_default = fetch;
|
|
231
223
|
|
|
232
224
|
// src/fetchDeferred.ts
|
|
@@ -261,14 +253,14 @@ var fetchDeferred_default = fetchDeferred;
|
|
|
261
253
|
import PromisE4 from "@superutils/promise";
|
|
262
254
|
|
|
263
255
|
// src/post.ts
|
|
264
|
-
import { isStr } from "@superutils/core";
|
|
256
|
+
import { isFn as isFn3, isStr } from "@superutils/core";
|
|
265
257
|
function post(...[url = "", data, options = {}]) {
|
|
266
258
|
return fetch_default(
|
|
267
259
|
url,
|
|
268
260
|
mergeFetchOptions_default(
|
|
269
261
|
{
|
|
270
262
|
method: "post",
|
|
271
|
-
body: isStr(data) ? data : JSON.stringify(data)
|
|
263
|
+
body: isStr(data) ? data : JSON.stringify(isFn3(data) ? data() : data)
|
|
272
264
|
},
|
|
273
265
|
options
|
|
274
266
|
)
|
|
@@ -288,10 +280,7 @@ function postDeferred(deferOptions = {}, globalUrl, globalData, defaultOptions)
|
|
|
288
280
|
if (globalData !== void 0) args.splice(1, 0, globalData);
|
|
289
281
|
const url = args[0];
|
|
290
282
|
const data = args[1];
|
|
291
|
-
const options = mergeFetchOptions_default(
|
|
292
|
-
defaultOptions != null ? defaultOptions : {},
|
|
293
|
-
(_a = args[2]) != null ? _a : {}
|
|
294
|
-
);
|
|
283
|
+
const options = mergeFetchOptions_default(defaultOptions != null ? defaultOptions : {}, (_a = args[2]) != null ? _a : {});
|
|
295
284
|
(_b = options.abortCtrl) != null ? _b : options.abortCtrl = new AbortController();
|
|
296
285
|
(_c = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _c.call(_abortCtrl);
|
|
297
286
|
_abortCtrl = options.abortCtrl;
|
|
@@ -304,33 +293,50 @@ function postDeferred(deferOptions = {}, globalUrl, globalData, defaultOptions)
|
|
|
304
293
|
var postDeferred_default = postDeferred;
|
|
305
294
|
|
|
306
295
|
// src/index.ts
|
|
307
|
-
import { isObj } from "@superutils/core";
|
|
308
296
|
var createFetchMethodFunc = (method = "get") => {
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
297
|
+
const deferred = (...args) => fetchDeferred_default(...args);
|
|
298
|
+
const methodFunc = (url, options) => {
|
|
299
|
+
options != null ? options : options = {};
|
|
300
|
+
options.method = method;
|
|
301
|
+
return fetch_default(url, options);
|
|
302
|
+
};
|
|
303
|
+
methodFunc.deferred = deferred;
|
|
315
304
|
return methodFunc;
|
|
316
305
|
};
|
|
317
306
|
var createPostMethodFunc = (method = "post") => {
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
return
|
|
322
|
-
|
|
323
|
-
|
|
307
|
+
const deferredFunc = (deferOptions = {}, globalUrl, globalData, defaultOptions) => {
|
|
308
|
+
defaultOptions != null ? defaultOptions : defaultOptions = {};
|
|
309
|
+
defaultOptions.method = method;
|
|
310
|
+
return postDeferred_default(
|
|
311
|
+
deferOptions,
|
|
312
|
+
globalUrl,
|
|
313
|
+
globalData,
|
|
314
|
+
defaultOptions
|
|
315
|
+
);
|
|
316
|
+
};
|
|
317
|
+
const methodFunc = (url, data, options) => {
|
|
318
|
+
options != null ? options : options = {};
|
|
319
|
+
options.method = method;
|
|
320
|
+
return post(url, data, options);
|
|
321
|
+
};
|
|
322
|
+
methodFunc.deferred = deferredFunc;
|
|
324
323
|
return methodFunc;
|
|
325
324
|
};
|
|
325
|
+
var _get = createFetchMethodFunc("get");
|
|
326
|
+
var _head = createFetchMethodFunc("head");
|
|
327
|
+
var _options = createFetchMethodFunc("options");
|
|
328
|
+
var _delete = createPostMethodFunc("delete");
|
|
329
|
+
var _patch = createPostMethodFunc("patch");
|
|
330
|
+
var _post = createPostMethodFunc("post");
|
|
331
|
+
var _put = createPostMethodFunc("put");
|
|
326
332
|
var fetch2 = fetch_default;
|
|
327
|
-
fetch2.get =
|
|
328
|
-
fetch2.head =
|
|
329
|
-
fetch2.options =
|
|
330
|
-
fetch2.delete =
|
|
331
|
-
fetch2.patch =
|
|
332
|
-
fetch2.post =
|
|
333
|
-
fetch2.put =
|
|
333
|
+
fetch2.get = _get;
|
|
334
|
+
fetch2.head = _head;
|
|
335
|
+
fetch2.options = _options;
|
|
336
|
+
fetch2.delete = _delete;
|
|
337
|
+
fetch2.patch = _patch;
|
|
338
|
+
fetch2.post = _post;
|
|
339
|
+
fetch2.put = _put;
|
|
334
340
|
var index_default = fetch2;
|
|
335
341
|
export {
|
|
336
342
|
FetchAs,
|
package/package.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"author": "Toufiqur Rahaman Chowdhury",
|
|
3
3
|
"description": "A lightweight `fetch` wrapper for browsers and Node.js, designed to simplify data fetching and reduce boilerplate.",
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@superutils/core": "^1.0.
|
|
6
|
-
"@superutils/promise": "^1.0.
|
|
5
|
+
"@superutils/core": "^1.0.8",
|
|
6
|
+
"@superutils/promise": "^1.0.9"
|
|
7
7
|
},
|
|
8
8
|
"files": [
|
|
9
9
|
"dist",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"main": "dist/index.js",
|
|
21
21
|
"name": "@superutils/fetch",
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@superutils/core": "^1.0.
|
|
24
|
-
"@superutils/promise": "^1.0.
|
|
23
|
+
"@superutils/core": "^1.0.8",
|
|
24
|
+
"@superutils/promise": "^1.0.9"
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"sideEffects": false,
|
|
38
38
|
"type": "module",
|
|
39
39
|
"types": "dist/index.d.ts",
|
|
40
|
-
"version": "1.0.
|
|
40
|
+
"version": "1.0.2"
|
|
41
41
|
}
|