enhance-axios 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,670 @@
1
+ "use strict";
2
+ var EnhanceAxios = (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ createEnhanceInstance: () => createEnhanceInstance,
25
+ defaultRetryCondition: () => defaultRetryCondition,
26
+ getFormData: () => getFormData,
27
+ hash: () => hash,
28
+ version: () => version
29
+ });
30
+
31
+ // src/axios-shim.ts
32
+ var axios_shim_default = window.axios;
33
+
34
+ // src/core/requestManager.ts
35
+ var RequestManager = class {
36
+ constructor() {
37
+ this.preventPending = /* @__PURE__ */ new Map();
38
+ this.cancelPending = /* @__PURE__ */ new Map();
39
+ }
40
+ /**
41
+ * 注册一个新请求
42
+ */
43
+ registerRequest(key, type, controller, promise, config) {
44
+ const pending = {
45
+ key,
46
+ config: config || {},
47
+ controller,
48
+ promise,
49
+ timestamp: Date.now()
50
+ };
51
+ (type === "prevent" ? this.preventPending : this.cancelPending).set(key, pending);
52
+ }
53
+ /**
54
+ * 移除请求记录
55
+ */
56
+ unregisterRequest(key, type) {
57
+ (type === "prevent" ? this.preventPending : this.cancelPending).delete(key);
58
+ }
59
+ /**
60
+ * 取消并移除请求,同时检查两个 Map
61
+ */
62
+ cancelRequest(key) {
63
+ let cancelled = false;
64
+ const abort = (map) => {
65
+ const req = map.get(key);
66
+ if (req) {
67
+ try {
68
+ req.controller.abort("Cancelled by cancelRequest");
69
+ } catch {
70
+ }
71
+ map.delete(key);
72
+ cancelled = true;
73
+ }
74
+ };
75
+ abort(this.preventPending);
76
+ abort(this.cancelPending);
77
+ return cancelled;
78
+ }
79
+ /**
80
+ * 获取请求状态(优先返回 preventPending)
81
+ */
82
+ getRequestStatus(key) {
83
+ return this.preventPending.get(key) ?? this.cancelPending.get(key);
84
+ }
85
+ getPreventPending(key) {
86
+ return this.preventPending.get(key);
87
+ }
88
+ getCancelPending(key) {
89
+ return this.cancelPending.get(key);
90
+ }
91
+ /**
92
+ * 清空所有 pending 请求
93
+ */
94
+ clearAll() {
95
+ const abortAll = (map, reason) => {
96
+ for (const req of map.values()) {
97
+ try {
98
+ req.controller.abort(reason);
99
+ } catch {
100
+ }
101
+ }
102
+ map.clear();
103
+ };
104
+ abortAll(this.preventPending, "Cleared by clearAll");
105
+ abortAll(this.cancelPending, "Cleared by clearAll");
106
+ }
107
+ /**
108
+ * 获取 pending 数量(注意两 Map 独立,合计可能重复计数)
109
+ */
110
+ getPendingCount() {
111
+ return {
112
+ prevent: this.preventPending.size,
113
+ cancel: this.cancelPending.size,
114
+ total: this.preventPending.size + this.cancelPending.size
115
+ };
116
+ }
117
+ /**
118
+ * 获取所有 pending 的 key
119
+ */
120
+ getPendingKeys() {
121
+ return {
122
+ prevent: Array.from(this.preventPending.keys()),
123
+ cancel: Array.from(this.cancelPending.keys())
124
+ };
125
+ }
126
+ };
127
+
128
+ // src/utils/common.ts
129
+ function isPlainObject(value) {
130
+ if (typeof value !== "object" || value === null) return false;
131
+ if (Array.isArray(value)) return false;
132
+ if (value instanceof Blob) return false;
133
+ if (value instanceof Date) return false;
134
+ if (typeof FormData !== "undefined" && value instanceof FormData) return false;
135
+ if (typeof Map !== "undefined" && value instanceof Map) return false;
136
+ if (typeof Set !== "undefined" && value instanceof Set) return false;
137
+ return true;
138
+ }
139
+
140
+ // src/utils/keyGenerator.ts
141
+ function toPlain(value) {
142
+ if (value == null) return value;
143
+ if (typeof URLSearchParams !== "undefined" && value instanceof URLSearchParams) {
144
+ return Object.fromEntries(value);
145
+ }
146
+ return value;
147
+ }
148
+ function getNestedValue(obj, path) {
149
+ if (!path) return obj;
150
+ const normalized = path.replace(/\[(\d+)\]/g, ".$1");
151
+ return normalized.split(".").reduce(
152
+ (o, k) => o == null ? void 0 : o[k],
153
+ obj
154
+ );
155
+ }
156
+ function resolveTemplate(template, config) {
157
+ const context = {
158
+ method: config.method?.toUpperCase() || "GET",
159
+ url: config.url || "",
160
+ params: toPlain(config.params),
161
+ data: toPlain(config.data)
162
+ };
163
+ return template.replace(/\$\{([^}]+)\}/g, (_match, path) => {
164
+ const value = getNestedValue(context, path);
165
+ if (value == null) return "";
166
+ if (typeof value === "object") return JSON.stringify(value);
167
+ return String(value);
168
+ });
169
+ }
170
+ function generateDefaultKey(config) {
171
+ const parts = [
172
+ config.method?.toUpperCase() || "GET",
173
+ config.url || "",
174
+ config.params != null ? JSON.stringify(sortObject(stripCacheParam(toPlain(config.params)))) : "",
175
+ config.data != null ? JSON.stringify(sortObject(stripCacheParam(toPlain(config.data)))) : ""
176
+ ];
177
+ return hash(parts.join("|"));
178
+ }
179
+ function hash(str) {
180
+ let h = 2166136261;
181
+ for (let i = 0; i < str.length; i++) {
182
+ h ^= str.charCodeAt(i);
183
+ h = h * 16777619 >>> 0;
184
+ }
185
+ return h.toString(16).padStart(8, "0");
186
+ }
187
+ function resolveRequestKey(config, keyTemplate) {
188
+ if (!keyTemplate) return generateDefaultKey(config);
189
+ if (typeof keyTemplate === "function") {
190
+ return keyTemplate(config, hash);
191
+ }
192
+ if (typeof keyTemplate === "string" && keyTemplate.includes("${")) {
193
+ return hash(resolveTemplate(keyTemplate, config));
194
+ }
195
+ return keyTemplate;
196
+ }
197
+ function stripCacheParam(obj) {
198
+ if (obj == null || typeof obj !== "object") return obj;
199
+ if (Array.isArray(obj)) return obj;
200
+ if (!isPlainObject(obj)) return obj;
201
+ const { _, ...rest } = obj;
202
+ return rest;
203
+ }
204
+ function sortObject(obj) {
205
+ if (obj == null || typeof obj !== "object") return obj;
206
+ if (Array.isArray(obj)) return obj.map(sortObject);
207
+ if (!isPlainObject(obj)) return obj;
208
+ const sorted = {};
209
+ const keys = Object.keys(obj).sort();
210
+ for (const key of keys) {
211
+ sorted[key] = sortObject(obj[key]);
212
+ }
213
+ return sorted;
214
+ }
215
+
216
+ // src/utils/formData.ts
217
+ function appendValue(fd, key, value) {
218
+ if (value == null) return;
219
+ if (value instanceof File) {
220
+ fd.append(key, value);
221
+ } else if (value instanceof Blob) {
222
+ fd.append(key, value);
223
+ } else if (value instanceof Date) {
224
+ fd.append(key, value.toISOString());
225
+ } else if (Array.isArray(value)) {
226
+ for (const item of value) {
227
+ appendValue(fd, key, item);
228
+ }
229
+ } else if (isPlainObject(value)) {
230
+ for (const [subKey, subValue] of Object.entries(value)) {
231
+ appendValue(fd, `${key}.${subKey}`, subValue);
232
+ }
233
+ } else {
234
+ fd.append(key, String(value));
235
+ }
236
+ }
237
+ function getFormData(data, fieldName) {
238
+ const fd = new FormData();
239
+ if (data == null) return fd;
240
+ if (typeof FileList !== "undefined" && data instanceof FileList) {
241
+ const key = fieldName || "file";
242
+ for (let i = 0; i < data.length; i++) fd.append(key, data[i]);
243
+ return fd;
244
+ }
245
+ if (isPlainObject(data)) {
246
+ for (const [key, value] of Object.entries(data)) {
247
+ appendValue(fd, key, value);
248
+ }
249
+ return fd;
250
+ }
251
+ appendValue(fd, fieldName || "file", data);
252
+ return fd;
253
+ }
254
+
255
+ // src/types/index.ts
256
+ var CONTENT_TYPE_MAP = {
257
+ json: "application/json;charset=UTF-8",
258
+ form: "application/x-www-form-urlencoded"
259
+ };
260
+
261
+ // src/core/index.ts
262
+ var DEFAULT_PREVENT_CONFIG = {
263
+ enabled: true,
264
+ methods: ["POST", "PUT", "PATCH", "DELETE"],
265
+ intervalMs: 1e3
266
+ };
267
+ var DEFAULT_CANCEL_CONFIG = {
268
+ enabled: true,
269
+ methods: ["GET"]
270
+ };
271
+ function defaultRetryCondition(error) {
272
+ if (!error.response) {
273
+ return true;
274
+ }
275
+ const status = error.response.status;
276
+ if (status === 408 || status === 429) {
277
+ return true;
278
+ }
279
+ if (status >= 500 && status < 600) {
280
+ return true;
281
+ }
282
+ return false;
283
+ }
284
+ var DEFAULT_RETRY_CONFIG = {
285
+ enabled: true,
286
+ retries: 3,
287
+ retryDelay: 1e3,
288
+ retryCondition: defaultRetryCondition,
289
+ exponential: true,
290
+ maxDelay: 3e4
291
+ };
292
+ function shouldApply(method, methods) {
293
+ if (methods == null) return true;
294
+ if (methods.length === 0) return false;
295
+ return methods.includes(method?.toUpperCase() || "GET");
296
+ }
297
+ function calculateRetryDelay(retryConfig, retryCount) {
298
+ let delay = retryConfig.retryDelay;
299
+ if (retryConfig.exponential) {
300
+ delay = Math.min(
301
+ retryConfig.retryDelay * Math.pow(2, retryCount),
302
+ retryConfig.maxDelay
303
+ );
304
+ }
305
+ return delay;
306
+ }
307
+ function getDataFormat(config) {
308
+ const headers = config.headers || {};
309
+ const ctKey = Object.keys(headers).find((k) => k.toLowerCase() === "content-type");
310
+ if (ctKey) {
311
+ const ct = String(headers[ctKey]).toLowerCase();
312
+ if (ct.includes("multipart/form-data")) return "file";
313
+ if (ct.includes("application/x-www-form-urlencoded")) return "form";
314
+ if (ct.includes("application/json") || ct.includes("+json")) return "json";
315
+ }
316
+ return config.contentType;
317
+ }
318
+ function injectDataTransform(config, format, instance) {
319
+ if (config.__dataTransformInjected) return;
320
+ config.__dataTransformInjected = true;
321
+ const ourTransform = (data) => {
322
+ if (data == null || data instanceof FormData || data instanceof URLSearchParams) return data;
323
+ if (typeof data !== "object") return data;
324
+ if (format === "file") return getFormData(data);
325
+ return new URLSearchParams(data);
326
+ };
327
+ const existing = config.transformRequest;
328
+ const defaults = instance.defaults.transformRequest;
329
+ const source = existing != null ? existing : defaults;
330
+ let chain = [];
331
+ if (source != null) {
332
+ chain = Array.isArray(source) ? [...source] : [source];
333
+ }
334
+ config.transformRequest = [ourTransform, ...chain];
335
+ }
336
+ function isConfigSet(config) {
337
+ return config != null;
338
+ }
339
+ function normalizePreventConfig(config, defaults) {
340
+ if (!isConfigSet(config)) {
341
+ return defaults;
342
+ }
343
+ if (typeof config === "boolean") {
344
+ return { ...defaults, enabled: config };
345
+ }
346
+ if (typeof config === "string") {
347
+ return { ...defaults, enabled: true, requestKey: config };
348
+ }
349
+ if (typeof config === "function") {
350
+ return { ...defaults, enabled: true, requestKey: config };
351
+ }
352
+ if (typeof config === "number") {
353
+ return { ...defaults, enabled: true, intervalMs: config };
354
+ }
355
+ if (Array.isArray(config)) {
356
+ return { ...defaults, enabled: true, methods: [...config] };
357
+ }
358
+ return {
359
+ enabled: config.enabled ?? true,
360
+ requestKey: config.requestKey ?? defaults.requestKey,
361
+ methods: config.methods != null ? config.methods : defaults.methods,
362
+ intervalMs: config.intervalMs ?? defaults.intervalMs
363
+ };
364
+ }
365
+ function normalizeCancelConfig(config, defaults) {
366
+ if (!isConfigSet(config)) {
367
+ return defaults;
368
+ }
369
+ if (typeof config === "boolean") {
370
+ return { ...defaults, enabled: config };
371
+ }
372
+ if (typeof config === "string") {
373
+ return { ...defaults, enabled: true, requestKey: config };
374
+ }
375
+ if (typeof config === "function") {
376
+ return { ...defaults, enabled: true, requestKey: config };
377
+ }
378
+ if (Array.isArray(config)) {
379
+ return { ...defaults, enabled: true, methods: [...config] };
380
+ }
381
+ return {
382
+ enabled: config.enabled ?? true,
383
+ requestKey: config.requestKey ?? defaults.requestKey,
384
+ methods: config.methods != null ? config.methods : defaults.methods
385
+ };
386
+ }
387
+ function normalizeRetryConfig(config, defaults) {
388
+ if (!isConfigSet(config)) {
389
+ return defaults;
390
+ }
391
+ if (typeof config === "boolean") {
392
+ return { ...defaults, enabled: config };
393
+ }
394
+ if (typeof config === "number") {
395
+ return { ...defaults, enabled: true, retries: config };
396
+ }
397
+ if (typeof config === "function") {
398
+ return { ...defaults, enabled: true, retryCondition: config };
399
+ }
400
+ if (Array.isArray(config)) {
401
+ const codes = config;
402
+ return {
403
+ ...defaults,
404
+ enabled: true,
405
+ retryCondition: (error) => {
406
+ if (!error.response) return true;
407
+ return codes.includes(error.response.status);
408
+ }
409
+ };
410
+ }
411
+ return {
412
+ enabled: config.enabled ?? true,
413
+ retries: config.retries ?? defaults.retries,
414
+ retryDelay: config.retryDelay ?? defaults.retryDelay,
415
+ retryCondition: config.retryCondition ?? defaults.retryCondition,
416
+ exponential: config.exponential ?? defaults.exponential,
417
+ maxDelay: config.maxDelay ?? defaults.maxDelay,
418
+ methods: config.methods != null ? config.methods : defaults.methods
419
+ };
420
+ }
421
+ function getEffectiveConfig(config, instanceDefaults) {
422
+ const prevent = isConfigSet(config.preventDuplicate) ? normalizePreventConfig(config.preventDuplicate, instanceDefaults.prevent) : { ...instanceDefaults.prevent };
423
+ const cancel = isConfigSet(config.cancelRequest) ? normalizeCancelConfig(config.cancelRequest, instanceDefaults.cancel) : { ...instanceDefaults.cancel };
424
+ return { prevent, cancel };
425
+ }
426
+ function getPendingKey(config) {
427
+ return config.__pendingKey;
428
+ }
429
+ function getCancelKey(config) {
430
+ return config.__cancelKey;
431
+ }
432
+ function cleanupRegistered(config, rm) {
433
+ const pk = getPendingKey(config);
434
+ const ck = getCancelKey(config);
435
+ if (pk) rm.unregisterRequest(pk, "prevent");
436
+ if (ck && ck !== pk) rm.unregisterRequest(ck, "cancel");
437
+ }
438
+ function rejectAndCleanup(config, rm, pr, reason) {
439
+ const pk = getPendingKey(config);
440
+ const ck = getCancelKey(config);
441
+ if (pk) {
442
+ const df = pr.get(pk);
443
+ if (df) {
444
+ df.reject(reason);
445
+ pr.delete(pk);
446
+ }
447
+ rm.unregisterRequest(pk, "prevent");
448
+ }
449
+ if (ck && ck !== pk) rm.unregisterRequest(ck, "cancel");
450
+ }
451
+ function resolveAndCleanup(config, rm, pr, data) {
452
+ const pk = getPendingKey(config);
453
+ const ck = getCancelKey(config);
454
+ if (pk) {
455
+ const df = pr.get(pk);
456
+ if (df) {
457
+ df.resolve(data);
458
+ pr.delete(pk);
459
+ }
460
+ rm.unregisterRequest(pk, "prevent");
461
+ }
462
+ if (ck && ck !== pk) rm.unregisterRequest(ck, "cancel");
463
+ }
464
+ function createEnhanceInstance(options = {}) {
465
+ const instance = axios_shim_default.create(options);
466
+ const defaultPrevent = { ...DEFAULT_PREVENT_CONFIG };
467
+ const defaultCancel = { ...DEFAULT_CANCEL_CONFIG };
468
+ const defaultRetry = { ...DEFAULT_RETRY_CONFIG };
469
+ if (isConfigSet(options.preventDuplicate)) {
470
+ const normalized = normalizePreventConfig(options.preventDuplicate, DEFAULT_PREVENT_CONFIG);
471
+ Object.assign(defaultPrevent, normalized);
472
+ }
473
+ if (isConfigSet(options.cancelRequest)) {
474
+ const normalized = normalizeCancelConfig(options.cancelRequest, DEFAULT_CANCEL_CONFIG);
475
+ Object.assign(defaultCancel, normalized);
476
+ }
477
+ if (isConfigSet(options.retry)) {
478
+ const normalized = normalizeRetryConfig(options.retry, DEFAULT_RETRY_CONFIG);
479
+ Object.assign(defaultRetry, normalized);
480
+ }
481
+ const needCacheBust = options.needCacheBust ?? true;
482
+ const requestManager = new RequestManager();
483
+ const pendingReturns = /* @__PURE__ */ new Map();
484
+ const enhanceInstance = {
485
+ requestManager,
486
+ clearAll: () => {
487
+ for (const [_key, deferred] of pendingReturns) {
488
+ try {
489
+ deferred.reject(new Error("All requests cleared"));
490
+ } catch {
491
+ }
492
+ }
493
+ pendingReturns.clear();
494
+ requestManager.clearAll();
495
+ },
496
+ cancelRequest: (key) => requestManager.cancelRequest(key),
497
+ getRequestStatus: (key) => requestManager.getRequestStatus(key)
498
+ };
499
+ instance.interceptors.request.use(
500
+ (config) => {
501
+ const method = config.method?.toUpperCase() || "GET";
502
+ const { prevent, cancel } = getEffectiveConfig(config, { prevent: defaultPrevent, cancel: defaultCancel });
503
+ const headers = config.headers || {};
504
+ const hasContentType = typeof headers === "object" && Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
505
+ if (!hasContentType) {
506
+ const contentType = config.contentType;
507
+ if (contentType !== "file") {
508
+ config.headers = config.headers || {};
509
+ const value = contentType != null ? CONTENT_TYPE_MAP[contentType] || contentType : CONTENT_TYPE_MAP.json;
510
+ config.headers["Content-Type"] = value;
511
+ }
512
+ }
513
+ if (cancel.enabled && shouldApply(method, cancel.methods)) {
514
+ const key = resolveRequestKey(config, cancel.requestKey);
515
+ const existing = requestManager.getRequestStatus(key);
516
+ if (existing?.config) {
517
+ existing.config.__cancelKey = void 0;
518
+ existing.config.__pendingKey = void 0;
519
+ }
520
+ requestManager.cancelRequest(key);
521
+ }
522
+ if (prevent.enabled && shouldApply(method, prevent.methods)) {
523
+ const key = resolveRequestKey(config, prevent.requestKey);
524
+ const existing = requestManager.getRequestStatus(key);
525
+ if (existing) {
526
+ const now = Date.now();
527
+ if (now - existing.timestamp < prevent.intervalMs) {
528
+ const deferred = pendingReturns.get(key);
529
+ if (deferred) {
530
+ const controller = new AbortController();
531
+ config.signal = controller.signal;
532
+ controller.abort("Request prevented by duplicate");
533
+ config.__pendingKey = key;
534
+ const error = new Error("Request prevented by duplicate");
535
+ error.__preventReturn = true;
536
+ error.__pendingPromise = deferred.promise;
537
+ error.__pendingKey = key;
538
+ error.config = config;
539
+ return Promise.reject(error);
540
+ }
541
+ }
542
+ }
543
+ }
544
+ const needsPrevent = prevent.enabled && shouldApply(method, prevent.methods);
545
+ const needsCancel = cancel.enabled && shouldApply(method, cancel.methods);
546
+ if (needsPrevent || needsCancel) {
547
+ const controller = new AbortController();
548
+ config.signal = controller.signal;
549
+ config.__controller = controller;
550
+ if (needsCancel) {
551
+ const cancelKey = resolveRequestKey(config, cancel.requestKey);
552
+ config.__cancelKey = cancelKey;
553
+ requestManager.registerRequest(cancelKey, "cancel", controller, Promise.resolve(), config);
554
+ }
555
+ if (needsPrevent) {
556
+ const preventKey = resolveRequestKey(config, prevent.requestKey);
557
+ config.__pendingKey = preventKey;
558
+ let deferred = pendingReturns.get(preventKey);
559
+ if (!deferred) {
560
+ let resolveFn;
561
+ let rejectFn;
562
+ const promise = new Promise((resolve, reject) => {
563
+ resolveFn = resolve;
564
+ rejectFn = reject;
565
+ });
566
+ deferred = { resolve: resolveFn, reject: rejectFn, promise };
567
+ pendingReturns.set(preventKey, deferred);
568
+ }
569
+ requestManager.registerRequest(preventKey, "prevent", controller, deferred.promise, config);
570
+ }
571
+ }
572
+ const format = getDataFormat(config);
573
+ if (format === "file" || format === "form") {
574
+ injectDataTransform(config, format, instance);
575
+ }
576
+ if ((config.needCacheBust ?? needCacheBust) !== false) {
577
+ const stamp = Date.now().toString(36);
578
+ if (config.params instanceof URLSearchParams) {
579
+ config.params.append("_", stamp);
580
+ } else if (typeof config.params === "object" && config.params !== null) {
581
+ config.params = { ...config.params, _: stamp };
582
+ } else {
583
+ config.params = { _: stamp };
584
+ }
585
+ }
586
+ return config;
587
+ },
588
+ (error) => {
589
+ if (error?.config) rejectAndCleanup(error.config, requestManager, pendingReturns, error);
590
+ return Promise.reject(error);
591
+ }
592
+ );
593
+ instance.interceptors.response.use(
594
+ // ─────────────────────────────────────────────────────────────────────────
595
+ // 成功响应处理 (2xx)
596
+ // ─────────────────────────────────────────────────────────────────────────
597
+ async (response) => {
598
+ const config = response.config;
599
+ const retryConfig = normalizeRetryConfig(config.retry, defaultRetry);
600
+ if (retryConfig.enabled && shouldApply(config.method, retryConfig.methods)) {
601
+ const syntheticError = new Error("Business logic error");
602
+ syntheticError.config = config;
603
+ syntheticError.response = response;
604
+ syntheticError.isAxiosError = true;
605
+ if (retryConfig.retryCondition(syntheticError)) {
606
+ const retryCount = config.__retryCount || 0;
607
+ if (retryCount < retryConfig.retries) {
608
+ await new Promise((resolve) => setTimeout(resolve, calculateRetryDelay(retryConfig, retryCount)));
609
+ cleanupRegistered(config, requestManager);
610
+ config.__retryCount = retryCount + 1;
611
+ return instance.request(config);
612
+ }
613
+ }
614
+ }
615
+ resolveAndCleanup(config, requestManager, pendingReturns, response);
616
+ return response;
617
+ },
618
+ // ─────────────────────────────────────────────────────────────────────────
619
+ // 错误响应处理 (非 2xx / 网络错误 / 取消 / 防重复拦截)
620
+ // ─────────────────────────────────────────────────────────────────────────
621
+ async (error) => {
622
+ const config = error.config || error.config;
623
+ if (!config) return Promise.reject(error);
624
+ if (error?.__preventReturn && error?.__pendingPromise) {
625
+ return error.__pendingPromise;
626
+ }
627
+ if (axios_shim_default.isCancel(error)) {
628
+ rejectAndCleanup(config, requestManager, pendingReturns, error);
629
+ return Promise.reject(error);
630
+ }
631
+ const retryConfig = normalizeRetryConfig(config.retry, defaultRetry);
632
+ if (retryConfig.enabled && shouldApply(config.method, retryConfig.methods)) {
633
+ const retryCount = config.__retryCount || 0;
634
+ const shouldRetry = retryCount < retryConfig.retries && retryConfig.retryCondition(error);
635
+ if (shouldRetry) {
636
+ await new Promise((resolve) => setTimeout(resolve, calculateRetryDelay(retryConfig, retryCount)));
637
+ cleanupRegistered(config, requestManager);
638
+ config.__retryCount = retryCount + 1;
639
+ return instance.request(config);
640
+ }
641
+ }
642
+ rejectAndCleanup(config, requestManager, pendingReturns, error);
643
+ return Promise.reject(error);
644
+ }
645
+ );
646
+ const methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
647
+ for (const method of methods) {
648
+ instance[method.toLowerCase()] = (url, data, config) => {
649
+ const finalConfig = {
650
+ ...config,
651
+ url,
652
+ method
653
+ };
654
+ if (["GET", "HEAD", "OPTIONS"].includes(method)) {
655
+ if (data) finalConfig.params = data;
656
+ } else {
657
+ if (data !== void 0) finalConfig.data = data;
658
+ }
659
+ return instance.request(finalConfig);
660
+ };
661
+ }
662
+ instance.enhance = enhanceInstance;
663
+ return instance;
664
+ }
665
+
666
+ // src/version.ts
667
+ var version = "1.0.2";
668
+ return __toCommonJS(index_exports);
669
+ })();
670
+ //# sourceMappingURL=index.global.js.map