@superutils/fetch 1.5.1 → 1.5.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 +49 -0
- package/dist/browser/index.min.js +1 -1123
- package/dist/browser/index.min.js.map +1 -1
- package/dist/index.cjs +51 -31
- package/dist/index.d.cts +147 -138
- package/dist/index.d.ts +147 -138
- package/dist/index.js +51 -28
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _superutils_promise from '@superutils/promise';
|
|
2
2
|
import { RetryOptions, RetryIfFunc, TimeoutOptions, IPromisE_Timeout, DeferredAsyncOptions } from '@superutils/promise';
|
|
3
|
-
export { DeferredAsyncOptions, ResolveError, ResolveIgnored, TIMEOUT_FALLBACK, TIMEOUT_MAX, TimeoutPromise } from '@superutils/promise';
|
|
3
|
+
export { DeferredAsyncOptions, OnEarlyFinalize, OnFinalize, ResolveError, ResolveIgnored, RetryIfFunc, RetryOptions, TIMEOUT_FALLBACK, TIMEOUT_MAX, TimeoutOptions, TimeoutPromise } from '@superutils/promise';
|
|
4
4
|
import { ValueOrPromise, DropFirst } from '@superutils/core';
|
|
5
5
|
|
|
6
6
|
/** Commonly used content types for easier access */
|
|
@@ -44,34 +44,36 @@ type Interceptor<T, TArgs extends unknown[]> = (...args: [value: T, ...TArgs]) =
|
|
|
44
44
|
*
|
|
45
45
|
* @returns returning undefined or not returning anything will not override the error
|
|
46
46
|
*
|
|
47
|
-
* @example
|
|
48
|
-
*
|
|
49
|
-
*
|
|
47
|
+
* @example
|
|
48
|
+
* #### Intercept fetch errors to log errors
|
|
49
|
+
* ```javascript
|
|
50
|
+
* import fetch from '@superutils/fetch'
|
|
50
51
|
*
|
|
51
52
|
* // not returning anything or returning undefined will avoid transforming the error.
|
|
52
53
|
* const logError = fetchErr => console.log(fetchErr)
|
|
53
|
-
* const result = await
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
54
|
+
* const result = await fetch.get('https://dummyjson.com/http/400', {
|
|
55
|
+
* interceptors: {
|
|
56
|
+
* error: [logError]
|
|
57
|
+
* }
|
|
57
58
|
* })
|
|
58
59
|
* ```
|
|
59
60
|
*
|
|
60
|
-
* @example
|
|
61
|
-
*
|
|
62
|
-
*
|
|
61
|
+
* @example
|
|
62
|
+
* #### Intercept & transform fetch errors
|
|
63
|
+
* ```javascript
|
|
64
|
+
* import fetch from '@superutils/fetch'
|
|
63
65
|
*
|
|
64
66
|
* // Interceptors can be async functions or just return a promise that resolves to the error.
|
|
65
67
|
* // If the execution of the interceptor fails or promise rejects, it will be ignored.
|
|
66
68
|
* // To transform the error it must directly return an error or a Promise that `resolves` with an error.
|
|
67
69
|
* const transformError = async (fetchErr, url, options) => {
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
+
* fetchErr.message = 'Custom errormessage'
|
|
71
|
+
* return Promise.resolve(fetchErr)
|
|
70
72
|
* }
|
|
71
|
-
* const result = await
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
73
|
+
* const result = await fetch.get('https://dummyjson.com/http/400', {
|
|
74
|
+
* interceptors: {
|
|
75
|
+
* error: [transformError]
|
|
76
|
+
* }
|
|
75
77
|
* })
|
|
76
78
|
* ```
|
|
77
79
|
*/
|
|
@@ -82,19 +84,21 @@ type FetchInterceptorError = Interceptor<FetchError, FetchArgsInterceptor>;
|
|
|
82
84
|
* 1. by returning an API URL (string/URL)
|
|
83
85
|
* 2. by modifying the properties of the options parameter to be used before making the fetch request
|
|
84
86
|
*
|
|
85
|
-
* @example
|
|
87
|
+
* @example
|
|
88
|
+
* #### Intercept and transform fetch request
|
|
86
89
|
* ```typescript
|
|
87
|
-
* import
|
|
90
|
+
* import fetch from '@superutils/fetch'
|
|
88
91
|
*
|
|
89
92
|
* // update API version number
|
|
90
93
|
* const apiV1ToV2 = url => `${url}`.replace('api/v1', 'api/v2')
|
|
91
94
|
* const includeAuthToken = (url, options) => {
|
|
92
|
-
*
|
|
95
|
+
* options.headers.set('x-auth-token', 'my-auth-token')
|
|
93
96
|
* }
|
|
94
|
-
* const
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
97
|
+
* const result = await fetch.get('https://dummyjson.com/products', {
|
|
98
|
+
* method: 'post',
|
|
99
|
+
* interceptors: {
|
|
100
|
+
* result: [apiV1ToV2, includeAuthToken]
|
|
101
|
+
* }
|
|
98
102
|
* })
|
|
99
103
|
* ```
|
|
100
104
|
*/
|
|
@@ -106,24 +110,29 @@ type FetchInterceptorRequest = Interceptor<FetchArgs[0], [
|
|
|
106
110
|
*
|
|
107
111
|
* This interceptor can also be used as a transformer by return a different/modified {@link Response}.
|
|
108
112
|
*
|
|
109
|
-
* @example
|
|
110
|
-
*
|
|
111
|
-
*
|
|
113
|
+
* @example
|
|
114
|
+
* #### Intercept and transform response:
|
|
115
|
+
* ```javascript
|
|
116
|
+
* import fetch from '@superutils/fetch'
|
|
112
117
|
*
|
|
113
|
-
* // After successful login, retrieve user
|
|
118
|
+
* // After successful login, retrieve full user details.
|
|
114
119
|
* // This is probably better suited as a result transformer but play along as this is
|
|
115
120
|
* // just a hypothetical scenario ;)
|
|
116
|
-
* const
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
+
* const getUser = async response => {
|
|
122
|
+
* const authResult = await response.json()
|
|
123
|
+
* const userDetails = await fetch.get('https://dummyjson.com/users/1')
|
|
124
|
+
* const userAuth = { ...userDetails, ...authResult }
|
|
125
|
+
* return new Response(JSON.stringify(userAuth))
|
|
121
126
|
* }
|
|
122
|
-
* const user = await
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
+
* const user = await fetch.post(
|
|
128
|
+
* 'https://dummyjson.com/user/login',
|
|
129
|
+
* { // data/request body
|
|
130
|
+
* username: 'emilys',
|
|
131
|
+
* password: 'emilyspass',
|
|
132
|
+
* expiresInMins: 30,
|
|
133
|
+
* },
|
|
134
|
+
* { interceptors: { response: [getUser] } }
|
|
135
|
+
* )
|
|
127
136
|
* ```
|
|
128
137
|
*/
|
|
129
138
|
type FetchInterceptorResponse = Interceptor<Response, FetchArgsInterceptor>;
|
|
@@ -140,32 +149,45 @@ type FetchInterceptorResponse = Interceptor<Response, FetchArgsInterceptor>;
|
|
|
140
149
|
* This interceptor can also be used as a transformer by returns a different/modified result.
|
|
141
150
|
*
|
|
142
151
|
*
|
|
143
|
-
* @example
|
|
144
|
-
*
|
|
145
|
-
*
|
|
152
|
+
* @example
|
|
153
|
+
* #### Intercept and transform fetch result
|
|
154
|
+
* ```javascript
|
|
155
|
+
* import fetch from '@superutils/fetch'
|
|
146
156
|
*
|
|
147
|
-
* // first transform result
|
|
148
|
-
* const
|
|
157
|
+
* // first transform result (user object) and ensure user result alwasy contain a hexadecimal crypto balance
|
|
158
|
+
* const ensureBalanceHex = (user = {}) => {
|
|
159
|
+
* user.crypto ??= {}
|
|
160
|
+
* user.crypto.balance ??= '0x0'
|
|
161
|
+
* return user
|
|
162
|
+
* }
|
|
149
163
|
* // then check convert hexadecimal number to BigInt
|
|
150
|
-
* const hexToBigInt =
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* }
|
|
154
|
-
* return data
|
|
164
|
+
* const hexToBigInt = user => {
|
|
165
|
+
* user.crypto.balance = BigInt(user.crypto.balance)
|
|
166
|
+
* return user
|
|
155
167
|
* }
|
|
156
168
|
* // then log balance (no transformation)
|
|
157
|
-
* const logBalance =
|
|
158
|
-
*
|
|
169
|
+
* const logBalance = (result, url) => {
|
|
170
|
+
* // only log balance for single user requests
|
|
171
|
+
* const shouldLog = result?.hasOwnProperty('crypto') && /^[0-9]+$/.test(
|
|
172
|
+
* url?.split('/users/')[1].replace('/', '')
|
|
173
|
+
* )
|
|
174
|
+
* shouldLog && console.log(
|
|
175
|
+
* new Date().toISOString(),
|
|
176
|
+
* '[UserBalance] UserID:', result.id,
|
|
177
|
+
* result.crypto.balance
|
|
178
|
+
* )
|
|
159
179
|
* }
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
180
|
+
* // now we make the actaul fetch request
|
|
181
|
+
* const result = await fetch.get('https://dummyjson.com/users/1', {
|
|
182
|
+
* interceptors: {
|
|
183
|
+
* result: [
|
|
184
|
+
* ensureBalanceHex,
|
|
185
|
+
* hexToBigInt,
|
|
186
|
+
* logBalance
|
|
187
|
+
* ]
|
|
188
|
+
* }
|
|
168
189
|
* })
|
|
190
|
+
* console.log({result})
|
|
169
191
|
* ```
|
|
170
192
|
*/
|
|
171
193
|
type FetchInterceptorResult<Args extends unknown[] = FetchArgsInterceptor> = Interceptor<unknown, Args>;
|
|
@@ -277,7 +299,7 @@ type FetchCustomOptions = {
|
|
|
277
299
|
* See {@link FetchInterceptors} for more details.
|
|
278
300
|
*/
|
|
279
301
|
interceptors?: FetchInterceptors;
|
|
280
|
-
/** Whether to validate URL before making the request. Default: `
|
|
302
|
+
/** Whether to validate URL before making the request. Default: `false` */
|
|
281
303
|
validateUrl?: boolean;
|
|
282
304
|
} & FetchRetryOptions & TimeoutOptions<[]>;
|
|
283
305
|
/** Default args */
|
|
@@ -303,8 +325,24 @@ type FetchFunc = (...args: FetchArgs) => Promise<Response>;
|
|
|
303
325
|
*/
|
|
304
326
|
type FetchOptions = Omit<RequestInit, 'body'> & FetchCustomOptions;
|
|
305
327
|
/** Default fetch options */
|
|
306
|
-
type FetchOptionsDefault = Omit<FetchOptionsInterceptor, 'abortCtrl' | 'as' | 'method' | 'signal' | 'timeout'> & {
|
|
307
|
-
/**
|
|
328
|
+
type FetchOptionsDefault = Omit<FetchOptionsInterceptor, 'abortCtrl' | 'as' | 'method' | 'signal' | 'timeout' | 'headers'> & {
|
|
329
|
+
/**
|
|
330
|
+
* Request headers.
|
|
331
|
+
*
|
|
332
|
+
* Deafult:
|
|
333
|
+
* - No default content type set when `fetch()` is directly invoked.
|
|
334
|
+
* - `"content-type": "application/json"`: for `createPostClient()`, `fetch.post()`,
|
|
335
|
+
* `fetch.post.deferred()` and other method specific functions
|
|
336
|
+
*/
|
|
337
|
+
headers: HeadersInit;
|
|
338
|
+
/**
|
|
339
|
+
* Request timeout duration in milliseconds.
|
|
340
|
+
*
|
|
341
|
+
* Default:
|
|
342
|
+
* - `30_000` for `createClient()`, `createPostClient()` and
|
|
343
|
+
* all method specific functions (`fetch.METHOD` & `fetch.METHOD.deferred()`
|
|
344
|
+
* - `2147483647` when `fetch()` invoked directly
|
|
345
|
+
*/
|
|
308
346
|
timeout: number;
|
|
309
347
|
};
|
|
310
348
|
/**
|
|
@@ -360,30 +398,10 @@ type PostArgs = [
|
|
|
360
398
|
* ```typescript
|
|
361
399
|
* import fetch, { type PostDeferredCbArgs } from '@superutils/fetch'
|
|
362
400
|
*
|
|
363
|
-
* // test with types
|
|
364
401
|
* type T1 = PostDeferredCbArgs<string | URL, undefined> // expected: [data, options]
|
|
365
|
-
* type T2 = PostDeferredCbArgs<undefined, string> // expected: [url, options]
|
|
402
|
+
* type T2 = PostDeferredCbArgs<string | undefined, string> // expected: [url, options]
|
|
366
403
|
* type T3 = PostDeferredCbArgs // expected: [url, data, options]
|
|
367
404
|
* type T4 = PostDeferredCbArgs<string, string> // expected: [options]
|
|
368
|
-
*
|
|
369
|
-
* const data = { name: 'test' }
|
|
370
|
-
* const url = 'https://domain.com'
|
|
371
|
-
* // test with fetch.post.deferred()
|
|
372
|
-
* const f1 = fetch.post.deferred({}, 'https://domain.com')
|
|
373
|
-
* // expected: [data, options]
|
|
374
|
-
* f1({data: 1}).then(console.log, console.warn)
|
|
375
|
-
*
|
|
376
|
-
* const f2 = fetch.post.deferred({}, undefined, 'dome data')
|
|
377
|
-
* // expected: [url, options]
|
|
378
|
-
* f2('https').then(console.log, console.warn)
|
|
379
|
-
*
|
|
380
|
-
* const f3 = fetch.post.deferred({})
|
|
381
|
-
* // expected: [url, data, options]
|
|
382
|
-
* f3('https://domain.com').then(console.log, console.warn)
|
|
383
|
-
*
|
|
384
|
-
* const f4 = fetch.post.deferred({}, 'url', 'data')
|
|
385
|
-
* // expected: [options]
|
|
386
|
-
* f4().then(console.log, console.warn)
|
|
387
405
|
* ```
|
|
388
406
|
*/
|
|
389
407
|
type PostDeferredCbArgs<DefaultUrl = undefined, DefaultData = undefined, Options = PostArgs[2], PostArgsReq extends unknown[] = Required<PostArgs>, _url = undefined extends DefaultUrl ? undefined : DefaultUrl, _data = undefined extends DefaultData ? undefined : DefaultData> = [_url, _data] extends [PostArgsReq[0], undefined] ? [
|
|
@@ -440,45 +458,41 @@ type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ?
|
|
|
440
458
|
* The returned client also includes a `.deferred()` method, providing the same debounce, throttle, and sequential
|
|
441
459
|
* execution capabilities found in functions like `fetch.get.deferred()`.
|
|
442
460
|
*
|
|
443
|
-
* @example
|
|
461
|
+
* @example
|
|
462
|
+
* #### Create reusable clients
|
|
444
463
|
* ```javascript
|
|
445
464
|
* import { createClient } from '@superutils/fetch'
|
|
446
465
|
*
|
|
447
466
|
* // Create a "GET" client with default headers and a 5-second timeout
|
|
448
467
|
* const apiClient = createClient(
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
* {
|
|
462
|
-
* // default defer options (can be overridden)
|
|
463
|
-
* delay: 300,
|
|
464
|
-
* retry: 2, // If request fails, retry up to two more times
|
|
465
|
-
* },
|
|
468
|
+
* { method: 'get' }, // fixed options cannot be overridden
|
|
469
|
+
* { // default options can be overridden
|
|
470
|
+
* headers: {
|
|
471
|
+
* Authorization: 'Bearer my-secret-token',
|
|
472
|
+
* 'Content-Type': 'application/json',
|
|
473
|
+
* },
|
|
474
|
+
* timeout: 5000,
|
|
475
|
+
* },
|
|
476
|
+
* {// default defer options (can be overridden)
|
|
477
|
+
* delay: 300,
|
|
478
|
+
* retry: 2, // If request fails, retry up to two more times
|
|
479
|
+
* },
|
|
466
480
|
* )
|
|
467
481
|
*
|
|
468
482
|
* // Use it just like the standard fetch
|
|
469
483
|
* apiClient('https://dummyjson.com/products/1', {
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
484
|
+
* // The 'method' property cannot be overridden as it is used in the fixed options when creating the client.
|
|
485
|
+
* // In TypeScript, the compiler will not allow this property.
|
|
486
|
+
* // In Javascript, it will simply be ignored.
|
|
487
|
+
* // method: 'post',
|
|
488
|
+
* timeout: 3000, // The 'timeout' property can be overridden
|
|
475
489
|
* }).then(console.log, console.warn)
|
|
476
490
|
*
|
|
477
491
|
* // create a deferred client using "apiClient"
|
|
478
492
|
* const deferredClient = apiClient.deferred(
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
493
|
+
* { retry: 0 }, // disable retrying by overriding the `retry` defer option
|
|
494
|
+
* 'https://dummyjson.com/products/1',
|
|
495
|
+
* { timeout: 3000 },
|
|
482
496
|
* )
|
|
483
497
|
* deferredClient({ timeout: 10000 }) // timeout is overridden by individual request
|
|
484
498
|
* .then(console.log, console.warn)
|
|
@@ -503,24 +517,25 @@ commonOptions?: FetchOptions & CommonOptions, commonDeferOptions?: DeferredAsync
|
|
|
503
517
|
* Similar to `createClient`, the returned function comes equipped with a `.deferred()` method, enabling debounced,
|
|
504
518
|
* throttled, or sequential execution.
|
|
505
519
|
*
|
|
506
|
-
* @example
|
|
520
|
+
* @example
|
|
521
|
+
* #### Create reusable clients
|
|
507
522
|
* ```javascript
|
|
508
523
|
* import { createPostClient, FetchAs } from '@superutils/fetch'
|
|
509
524
|
*
|
|
510
525
|
* // Create a POST client with 10-second as the default timeout
|
|
511
526
|
* const postClient = createPostClient(
|
|
512
|
-
* {
|
|
513
|
-
*
|
|
514
|
-
*
|
|
527
|
+
* { // fixed options cannot be overrided by client calls
|
|
528
|
+
* method: 'post',
|
|
529
|
+
* headers: { 'content-type': 'application/json' },
|
|
515
530
|
* },
|
|
516
|
-
* { timeout: 10000 },
|
|
531
|
+
* { timeout: 10000 }, // common options that can be overriden by client calls
|
|
517
532
|
* )
|
|
518
533
|
*
|
|
519
534
|
* // Invoking `postClient()` automatically applies the pre-configured options
|
|
520
535
|
* postClient(
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
536
|
+
* 'https://dummyjson.com/products/add',
|
|
537
|
+
* { title: 'New Product' }, // data/body
|
|
538
|
+
* {}, // other options
|
|
524
539
|
* ).then(console.log)
|
|
525
540
|
*
|
|
526
541
|
* // create a deferred client using "postClient"
|
|
@@ -530,10 +545,7 @@ commonOptions?: FetchOptions & CommonOptions, commonDeferOptions?: DeferredAsync
|
|
|
530
545
|
* onResult: console.log, // prints only successful results
|
|
531
546
|
* },
|
|
532
547
|
* 'https://dummyjson.com/products/add',
|
|
533
|
-
* {
|
|
534
|
-
* method: 'patch',
|
|
535
|
-
* timeout: 3000,
|
|
536
|
-
* },
|
|
548
|
+
* { method: 'patch', timeout: 3000 },
|
|
537
549
|
* )
|
|
538
550
|
* updateProduct({ title: 'New title 1' }) // ignored by debounce
|
|
539
551
|
* updateProduct({ title: 'New title 2' }) // executed
|
|
@@ -574,12 +586,13 @@ declare const executeInterceptors: <T, TArgs extends unknown[]>(value: T, signal
|
|
|
574
586
|
* @param options.as (optional) determines how to parse the result. Default: {@link FetchAs.json}
|
|
575
587
|
* @param options.method (optional) fetch method. Default: `'get'`
|
|
576
588
|
*
|
|
577
|
-
* @example
|
|
578
|
-
*
|
|
589
|
+
* @example
|
|
590
|
+
* #### Make a simple HTTP requests
|
|
591
|
+
* ```javascript
|
|
579
592
|
* import { fetch } from '@superutils/fetch'
|
|
580
593
|
*
|
|
581
594
|
* // no need for `response.json()` or `result.data.data` drilling
|
|
582
|
-
* fetch('https://dummyjson.com/products/1')
|
|
595
|
+
* fetch.get('https://dummyjson.com/products/1')
|
|
583
596
|
* .then(product => console.log(product))
|
|
584
597
|
* ```
|
|
585
598
|
*/
|
|
@@ -594,10 +607,10 @@ declare const fetch$1: {
|
|
|
594
607
|
*
|
|
595
608
|
* Notes:
|
|
596
609
|
* - item properties will be prioritized in the order of sequence they were passed in
|
|
597
|
-
* - the following properties will be merged
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
610
|
+
* - the following properties will be merged:
|
|
611
|
+
* * `errMsgs`
|
|
612
|
+
* * `headers`
|
|
613
|
+
* * `interceptors`
|
|
601
614
|
* - all other properties will simply override previous values
|
|
602
615
|
*
|
|
603
616
|
* @returns combined
|
|
@@ -856,8 +869,8 @@ declare const methods: {
|
|
|
856
869
|
* import fetch from '@superutils/fetch'
|
|
857
870
|
*
|
|
858
871
|
* fetch('https://dummyjson.com/products/1')
|
|
859
|
-
*
|
|
860
|
-
*
|
|
872
|
+
* .then(response => response.json())
|
|
873
|
+
* .then(console.log, console.error)
|
|
861
874
|
* ```
|
|
862
875
|
*
|
|
863
876
|
* @example
|
|
@@ -867,13 +880,9 @@ declare const methods: {
|
|
|
867
880
|
*
|
|
868
881
|
* // no need for `response.json()` or `result.data.data` drilling
|
|
869
882
|
* fetch.get('https://dummyjson.com/products/1')
|
|
870
|
-
*
|
|
871
|
-
* fetch.get('https://dummyjson.com/products/1')
|
|
872
|
-
* .then(product => console.log(product))
|
|
873
|
-
*
|
|
874
|
-
*
|
|
883
|
+
* .then(product => console.log(product))
|
|
875
884
|
* fetch.post('https://dummyjson.com/products/add', { title: 'Product title' })
|
|
876
|
-
*
|
|
885
|
+
* .then(product => console.log(product))
|
|
877
886
|
* ```
|
|
878
887
|
*
|
|
879
888
|
*
|
|
@@ -903,10 +912,10 @@ declare const methods: {
|
|
|
903
912
|
*
|
|
904
913
|
* // add an interceptor to conditionally include header before making requests
|
|
905
914
|
* interceptors.request.push((url, options) => {
|
|
906
|
-
*
|
|
907
|
-
*
|
|
915
|
+
* // ignore login requests
|
|
916
|
+
* if (`${url}`.includes('/login')) return
|
|
908
917
|
*
|
|
909
|
-
*
|
|
918
|
+
* options.headers.set('x-auth-token', 'my-auth-token')
|
|
910
919
|
* })
|
|
911
920
|
* ```
|
|
912
921
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
ResolveError,
|
|
4
|
+
ResolveIgnored,
|
|
5
|
+
TIMEOUT_FALLBACK,
|
|
6
|
+
TIMEOUT_MAX as TIMEOUT_MAX2,
|
|
7
|
+
TimeoutPromise
|
|
8
|
+
} from "@superutils/promise";
|
|
9
|
+
|
|
1
10
|
// src/createClient.ts
|
|
2
11
|
import { deferredCallback } from "@superutils/promise";
|
|
3
12
|
|
|
@@ -6,10 +15,11 @@ import {
|
|
|
6
15
|
fallbackIfFails as fallbackIfFails3,
|
|
7
16
|
isError,
|
|
8
17
|
isFn as isFn4,
|
|
18
|
+
isObj as isObj2,
|
|
9
19
|
isPromise,
|
|
10
20
|
isUrlValid
|
|
11
21
|
} from "@superutils/core";
|
|
12
|
-
import { timeout as PromisE_timeout } from "@superutils/promise";
|
|
22
|
+
import { timeout as PromisE_timeout, TIMEOUT_MAX } from "@superutils/promise";
|
|
13
23
|
|
|
14
24
|
// src/executeInterceptors.ts
|
|
15
25
|
import { fallbackIfFails, isFn } from "@superutils/core";
|
|
@@ -166,20 +176,25 @@ var FetchError = class _FetchError extends Error {
|
|
|
166
176
|
}
|
|
167
177
|
};
|
|
168
178
|
|
|
169
|
-
// src/types/index.ts
|
|
170
|
-
import {
|
|
171
|
-
ResolveError,
|
|
172
|
-
ResolveIgnored,
|
|
173
|
-
TIMEOUT_FALLBACK,
|
|
174
|
-
TIMEOUT_MAX,
|
|
175
|
-
TimeoutPromise
|
|
176
|
-
} from "@superutils/promise";
|
|
177
|
-
|
|
178
179
|
// src/fetch.ts
|
|
179
180
|
var fetch = (url, options = {}) => {
|
|
180
181
|
var _a, _b, _c;
|
|
182
|
+
if (!isObj2(options)) options = {};
|
|
183
|
+
let fromPostClient = false;
|
|
184
|
+
if (options.fromPostClient) {
|
|
185
|
+
delete options.fromPostClient;
|
|
186
|
+
fromPostClient = true;
|
|
187
|
+
}
|
|
181
188
|
let response;
|
|
182
|
-
const opts = mergeOptions_default(
|
|
189
|
+
const opts = mergeOptions_default(
|
|
190
|
+
{
|
|
191
|
+
abortOnEarlyFinalize: fetch.defaults.abortOnEarlyFinalize,
|
|
192
|
+
errMsgs: fetch.defaults.errMsgs,
|
|
193
|
+
timeout: TIMEOUT_MAX,
|
|
194
|
+
validateUrl: false
|
|
195
|
+
},
|
|
196
|
+
options
|
|
197
|
+
);
|
|
183
198
|
opts.abortCtrl = opts.abortCtrl instanceof AbortController ? opts.abortCtrl : new AbortController();
|
|
184
199
|
(_a = opts.as) != null ? _a : opts.as = "response" /* response */;
|
|
185
200
|
(_b = opts.method) != null ? _b : opts.method = "get";
|
|
@@ -210,29 +225,31 @@ var fetch = (url, options = {}) => {
|
|
|
210
225
|
return PromisE_timeout(opts, async () => {
|
|
211
226
|
var _a2, _b2, _c2, _d, _e;
|
|
212
227
|
try {
|
|
213
|
-
let contentType = headers.get("content-type");
|
|
214
|
-
if (!contentType) {
|
|
215
|
-
headers.set("content-type", ContentType.APPLICATION_JSON);
|
|
216
|
-
contentType = ContentType.APPLICATION_JSON;
|
|
217
|
-
}
|
|
218
228
|
url = await executeInterceptors_default(
|
|
219
229
|
url,
|
|
220
230
|
abortCtrl.signal,
|
|
221
231
|
(_a2 = opts.interceptors) == null ? void 0 : _a2.request,
|
|
222
232
|
opts
|
|
223
233
|
);
|
|
224
|
-
const { body, errMsgs, validateUrl =
|
|
234
|
+
const { body, errMsgs, validateUrl = false } = opts;
|
|
225
235
|
(_b2 = opts.signal) != null ? _b2 : opts.signal = abortCtrl.signal;
|
|
226
236
|
if (validateUrl && !isUrlValid(url, false))
|
|
227
237
|
throw new Error(errMsgs.invalidUrl);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
238
|
+
if (fromPostClient) {
|
|
239
|
+
let contentType = headers.get("content-type");
|
|
240
|
+
if (!contentType) {
|
|
241
|
+
headers.set("content-type", ContentType.APPLICATION_JSON);
|
|
242
|
+
contentType = ContentType.APPLICATION_JSON;
|
|
243
|
+
}
|
|
244
|
+
const shouldStringifyBody = ["delete", "patch", "post", "put"].includes(
|
|
245
|
+
`${opts.method}`.toLowerCase()
|
|
246
|
+
) && !["undefined", "string"].includes(typeof body) && isObj2(body, true) && contentType === ContentType.APPLICATION_JSON;
|
|
247
|
+
if (shouldStringifyBody) {
|
|
248
|
+
opts.body = JSON.stringify(
|
|
249
|
+
isFn4(body) ? fallbackIfFails3(body, [], void 0) : body
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
236
253
|
response = await getResponse_default(url, opts);
|
|
237
254
|
response = await executeInterceptors_default(
|
|
238
255
|
response,
|
|
@@ -298,8 +315,8 @@ fetch.defaults = {
|
|
|
298
315
|
response: [],
|
|
299
316
|
result: []
|
|
300
317
|
},
|
|
301
|
-
timeout:
|
|
302
|
-
validateUrl:
|
|
318
|
+
timeout: 6e4,
|
|
319
|
+
validateUrl: false
|
|
303
320
|
};
|
|
304
321
|
var interceptErr = async (err, url, options, response) => {
|
|
305
322
|
var _a, _b, _c;
|
|
@@ -325,6 +342,7 @@ var createClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
325
342
|
function client(url, options) {
|
|
326
343
|
var _a;
|
|
327
344
|
const mergedOptions = mergeOptions_default(
|
|
345
|
+
fetch_default.defaults,
|
|
328
346
|
commonOptions,
|
|
329
347
|
options,
|
|
330
348
|
fixedOptions
|
|
@@ -338,6 +356,7 @@ var createClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
338
356
|
const fetchCb = (...args) => {
|
|
339
357
|
var _a, _b, _c;
|
|
340
358
|
const mergedOptions = (_a = mergeOptions_default(
|
|
359
|
+
fetch_default.defaults,
|
|
341
360
|
commonOptions,
|
|
342
361
|
defaultOptions,
|
|
343
362
|
defaultUrl === void 0 ? args[1] : args[0],
|
|
@@ -367,6 +386,7 @@ var createPostClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
367
386
|
function client(url, data, options) {
|
|
368
387
|
var _a, _b;
|
|
369
388
|
const mergedOptions = mergeOptions_default(
|
|
389
|
+
fetch_default.defaults,
|
|
370
390
|
commonOptions,
|
|
371
391
|
options,
|
|
372
392
|
fixedOptions
|
|
@@ -375,6 +395,7 @@ var createPostClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
375
395
|
(_a = mergedOptions.as) != null ? _a : mergedOptions.as = "json" /* json */;
|
|
376
396
|
mergedOptions.body = data;
|
|
377
397
|
(_b = mergedOptions.method) != null ? _b : mergedOptions.method = "post";
|
|
398
|
+
mergedOptions.fromPostClient = true;
|
|
378
399
|
return fetch_default(url, mergedOptions);
|
|
379
400
|
}
|
|
380
401
|
client.deferred = (deferOptions, defaultUrl, defaultData, defaultOptions) => {
|
|
@@ -384,6 +405,7 @@ var createPostClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
384
405
|
if (defaultUrl !== void 0) args.splice(0, 0, defaultUrl);
|
|
385
406
|
if (defaultData !== void 0) args.splice(1, 0, defaultData);
|
|
386
407
|
const mergedOptions = (_a = mergeOptions_default(
|
|
408
|
+
fetch_default.defaults,
|
|
387
409
|
commonOptions,
|
|
388
410
|
defaultOptions,
|
|
389
411
|
args[2],
|
|
@@ -395,6 +417,7 @@ var createPostClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
395
417
|
_abortCtrl = new AbortController();
|
|
396
418
|
mergedOptions.body = (_d = args[1]) != null ? _d : mergedOptions.body;
|
|
397
419
|
(_e = mergedOptions.method) != null ? _e : mergedOptions.method = "post";
|
|
420
|
+
mergedOptions.fromPostClient = true;
|
|
398
421
|
return fetch_default(args[0], mergedOptions);
|
|
399
422
|
};
|
|
400
423
|
return deferredCallback2(postCb, {
|
|
@@ -439,7 +462,7 @@ export {
|
|
|
439
462
|
ResolveError,
|
|
440
463
|
ResolveIgnored,
|
|
441
464
|
TIMEOUT_FALLBACK,
|
|
442
|
-
TIMEOUT_MAX,
|
|
465
|
+
TIMEOUT_MAX2 as TIMEOUT_MAX,
|
|
443
466
|
TimeoutPromise,
|
|
444
467
|
createClient,
|
|
445
468
|
createPostClient,
|
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.2.
|
|
9
|
-
"@superutils/promise": "^1.3.
|
|
8
|
+
"@superutils/core": "^1.2.4",
|
|
9
|
+
"@superutils/promise": "^1.3.2"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
@@ -53,6 +53,6 @@
|
|
|
53
53
|
"module": "./dist/index.js",
|
|
54
54
|
"type": "module",
|
|
55
55
|
"types": "./dist/index.d.ts",
|
|
56
|
-
"version": "1.5.
|
|
57
|
-
"gitHead": "
|
|
56
|
+
"version": "1.5.2",
|
|
57
|
+
"gitHead": "bdecb6b7e72557ac91be0b4e2b2cf47dc8dc15eb"
|
|
58
58
|
}
|