@superutils/fetch 1.0.3 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,7 +20,7 @@ This package enhances the native `fetch` API by providing a streamlined interfac
20
20
  - **Simplified API**: Automatically parses JSON responses, eliminating the need for `.then(res => res.json())`.
21
21
  - **Built-in Retries**: Automatic request retries with configurable exponential or fixed backoff strategies.
22
22
  - **Request Timeouts**: Easily specify a timeout for any request to prevent it from hanging indefinitely.
23
- - **Cancellable & Debounced Requests**: The `fetchDeferred` utility provides debouncing and throttling capabilities, automatically cancelling stale or intermediate requests. This is ideal for features like live search inputs.
23
+ - **Cancellable & Debounced Requests**: The `fetch.METHOD.deferred()` utilities provide debouncing and throttling capabilities, automatically cancelling stale or intermediate requests. This is ideal for features like live search inputs.
24
24
  - **Interceptors**: Hook into the request/response lifecycle to globally modify requests, handle responses, or manage errors.
25
25
  - **Strongly Typed**: Written in TypeScript for excellent autocompletion and type safety.
26
26
  - **Isomorphic**: Works seamlessly in both Node.js and browser environments.
@@ -42,13 +42,13 @@ Make a simple GET request. No need for `response.json()` or `result.data.theActu
42
42
  ```typescript
43
43
  import fetch from '@superutils/fetch'
44
44
 
45
- const theActualData = await fetch('https://dummyjson.com/products/1', {
45
+ fetch('https://dummyjson.com/products/1', {
46
46
  method: 'get', // default
47
- })
48
- console.log(theActualData)
47
+ }).then(theActualData => console.log(theActualData))
49
48
  // Alternative:
50
- const theActualData2 = await fetch.get('https://dummyjson.com/products/1')
51
- console.log(theActualData2)
49
+ fetch
50
+ .get('https://dummyjson.com/products/1')
51
+ .then(theActualData => console.log(theActualData))
52
52
  ```
53
53
 
54
54
  <div id="methods"></div>
@@ -81,13 +81,13 @@ While `fetch()` provides access to all HTTP request methods by specifying it in
81
81
 
82
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.
83
83
 
84
- ```typescript
85
- import fetch, { fetchDeferred, ResolveIgnored } from '@superutils/fetch'
84
+ ```javascript
85
+ import fetch from '@superutils/fetch'
86
86
 
87
87
  // Create a debounced search function with a 300ms delay.
88
88
  const searchProducts = fetch.get.deferred({
89
89
  delayMs: 300, // Debounce delay
90
- resolveIgnored: ResolveIgnored.WITH_UNDEFINED, // Ignored (aborted) promises will resolve with `undefined`
90
+ resolveIgnored: 'WITH_UNDEFINED', // Ignored (aborted) promises will resolve with `undefined`
91
91
  })
92
92
 
93
93
  // User types 'iphone'
@@ -97,34 +97,34 @@ searchProducts('https://dummyjson.com/products/search?q=iphone').then(
97
97
  },
98
98
  )
99
99
 
100
- // Before 300ms has passed, the user continues typing 'iphone 9'
100
+ // Before 300ms has passed, the user continues typing 'iphone 12'
101
101
  setTimeout(() => {
102
- searchProducts('https://dummyjson.com/products/search?q=iphone 9').then(
102
+ searchProducts('https://dummyjson.com/products/search?q=iphone 12').then(
103
103
  result => {
104
- console.log('Result for "iphone 9":', result)
104
+ console.log('Result for "iphone 12":', result)
105
105
  },
106
106
  )
107
107
  }, 200)
108
108
  // Outcome:
109
109
  // The first request for "iphone" is aborted.
110
110
  // The first promise resolves with `undefined`.
111
- // The second request for "iphone 9" is executed after the 300ms debounce delay.
111
+ // The second request for "iphone 12" is executed after the 300ms debounce delay.
112
112
  ```
113
113
 
114
114
  **Behavior with different `deferOptions` in the example above:**
115
115
 
116
116
  - **`throttle: true`**: Switches from debounce to throttle mode. The first request for "iphone" would
