enhance-axios 1.0.3 → 1.1.0
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/cjs/index.js +175 -80
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +1 -1
- package/dist/esm/index.d.mts +50 -22
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/index.mjs +175 -80
- package/dist/esm/index.mjs.map +1 -1
- package/dist/umd/index.global.js +175 -80
- package/dist/umd/index.global.js.map +1 -1
- package/dist/umd/index.min.global.js +1 -1
- package/dist/umd.bundle/index.axios.global.js +178 -83
- package/dist/umd.bundle/index.axios.global.js.map +1 -1
- package/dist/umd.bundle/index.axios.min.global.js +8 -8
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -38,6 +38,9 @@ __export(index_exports, {
|
|
|
38
38
|
});
|
|
39
39
|
module.exports = __toCommonJS(index_exports);
|
|
40
40
|
|
|
41
|
+
// package.json
|
|
42
|
+
var version = "1.1.0";
|
|
43
|
+
|
|
41
44
|
// src/core/index.ts
|
|
42
45
|
var import_axios = __toESM(require("axios"));
|
|
43
46
|
|
|
@@ -268,52 +271,89 @@ var CONTENT_TYPE_MAP = {
|
|
|
268
271
|
form: "application/x-www-form-urlencoded"
|
|
269
272
|
};
|
|
270
273
|
|
|
271
|
-
// src/core/
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
274
|
+
// src/core/tokenManager.ts
|
|
275
|
+
function formatHeader(token, fmt) {
|
|
276
|
+
if (typeof fmt === "function") return fmt(token).trim();
|
|
277
|
+
if (typeof fmt === "string") {
|
|
278
|
+
const tpl = fmt.includes("{token}") ? fmt : `${fmt} {token}`;
|
|
279
|
+
return tpl.replace("{token}", token).trim();
|
|
280
|
+
}
|
|
281
|
+
return `Bearer ${token}`;
|
|
282
|
+
}
|
|
283
|
+
function setHeader(config, token, auth) {
|
|
284
|
+
config.headers = config.headers || {};
|
|
285
|
+
config.headers[auth.headerName || "Authorization"] = formatHeader(token, auth.headerFormat);
|
|
286
|
+
}
|
|
287
|
+
function shouldUseToken(config, instanceNeedToken) {
|
|
288
|
+
if (config.needToken !== void 0) return config.needToken;
|
|
289
|
+
if (typeof instanceNeedToken === "function") return instanceNeedToken(config);
|
|
290
|
+
if (instanceNeedToken !== void 0) return instanceNeedToken;
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
function defaultShouldRefresh(err) {
|
|
294
|
+
return err?.response?.status === 401 || err?.response?.data?.code === 401;
|
|
295
|
+
}
|
|
296
|
+
var TokenManager = class {
|
|
297
|
+
constructor(auth, needTokenDefault) {
|
|
298
|
+
this.auth = auth;
|
|
299
|
+
this.needTokenDefault = needTokenDefault;
|
|
300
|
+
this.pendingRefresh = null;
|
|
301
|
+
}
|
|
302
|
+
/** 请求拦截器:注入 token header */
|
|
303
|
+
async handleRequest(config) {
|
|
304
|
+
if (!shouldUseToken(config, this.needTokenDefault)) return;
|
|
305
|
+
if (this.pendingRefresh) {
|
|
306
|
+
try {
|
|
307
|
+
const info = await this.pendingRefresh;
|
|
308
|
+
setHeader(config, info.accessToken, this.auth);
|
|
309
|
+
return;
|
|
310
|
+
} catch {
|
|
311
|
+
this.pendingRefresh = null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
try {
|
|
315
|
+
const local = await Promise.resolve(this.auth.getLocalToken());
|
|
316
|
+
if (local) {
|
|
317
|
+
setHeader(config, local.accessToken, this.auth);
|
|
318
|
+
}
|
|
319
|
+
} catch {
|
|
320
|
+
}
|
|
284
321
|
}
|
|
285
|
-
|
|
286
|
-
|
|
322
|
+
/**
|
|
323
|
+
* 响应拦截器(resolve / reject):
|
|
324
|
+
* 检测到 token 过期则刷新并注入新 token。
|
|
325
|
+
* 返回 true 表示调用方需要调用 instance.request(config) 重试。
|
|
326
|
+
* 抛出异常表示刷新失败,调用方应 reject。
|
|
327
|
+
*/
|
|
328
|
+
async handleAuthError(responseOrError, config) {
|
|
329
|
+
if (!shouldUseToken(config, this.needTokenDefault)) return false;
|
|
330
|
+
const check = this.auth.shouldRefreshToken || defaultShouldRefresh;
|
|
331
|
+
if (!check(responseOrError)) return false;
|
|
332
|
+
if (!this.pendingRefresh) {
|
|
333
|
+
this.pendingRefresh = this.auth.refreshToken().then(async (info2) => {
|
|
334
|
+
if (this.auth.setLocalToken) {
|
|
335
|
+
await Promise.resolve(this.auth.setLocalToken(info2)).catch(() => {
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
return info2;
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
const info = await this.pendingRefresh;
|
|
342
|
+
this.pendingRefresh = null;
|
|
343
|
+
setHeader(config, info.accessToken, this.auth);
|
|
287
344
|
return true;
|
|
288
345
|
}
|
|
289
|
-
|
|
290
|
-
|
|
346
|
+
/** 刷新失败时调用 */
|
|
347
|
+
handleRefreshFailure(err) {
|
|
348
|
+
this.pendingRefresh = null;
|
|
349
|
+
const handler = this.auth.tokenFailureHandler;
|
|
350
|
+
if (handler) {
|
|
351
|
+
handler("refresh", err);
|
|
352
|
+
}
|
|
291
353
|
}
|
|
292
|
-
return false;
|
|
293
|
-
}
|
|
294
|
-
var DEFAULT_RETRY_CONFIG = {
|
|
295
|
-
enabled: true,
|
|
296
|
-
retries: 3,
|
|
297
|
-
retryDelay: 1e3,
|
|
298
|
-
retryCondition: defaultRetryCondition,
|
|
299
|
-
exponential: true,
|
|
300
|
-
maxDelay: 3e4
|
|
301
354
|
};
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if (methods.length === 0) return false;
|
|
305
|
-
return methods.includes(method?.toUpperCase() || "GET");
|
|
306
|
-
}
|
|
307
|
-
function calculateRetryDelay(retryConfig, retryCount) {
|
|
308
|
-
let delay = retryConfig.retryDelay;
|
|
309
|
-
if (retryConfig.exponential) {
|
|
310
|
-
delay = Math.min(
|
|
311
|
-
retryConfig.retryDelay * Math.pow(2, retryCount),
|
|
312
|
-
retryConfig.maxDelay
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
return delay;
|
|
316
|
-
}
|
|
355
|
+
|
|
356
|
+
// src/core/dataTransform.ts
|
|
317
357
|
function getDataFormat(config) {
|
|
318
358
|
const headers = config.headers || {};
|
|
319
359
|
const ctKey = Object.keys(headers).find((k) => k.toLowerCase() === "content-type");
|
|
@@ -343,9 +383,74 @@ function injectDataTransform(config, format, instance) {
|
|
|
343
383
|
}
|
|
344
384
|
config.transformRequest = [ourTransform, ...chain];
|
|
345
385
|
}
|
|
386
|
+
|
|
387
|
+
// src/core/helpers.ts
|
|
388
|
+
function shouldApply(method, methods) {
|
|
389
|
+
if (methods == null) return true;
|
|
390
|
+
if (methods.length === 0) return false;
|
|
391
|
+
return methods.includes(method?.toUpperCase() || "GET");
|
|
392
|
+
}
|
|
346
393
|
function isConfigSet(config) {
|
|
347
394
|
return config != null;
|
|
348
395
|
}
|
|
396
|
+
|
|
397
|
+
// src/core/retry.ts
|
|
398
|
+
function defaultRetryCondition(error) {
|
|
399
|
+
if (!error.response) return true;
|
|
400
|
+
const status = error.response.status;
|
|
401
|
+
if (status === 408 || status === 429) return true;
|
|
402
|
+
if (status >= 500 && status < 600) return true;
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
var DEFAULT_RETRY_CONFIG = {
|
|
406
|
+
enabled: true,
|
|
407
|
+
retries: 3,
|
|
408
|
+
retryDelay: 1e3,
|
|
409
|
+
retryCondition: defaultRetryCondition,
|
|
410
|
+
exponential: true,
|
|
411
|
+
maxDelay: 3e4
|
|
412
|
+
};
|
|
413
|
+
function calculateRetryDelay(config, retryCount) {
|
|
414
|
+
if (!config.exponential) return config.retryDelay;
|
|
415
|
+
return Math.min(config.retryDelay * Math.pow(2, retryCount), config.maxDelay);
|
|
416
|
+
}
|
|
417
|
+
function normalizeRetryConfig(config, defaults) {
|
|
418
|
+
if (!isConfigSet(config)) return defaults;
|
|
419
|
+
if (typeof config === "boolean") return { ...defaults, enabled: config };
|
|
420
|
+
if (typeof config === "number") return { ...defaults, enabled: true, retries: config };
|
|
421
|
+
if (typeof config === "function") return { ...defaults, enabled: true, retryCondition: config };
|
|
422
|
+
if (Array.isArray(config)) {
|
|
423
|
+
const codes = config;
|
|
424
|
+
return {
|
|
425
|
+
...defaults,
|
|
426
|
+
enabled: true,
|
|
427
|
+
retryCondition: (error) => {
|
|
428
|
+
if (!error.response) return true;
|
|
429
|
+
return codes.includes(error.response.status);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
enabled: config.enabled ?? true,
|
|
435
|
+
retries: config.retries ?? defaults.retries,
|
|
436
|
+
retryDelay: config.retryDelay ?? defaults.retryDelay,
|
|
437
|
+
retryCondition: config.retryCondition ?? defaults.retryCondition,
|
|
438
|
+
exponential: config.exponential ?? defaults.exponential,
|
|
439
|
+
maxDelay: config.maxDelay ?? defaults.maxDelay,
|
|
440
|
+
methods: config.methods != null ? config.methods : defaults.methods
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// src/core/index.ts
|
|
445
|
+
var DEFAULT_PREVENT_CONFIG = {
|
|
446
|
+
enabled: true,
|
|
447
|
+
methods: ["POST", "PUT", "PATCH", "DELETE"],
|
|
448
|
+
intervalMs: 1e3
|
|
449
|
+
};
|
|
450
|
+
var DEFAULT_CANCEL_CONFIG = {
|
|
451
|
+
enabled: true,
|
|
452
|
+
methods: ["GET"]
|
|
453
|
+
};
|
|
349
454
|
function normalizePreventConfig(config, defaults) {
|
|
350
455
|
if (!isConfigSet(config)) {
|
|
351
456
|
return defaults;
|
|
@@ -394,40 +499,6 @@ function normalizeCancelConfig(config, defaults) {
|
|
|
394
499
|
methods: config.methods != null ? config.methods : defaults.methods
|
|
395
500
|
};
|
|
396
501
|
}
|
|
397
|
-
function normalizeRetryConfig(config, defaults) {
|
|
398
|
-
if (!isConfigSet(config)) {
|
|
399
|
-
return defaults;
|
|
400
|
-
}
|
|
401
|
-
if (typeof config === "boolean") {
|
|
402
|
-
return { ...defaults, enabled: config };
|
|
403
|
-
}
|
|
404
|
-
if (typeof config === "number") {
|
|
405
|
-
return { ...defaults, enabled: true, retries: config };
|
|
406
|
-
}
|
|
407
|
-
if (typeof config === "function") {
|
|
408
|
-
return { ...defaults, enabled: true, retryCondition: config };
|
|
409
|
-
}
|
|
410
|
-
if (Array.isArray(config)) {
|
|
411
|
-
const codes = config;
|
|
412
|
-
return {
|
|
413
|
-
...defaults,
|
|
414
|
-
enabled: true,
|
|
415
|
-
retryCondition: (error) => {
|
|
416
|
-
if (!error.response) return true;
|
|
417
|
-
return codes.includes(error.response.status);
|
|
418
|
-
}
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
return {
|
|
422
|
-
enabled: config.enabled ?? true,
|
|
423
|
-
retries: config.retries ?? defaults.retries,
|
|
424
|
-
retryDelay: config.retryDelay ?? defaults.retryDelay,
|
|
425
|
-
retryCondition: config.retryCondition ?? defaults.retryCondition,
|
|
426
|
-
exponential: config.exponential ?? defaults.exponential,
|
|
427
|
-
maxDelay: config.maxDelay ?? defaults.maxDelay,
|
|
428
|
-
methods: config.methods != null ? config.methods : defaults.methods
|
|
429
|
-
};
|
|
430
|
-
}
|
|
431
502
|
function getEffectiveConfig(config, instanceDefaults) {
|
|
432
503
|
const prevent = isConfigSet(config.preventDuplicate) ? normalizePreventConfig(config.preventDuplicate, instanceDefaults.prevent) : { ...instanceDefaults.prevent };
|
|
433
504
|
const cancel = isConfigSet(config.cancelRequest) ? normalizeCancelConfig(config.cancelRequest, instanceDefaults.cancel) : { ...instanceDefaults.cancel };
|
|
@@ -472,7 +543,8 @@ function resolveAndCleanup(config, rm, pr, data) {
|
|
|
472
543
|
if (ck && ck !== pk) rm.unregisterRequest(ck, "cancel");
|
|
473
544
|
}
|
|
474
545
|
function createEnhanceInstance(options = {}) {
|
|
475
|
-
const
|
|
546
|
+
const { tokenAuth: _ta, needToken: _nt, ...axiosOptions } = options;
|
|
547
|
+
const instance = import_axios.default.create(axiosOptions);
|
|
476
548
|
const defaultPrevent = { ...DEFAULT_PREVENT_CONFIG };
|
|
477
549
|
const defaultCancel = { ...DEFAULT_CANCEL_CONFIG };
|
|
478
550
|
const defaultRetry = { ...DEFAULT_RETRY_CONFIG };
|
|
@@ -489,6 +561,7 @@ function createEnhanceInstance(options = {}) {
|
|
|
489
561
|
Object.assign(defaultRetry, normalized);
|
|
490
562
|
}
|
|
491
563
|
const needCacheBust = options.needCacheBust ?? true;
|
|
564
|
+
const tokenManager = _ta ? new TokenManager(_ta, _nt) : null;
|
|
492
565
|
const requestManager = new RequestManager();
|
|
493
566
|
const pendingReturns = /* @__PURE__ */ new Map();
|
|
494
567
|
const enhanceInstance = {
|
|
@@ -507,9 +580,10 @@ function createEnhanceInstance(options = {}) {
|
|
|
507
580
|
getRequestStatus: (key) => requestManager.getRequestStatus(key)
|
|
508
581
|
};
|
|
509
582
|
instance.interceptors.request.use(
|
|
510
|
-
(config) => {
|
|
583
|
+
async (config) => {
|
|
511
584
|
const method = config.method?.toUpperCase() || "GET";
|
|
512
585
|
const { prevent, cancel } = getEffectiveConfig(config, { prevent: defaultPrevent, cancel: defaultCancel });
|
|
586
|
+
if (tokenManager) await tokenManager.handleRequest(config);
|
|
513
587
|
const headers = config.headers || {};
|
|
514
588
|
const hasContentType = typeof headers === "object" && Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
|
|
515
589
|
if (!hasContentType) {
|
|
@@ -606,6 +680,18 @@ function createEnhanceInstance(options = {}) {
|
|
|
606
680
|
// ─────────────────────────────────────────────────────────────────────────
|
|
607
681
|
async (response) => {
|
|
608
682
|
const config = response.config;
|
|
683
|
+
if (tokenManager) {
|
|
684
|
+
try {
|
|
685
|
+
if (await tokenManager.handleAuthError(response, config)) {
|
|
686
|
+
cleanupRegistered(config, requestManager);
|
|
687
|
+
return instance.request(config);
|
|
688
|
+
}
|
|
689
|
+
} catch (err) {
|
|
690
|
+
tokenManager.handleRefreshFailure(err);
|
|
691
|
+
rejectAndCleanup(config, requestManager, pendingReturns, err);
|
|
692
|
+
return Promise.reject(err);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
609
695
|
const retryConfig = normalizeRetryConfig(config.retry, defaultRetry);
|
|
610
696
|
if (retryConfig.enabled && shouldApply(config.method, retryConfig.methods)) {
|
|
611
697
|
const syntheticError = new Error("Business logic error");
|
|
@@ -638,6 +724,18 @@ function createEnhanceInstance(options = {}) {
|
|
|
638
724
|
rejectAndCleanup(config, requestManager, pendingReturns, error);
|
|
639
725
|
return Promise.reject(error);
|
|
640
726
|
}
|
|
727
|
+
if (tokenManager) {
|
|
728
|
+
try {
|
|
729
|
+
if (await tokenManager.handleAuthError(error, config)) {
|
|
730
|
+
cleanupRegistered(config, requestManager);
|
|
731
|
+
return instance.request(config);
|
|
732
|
+
}
|
|
733
|
+
} catch (err) {
|
|
734
|
+
tokenManager.handleRefreshFailure(err);
|
|
735
|
+
rejectAndCleanup(config, requestManager, pendingReturns, err);
|
|
736
|
+
return Promise.reject(err);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
641
739
|
const retryConfig = normalizeRetryConfig(config.retry, defaultRetry);
|
|
642
740
|
if (retryConfig.enabled && shouldApply(config.method, retryConfig.methods)) {
|
|
643
741
|
const retryCount = config.__retryCount || 0;
|
|
@@ -672,9 +770,6 @@ function createEnhanceInstance(options = {}) {
|
|
|
672
770
|
instance.enhance = enhanceInstance;
|
|
673
771
|
return instance;
|
|
674
772
|
}
|
|
675
|
-
|
|
676
|
-
// src/version.ts
|
|
677
|
-
var version = "1.0.3";
|
|
678
773
|
// Annotate the CommonJS export names for ESM import in node:
|
|
679
774
|
0 && (module.exports = {
|
|
680
775
|
createEnhanceInstance,
|