@superutils/fetch 1.5.3 → 1.5.5
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 +128 -112
- package/dist/browser/index.min.js +1 -1
- package/dist/browser/index.min.js.map +1 -1
- package/dist/index.cjs +42 -56
- package/dist/index.d.cts +23 -54
- package/dist/index.d.ts +23 -54
- package/dist/index.js +45 -59
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -76,14 +76,14 @@ var getResponse = (url, options = {}) => {
|
|
|
76
76
|
{
|
|
77
77
|
...options,
|
|
78
78
|
retryIf: async (res, count, error) => {
|
|
79
|
-
var _a;
|
|
79
|
+
var _a, _b;
|
|
80
80
|
const { abortCtrl, retryIf, signal } = options;
|
|
81
|
-
if ((abortCtrl == null ? void 0 : abortCtrl.signal.aborted) || (signal == null ? void 0 : signal.aborted)) return false;
|
|
82
|
-
return !!((
|
|
81
|
+
if (((_a = abortCtrl == null ? void 0 : abortCtrl.signal) == null ? void 0 : _a.aborted) || (signal == null ? void 0 : signal.aborted)) return false;
|
|
82
|
+
return !!((_b = await (0, import_core2.fallbackIfFails)(
|
|
83
83
|
retryIf,
|
|
84
84
|
[res, count, error],
|
|
85
85
|
void 0
|
|
86
|
-
)) != null ?
|
|
86
|
+
)) != null ? _b : !!error || !(res == null ? void 0 : res.ok));
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
).catch(
|
|
@@ -201,22 +201,20 @@ var FetchError = class _FetchError extends Error {
|
|
|
201
201
|
};
|
|
202
202
|
|
|
203
203
|
// src/fetch.ts
|
|
204
|
+
var defaultErrorMsgs = Object.freeze({
|
|
205
|
+
aborted: "Request aborted",
|
|
206
|
+
invalidUrl: "Invalid URL",
|
|
207
|
+
parseFailed: "Failed to parse response as",
|
|
208
|
+
timedout: "Request timed out",
|
|
209
|
+
requestFailed: "Request failed with status code:"
|
|
210
|
+
});
|
|
204
211
|
var fetch = (url, options = {}) => {
|
|
205
212
|
var _a, _b, _c;
|
|
206
213
|
if (!(0, import_core4.isObj)(options)) options = {};
|
|
207
|
-
let fromPostClient = false;
|
|
208
|
-
if (options.fromPostClient) {
|
|
209
|
-
delete options.fromPostClient;
|
|
210
|
-
fromPostClient = true;
|
|
211
|
-
}
|
|
212
214
|
let response;
|
|
213
215
|
const opts = mergeOptions_default(
|
|
214
|
-
{
|
|
215
|
-
|
|
216
|
-
errMsgs: fetch.defaults.errMsgs,
|
|
217
|
-
timeout: import_promise2.TIMEOUT_MAX,
|
|
218
|
-
validateUrl: false
|
|
219
|
-
},
|
|
216
|
+
{ errMsgs: defaultErrorMsgs },
|
|
217
|
+
fetch.defaults,
|
|
220
218
|
options
|
|
221
219
|
);
|
|
222
220
|
opts.abortCtrl = opts.abortCtrl instanceof AbortController ? opts.abortCtrl : new AbortController();
|
|
@@ -225,11 +223,7 @@ var fetch = (url, options = {}) => {
|
|
|
225
223
|
(_c = opts.signal) != null ? _c : opts.signal = opts.abortCtrl.signal;
|
|
226
224
|
const { abortCtrl, as: parseAs, headers, onAbort, onTimeout } = opts;
|
|
227
225
|
opts.onAbort = async () => {
|
|
228
|
-
|
|
229
|
-
const err = (_f = (_e = (_c2 = await (0, import_core4.fallbackIfFails)(onAbort, [], void 0)) != null ? _c2 : (_b2 = (_a2 = opts.abortCtrl) == null ? void 0 : _a2.signal) == null ? void 0 : _b2.reason) != null ? _e : (_d = opts.signal) == null ? void 0 : _d.reason) != null ? _f : opts.errMsgs.aborted;
|
|
230
|
-
if ((0, import_core4.isError)(err) && err.name === "AbortError") {
|
|
231
|
-
err.message = ["This operation was aborted"].includes(err.message) ? opts.errMsgs.aborted : err.message;
|
|
232
|
-
}
|
|
226
|
+
const err = await (0, import_core4.fallbackIfFails)(onAbort, [], void 0);
|
|
233
227
|
return await interceptErr(
|
|
234
228
|
(0, import_core4.isError)(err) ? err : new Error(err),
|
|
235
229
|
url,
|
|
@@ -247,7 +241,7 @@ var fetch = (url, options = {}) => {
|
|
|
247
241
|
);
|
|
248
242
|
};
|
|
249
243
|
return (0, import_promise2.timeout)(opts, async () => {
|
|
250
|
-
var _a2, _b2, _c2, _d
|
|
244
|
+
var _a2, _b2, _c2, _d;
|
|
251
245
|
try {
|
|
252
246
|
opts.body = await (0, import_core4.fallbackIfFails)(
|
|
253
247
|
opts.body,
|
|
@@ -264,17 +258,10 @@ var fetch = (url, options = {}) => {
|
|
|
264
258
|
(_b2 = opts.signal) != null ? _b2 : opts.signal = abortCtrl.signal;
|
|
265
259
|
if (validateUrl && !(0, import_core4.isUrlValid)(url, false))
|
|
266
260
|
throw new Error(errMsgs.invalidUrl);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
contentType = ContentType.APPLICATION_JSON;
|
|
272
|
-
}
|
|
273
|
-
const shouldStringifyBody = ["delete", "patch", "post", "put"].includes(
|
|
274
|
-
`${opts.method}`.toLowerCase()
|
|
275
|
-
) && !["undefined", "string"].includes(typeof body) && (0, import_core4.isObj)(body, true) && contentType === ContentType.APPLICATION_JSON;
|
|
276
|
-
if (shouldStringifyBody) opts.body = JSON.stringify(opts.body);
|
|
277
|
-
}
|
|
261
|
+
const stringify = ["delete", "patch", "post", "put"].includes(
|
|
262
|
+
`${opts.method}`.toLowerCase()
|
|
263
|
+
) && !["undefined", "string"].includes(typeof body) && (0, import_core4.isObj)(body, true) && headers.get("content-type") === ContentType.APPLICATION_JSON;
|
|
264
|
+
if (stringify) opts.body = JSON.stringify(opts.body);
|
|
278
265
|
response = await getResponse_default(url, opts);
|
|
279
266
|
response = await executeInterceptors_default(
|
|
280
267
|
response,
|
|
@@ -283,7 +270,7 @@ var fetch = (url, options = {}) => {
|
|
|
283
270
|
url,
|
|
284
271
|
opts
|
|
285
272
|
);
|
|
286
|
-
const status =
|
|
273
|
+
const status = response == null ? void 0 : response.status;
|
|
287
274
|
const isSuccess = status >= 200 && status < 300;
|
|
288
275
|
if (!isSuccess) {
|
|
289
276
|
const jsonError = await (0, import_core4.fallbackIfFails)(
|
|
@@ -311,7 +298,7 @@ var fetch = (url, options = {}) => {
|
|
|
311
298
|
result = await executeInterceptors_default(
|
|
312
299
|
result,
|
|
313
300
|
abortCtrl.signal,
|
|
314
|
-
(
|
|
301
|
+
(_d = opts.interceptors) == null ? void 0 : _d.result,
|
|
315
302
|
url,
|
|
316
303
|
opts
|
|
317
304
|
);
|
|
@@ -325,13 +312,7 @@ var fetch = (url, options = {}) => {
|
|
|
325
312
|
};
|
|
326
313
|
fetch.defaults = {
|
|
327
314
|
abortOnEarlyFinalize: true,
|
|
328
|
-
errMsgs: {
|
|
329
|
-
aborted: "Request aborted",
|
|
330
|
-
invalidUrl: "Invalid URL",
|
|
331
|
-
parseFailed: "Failed to parse response as",
|
|
332
|
-
timedout: "Request timed out",
|
|
333
|
-
requestFailed: "Request failed with status code:"
|
|
334
|
-
},
|
|
315
|
+
errMsgs: { ...defaultErrorMsgs },
|
|
335
316
|
// all error messages must be defined here
|
|
336
317
|
headers: new Headers(),
|
|
337
318
|
interceptors: {
|
|
@@ -379,17 +360,17 @@ var createClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
379
360
|
client.deferred = (deferOptions, defaultUrl, defaultOptions) => {
|
|
380
361
|
let _abortCtrl;
|
|
381
362
|
const fetchCb = (...args) => {
|
|
382
|
-
var _a, _b
|
|
383
|
-
const mergedOptions =
|
|
363
|
+
var _a, _b;
|
|
364
|
+
const mergedOptions = mergeOptions_default(
|
|
384
365
|
fetch_default.defaults,
|
|
385
366
|
commonOptions,
|
|
386
367
|
defaultOptions,
|
|
387
368
|
defaultUrl === void 0 ? args[1] : args[0],
|
|
388
369
|
fixedOptions
|
|
389
370
|
// fixed options will always override other options
|
|
390
|
-
)
|
|
391
|
-
(
|
|
392
|
-
(
|
|
371
|
+
);
|
|
372
|
+
(_a = mergedOptions.as) != null ? _a : mergedOptions.as = "json" /* json */;
|
|
373
|
+
(_b = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _b.call(_abortCtrl);
|
|
393
374
|
_abortCtrl = new AbortController();
|
|
394
375
|
return fetch_default(
|
|
395
376
|
defaultUrl != null ? defaultUrl : args[0],
|
|
@@ -411,7 +392,6 @@ var createPostClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
411
392
|
function client(url, data, options) {
|
|
412
393
|
var _a, _b;
|
|
413
394
|
const mergedOptions = mergeOptions_default(
|
|
414
|
-
fetch_default.defaults,
|
|
415
395
|
commonOptions,
|
|
416
396
|
options,
|
|
417
397
|
fixedOptions
|
|
@@ -420,29 +400,35 @@ var createPostClient = (fixedOptions, commonOptions, commonDeferOptions) => {
|
|
|
420
400
|
(_a = mergedOptions.as) != null ? _a : mergedOptions.as = "json" /* json */;
|
|
421
401
|
mergedOptions.body = data != null ? data : mergedOptions.body;
|
|
422
402
|
(_b = mergedOptions.method) != null ? _b : mergedOptions.method = "post";
|
|
423
|
-
|
|
403
|
+
const headers = mergedOptions.headers;
|
|
404
|
+
if (!headers.get("content-type")) {
|
|
405
|
+
headers.set("content-type", ContentType.APPLICATION_JSON);
|
|
406
|
+
}
|
|
424
407
|
return fetch_default(url, mergedOptions);
|
|
425
408
|
}
|
|
426
409
|
client.deferred = (deferOptions, defaultUrl, defaultData, defaultOptions) => {
|
|
427
410
|
let _abortCtrl;
|
|
428
411
|
const postCb = (...args) => {
|
|
429
|
-
var _a, _b, _c, _d
|
|
412
|
+
var _a, _b, _c, _d;
|
|
430
413
|
if (defaultUrl !== void 0) args.splice(0, 0, defaultUrl);
|
|
431
414
|
if (defaultData !== void 0) args.splice(1, 0, defaultData);
|
|
432
|
-
const mergedOptions =
|
|
415
|
+
const mergedOptions = mergeOptions_default(
|
|
433
416
|
fetch_default.defaults,
|
|
434
417
|
commonOptions,
|
|
435
418
|
defaultOptions,
|
|
436
419
|
args[2],
|
|
437
420
|
fixedOptions
|
|
438
421
|
// fixed options will always override other options
|
|
439
|
-
)
|
|
440
|
-
(
|
|
441
|
-
(
|
|
422
|
+
);
|
|
423
|
+
(_a = mergedOptions.as) != null ? _a : mergedOptions.as = "json" /* json */;
|
|
424
|
+
(_b = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _b.call(_abortCtrl);
|
|
442
425
|
_abortCtrl = new AbortController();
|
|
443
|
-
mergedOptions.body = (
|
|
444
|
-
(
|
|
445
|
-
|
|
426
|
+
mergedOptions.body = (_c = args[1]) != null ? _c : mergedOptions.body;
|
|
427
|
+
(_d = mergedOptions.method) != null ? _d : mergedOptions.method = "post";
|
|
428
|
+
const headers = mergedOptions.headers;
|
|
429
|
+
if (!headers.get("content-type")) {
|
|
430
|
+
headers.set("content-type", ContentType.APPLICATION_JSON);
|
|
431
|
+
}
|
|
446
432
|
return fetch_default(args[0], mergedOptions);
|
|
447
433
|
};
|
|
448
434
|
return (0, import_promise4.deferredCallback)(postCb, {
|
package/dist/index.d.cts
CHANGED
|
@@ -52,7 +52,7 @@ type Interceptor<T, TArgs extends unknown[]> = (...args: [value: T, ...TArgs]) =
|
|
|
52
52
|
*
|
|
53
53
|
* // not returning anything or returning undefined will avoid transforming the error.
|
|
54
54
|
* const logError = fetchErr => console.log(fetchErr)
|
|
55
|
-
* const result = await fetch.get('
|
|
55
|
+
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/http/400', {
|
|
56
56
|
* interceptors: {
|
|
57
57
|
* error: [logError]
|
|
58
58
|
* }
|
|
@@ -71,7 +71,7 @@ type Interceptor<T, TArgs extends unknown[]> = (...args: [value: T, ...TArgs]) =
|
|
|
71
71
|
* fetchErr.message = 'Custom errormessage'
|
|
72
72
|
* return Promise.resolve(fetchErr)
|
|
73
73
|
* }
|
|
74
|
-
* const result = await fetch.get('
|
|
74
|
+
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/http/400', {
|
|
75
75
|
* interceptors: {
|
|
76
76
|
* error: [transformError]
|
|
77
77
|
* }
|
|
@@ -95,7 +95,7 @@ type FetchInterceptorError = Interceptor<FetchError, FetchArgsInterceptor>;
|
|
|
95
95
|
* const includeAuthToken = (url, options) => {
|
|
96
96
|
* options.headers.set('x-auth-token', 'my-auth-token')
|
|
97
97
|
* }
|
|
98
|
-
* const result = await fetch.get('
|
|
98
|
+
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/products', {
|
|
99
99
|
* method: 'post',
|
|
100
100
|
* interceptors: {
|
|
101
101
|
* result: [apiV1ToV2, includeAuthToken]
|
|
@@ -121,12 +121,12 @@ type FetchInterceptorRequest = Interceptor<FetchArgs[0], [
|
|
|
121
121
|
* // just a hypothetical scenario ;)
|
|
122
122
|
* const getUser = async response => {
|
|
123
123
|
* const authResult = await response.json()
|
|
124
|
-
* const userDetails = await fetch.get('
|
|
124
|
+
* const userDetails = await fetch.get('[DUMMYJSON-DOT-COM]/users/1')
|
|
125
125
|
* const userAuth = { ...userDetails, ...authResult }
|
|
126
126
|
* return new Response(JSON.stringify(userAuth))
|
|
127
127
|
* }
|
|
128
128
|
* const user = await fetch.post(
|
|
129
|
-
* '
|
|
129
|
+
* '[DUMMYJSON-DOT-COM]/user/login',
|
|
130
130
|
* { // data/request body
|
|
131
131
|
* username: 'emilys',
|
|
132
132
|
* password: 'emilyspass',
|
|
@@ -179,7 +179,7 @@ type FetchInterceptorResponse = Interceptor<Response, FetchArgsInterceptor>;
|
|
|
179
179
|
* )
|
|
180
180
|
* }
|
|
181
181
|
* // now we make the actaul fetch request
|
|
182
|
-
* const result = await fetch.get('
|
|
182
|
+
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/users/1', {
|
|
183
183
|
* interceptors: {
|
|
184
184
|
* result: [
|
|
185
185
|
* ensureBalanceHex,
|
|
@@ -257,10 +257,8 @@ type ExtractAs<T extends unknown[], //FetchOptions/FetchAs/...
|
|
|
257
257
|
Fallback = FetchAs.json> = T['length'] extends 0 ? Fallback : T[0] extends FetchAs ? T[0] : T[0] extends {
|
|
258
258
|
as: infer OptAs;
|
|
259
259
|
} ? OptAs extends FetchAs ? OptAs : ExtractAs<DropFirst<T>, Fallback> : ExtractAs<DropFirst<T>, Fallback>;
|
|
260
|
-
type ExtractFetchAs<T, TFallback = FetchAs.json> = T extends FetchAs ? T : T extends {
|
|
261
|
-
as: infer As;
|
|
262
|
-
} ? As extends FetchAs ? As : TFallback : TFallback;
|
|
263
260
|
type FetchArgs = [url: string | URL, options?: FetchOptions];
|
|
261
|
+
/** Additional arguments provided to interceptors */
|
|
264
262
|
type FetchArgsInterceptor = [
|
|
265
263
|
url: string | URL,
|
|
266
264
|
options: FetchOptionsInterceptor
|
|
@@ -303,11 +301,6 @@ type FetchCustomOptions = {
|
|
|
303
301
|
/** Whether to validate URL before making the request. Default: `false` */
|
|
304
302
|
validateUrl?: boolean;
|
|
305
303
|
} & FetchRetryOptions & TimeoutOptions<[]>;
|
|
306
|
-
/** Default args */
|
|
307
|
-
type FetchDeferredArgs = [
|
|
308
|
-
url?: string | URL,
|
|
309
|
-
options?: Omit<FetchOptions, 'abortCtrl'>
|
|
310
|
-
];
|
|
311
304
|
type FetchErrMsgs = {
|
|
312
305
|
/** Error message to be used when request is aborted without specifying a message */
|
|
313
306
|
aborted?: string;
|
|
@@ -320,6 +313,7 @@ type FetchErrMsgs = {
|
|
|
320
313
|
/** Error message to be used when request fails */
|
|
321
314
|
requestFailed?: string;
|
|
322
315
|
};
|
|
316
|
+
/** Optional, custom fetch function to replace the built-in `fetch` */
|
|
323
317
|
type FetchFunc = (...args: FetchArgs) => Promise<Response>;
|
|
324
318
|
/**
|
|
325
319
|
* Fetch request options
|
|
@@ -332,17 +326,14 @@ type FetchOptionsDefault = Omit<FetchOptionsInterceptor, 'abortCtrl' | 'as' | 'b
|
|
|
332
326
|
*
|
|
333
327
|
* Deafult:
|
|
334
328
|
* - No default content type set when `fetch()` is directly invoked.
|
|
335
|
-
* -
|
|
336
|
-
* `fetch.post.
|
|
329
|
+
* - Content type `"application/json"` is used as the default for all `createPostClient()`
|
|
330
|
+
* derived functions (eg: `fetch.post()`, `fetch.put()`...),
|
|
337
331
|
*/
|
|
338
332
|
headers: HeadersInit;
|
|
339
333
|
/**
|
|
340
334
|
* Request timeout duration in milliseconds.
|
|
341
335
|
*
|
|
342
|
-
* Default:
|
|
343
|
-
* - `30_000` for `createClient()`, `createPostClient()` and
|
|
344
|
-
* all method specific functions (`fetch.METHOD` & `fetch.METHOD.deferred()`
|
|
345
|
-
* - `2147483647` when `fetch()` invoked directly
|
|
336
|
+
* Default: `60_000`
|
|
346
337
|
*/
|
|
347
338
|
timeout: number;
|
|
348
339
|
};
|
|
@@ -352,7 +343,7 @@ type FetchOptionsDefault = Omit<FetchOptionsInterceptor, 'abortCtrl' | 'as' | 'b
|
|
|
352
343
|
*/
|
|
353
344
|
type FetchOptionsInterceptor = Omit<FetchOptions, 'as' | 'body' | 'errMsgs' | 'interceptors' | 'headers' | 'timeout' | keyof FetchRetryOptions> & {
|
|
354
345
|
as: FetchAs;
|
|
355
|
-
body
|
|
346
|
+
body?: PostBody;
|
|
356
347
|
/** Error messages */
|
|
357
348
|
errMsgs: Required<FetchErrMsgs>;
|
|
358
349
|
headers: Headers;
|
|
@@ -452,7 +443,7 @@ type IPromise_Fetch<T = unknown> = Omit<IPromisE_Timeout<T>, 'abortCtrl'> & {
|
|
|
452
443
|
/**
|
|
453
444
|
* Defines client generic parameter T based on fixed options.
|
|
454
445
|
*
|
|
455
|
-
* If
|
|
446
|
+
* If "fixedOptions.as" is defined and not `FetcAs.json`, then `T` will be `never`.
|
|
456
447
|
*/
|
|
457
448
|
type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ? unknown : never;
|
|
458
449
|
/**
|
|
@@ -489,7 +480,7 @@ type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ?
|
|
|
489
480
|
* )
|
|
490
481
|
*
|
|
491
482
|
* // Use it just like the standard fetch
|
|
492
|
-
* apiClient('
|
|
483
|
+
* apiClient('[DUMMYJSON-DOT-COM]/products/1', {
|
|
493
484
|
* // The 'method' property cannot be overridden as it is used in the fixed options when creating the client.
|
|
494
485
|
* // In TypeScript, the compiler will not allow this property.
|
|
495
486
|
* // In Javascript, it will simply be ignored.
|
|
@@ -500,7 +491,7 @@ type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ?
|
|
|
500
491
|
* // create a deferred client using "apiClient"
|
|
501
492
|
* const deferredClient = apiClient.deferred(
|
|
502
493
|
* { retry: 0 }, // disable retrying by overriding the `retry` defer option
|
|
503
|
-
* '
|
|
494
|
+
* '[DUMMYJSON-DOT-COM]/products/1',
|
|
504
495
|
* { timeout: 3000 },
|
|
505
496
|
* )
|
|
506
497
|
* deferredClient({ timeout: 10000 }) // timeout is overridden by individual request
|
|
@@ -542,7 +533,7 @@ commonOptions?: FetchOptions & CommonOptions, commonDeferOptions?: DeferredAsync
|
|
|
542
533
|
*
|
|
543
534
|
* // Invoking `postClient()` automatically applies the pre-configured options
|
|
544
535
|
* postClient(
|
|
545
|
-
* '
|
|
536
|
+
* '[DUMMYJSON-DOT-COM]/products/add',
|
|
546
537
|
* { title: 'New Product' }, // data/body
|
|
547
538
|
* {}, // other options
|
|
548
539
|
* ).then(console.log)
|
|
@@ -553,7 +544,7 @@ commonOptions?: FetchOptions & CommonOptions, commonDeferOptions?: DeferredAsync
|
|
|
553
544
|
* delay: 300, // debounce duration
|
|
554
545
|
* onResult: console.log, // prints only successful results
|
|
555
546
|
* },
|
|
556
|
-
* '
|
|
547
|
+
* '[DUMMYJSON-DOT-COM]/products/add',
|
|
557
548
|
* { method: 'patch', timeout: 3000 },
|
|
558
549
|
* )
|
|
559
550
|
* updateProduct({ title: 'New title 1' }) // ignored by debounce
|
|
@@ -586,25 +577,6 @@ commonOptions?: PostOptions & CommonOptions, commonDeferOptions?: DeferredAsyncO
|
|
|
586
577
|
*/
|
|
587
578
|
declare const executeInterceptors: <T, TArgs extends unknown[]>(value: T, signal?: AbortSignal, interceptors?: Interceptor<T, TArgs>[], ...args: TArgs) => Promise<T>;
|
|
588
579
|
|
|
589
|
-
/**
|
|
590
|
-
* Extended `fetch` with timeout, retry, and other options. Automatically parses as JSON by default on success.
|
|
591
|
-
*
|
|
592
|
-
* @param url request URL
|
|
593
|
-
* @param options (optional) Standard `fetch` options extended with {@link FetchCustomOptions}.
|
|
594
|
-
* Default "content-type" header is 'application/json'.
|
|
595
|
-
* @param options.as (optional) determines how to parse the result. Default: {@link FetchAs.json}
|
|
596
|
-
* @param options.method (optional) fetch method. Default: `'get'`
|
|
597
|
-
*
|
|
598
|
-
* @example
|
|
599
|
-
* #### Make a simple HTTP requests
|
|
600
|
-
* ```javascript
|
|
601
|
-
* import { fetch } from '@superutils/fetch'
|
|
602
|
-
*
|
|
603
|
-
* // no need for `response.json()` or `result.data.data` drilling
|
|
604
|
-
* fetch.get('https://dummyjson.com/products/1')
|
|
605
|
-
* .then(product => console.log(product))
|
|
606
|
-
* ```
|
|
607
|
-
*/
|
|
608
580
|
declare const fetch$1: {
|
|
609
581
|
<T = unknown, TOptions extends FetchOptions = FetchOptions, TAs extends FetchAs = TOptions["as"] extends FetchAs ? TOptions["as"] : FetchAs.response, TReturn = FetchResult<T>[TAs]>(url: string | URL, options?: FetchOptions & TOptions): IPromise_Fetch<TReturn>;
|
|
610
582
|
/** Default fetch options */
|
|
@@ -865,9 +837,7 @@ declare const methods: {
|
|
|
865
837
|
* @param options.timeout (optional) duration in milliseconds to abort the request.
|
|
866
838
|
* This duration includes the execution of all interceptors/transformers.
|
|
867
839
|
*
|
|
868
|
-
* Default: `
|
|
869
|
-
*
|
|
870
|
-
*
|
|
840
|
+
* Default: `60_000`
|
|
871
841
|
*
|
|
872
842
|
* ---
|
|
873
843
|
*
|
|
@@ -877,7 +847,7 @@ declare const methods: {
|
|
|
877
847
|
* ```javascript
|
|
878
848
|
* import fetch from '@superutils/fetch'
|
|
879
849
|
*
|
|
880
|
-
* fetch('
|
|
850
|
+
* fetch('[DUMMYJSON-DOT-COM]/products/1')
|
|
881
851
|
* .then(response => response.json())
|
|
882
852
|
* .then(console.log, console.error)
|
|
883
853
|
* ```
|
|
@@ -887,14 +857,13 @@ declare const methods: {
|
|
|
887
857
|
* ```javascript
|
|
888
858
|
* import fetch from '@superutils/fetch'
|
|
889
859
|
*
|
|
890
|
-
* // no need for `response.json()` or
|
|
891
|
-
* fetch.get('
|
|
860
|
+
* // no need for `response.json()` or "result.data.data" drilling
|
|
861
|
+
* fetch.get('[DUMMYJSON-DOT-COM]/products/1')
|
|
892
862
|
* .then(product => console.log(product))
|
|
893
|
-
* fetch.post('
|
|
863
|
+
* fetch.post('[DUMMYJSON-DOT-COM]/products/add', { title: 'Product title' })
|
|
894
864
|
* .then(product => console.log(product))
|
|
895
865
|
* ```
|
|
896
866
|
*
|
|
897
|
-
*
|
|
898
867
|
* @example
|
|
899
868
|
* #### Set default options.
|
|
900
869
|
*
|
|
@@ -930,4 +899,4 @@ declare const methods: {
|
|
|
930
899
|
*/
|
|
931
900
|
declare const fetch: typeof fetch$1 & typeof methods;
|
|
932
901
|
|
|
933
|
-
export { type ClientData, ContentType, type ExcludeOptions, type ExcludePostOptions, type ExtractAs, type
|
|
902
|
+
export { type ClientData, ContentType, type ExcludeOptions, type ExcludePostOptions, type ExtractAs, type FetchArgs, type FetchArgsInterceptor, FetchAs, type FetchCustomOptions, type FetchErrMsgs, FetchError, type FetchFunc, type FetchInterceptorError, type FetchInterceptorRequest, type FetchInterceptorResponse, type FetchInterceptorResult, type FetchInterceptors, type FetchInterceptorsMerged, type FetchOptions, type FetchOptionsDefault, type FetchOptionsInterceptor, type FetchResult, type FetchRetryOptions, type GetFetchResult, type IPromise_Fetch, type Interceptor, type PostArgs, type PostBody, type PostDeferredCbArgs, type PostOptions, createClient, createPostClient, fetch as default, executeInterceptors, fetch, mergeOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ type Interceptor<T, TArgs extends unknown[]> = (...args: [value: T, ...TArgs]) =
|
|
|
52
52
|
*
|
|
53
53
|
* // not returning anything or returning undefined will avoid transforming the error.
|
|
54
54
|
* const logError = fetchErr => console.log(fetchErr)
|
|
55
|
-
* const result = await fetch.get('
|
|
55
|
+
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/http/400', {
|
|
56
56
|
* interceptors: {
|
|
57
57
|
* error: [logError]
|
|
58
58
|
* }
|
|
@@ -71,7 +71,7 @@ type Interceptor<T, TArgs extends unknown[]> = (...args: [value: T, ...TArgs]) =
|
|
|
71
71
|
* fetchErr.message = 'Custom errormessage'
|
|
72
72
|
* return Promise.resolve(fetchErr)
|
|
73
73
|
* }
|
|
74
|
-
* const result = await fetch.get('
|
|
74
|
+
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/http/400', {
|
|
75
75
|
* interceptors: {
|
|
76
76
|
* error: [transformError]
|
|
77
77
|
* }
|
|
@@ -95,7 +95,7 @@ type FetchInterceptorError = Interceptor<FetchError, FetchArgsInterceptor>;
|
|
|
95
95
|
* const includeAuthToken = (url, options) => {
|
|
96
96
|
* options.headers.set('x-auth-token', 'my-auth-token')
|
|
97
97
|
* }
|
|
98
|
-
* const result = await fetch.get('
|
|
98
|
+
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/products', {
|
|
99
99
|
* method: 'post',
|
|
100
100
|
* interceptors: {
|
|
101
101
|
* result: [apiV1ToV2, includeAuthToken]
|
|
@@ -121,12 +121,12 @@ type FetchInterceptorRequest = Interceptor<FetchArgs[0], [
|
|
|
121
121
|
* // just a hypothetical scenario ;)
|
|
122
122
|
* const getUser = async response => {
|
|
123
123
|
* const authResult = await response.json()
|
|
124
|
-
* const userDetails = await fetch.get('
|
|
124
|
+
* const userDetails = await fetch.get('[DUMMYJSON-DOT-COM]/users/1')
|
|
125
125
|
* const userAuth = { ...userDetails, ...authResult }
|
|
126
126
|
* return new Response(JSON.stringify(userAuth))
|
|
127
127
|
* }
|
|
128
128
|
* const user = await fetch.post(
|
|
129
|
-
* '
|
|
129
|
+
* '[DUMMYJSON-DOT-COM]/user/login',
|
|
130
130
|
* { // data/request body
|
|
131
131
|
* username: 'emilys',
|
|
132
132
|
* password: 'emilyspass',
|
|
@@ -179,7 +179,7 @@ type FetchInterceptorResponse = Interceptor<Response, FetchArgsInterceptor>;
|
|
|
179
179
|
* )
|
|
180
180
|
* }
|
|
181
181
|
* // now we make the actaul fetch request
|
|
182
|
-
* const result = await fetch.get('
|
|
182
|
+
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/users/1', {
|
|
183
183
|
* interceptors: {
|
|
184
184
|
* result: [
|
|
185
185
|
* ensureBalanceHex,
|
|
@@ -257,10 +257,8 @@ type ExtractAs<T extends unknown[], //FetchOptions/FetchAs/...
|
|
|
257
257
|
Fallback = FetchAs.json> = T['length'] extends 0 ? Fallback : T[0] extends FetchAs ? T[0] : T[0] extends {
|
|
258
258
|
as: infer OptAs;
|
|
259
259
|
} ? OptAs extends FetchAs ? OptAs : ExtractAs<DropFirst<T>, Fallback> : ExtractAs<DropFirst<T>, Fallback>;
|
|
260
|
-
type ExtractFetchAs<T, TFallback = FetchAs.json> = T extends FetchAs ? T : T extends {
|
|
261
|
-
as: infer As;
|
|
262
|
-
} ? As extends FetchAs ? As : TFallback : TFallback;
|
|
263
260
|
type FetchArgs = [url: string | URL, options?: FetchOptions];
|
|
261
|
+
/** Additional arguments provided to interceptors */
|
|
264
262
|
type FetchArgsInterceptor = [
|
|
265
263
|
url: string | URL,
|
|
266
264
|
options: FetchOptionsInterceptor
|
|
@@ -303,11 +301,6 @@ type FetchCustomOptions = {
|
|
|
303
301
|
/** Whether to validate URL before making the request. Default: `false` */
|
|
304
302
|
validateUrl?: boolean;
|
|
305
303
|
} & FetchRetryOptions & TimeoutOptions<[]>;
|
|
306
|
-
/** Default args */
|
|
307
|
-
type FetchDeferredArgs = [
|
|
308
|
-
url?: string | URL,
|
|
309
|
-
options?: Omit<FetchOptions, 'abortCtrl'>
|
|
310
|
-
];
|
|
311
304
|
type FetchErrMsgs = {
|
|
312
305
|
/** Error message to be used when request is aborted without specifying a message */
|
|
313
306
|
aborted?: string;
|
|
@@ -320,6 +313,7 @@ type FetchErrMsgs = {
|
|
|
320
313
|
/** Error message to be used when request fails */
|
|
321
314
|
requestFailed?: string;
|
|
322
315
|
};
|
|
316
|
+
/** Optional, custom fetch function to replace the built-in `fetch` */
|
|
323
317
|
type FetchFunc = (...args: FetchArgs) => Promise<Response>;
|
|
324
318
|
/**
|
|
325
319
|
* Fetch request options
|
|
@@ -332,17 +326,14 @@ type FetchOptionsDefault = Omit<FetchOptionsInterceptor, 'abortCtrl' | 'as' | 'b
|
|
|
332
326
|
*
|
|
333
327
|
* Deafult:
|
|
334
328
|
* - No default content type set when `fetch()` is directly invoked.
|
|
335
|
-
* -
|
|
336
|
-
* `fetch.post.
|
|
329
|
+
* - Content type `"application/json"` is used as the default for all `createPostClient()`
|
|
330
|
+
* derived functions (eg: `fetch.post()`, `fetch.put()`...),
|
|
337
331
|
*/
|
|
338
332
|
headers: HeadersInit;
|
|
339
333
|
/**
|
|
340
334
|
* Request timeout duration in milliseconds.
|
|
341
335
|
*
|
|
342
|
-
* Default:
|
|
343
|
-
* - `30_000` for `createClient()`, `createPostClient()` and
|
|
344
|
-
* all method specific functions (`fetch.METHOD` & `fetch.METHOD.deferred()`
|
|
345
|
-
* - `2147483647` when `fetch()` invoked directly
|
|
336
|
+
* Default: `60_000`
|
|
346
337
|
*/
|
|
347
338
|
timeout: number;
|
|
348
339
|
};
|
|
@@ -352,7 +343,7 @@ type FetchOptionsDefault = Omit<FetchOptionsInterceptor, 'abortCtrl' | 'as' | 'b
|
|
|
352
343
|
*/
|
|
353
344
|
type FetchOptionsInterceptor = Omit<FetchOptions, 'as' | 'body' | 'errMsgs' | 'interceptors' | 'headers' | 'timeout' | keyof FetchRetryOptions> & {
|
|
354
345
|
as: FetchAs;
|
|
355
|
-
body
|
|
346
|
+
body?: PostBody;
|
|
356
347
|
/** Error messages */
|
|
357
348
|
errMsgs: Required<FetchErrMsgs>;
|
|
358
349
|
headers: Headers;
|
|
@@ -452,7 +443,7 @@ type IPromise_Fetch<T = unknown> = Omit<IPromisE_Timeout<T>, 'abortCtrl'> & {
|
|
|
452
443
|
/**
|
|
453
444
|
* Defines client generic parameter T based on fixed options.
|
|
454
445
|
*
|
|
455
|
-
* If
|
|
446
|
+
* If "fixedOptions.as" is defined and not `FetcAs.json`, then `T` will be `never`.
|
|
456
447
|
*/
|
|
457
448
|
type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ? unknown : never;
|
|
458
449
|
/**
|
|
@@ -489,7 +480,7 @@ type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ?
|
|
|
489
480
|
* )
|
|
490
481
|
*
|
|
491
482
|
* // Use it just like the standard fetch
|
|
492
|
-
* apiClient('
|
|
483
|
+
* apiClient('[DUMMYJSON-DOT-COM]/products/1', {
|
|
493
484
|
* // The 'method' property cannot be overridden as it is used in the fixed options when creating the client.
|
|
494
485
|
* // In TypeScript, the compiler will not allow this property.
|
|
495
486
|
* // In Javascript, it will simply be ignored.
|
|
@@ -500,7 +491,7 @@ type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ?
|
|
|
500
491
|
* // create a deferred client using "apiClient"
|
|
501
492
|
* const deferredClient = apiClient.deferred(
|
|
502
493
|
* { retry: 0 }, // disable retrying by overriding the `retry` defer option
|
|
503
|
-
* '
|
|
494
|
+
* '[DUMMYJSON-DOT-COM]/products/1',
|
|
504
495
|
* { timeout: 3000 },
|
|
505
496
|
* )
|
|
506
497
|
* deferredClient({ timeout: 10000 }) // timeout is overridden by individual request
|
|
@@ -542,7 +533,7 @@ commonOptions?: FetchOptions & CommonOptions, commonDeferOptions?: DeferredAsync
|
|
|
542
533
|
*
|
|
543
534
|
* // Invoking `postClient()` automatically applies the pre-configured options
|
|
544
535
|
* postClient(
|
|
545
|
-
* '
|
|
536
|
+
* '[DUMMYJSON-DOT-COM]/products/add',
|
|
546
537
|
* { title: 'New Product' }, // data/body
|
|
547
538
|
* {}, // other options
|
|
548
539
|
* ).then(console.log)
|
|
@@ -553,7 +544,7 @@ commonOptions?: FetchOptions & CommonOptions, commonDeferOptions?: DeferredAsync
|
|
|
553
544
|
* delay: 300, // debounce duration
|
|
554
545
|
* onResult: console.log, // prints only successful results
|
|
555
546
|
* },
|
|
556
|
-
* '
|
|
547
|
+
* '[DUMMYJSON-DOT-COM]/products/add',
|
|
557
548
|
* { method: 'patch', timeout: 3000 },
|
|
558
549
|
* )
|
|
559
550
|
* updateProduct({ title: 'New title 1' }) // ignored by debounce
|
|
@@ -586,25 +577,6 @@ commonOptions?: PostOptions & CommonOptions, commonDeferOptions?: DeferredAsyncO
|
|
|
586
577
|
*/
|
|
587
578
|
declare const executeInterceptors: <T, TArgs extends unknown[]>(value: T, signal?: AbortSignal, interceptors?: Interceptor<T, TArgs>[], ...args: TArgs) => Promise<T>;
|
|
588
579
|
|
|
589
|
-
/**
|
|
590
|
-
* Extended `fetch` with timeout, retry, and other options. Automatically parses as JSON by default on success.
|
|
591
|
-
*
|
|
592
|
-
* @param url request URL
|
|
593
|
-
* @param options (optional) Standard `fetch` options extended with {@link FetchCustomOptions}.
|
|
594
|
-
* Default "content-type" header is 'application/json'.
|
|
595
|
-
* @param options.as (optional) determines how to parse the result. Default: {@link FetchAs.json}
|
|
596
|
-
* @param options.method (optional) fetch method. Default: `'get'`
|
|
597
|
-
*
|
|
598
|
-
* @example
|
|
599
|
-
* #### Make a simple HTTP requests
|
|
600
|
-
* ```javascript
|
|
601
|
-
* import { fetch } from '@superutils/fetch'
|
|
602
|
-
*
|
|
603
|
-
* // no need for `response.json()` or `result.data.data` drilling
|
|
604
|
-
* fetch.get('https://dummyjson.com/products/1')
|
|
605
|
-
* .then(product => console.log(product))
|
|
606
|
-
* ```
|
|
607
|
-
*/
|
|
608
580
|
declare const fetch$1: {
|
|
609
581
|
<T = unknown, TOptions extends FetchOptions = FetchOptions, TAs extends FetchAs = TOptions["as"] extends FetchAs ? TOptions["as"] : FetchAs.response, TReturn = FetchResult<T>[TAs]>(url: string | URL, options?: FetchOptions & TOptions): IPromise_Fetch<TReturn>;
|
|
610
582
|
/** Default fetch options */
|
|
@@ -865,9 +837,7 @@ declare const methods: {
|
|
|
865
837
|
* @param options.timeout (optional) duration in milliseconds to abort the request.
|
|
866
838
|
* This duration includes the execution of all interceptors/transformers.
|
|
867
839
|
*
|
|
868
|
-
* Default: `
|
|
869
|
-
*
|
|
870
|
-
*
|
|
840
|
+
* Default: `60_000`
|
|
871
841
|
*
|
|
872
842
|
* ---
|
|
873
843
|
*
|
|
@@ -877,7 +847,7 @@ declare const methods: {
|
|
|
877
847
|
* ```javascript
|
|
878
848
|
* import fetch from '@superutils/fetch'
|
|
879
849
|
*
|
|
880
|
-
* fetch('
|
|
850
|
+
* fetch('[DUMMYJSON-DOT-COM]/products/1')
|
|
881
851
|
* .then(response => response.json())
|
|
882
852
|
* .then(console.log, console.error)
|
|
883
853
|
* ```
|
|
@@ -887,14 +857,13 @@ declare const methods: {
|
|
|
887
857
|
* ```javascript
|
|
888
858
|
* import fetch from '@superutils/fetch'
|
|
889
859
|
*
|
|
890
|
-
* // no need for `response.json()` or
|
|
891
|
-
* fetch.get('
|
|
860
|
+
* // no need for `response.json()` or "result.data.data" drilling
|
|
861
|
+
* fetch.get('[DUMMYJSON-DOT-COM]/products/1')
|
|
892
862
|
* .then(product => console.log(product))
|
|
893
|
-
* fetch.post('
|
|
863
|
+
* fetch.post('[DUMMYJSON-DOT-COM]/products/add', { title: 'Product title' })
|
|
894
864
|
* .then(product => console.log(product))
|
|
895
865
|
* ```
|
|
896
866
|
*
|
|
897
|
-
*
|
|
898
867
|
* @example
|
|
899
868
|
* #### Set default options.
|
|
900
869
|
*
|
|
@@ -930,4 +899,4 @@ declare const methods: {
|
|
|
930
899
|
*/
|
|
931
900
|
declare const fetch: typeof fetch$1 & typeof methods;
|
|
932
901
|
|
|
933
|
-
export { type ClientData, ContentType, type ExcludeOptions, type ExcludePostOptions, type ExtractAs, type
|
|
902
|
+
export { type ClientData, ContentType, type ExcludeOptions, type ExcludePostOptions, type ExtractAs, type FetchArgs, type FetchArgsInterceptor, FetchAs, type FetchCustomOptions, type FetchErrMsgs, FetchError, type FetchFunc, type FetchInterceptorError, type FetchInterceptorRequest, type FetchInterceptorResponse, type FetchInterceptorResult, type FetchInterceptors, type FetchInterceptorsMerged, type FetchOptions, type FetchOptionsDefault, type FetchOptionsInterceptor, type FetchResult, type FetchRetryOptions, type GetFetchResult, type IPromise_Fetch, type Interceptor, type PostArgs, type PostBody, type PostDeferredCbArgs, type PostOptions, createClient, createPostClient, fetch as default, executeInterceptors, fetch, mergeOptions };
|