117
- execute immediately. The second request for "iphone 9", made within the 300ms throttle window, would be ignored.
117
+ execute immediately. The second request for "iphone 12", made within the 300ms throttle window, would be ignored.
118
118
  - **`delayMs: 0`**: Disables debouncing and throttling, enabling sequential/queue mode. Both requests ("iphone"
119
- and "iphone 9") would execute, but one after the other, never simultaneously.
120
- - **`resolveIgnored`**: Controls how the promise for an aborted request (like the first "iphone" call) resolves.
119
+ and "iphone 12") would execute, but one after the other, never simultaneously.
120
+ - **`resolveIgnored` (enum)**: Controls how the promise for an aborted request (like the first "iphone" call) resolves.
121
121
  1. `ResolveIgnored.WITH_UNDEFINED` (used in the example): The promise for the aborted "iphone"
122
122
  request resolves with `undefined`.
123
123
  2. `ResolveIgnored.WITH_LAST`: The promise for the aborted "iphone" request waits and resolves with the result
124
- of the final "iphone 9" request. Both promises resolve to the same value.
124
+ of the final "iphone 12" request. Both promises resolve to the same value.
125
125
  3. `ResolveIgnored.NEVER`: The promise for the aborted "iphone" request is neither resolved nor rejected.
126
126
  It will remain pending indefinitely.
127
- - **`resolveError`**: Controls how failed requests are handled.
127
+ - **`resolveError` (enum)**: Controls how failed requests are handled.
128
128
  1. `ResolveError.NEVER`: Never resolve ignored promises. Caution: make sure this doesn't cause any memory leaks.
129
129
  2. `ResolveError.WITH_LAST`: (default) resolve with active promise result, the one that caused the current promise/callback to be ignored.
130
130
  3. `ResolveError.WITH_UNDEFINED`: resolve failed requests with `undefined` value
@@ -132,8 +132,8 @@ setTimeout(() => {
132
132
 
133
133
  #### Using defaults to reduce redundancy
134
134
 
135
- ```typescript
136
- import fetch, { ResolveIgnored } from '@superutils/fetch'
135
+ ```javascript
136
+ import fetch from '@superutils/fetch'
137
137
 
138
138
  // Create a throttled function to fetch a random quote.
139
139
  // The URL and a 3-second timeout are set as defaults, creating a reusable client.
@@ -142,16 +142,16 @@ const getRandomQuote = fetch.get.deferred(
142
142
  delayMs: 300, // Throttle window
143
143
  throttle: true,
144
144
  // Ignored calls will resolve with the result of the last successful call.
145
- resolveIgnored: ResolveIgnored.WITH_LAST,
145
+ resolveIgnored: 'WITH_LAST',
146
146
  },
147
147
  'https://dummyjson.com/quotes/random', // Default URL
148
148
  { timeout: 3000 }, // Default fetch options
149
149
  )
150
150
 
151
151
  // Call the function multiple times in quick succession.
152
- getRandomQuote().then(quote => console.log('Call 1 resolved:', quote.id))
153
- getRandomQuote().then(quote => console.log('Call 2 resolved:', quote.id))
154
- getRandomQuote().then(quote => console.log('Call 3 resolved:', quote.id))
152
+ getRandomQuote().then(quote => console.log('Call 1 resolved:', quote))
153
+ getRandomQuote().then(quote => console.log('Call 2 resolved:', quote))
154
+ getRandomQuote().then(quote => console.log('Call 3 resolved:', quote))
155
155
 
156
156
  // Outcome:
157
157
  // Due to throttling, only one network request is made.
@@ -197,19 +197,19 @@ const saveProductThrottled = fetch.post.deferred(
197
197
  trailing: true, // Ensures the very last update is always saved
198
198
  onResult: product => console.log(`[Saved] Product: ${product.title}`),
199
199
  },
200
- 'https://dummyjson.com/products/1', // Default URL
201
- undefined, // No default data
202
- { method: 'put' }, // Default method
200
+ 'https://dummyjson.com/products/add', // Default URL
203
201
  )
204
202
  // Simulate a user typing quickly, triggering multiple saves.
205
203
  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
204
+
205
+ // Executed immediately (leading edge)
206
+ saveProductThrottled({ title: 'iPhone' })
207
+ // Ignored (within 1000ms throttle window)
208
+ PromisE.delay(200, () => saveProductThrottled({ title: 'iPhone 15' }))
209
+ // Ignored
210
+ PromisE.delay(300, () => saveProductThrottled({ title: 'iPhone 15 Pro' }))
211
+ // Queued to execute on the trailing edge
212
+ PromisE.delay(400, () => saveProductThrottled({ title: 'iPhone 15 Pro Max' }))
213
213
  // Outcome:
