@superutils/fetch 1.2.2 → 1.2.3

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/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import PromisE3 from "@superutils/promise";
3
3
 
4
4
  // src/fetch.ts
5
5
  import {
6
- fallbackIfFails as fallbackIfFails2,
6
+ fallbackIfFails as fallbackIfFails3,
7
7
  isFn as isFn2,
8
8
  isPositiveNumber,
9
9
  isPromise,
@@ -13,9 +13,9 @@ import PromisE2 from "@superutils/promise";
13
13
 
14
14
  // src/executeInterceptors.ts
15
15
  import { fallbackIfFails, isFn } from "@superutils/core";
16
- var executeInterceptors = async (value, interceptors = [], ...args) => {
16
+ var executeInterceptors = async (value, interceptors, ...args) => {
17
17
  var _a;
18
- for (const interceptor of [...interceptors || []].filter(isFn)) {
18
+ for (const interceptor of [...interceptors != null ? interceptors : []].filter(isFn)) {
19
19
  value = (_a = await fallbackIfFails(
20
20
  interceptor,
21
21
  [value, ...args],
@@ -26,10 +26,28 @@ var executeInterceptors = async (value, interceptors = [], ...args) => {
26
26
  };
27
27
  var executeInterceptors_default = executeInterceptors;
28
28
 
29
+ // src/getAbortCtrl.ts
30
+ var getAbortCtrl = (options) => {
31
+ options != null ? options : options = {};
32
+ if (!(options.abortCtrl instanceof AbortController))
33
+ options.abortCtrl = new AbortController();
34
+ const { abortCtrl, signal } = options;
35
+ if (signal instanceof AbortSignal && !signal.aborted) {
36
+ const handleAbort = () => abortCtrl.abort();
37
+ signal.addEventListener("abort", handleAbort, { once: true });
38
+ abortCtrl.signal.addEventListener(
39
+ "abort",
40
+ () => signal.removeEventListener("abort", handleAbort),
41
+ { once: true }
42
+ );
43
+ }
44
+ return abortCtrl;
45
+ };
46
+
29
47
  // src/getResponse.ts
48
+ import { fallbackIfFails as fallbackIfFails2, isPositiveInteger } from "@superutils/core";
30
49
  import PromisE from "@superutils/promise";
31
- import { isPositiveInteger } from "@superutils/core";
32
- var getResponse = async (...[url, options = {}]) => {
50
+ var getResponse = async (url, options = {}) => {
33
51
  const fetchFunc = globalThis.fetch;
34
52
  if (!isPositiveInteger(options.retry))
35
53
  return fetchFunc(url, options);
@@ -41,9 +59,14 @@ var getResponse = async (...[url, options = {}]) => {
41
59
  },
42
60
  {
43
61
  ...options,
44
- retryIf: async (res, count) => {
45
- var _a;
46
- return (res == null ? void 0 : res.ok) === false || await ((_a = options == null ? void 0 : options.retryIf) == null ? void 0 : _a.call(options, res, count)) === true;
62
+ retryIf: async (res, count, error) => {
63
+ var _a, _b;
64
+ const failed = !!error || !(res == null ? void 0 : res.ok);
65
+ return !!((_b = await fallbackIfFails2(
66
+ (_a = options == null ? void 0 : options.retryIf) != null ? _a : failed,
67
+ [res, count, error],
68
+ failed
69
+ )) != null ? _b : failed);
47
70
  }
48
71
  }
49
72
  ).catch(
@@ -58,21 +81,22 @@ var getResponse = async (...[url, options = {}]) => {
58
81
  var getResponse_default = getResponse;
59
82
 
60
83
  // src/mergeFetchOptions.ts
61
- import { isEmpty, objKeys } from "@superutils/core";
84
+ import { isEmpty, isObj, objKeys } from "@superutils/core";
62
85
  var mergeFetchOptions = (...allOptions) => allOptions.reduce(
63
- (o1, o2) => {
86
+ (merged, next) => {
64
87
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
65
- const { errMsgs = {}, headers, interceptors: ints1 = {} } = o1;
66
- const { errMsgs: msgs2 = {}, interceptors: ints2 = {} } = o2;
67
- o2.headers && new Headers(o2.headers).forEach((value, key) => {
88
+ next = isObj(next) ? next : {};
89
+ const { errMsgs = {}, headers, interceptors: ints1 = {} } = merged;
90
+ const { errMsgs: msgs2 = {}, interceptors: ints2 = {} } = next;
91
+ next.headers && new Headers(next.headers).forEach((value, key) => {
68
92
  headers && headers.set(key, value);
69
93
  });
70
94
  for (const key of objKeys(msgs2)) {
71
95
  if (!isEmpty(msgs2[key])) errMsgs[key] = msgs2[key];
72
96
  }
73
97
  return {
74
- ...o1,
75
- ...o2,
98
+ ...merged,
99
+ ...next,
76
100
  errMsgs,
77
101
  headers,
78
102
  interceptors: {
@@ -90,7 +114,7 @@ var mergeFetchOptions = (...allOptions) => allOptions.reduce(
90
114
  ...(_h = ints2 == null ? void 0 : ints2.result) != null ? _h : []
91
115
  ]
92
116
  },
93
- timeout: (_j = (_i = o2.timeout) != null ? _i : o1.timeout) != null ? _j : 0
117
+ timeout: (_j = (_i = next.timeout) != null ? _i : merged.timeout) != null ? _j : 0
94
118
  };
95
119
  },
96
120
  { headers: new Headers() }
@@ -106,6 +130,21 @@ import {
106
130
  ResolveError,
107
131
  ResolveIgnored
108
132
  } from "@superutils/promise";
133
+ var ContentType = {
134
+ APPLICATION_JAVASCRIPT: "application/javascript",
135
+ APPLICATION_JSON: "application/json",
136
+ APPLICATION_OCTET_STREAM: "application/octet-stream",
137
+ APPLICATION_PDF: "application/pdf",
138
+ APPLICATION_X_WWW_FORM_URLENCODED: "application/x-www-form-urlencoded",
139
+ APPLICATION_XML: "application/xml",
140
+ APPLICATION_ZIP: "application/zip",
141
+ AUDIO_MPEG: "audio/mpeg",
142
+ MULTIPART_FORM_DATA: "multipart/form-data",
143
+ TEXT_CSS: "text/css",
144
+ TEXT_HTML: "text/html",
145
+ TEXT_PLAIN: "text/plain",
146
+ VIDEO_MP4: "video/mp4"
147
+ };
109
148
  var FetchAs = /* @__PURE__ */ ((FetchAs2) => {
110
149
  FetchAs2["arrayBuffer"] = "arrayBuffer";
111
150
  FetchAs2["blob"] = "blob";
@@ -134,19 +173,23 @@ var FetchError = class _FetchError extends Error {
134
173
 
135
174
  // src/fetch.ts
136
175
  var fetch = (url, options = {}) => {
137
- let abortCtrl;
138
176
  let timeoutId;
177
+ const abortCtrl = getAbortCtrl(options);
139
178
  const promise = new PromisE2(async (resolve, reject) => {
140
179
  var _a, _b, _c;
141
180
  let errResponse;
142
- const _options2 = mergeFetchOptions_default(fetch.defaults, options);
143
- (_a = _options2.as) != null ? _a : _options2.as = "json" /* json */;
144
- (_b = _options2.method) != null ? _b : _options2.method = "get";
145
- _options2.abortCtrl = _options2.abortCtrl instanceof AbortController ? _options2.abortCtrl : new AbortController();
181
+ const _options = mergeFetchOptions_default(fetch.defaults, options);
182
+ (_a = _options.as) != null ? _a : _options.as = "json" /* json */;
183
+ (_b = _options.method) != null ? _b : _options.method = "get";
184
+ let contentType = _options.headers.get("content-type");
185
+ if (!contentType) {
186
+ _options.headers.set("content-type", ContentType.APPLICATION_JSON);
187
+ contentType = ContentType.APPLICATION_JSON;
188
+ }
146
189
  url = await executeInterceptors_default(
147
190
  url,
148
- _options2.interceptors.request,
149
- _options2
191
+ _options.interceptors.request,
192
+ _options
150
193
  );
151
194
  const {
152
195
  as: parseAs,
@@ -154,35 +197,35 @@ var fetch = (url, options = {}) => {
154
197
  errMsgs,
155
198
  timeout,
156
199
  validateUrl = true
157
- } = _options2;
200
+ } = _options;
158
201
  if (isPositiveNumber(timeout)) {
159
- timeoutId = setTimeout(() => {
160
- var _a2;
161
- return (_a2 = _options2.abortCtrl) == null ? void 0 : _a2.abort();
162
- }, timeout);
202
+ timeoutId = setTimeout(() => abortCtrl.abort(), timeout);
163
203
  }
164
- abortCtrl = _options2.abortCtrl;
165
- if (_options2.abortCtrl) _options2.signal = _options2.abortCtrl.signal;
204
+ if (_options.abortCtrl) _options.signal = _options.abortCtrl.signal;
166
205
  try {
167
206
  if (validateUrl && !isUrlValid(url, false))
168
207
  throw new Error(errMsgs.invalidUrl);
169
- if (!["undefined", "string"].includes(typeof body))
170
- _options2.body = JSON.stringify(
171
- isFn2(body) ? fallbackIfFails2(body, [], void 0) : body
208
+ const shouldStringifyBody = [
209
+ ContentType.APPLICATION_JSON,
210
+ ContentType.APPLICATION_X_WWW_FORM_URLENCODED
211
+ ].find((x) => contentType.includes(x)) && !["undefined", "string"].includes(typeof body);
212
+ if (shouldStringifyBody)
213
+ _options.body = JSON.stringify(
214
+ isFn2(body) ? fallbackIfFails3(body, [], void 0) : body
172
215
  );
173
- let response = await getResponse_default(url, _options2);
216
+ let response = await getResponse_default(url, _options);
174
217
  response = await executeInterceptors_default(
175
218
  response,
176
- _options2.interceptors.response,
219
+ _options.interceptors.response,
177
220
  url,
178
- _options2
221
+ _options
179
222
  );
180
223
  errResponse = response;
181
224
  const { status = 0 } = response;
182
225
  const isSuccess = status >= 200 && status < 300;
183
226
  if (!isSuccess) {
184
227
  const fallbackMsg = `${errMsgs.requestFailed} ${status}`;
185
- const jsonError = await fallbackIfFails2(
228
+ const jsonError = await fallbackIfFails3(
186
229
  // try to parse error response as json first
187
230
  () => response.json(),
188
231
  [],
@@ -208,9 +251,9 @@ var fetch = (url, options = {}) => {
208
251
  }
209
252
  result = await executeInterceptors_default(
210
253
  result,
211
- _options2.interceptors.result,
254
+ _options.interceptors.result,
212
255
  url,
213
- _options2
256
+ _options
214
257
  );
215
258
  resolve(result);
216
259
  } catch (err) {
@@ -219,20 +262,20 @@ var fetch = (url, options = {}) => {
219
262
  let error = new FetchError(msg, {
220
263
  cause: (_c = errX == null ? void 0 : errX.cause) != null ? _c : err,
221
264
  response: errResponse,
222
- options: _options2,
265
+ options: _options,
223
266
  url
224
267
  });
225
268
  error = await executeInterceptors_default(
226
269
  error,
227
- _options2.interceptors.error,
270
+ _options.interceptors.error,
228
271
  url,
229
- _options2
272
+ _options
230
273
  );
231
274
  reject(error);
232
275
  }
233
276
  timeoutId && clearTimeout(timeoutId);
234
277
  });
235
- promise.onEarlyFinalize.push(() => abortCtrl == null ? void 0 : abortCtrl.abort());
278
+ promise.onEarlyFinalize.push(() => abortCtrl.abort());
236
279
  return promise;
237
280
  };
238
281
  fetch.defaults = {
@@ -243,7 +286,7 @@ fetch.defaults = {
243
286
  requestFailed: "Request failed with status code:"
244
287
  },
245
288
  // all error messages must be defined here
246
- headers: new Headers([["content-type", "application/json"]]),
289
+ headers: new Headers(),
247
290
  /** Global interceptors for fetch requests */
248
291
  interceptors: {
249
292
  /**
@@ -263,14 +306,14 @@ fetch.defaults = {
263
306
  var fetch_default = fetch;
264
307
 
265
308
  // src/createClient.ts
266
- var createClient = (mandatoryOptions, commonOptions, commonDeferOptions) => {
309
+ var createClient = (fixedOptions, commonOptions, commonDeferOptions) => {
267
310
  const func = (url, options) => {
268
311
  return fetch_default(
269
312
  url,
270
313
  mergePartialOptions(
271
314
  commonOptions,
272
315
  options,
273
- mandatoryOptions
316
+ fixedOptions
274
317
  )
275
318
  );
276
319
  };
@@ -282,11 +325,10 @@ var createClient = (mandatoryOptions, commonOptions, commonDeferOptions) => {
282
325
  commonOptions,
283
326
  defaultOptions,
284
327
  defaultUrl === void 0 ? args[1] : args[0],
285
- mandatoryOptions
328
+ fixedOptions
286
329
  );
287
- (_a = options.abortCtrl) != null ? _a : options.abortCtrl = new AbortController();
288
- (_b = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _b.call(_abortCtrl);
289
- _abortCtrl = options.abortCtrl;
330
+ ((_a = _abortCtrl == null ? void 0 : _abortCtrl.signal) == null ? void 0 : _a.aborted) === false && ((_b = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _b.call(_abortCtrl));
331
+ _abortCtrl = getAbortCtrl(options);
290
332
  const promise = fetch_default(
291
333
  defaultUrl != null ? defaultUrl : args[0],
292
334
  options
@@ -305,19 +347,19 @@ var createClient_default = createClient;
305
347
 
306
348
  // src/createPostClient.ts
307
349
  import PromisE4 from "@superutils/promise";
308
- var createPostClient = (mandatoryOptions, commonOptions, commonDeferOptions) => {
309
- const func = (url, data, options) => {
350
+ var createPostClient = (fixedOptions, commonOptions, commonDeferOptions) => {
351
+ const client2 = (url, data, options) => {
310
352
  var _a;
311
- const _options2 = mergePartialOptions(
353
+ const _options = mergePartialOptions(
312
354
  commonOptions,
313
355
  options,
314
- mandatoryOptions
356
+ fixedOptions
315
357
  );
316
- _options2.body = data;
317
- (_a = _options2.method) != null ? _a : _options2.method = "post";
318
- return fetch_default(url, _options2);
358
+ _options.body = data;
359
+ (_a = _options.method) != null ? _a : _options.method = "post";
360
+ return fetch_default(url, _options);
319
361
  };
320
- func.deferred = (deferOptions = {}, defaultUrl, defaultData, defaultOptions) => {
362
+ client2.deferred = (deferOptions = {}, defaultUrl, defaultData, defaultOptions) => {
321
363
  let _abortCtrl;
322
364
  const postCb = (...args) => {
323
365
  var _a, _b, _c, _d;
@@ -327,11 +369,10 @@ var createPostClient = (mandatoryOptions, commonOptions, commonDeferOptions) =>
327
369
  commonOptions,
328
370
  defaultOptions,
329
371
  args[2],
330
- mandatoryOptions
372
+ fixedOptions
331
373
  );
332
- (_a = options.abortCtrl) != null ? _a : options.abortCtrl = new AbortController();
333
- (_b = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _b.call(_abortCtrl);
334
- _abortCtrl = options.abortCtrl;
374
+ ((_a = _abortCtrl == null ? void 0 : _abortCtrl.signal) == null ? void 0 : _a.aborted) === false && ((_b = _abortCtrl == null ? void 0 : _abortCtrl.abort) == null ? void 0 : _b.call(_abortCtrl));
375
+ _abortCtrl = getAbortCtrl(options);
335
376
  options.body = (_c = args[1]) != null ? _c : options.body;
336
377
  (_d = options.method) != null ? _d : options.method = "post";
337
378
  const promise = fetch_default(args[0], options);
@@ -343,27 +384,38 @@ var createPostClient = (mandatoryOptions, commonOptions, commonDeferOptions) =>
343
384
  ...deferOptions
344
385
  });
345
386
  };
346
- return func;
387
+ return client2;
347
388
  };
348
389
  var createPostClient_default = createPostClient;
390
+ var client = createPostClient();
391
+ client.deferred();
349
392
 
350
393
  // src/fetchResponse.ts
351
- var fetchResponse = (...args) => {
352
- var _a, _b, _c;
353
- (_a = args[1]) != null ? _a : args[1] = {};
354
- (_c = (_b = args[1]).as) != null ? _c : _b.as = "response" /* response */;
355
- return fetch_default(...args);
394
+ var fetchResponse = (url, options) => {
395
+ var _a;
396
+ options != null ? options : options = {};
397
+ (_a = options.as) != null ? _a : options.as = "response" /* response */;
398
+ return fetch_default(url, options);
356
399
  };
357
400
  var fetchResponse_default = fetchResponse;
358
401
 
359
402
  // src/fetchDefault.ts
360
- var _get = createClient_default({ method: "get" });
361
- var _head = createClient_default({ method: "head" });
362
- var _options = createClient_default({ method: "options" });
363
- var _delete = createPostClient_default({ method: "delete" });
364
- var _patch = createPostClient_default({ method: "patch" });
365
- var _post = createPostClient_default({ method: "post" });
366
- var _put = createPostClient_default({ method: "put" });
403
+ var methods = {
404
+ /** Make HTTP requests with method GET */
405
+ get: createClient_default({ method: "get" }),
406
+ /** Make HTTP requests with method HEAD */
407
+ head: createClient_default({ method: "head" }),
408
+ /** Make HTTP requests with method OPTIONS */
409
+ options: createClient_default({ method: "options" }),
410
+ /** Make HTTP requests with method DELETE */
411
+ delete: createPostClient_default({ method: "delete" }),
412
+ /** Make HTTP requests with method PATCH */
413
+ patch: createPostClient_default({ method: "patch" }),
414
+ /** Make HTTP requests with method POST */
415
+ post: createPostClient_default({ method: "post" }),
416
+ /** Make HTTP requests with method PUT */
417
+ put: createPostClient_default({ method: "put" })
418
+ };
367
419
  var fetchDefault = fetchResponse_default;
368
420
  Object.defineProperty(fetchDefault, "defaults", {
369
421
  get() {
@@ -373,18 +425,20 @@ Object.defineProperty(fetchDefault, "defaults", {
373
425
  fetch_default.defaults = newDefaults;
374
426
  }
375
427
  });
376
- fetchDefault.delete = _delete;
377
- fetchDefault.get = _get;
378
- fetchDefault.head = _head;
379
- fetchDefault.options = _options;
380
- fetchDefault.patch = _patch;
381
- fetchDefault.post = _post;
382
- fetchDefault.put = _put;
428
+ fetchDefault.delete = methods.delete;
429
+ fetchDefault.get = methods.get;
430
+ fetchDefault.head = methods.head;
431
+ fetchDefault.options = methods.options;
432
+ fetchDefault.patch = methods.patch;
433
+ fetchDefault.post = methods.post;
434
+ fetchDefault.put = methods.put;
383
435
  var fetchDefault_default = fetchDefault;
384
436
 
385
437
  // src/index.ts
386
438
  var index_default = fetchDefault_default;
439
+ fetchDefault_default.get;
387
440
  export {
441
+ ContentType,
388
442
  FetchAs,
389
443
  FetchError,
390
444
  ResolveError,
@@ -392,8 +446,11 @@ export {
392
446
  createClient,
393
447
  createPostClient,
394
448
  index_default as default,
449
+ executeInterceptors,
395
450
  fetch,
396
451
  fetchResponse,
452
+ getAbortCtrl,
453
+ getResponse,
397
454
  mergeFetchOptions,
398
455
  mergePartialOptions
399
456
  };
package/package.json CHANGED
@@ -5,8 +5,8 @@
5
5
  },
6
6
  "description": "A lightweight `fetch` wrapper for browsers and Node.js, designed to simplify data fetching and reduce boilerplate.",
7
7
  "dependencies": {
8
- "@superutils/core": "^1.1.5",
9
- "@superutils/promise": "^1.1.5"
8
+ "@superutils/core": "^1.1.6",
9
+ "@superutils/promise": "^1.1.6"
10
10
  },
11
11
  "files": [
12
12
  "dist",
@@ -24,8 +24,8 @@
24
24
  "main": "dist/index.js",
25
25
  "name": "@superutils/fetch",
26
26
  "peerDependencies": {
27
- "@superutils/core": "^1.1.5",
28
- "@superutils/promise": "^1.1.5"
27
+ "@superutils/core": "^1.1.6",
28
+ "@superutils/promise": "^1.1.6"
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.2.2"
48
+ "version": "1.2.3"
49
49
  }