214
214
  // The first call ('iPhone') is executed immediately.
215
215
  // The next two calls are ignored by the throttle.
@@ -231,11 +231,11 @@ let currentRefreshToken = ''
231
231
  const requestNewToken = fetch.post.deferred(
232
232
  {
233
233
  delayMs: 300, // debounce delay
234
- onResult: ({ token = '' }) => {
234
+ onResult: ({ refreshToken = '' }) => {
235
235
  console.log(
236
236
  `Auth token successfully refreshed at ${new Date().toISOString()}`,
237
237
  )
238
- currentRefreshToken = token
238
+ currentRefreshToken = refreshToken
239
239
  },
240
240
  },
241
241
  'https://dummyjson.com/auth/refresh', // Default URL
package/dist/index.d.ts CHANGED
@@ -282,6 +282,7 @@ type PostArgs<OmitMethod = false> = [
282
282
  options?: OmitMethod extends true ? Omit<FetchOptions, 'method'> : PostOptions
283
283
  ];
284
284
  /**
285
+ * Dynamic arguments for deffered post-like methods.
285
286
  *
286
287
  * @example
287
288
  * ```typescript
@@ -311,7 +312,7 @@ type PostArgs<OmitMethod = false> = [
311
312
  * f4().then(console.log, console.warn)
312
313
  * ```
313
314
  */
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;
315
+ type PostDeferredCbArgs<TUrl = undefined, TData = undefined, OmitMethod extends boolean = true, CbArgs extends PostArgs<OmitMethod> = PostArgs<OmitMethod>, Options = CbArgs[2], CbArgsReq extends unknown[] = Required<CbArgs>> = [TUrl, TData] extends [CbArgsReq[0], undefined] ? [data?: CbArgs[1], options?: Options] : [TUrl, TData] extends [undefined, CbArgsReq[1]] ? [url: CbArgs[0], options?: Options] : [TUrl, TData] extends [CbArgsReq[0], CbArgsReq[1]] ? [options?: Options] : CbArgs;
315
316
  type PostOptions = Omit<FetchOptions, 'method'> & {
316
317
  /** Default: `'post'` */
317
318
  method?: 'post' | 'put' | 'patch' | 'delete' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
@@ -333,7 +334,7 @@ declare const fetch$1: {
333
334
  *
334
335
  * @param deferOptions Configuration for the deferred execution behavior (e.g., `delayMs`, `throttle`).
335
336
  * See {@link DeferredAsyncOptions} for details.
336
- * @param globalUrl (optional) If a global URL is `undefined`, returned callback will always require an URL.
337
+ * @param defaultUrl (optional) If a global URL is `undefined`, returned callback will always require an URL.
337
338
  * @param defaultOptions (optional) Default {@link FetchOptions} to be used by the returned function.
338
339
  * Default options will be merged with the options provided in the callback.
339
340
  * If the same property is provided in both cases, defaults will be overriden by the callback.
@@ -366,20 +367,6 @@ declare const fetch$1: {
366
367
  * // The second request for "iphone 9" is executed after the 300ms debounce delay.
367
368
  * ```
368
369
  *
369
- * **Behavior with different `deferOptions` in the example above:**
370
- * - **`throttle: true`**: Switches from debounce to throttle mode. The first request for "iphone" would
371
- * execute immediately. The second request for "iphone 9", made within the 300ms throttle window, would be ignored.
372
- * - **`delayMs: 0`**: Disables debouncing and throttling, enabling sequential/queue mode. Both requests ("iphone"
373
- * and "iphone 9") would execute, but one after the other, never simultaneously.
374
- * - **`resolveIgnored`**: Controls how the promise for an aborted request (like the first "iphone" call) resolves.
375
- * 1. `ResolveIgnored.WITH_UNDEFINED` (used in the example): The promise for the aborted "iphone"
376
- * request resolves with `undefined`.
377
- * 2. `ResolveIgnored.WITH_LAST`: The promise for the aborted "iphone" request waits and resolves with the result
378
- * of the final "iphone 9" request. Both promises resolve to the same value.
379
- * 3. `ResolveIgnored.NEVER`: The promise for the aborted "iphone" request is neither resolved nor rejected.
380
- * It will remain pending indefinitely.
381
- * 4. `ResolveIgnored.WITH_ERROR`: The promise for the aborted "iphone" request is rejected with a `FetchError`.
382
- *
383
370
  * @example Creating a reusable, pre-configured client
384
371
  * ```typescript
385
372
  * import { fetchDeferred, ResolveIgnored } from '@superutils/fetch'
@@ -409,7 +396,7 @@ declare const fetch$1: {
409
396
  * // Console output will show the same quote ID for all three calls.
410
397
  * ```
411
398
  */
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>;
399
+ declare function fetchDeferred<ThisArg = unknown, Delay extends number = number, DefaultUrl = FetchArgs[0] | undefined, CbArgs extends unknown[] = undefined extends DefaultUrl ? FetchArgs<false> : [options?: FetchArgs<false>[1]]>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, defaultUrl?: DefaultUrl, defaultOptions?: FetchArgs[1]): <TResult = unknown>(...args: CbArgs) => _superutils_promise.IPromisE<TResult>;
413
400
 
414
401
  /**
415
402
  * Creates a deferred/throttled function for making `DELETE`, `POST`, `PUT`, or `PATCH` requests, powered by
@@ -423,8 +410,8 @@ declare function fetchDeferred<ThisArg = unknown, Delay extends number = number,
423
410
  *
424
411
  * @param deferOptions Configuration for the deferred execution behavior (e.g., `delayMs`, `throttle`).
425
412
  * See {@link DeferredAsyncOptions} for details.
426
- * @param globalUrl (optional) If global URL is `undefined`, returned callback will always require an URL.
427
- * @param globalData (optional) If global data is `undefined`, returned callback will allow a data parameter.
413
+ * @param defaultUrl (optional) If default URL is `undefined`, returned callback will always require an URL.
414
+ * @param defaultData (optional) If default data is `undefined`, returned callback will allow a data parameter.
428
415
  * @param defaultOptions (optional) Default {@link FetchOptions} to be used by the returned function.
429
416
  * Default options will be merged with the options provided in the callback.
430
417
  * If the same property is provided in both cases, defaults will be overriden by the callback.
@@ -510,7 +497,7 @@ declare function fetchDeferred<ThisArg = unknown, Delay extends number = number,
510
497
  * // The token is refreshed only once, preventing redundant network requests.
511
498
  * ```
512
499
  */
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>;
500
+ declare function postDeferred<ThisArg, Delay extends number = number, DefaultUrl extends PostArgs[0] | undefined = undefined, DefaultData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<DefaultUrl, DefaultData, false>>(deferOptions?: DeferredAsyncOptions<ThisArg, Delay>, defaultUrl?: DefaultUrl, defaultData?: DefaultData, defaultOptions?: PostArgs[2]): <TResult = unknown>(...args: CbArgs) => _superutils_promise.IPromisE<TResult>;
514
501
 
515
502
  /**
516
503
  * Merge one or more {@link FetchOptions}
@@ -528,34 +515,43 @@ declare function postDeferred<ThisArg, Delay extends number = number, GlobalUrl
528
515
  */
529
516
  declare const mergeFetchOptions: (...allOptions: FetchOptions[]) => FetchOptionsInterceptor;
530
517
 
531
- type FetchWithoutMethods = typeof fetch$1;
518
+ /** Create a method-specific fetch function attached with a `.deferred()` function */
519
+ declare const createFetchMethodFunc: (method?: string) => {
520
+ <T>(url: string | URL, options?: Omit<FetchOptions, "method">): _superutils_promise.IPromisE<T>;
521
+ deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
522
+ };
523
+ /** Create a method-specific function for POST-like methods and with a `.deferred()` function */
524
+ declare const createPostMethodFunc: (method?: Pick<PostOptions, "method">["method"]) => {
525
+ <T, Args extends PostArgs<true> = PostArgs<true>>(url: Args[0], data?: Args[1], options?: Args[2]): _superutils_promise.IPromisE<T>;
526
+ deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
527
+ };
532
528
  declare const _get: {
533
529
  <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>;
530
+ deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
535
531
  };
536
532
  declare const _head: {
537
533
  <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>;
534
+ deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
539
535
  };
540
536
  declare const _options: {
541
537
  <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>;
538
+ deferred<ThisArg = unknown, Delay extends number = number, GlobalUrl = string | URL | undefined, CbArgs extends unknown[] = undefined extends GlobalUrl ? FetchArgs<true> : [options?: Omit<FetchOptions, "method"> | undefined]>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultOptions?: FetchOptions | undefined): <TResult = unknown>(...args: undefined extends GlobalUrl ? FetchArgs<false> : [options?: FetchOptions | undefined]) => _superutils_promise.IPromisE<TResult>;
543
539
  };
544
540
  declare const _delete: {
545
541
  <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>;
542
+ deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
547
543
  };
548
544
  declare const _patch: {
549
545
  <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>;
546
+ deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
551
547
  };
552
548
  declare const _post: {
553
549
  <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>;
550
+ deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
555
551
  };
556
552
  declare const _put: {
557
553
  <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>;
554
+ deferred<ThisArg, Delay extends number = number, GlobalUrl extends PostArgs[0] | undefined = undefined, GlobalData extends PostArgs[1] | undefined = undefined, CbArgs extends unknown[] = PostDeferredCbArgs<GlobalUrl, GlobalData, true>>(deferOptions?: _superutils_promise.DeferredAsyncOptions<ThisArg, Delay> | undefined, defaultUrl?: GlobalUrl | undefined, defaultData?: GlobalData | undefined, defaultOptions?: PostOptions | undefined): <TResult = unknown>(...args: PostDeferredCbArgs<GlobalUrl, GlobalData, false, PostArgs<false>, PostOptions | undefined, [url: string | URL, data: PostBody | (() => PostBody), options: PostOptions]>) => _superutils_promise.IPromisE<TResult>;
559
555
  };
560
556
  /**
561
557
  * @function fetch
@@ -606,6 +602,8 @@ declare const _put: {
606
602
  * Options' default values (excluding `method` and `retryIf`) can be configured to be EFFECTIVE GLOBALLY.
607
603
  *
608
604
  * ```typescript
605
+ * import fetch from '@superutils/fetch'
606
+ *
609
607
  * fetch.defaults = {
610
608
  * as: FetchAs.json,
611
609
  * errMsgs: {
@@ -622,15 +620,16 @@ declare const _put: {
622
620
  * result: [],
623
621
  * },
624
622
  * timeout: 0,
625
- * ........
623
+ * //........
626
624
  * }
627
625
  * ```
628
- * @param options.abortCtrl (optional) if not provided `AbortController` will be instantiated when `timeout` used.
629
- * @param options.headers (optional) request headers. Default: `{ 'content-type' : 'application/json'}`
630
- * @param options.interceptors (optional) request interceptor callbacks. See {@link FetchInterceptors} for details.
631
- * @param options.method (optional) Default: `"get"`
632
- * @param options.timeout (optional) duration in milliseconds to abort the request if it takes longer.
633
- * @param options.parse (optional) specify how to parse the result.
626
+ *
627
+ * @property options.abortCtrl (optional) if not provided `AbortController` will be instantiated when `timeout` used.
628
+ * @property options.headers (optional) request headers. Default: `{ 'content-type' : 'application/json'}`
629
+ * @property options.interceptors (optional) request interceptor callbacks. See {@link FetchInterceptors} for details.
630
+ * @property options.method (optional) Default: `"get"`
631
+ * @property options.timeout (optional) duration in milliseconds to abort the request if it takes longer.
632
+ * @property options.parse (optional) specify how to parse the result.
634
633
  * Default: {@link FetchAs.json}
635
634
  * For raw `Response` use {@link FetchAs.response}
636
635
  *
@@ -643,13 +642,13 @@ declare const _put: {
643
642
  * ```
644
643
  */
645
644
  declare const fetch: typeof fetch$1 & {
645
+ delete: typeof _delete;
646
646
  get: typeof _get;
647
647
  head: typeof _head;
648
648
  options: typeof _options;
649
- delete: typeof _delete;
650
649
  patch: typeof _patch;
651
650
  post: typeof _post;
652
651
  put: typeof _put;
653
652
  };
654
653
 
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 };
654
+ export { type FetchArgs, type FetchArgsInterceptor, FetchAs, type FetchCustomOptions, type FetchDeferredArgs, type FetchErrMsgs, FetchError, type FetchInterceptorError, type FetchInterceptorRequest, type FetchInterceptorResponse, type FetchInterceptorResult, type FetchInterceptors, type FetchOptions, type FetchOptionsDefaults, type FetchOptionsInterceptor, type FetchResult, type FetchRetryOptions, type Interceptor, type PostArgs, type PostBody, type PostDeferredCbArgs, type PostOptions, createFetchMethodFunc, createPostMethodFunc, fetch as default, fetch, fetchDeferred, mergeFetchOptions, postDeferred };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/fetch.ts
2
2
  import {
3
+ fallbackIfFails as fallbackIfFails2,
3
4
  isEmpty as isEmpty2,
4
5
  isFn as isFn2,
5
6
  isPositiveNumber,
@@ -90,6 +91,10 @@ var mergeFetchOptions = (...allOptions) => allOptions.reduce(
90
91
  var mergeFetchOptions_default = mergeFetchOptions;
91
92
 
92
93
  // src/types.ts
94
+ import {
95
+ ResolveError,
96
+ ResolveIgnored
97
+ } from "@superutils/promise";
93
98
  var FetchAs = /* @__PURE__ */ ((FetchAs2) => {
94
99
  FetchAs2["arrayBuffer"] = "arrayBuffer";
95
100
  FetchAs2["blob"] = "blob";
@@ -147,7 +152,13 @@ var fetch = (url, options = {}) => {
147
152
  const { status = 0 } = response;
148
153
  const isSuccess = status >= 200 && status < 300;
149
154
  if (!isSuccess) {
150
- const jsonError = await response.json();
155
+ const jsonError = await fallbackIfFails2(
156
+ // try to parse error response as json first
157
+ () => response.json(),
158
+ [],
159
+ // fallback to text if json parsing fails
160
+ `Request failed with status code: ${status}`
161
+ );
151
162
  const message = (jsonError == null ? void 0 : jsonError.message) || `${errMsgs.requestFailed} ${status}.`;
152
163
  throw new Error(`${message}`.replace("Error: ", ""), {
153
164
  cause: jsonError
@@ -223,23 +234,17 @@ var fetch_default = fetch;
223
234
 
224
235
  // src/fetchDeferred.ts
225
236
  import PromisE3 from "@superutils/promise";
226
- import {
227
- ResolveError,
228
- ResolveIgnored
229
- } from "@superutils/promise";
230
- function fetchDeferred(deferOptions = {}, globalUrl, defaultOptions) {
237
+ function fetchDeferred(deferOptions = {}, defaultUrl, defaultOptions) {
231
238
  let _abortCtrl;
232
239
  const fetchCallback = (...args) => {
233
240
  var _a, _b, _c;
234
- let options = {
235
- ...(_a = globalUrl === void 0 ? args[1] : args[0]) != null ? _a : {}
236
- };
241
+ let options = (_a = defaultUrl === void 0 ? args[1] : args[0]) != null ? _a : {};
237
242
  if (defaultOptions) options = mergeFetchOptions_default(defaultOptions, options);
238
243
  (_b = options.abortCtrl) != null ? _b : options.abortCtrl = new AbortController();
239
244
  (_c = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _c.call(_abortCtrl);
240
245
  _abortCtrl = options.abortCtrl;
241
246
  const promise = fetch_default(
242
- globalUrl != null ? globalUrl : args[0],
247
+ defaultUrl != null ? defaultUrl : args[0],
243
248
  options
244
249
  );
245
250
  promise.onEarlyFinalize.push(() => _abortCtrl == null ? void 0 : _abortCtrl.abort());
@@ -268,23 +273,21 @@ function post(...[url = "", data, options = {}]) {
268
273
  }
269
274
 
270
275
  // src/postDeferred.ts
271
- import {
272
- ResolveError as ResolveError2,
273
- ResolveIgnored as ResolveIgnored2
274
- } from "@superutils/promise";
275
- function postDeferred(deferOptions = {}, globalUrl, globalData, defaultOptions) {
276
+ function postDeferred(deferOptions = {}, defaultUrl, defaultData, defaultOptions) {
276
277
  let _abortCtrl;
277
278
  const doPost = (...args) => {
278
279
  var _a, _b, _c;
279
- if (globalUrl !== void 0) args.splice(0, 0, globalUrl);
280
- if (globalData !== void 0) args.splice(1, 0, globalData);
281
- const url = args[0];
282
- const data = args[1];
280
+ if (defaultUrl !== void 0) args.splice(0, 0, defaultUrl);
281
+ if (defaultData !== void 0) args.splice(1, 0, defaultData);
283
282
  const options = mergeFetchOptions_default(defaultOptions != null ? defaultOptions : {}, (_a = args[2]) != null ? _a : {});
284
283
  (_b = options.abortCtrl) != null ? _b : options.abortCtrl = new AbortController();
285
284
  (_c = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _c.call(_abortCtrl);
286
285
  _abortCtrl = options.abortCtrl;
287
- const promise = post(url, data, options);
286
+ const promise = post(
287
+ args[0],
288
+ args[1],
289
+ options
290
+ );
288
291
  promise.onEarlyFinalize.push(() => _abortCtrl == null ? void 0 : _abortCtrl.abort());
289
292
  return promise;
290
293
  };
@@ -294,32 +297,31 @@ var postDeferred_default = postDeferred;
294
297
 
295
298
  // src/index.ts
296
299
  var createFetchMethodFunc = (method = "get") => {
297
- const deferred = (...args) => fetchDeferred_default(...args);
298
300
  const methodFunc = (url, options) => {
299
301
  options != null ? options : options = {};
300
302
  options.method = method;
301
303
  return fetch_default(url, options);
302
304
  };
303
- methodFunc.deferred = deferred;
305
+ methodFunc.deferred = (...args) => {
306
+ var _a;
307
+ (_a = args[2]) != null ? _a : args[2] = {};
308
+ args[2].method = method;
309
+ return fetchDeferred_default(...args);
310
+ };
304
311
  return methodFunc;
305
312
  };
306
313
  var createPostMethodFunc = (method = "post") => {
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
314
  const methodFunc = (url, data, options) => {
318
315
  options != null ? options : options = {};
319
316
  options.method = method;
320
317
  return post(url, data, options);
321
318
  };
322
- methodFunc.deferred = deferredFunc;
319
+ methodFunc.deferred = (...args) => {
320
+ var _a;
321
+ (_a = args[3]) != null ? _a : args[3] = {};
322
+ args[3].method = method;
323
+ return postDeferred_default(...args);
324
+ };
323
325
  return methodFunc;
324
326
  };
325
327
  var _get = createFetchMethodFunc("get");
@@ -330,10 +332,10 @@ var _patch = createPostMethodFunc("patch");
330
332
  var _post = createPostMethodFunc("post");
331
333
  var _put = createPostMethodFunc("put");
332
334
  var fetch2 = fetch_default;
335
+ fetch2.delete = _delete;
333
336
  fetch2.get = _get;
334
337
  fetch2.head = _head;
335
338
  fetch2.options = _options;
336
- fetch2.delete = _delete;
337
339
  fetch2.patch = _patch;
338
340
  fetch2.post = _post;
339
341
  fetch2.put = _put;
@@ -341,6 +343,10 @@ var index_default = fetch2;
341
343
  export {
342
344
  FetchAs,
343
345
  FetchError,
346
+ ResolveError,
347
+ ResolveIgnored,
348
+ createFetchMethodFunc,
349
+ createPostMethodFunc,
344
350
  index_default as default,
345
351
  fetch2 as fetch,
346
352
  fetchDeferred,
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.0.8",
9
- "@superutils/promise": "^1.0.9"
8
+ "@superutils/core": "^1.1.1",
9
+ "@superutils/promise": "^1.1.1"
10
10
  },
11
11
  "files": [
12
12
  "dist",
@@ -24,8 +24,8 @@
24
24
  "main": "dist/index.js",
25
25
  "name": "@superutils/fetch",
26
26
  "peerDependencies": {
27
- "@superutils/core": "^1.0.8",
28
- "@superutils/promise": "^1.0.9"
27
+ "@superutils/core": "^1.1.1",
28
+ "@superutils/promise": "^1.1.1"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"
@@ -45,5 +45,5 @@
45
45
  "sideEffects": false,
46
46
  "type": "module",
47
47
  "types": "dist/index.d.ts",
48
- "version": "1.0.3"
48
+ "version": "1.1.1"
49
49
  }