fzkit 0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-http-client-pzpOS1bC.mjs","names":[],"sources":["../src/http-client/constants.ts","../src/http-client/utils/common.ts","../src/http-client/create-dedupe-adapter.ts","../src/http-client/dedupe-manager.ts","../src/http-client/token-refresh-manager.ts","../src/http-client/utils/error.ts","../src/http-client/utils/refresh.ts","../src/http-client/utils/token.ts","../src/http-client/create-http-client.ts"],"sourcesContent":["/**\n * 包内默认常量。\n *\n * @internal\n */\n/** Default error messages */\nexport const DEFAULT_MESSAGES = {\n refreshTokenExpired: \"Refresh token is invalid or expired\",\n loginExpired: \"Login session has expired\",\n refreshDisabled: \"Refresh token flow is not enabled\",\n} as const;\n\n/** Default proactive refresh buffer (ms) */\nexport const DEFAULT_REFRESH_BUFFER_MS = 0;\n\n/** Default retry delay cap (ms) */\nexport const DEFAULT_RETRY_DELAY_CAP = 30000;\n","/**\n * 通用纯工具函数。\n *\n * @internal\n */\nimport type { CancelToken, InternalAxiosRequestConfig } from \"axios\";\nimport axios, { AxiosError } from \"axios\";\n\ntype CancelTokenLike = CancelToken & {\n subscribe?: (listener: (reason?: unknown) => void) => void;\n unsubscribe?: (listener: (reason?: unknown) => void) => void;\n};\n\n/**\n * 判断 config 是否已通过 signal / cancelToken 取消。\n */\nexport const isCanceled = (config: InternalAxiosRequestConfig): boolean => {\n if (config.signal?.aborted) {\n return true;\n }\n try {\n config.cancelToken?.throwIfRequested();\n } catch {\n return true;\n }\n return false;\n};\n\n/**\n * 归一化 timeout:仅正数生效,其余视为 0(无超时)。\n */\nexport const normalizeTimeoutMs = (timeout: unknown): number =>\n typeof timeout === \"number\" && timeout > 0 ? timeout : 0;\n\n/**\n * 构造 axios CanceledError。\n */\nexport const createCanceledError = (config: InternalAxiosRequestConfig) =>\n new axios.CanceledError(\"canceled\", config);\n\n/**\n * 构造 axios timeout 错误(ECONNABORTED)。\n */\nexport const createTimeoutError = (\n config: InternalAxiosRequestConfig,\n timeoutMs: number,\n) =>\n new AxiosError(\n `timeout of ${timeoutMs}ms exceeded`,\n AxiosError.ECONNABORTED,\n config,\n );\n\n/**\n * 深拷贝任意值;不可 clone 时回退浅拷贝。\n */\nexport const cloneDeep = <T>(value: T): T => {\n if (value == null || typeof value !== \"object\") {\n return value;\n }\n\n try {\n return structuredClone(value);\n } catch {\n if (Array.isArray(value)) {\n return [...value] as T;\n }\n return { ...(value as Record<string, unknown>) } as T;\n }\n};\n\n/**\n * 订阅 config 的取消事件(signal / cancelToken),返回取消订阅函数。\n */\nexport const subscribeCancel = (\n config: InternalAxiosRequestConfig,\n onCancel: () => void,\n): (() => void) => {\n const signal = config.signal as AbortSignal | undefined;\n const onAbort = () => onCancel();\n signal?.addEventListener?.(\"abort\", onAbort);\n\n const cancelToken = config.cancelToken as CancelTokenLike | undefined;\n let cancelListener: ((reason?: unknown) => void) | undefined;\n if (cancelToken?.subscribe) {\n cancelListener = () => onCancel();\n cancelToken.subscribe(cancelListener);\n } else if (cancelToken?.promise) {\n void cancelToken.promise.then(onCancel, () => {});\n }\n\n return () => {\n signal?.removeEventListener?.(\"abort\", onAbort);\n if (cancelToken?.unsubscribe && cancelListener) {\n cancelToken.unsubscribe(cancelListener);\n }\n };\n};\n","import type {\n AxiosAdapter,\n AxiosResponse,\n InternalAxiosRequestConfig,\n} from 'axios';\nimport axios, { AxiosError } from 'axios';\nimport type { DedupeManager, SharedPendingEntry } from './dedupe-manager';\nimport type { RequestRetryState } from './types/common';\nimport {\n cloneDeep,\n createCanceledError,\n createTimeoutError,\n isCanceled,\n normalizeTimeoutMs,\n subscribeCancel,\n} from './utils/common';\n\ntype GetAdapter = (\n adapters: InternalAxiosRequestConfig['adapter'],\n config?: InternalAxiosRequestConfig\n) => AxiosAdapter;\n\n/**\n * 将 shared 错误分叉为绑定当前 consumer config 的独立错误实例。\n * 仅 dedupe 合并路径使用。\n */\nconst forkError = (error: unknown, config: InternalAxiosRequestConfig): unknown => {\n if (axios.isAxiosError(error)) {\n return new AxiosError(\n error.message,\n error.code,\n config,\n error.request,\n error.response\n ? {\n ...error.response,\n data: cloneDeep(error.response.data),\n config,\n }\n : undefined\n );\n }\n\n if (error instanceof Error) {\n const forked = new Error(error.message);\n forked.name = error.name;\n forked.stack = error.stack;\n if ('cause' in error) {\n (forked as Error & { cause?: unknown }).cause = (error as Error & {\n cause?: unknown;\n }).cause;\n }\n return forked;\n }\n\n return error;\n};\n\n/**\n * adapter 层 in-flight GET 合并。\n *\n * - 共享底层网络 Promise + 内部 AbortController\n * - 每个消费者绑定自己的 config / cancel / timeout\n * - 消费者取消仅为逻辑取消;refCount 归零才物理 abort\n * - shared timeout 取参与者中的 max(timeout);任一无限则 shared 不强制超时\n * - 成功响应只深拷贝 data,避免消费者互相污染\n *\n * @internal\n */\nexport const createDedupeAdapter = ({\n underlyingAdapter,\n dedupeManager,\n clientDedupeEnabled,\n}: {\n underlyingAdapter: InternalAxiosRequestConfig['adapter'];\n dedupeManager: DedupeManager;\n clientDedupeEnabled: boolean;\n}): AxiosAdapter => {\n // axios 运行时 getAdapter(adapters, config) 支持第二参;类型定义仅声明 1 参\n const getAdapter = axios.getAdapter as GetAdapter;\n\n const dispatch = (config: InternalAxiosRequestConfig): Promise<AxiosResponse> =>\n Promise.resolve(getAdapter(underlyingAdapter, config)(config));\n\n const createSharedEntry = (\n config: InternalAxiosRequestConfig\n ): SharedPendingEntry<AxiosResponse> => {\n const controller = new AbortController();\n // 剥离调用方 cancel / timeout,改绑内部 controller;timeout 由 manager 统一调度\n const {\n signal: _signal,\n cancelToken: _cancelToken,\n timeout: _timeout,\n ...rest\n } = config;\n\n const sharedConfig = {\n ...rest,\n signal: controller.signal,\n // 禁用 axios adapter 内置 timeout,避免与 shared max-timeout 双计时\n timeout: 0,\n } as InternalAxiosRequestConfig;\n\n return {\n promise: dispatch(sharedConfig),\n controller,\n refCount: 0,\n timeouts: [],\n maxTimeoutMs: 0,\n startedAt: Date.now(),\n closed: false,\n };\n };\n\n const bindConsumer = (\n entry: SharedPendingEntry<AxiosResponse>,\n config: InternalAxiosRequestConfig\n ): Promise<AxiosResponse> =>\n new Promise((resolve, reject) => {\n if (isCanceled(config)) {\n reject(createCanceledError(config));\n return;\n }\n\n const timeoutMs = normalizeTimeoutMs(config.timeout);\n dedupeManager.retain(entry, timeoutMs);\n\n let settled = false;\n let localTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n if (localTimeoutId != null) {\n clearTimeout(localTimeoutId);\n }\n cleanupCancel();\n dedupeManager.release(entry, timeoutMs);\n fn();\n };\n\n const onConsumerLeave = (error: unknown) => {\n settle(() => reject(error));\n };\n\n const cleanupCancel = subscribeCancel(config, () => {\n onConsumerLeave(createCanceledError(config));\n });\n\n if (timeoutMs > 0) {\n localTimeoutId = setTimeout(() => {\n onConsumerLeave(createTimeoutError(config, timeoutMs));\n }, timeoutMs);\n }\n\n void entry.promise.then(\n (response) => {\n if (isCanceled(config)) {\n onConsumerLeave(createCanceledError(config));\n return;\n }\n settle(() =>\n resolve({\n ...response,\n data: cloneDeep(response.data),\n config,\n })\n );\n },\n (error) => {\n if (isCanceled(config)) {\n onConsumerLeave(createCanceledError(config));\n return;\n }\n\n // shared 因 max-timeout / 全员取消 abort 时,映射为当前 consumer 语义\n if (\n axios.isCancel(error) ||\n (axios.isAxiosError(error) && error.code === AxiosError.ERR_CANCELED)\n ) {\n if (entry.abortReason === 'timeout') {\n onConsumerLeave(\n createTimeoutError(config, entry.maxTimeoutMs || timeoutMs || 0)\n );\n return;\n }\n onConsumerLeave(createCanceledError(config));\n return;\n }\n\n settle(() => reject(forkError(error, config)));\n }\n );\n });\n\n return (config) => {\n const method = (config.method ?? 'get').toLowerCase();\n const enabled =\n (config as InternalAxiosRequestConfig & RequestRetryState).dedupePolicy?.enabled ??\n clientDedupeEnabled;\n\n if (method !== 'get' || !enabled) {\n return dispatch(config);\n }\n\n // 已取消的请求不创建/join shared,避免孤儿请求\n if (isCanceled(config)) {\n return Promise.reject(createCanceledError(config));\n }\n\n const key = dedupeManager.getKey(config);\n let entry = dedupeManager.getPending<AxiosResponse>(key);\n if (!entry) {\n entry = createSharedEntry(config);\n dedupeManager.setPending(key, entry);\n }\n\n return bindConsumer(entry, config);\n };\n};\n","import type { AxiosRequestConfig } from \"axios\";\nimport type { RequestRetryState } from \"./types/common\";\n\n/**\n * shared abort 原因。\n *\n * @internal\n */\nexport type SharedAbortReason = \"timeout\" | \"release\";\n\n/**\n * 共享 in-flight 请求的运行时状态。\n *\n * @internal\n */\nexport interface SharedPendingEntry<T = unknown> {\n /** 底层网络 Promise(结果会被各 consumer fork) */\n promise: Promise<T>;\n /** 内部 AbortController:仅在 refCount 归零或 shared timeout 时 abort */\n controller: AbortController;\n /** 仍在等待结果的消费者数量 */\n refCount: number;\n /** 当前参与者 timeout 列表;0 表示无超时(无限) */\n timeouts: number[];\n /** 当前生效的 shared 物理 timeout(ms);0 表示无超时 */\n maxTimeoutMs: number;\n /** shared 请求开始时间,用于延长 timeout 时计算剩余时间 */\n startedAt: number;\n /** shared 侧 timeout 定时器 */\n timeoutId?: ReturnType<typeof setTimeout>;\n /** 已关闭:不可再 join,防止 abort 后 race 复用 */\n closed: boolean;\n /** 关闭原因,供 consumer 映射错误语义 */\n abortReason?: SharedAbortReason;\n}\n\n/**\n * 请求合并管理器。\n * 仅合并仍在进行中的相同请求(in-flight coalesce)。\n *\n * @internal\n */\nexport class DedupeManager {\n private pending = new Map<string, SharedPendingEntry>();\n private generateKey: (config: AxiosRequestConfig) => string;\n\n constructor(generateKey?: (config: AxiosRequestConfig) => string) {\n this.generateKey = generateKey ?? this.defaultGenerateKey;\n }\n\n /**\n * 默认的 key 生成器。\n * 由 lower-case method + baseURL + url + 稳定序列化 params + headersProvider 快照组成。\n */\n private defaultGenerateKey(config: AxiosRequestConfig): string {\n const method = (config.method ?? \"get\").toLowerCase();\n const baseURL = config.baseURL ?? \"\";\n const url = config.url ?? \"\";\n const sortedParams = this.stableSerialize(config.params);\n const providerHeaders = this.stableSerialize(\n (config as AxiosRequestConfig & RequestRetryState).__dedupeProviderHeaders ?? null,\n );\n return `${method}:${baseURL}:${url}:${sortedParams}:${providerHeaders}`;\n }\n\n private stableSerialize(value: unknown): string {\n if (value == null) {\n return \"\";\n }\n\n return JSON.stringify(this.normalizeForSerialize(value, new WeakSet<object>()));\n }\n\n private normalizeForSerialize(value: unknown, seen: WeakSet<object>): unknown {\n if (value == null || typeof value !== \"object\") {\n return value;\n }\n\n if (value instanceof Date) {\n return { __type: \"Date\", value: value.toISOString() };\n }\n\n if (value instanceof URLSearchParams) {\n return {\n __type: \"URLSearchParams\",\n value: Array.from(value.entries()).sort(([a], [b]) => a.localeCompare(b)),\n };\n }\n\n if (value instanceof Set) {\n const items = Array.from(value).map((item) => this.normalizeForSerialize(item, seen));\n return {\n __type: \"Set\",\n value: items\n .map((item) => JSON.stringify(item))\n .sort((a, b) => a.localeCompare(b))\n .map((item) => JSON.parse(item) as unknown),\n };\n }\n\n if (value instanceof Map) {\n const entries = Array.from(value.entries()).map(\n ([key, nested]) =>\n [\n this.normalizeForSerialize(key, seen),\n this.normalizeForSerialize(nested, seen),\n ] as const,\n );\n return {\n __type: \"Map\",\n value: entries\n .map(([key, nested]) => [JSON.stringify(key), key, nested] as const)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([, key, nested]) => [key, nested]),\n };\n }\n\n if (seen.has(value)) {\n throw new TypeError(\"Circular structure in dedupe key serialization\");\n }\n seen.add(value);\n\n if (Array.isArray(value)) {\n const normalized = value.map((item) => this.normalizeForSerialize(item, seen));\n seen.delete(value);\n return normalized;\n }\n\n const normalizedObject = Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, nested]) => [key, this.normalizeForSerialize(nested, seen)]),\n );\n seen.delete(value);\n return normalizedObject;\n }\n\n /**\n * 生成请求的唯一 key。\n */\n getKey(config: AxiosRequestConfig): string {\n return this.generateKey(config);\n }\n\n /**\n * 读取可 join 的 pending entry。\n * closed 的 entry 视为不可复用。\n */\n getPending<T>(key: string): SharedPendingEntry<T> | null {\n const entry = this.pending.get(key);\n if (!entry || entry.closed) {\n return null;\n }\n return entry as SharedPendingEntry<T>;\n }\n\n /**\n * 注册新的 shared 请求。\n */\n setPending<T>(key: string, entry: SharedPendingEntry<T>): void {\n this.pending.set(key, entry as SharedPendingEntry);\n\n const cleanup = () => {\n this.clearTimer(entry);\n if (this.pending.get(key) === entry) {\n this.pending.delete(key);\n }\n };\n // then 替代 finally,避免派生 Promise 未消费导致 unhandledrejection\n void entry.promise.then(cleanup, cleanup);\n }\n\n /**\n * consumer 加入 shared。\n * @param timeoutMs 0 表示无超时\n */\n retain(entry: SharedPendingEntry, timeoutMs: number): void {\n entry.refCount += 1;\n entry.timeouts.push(timeoutMs);\n this.recomputeTimeout(entry);\n }\n\n /**\n * consumer 离开 shared。\n * 当 refCount 归零时 abort 底层请求并标记 closed。\n */\n release(entry: SharedPendingEntry, timeoutMs: number): void {\n const index = entry.timeouts.indexOf(timeoutMs);\n if (index >= 0) {\n entry.timeouts.splice(index, 1);\n }\n\n entry.refCount = Math.max(0, entry.refCount - 1);\n\n if (entry.closed) {\n return;\n }\n\n if (entry.refCount === 0) {\n this.abortEntry(entry, \"release\");\n return;\n }\n\n this.recomputeTimeout(entry);\n }\n\n private recomputeTimeout(entry: SharedPendingEntry): void {\n if (entry.closed) {\n return;\n }\n\n // 任一参与者无 timeout(0)时,shared 不强制超时\n if (entry.timeouts.some((item) => item <= 0)) {\n entry.maxTimeoutMs = 0;\n this.clearTimer(entry);\n return;\n }\n\n const nextMax = entry.timeouts.length > 0 ? Math.max(...entry.timeouts) : 0;\n entry.maxTimeoutMs = nextMax;\n\n if (nextMax <= 0) {\n this.clearTimer(entry);\n return;\n }\n\n const elapsed = Date.now() - entry.startedAt;\n const remaining = nextMax - elapsed;\n\n this.clearTimer(entry);\n\n if (remaining <= 0) {\n this.abortEntry(entry, \"timeout\");\n return;\n }\n\n entry.timeoutId = setTimeout(() => {\n this.abortEntry(entry, \"timeout\");\n }, remaining);\n }\n\n private abortEntry(entry: SharedPendingEntry, reason: SharedAbortReason): void {\n if (entry.closed) {\n return;\n }\n\n entry.closed = true;\n entry.abortReason = reason;\n this.clearTimer(entry);\n\n if (!entry.controller.signal.aborted) {\n entry.controller.abort();\n }\n }\n\n private clearTimer(entry: SharedPendingEntry): void {\n if (entry.timeoutId != null) {\n clearTimeout(entry.timeoutId);\n entry.timeoutId = undefined;\n }\n }\n}\n","import type { AccessTokenResult } from \"./types/token\";\n\n/** @internal 冷却期内跳过刷新时的哨兵值,不对业务侧开放。 */\nexport const REFRESH_SKIPPED = Symbol(\"REFRESH_SKIPPED\");\n\nexport class TokenRefreshManager {\n private refreshingPromise: Promise<AccessTokenResult> | null = null;\n private lastRefreshTime: number | null = null;\n private readonly cooldownMs: number;\n\n constructor(cooldownMs = 15_000) {\n this.cooldownMs = cooldownMs;\n }\n\n /** @internal 供 createHttpClient 内部调用。 */\n async runRefresh(\n task: () => Promise<AccessTokenResult>,\n ): Promise<AccessTokenResult | typeof REFRESH_SKIPPED> {\n // 冷却期内跳过刷新\n if (\n this.lastRefreshTime !== null &&\n Date.now() - this.lastRefreshTime < this.cooldownMs\n ) {\n return REFRESH_SKIPPED;\n }\n\n if (!this.refreshingPromise) {\n this.refreshingPromise = (async () => {\n try {\n const result = await task();\n this.lastRefreshTime = Date.now();\n return result;\n } finally {\n this.refreshingPromise = null;\n }\n })();\n }\n\n return this.refreshingPromise;\n }\n}\n","/**\n * 错误归一化与 onError 调用辅助。\n *\n * @internal\n */\nimport axios, { AxiosError } from \"axios\";\nimport type { ErrorContext } from \"../types/common\";\nimport { cloneDeep } from \"./common\";\n\n/**\n * 将任意值标准化为 Error 实例。\n */\nexport const normalizeError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n return new Error(error.message);\n }\n\n try {\n return new Error(JSON.stringify(error));\n } catch {\n return new Error(String(error));\n }\n};\n\n/**\n * 分叉错误实例,避免共享 Promise rejection 让多个消费者拿到同一引用。\n */\nexport const cloneError = (error: unknown): unknown => {\n if (axios.isAxiosError(error)) {\n return new AxiosError(\n error.message,\n error.code,\n error.config,\n error.request,\n error.response\n ? {\n ...error.response,\n data: cloneDeep(error.response.data),\n }\n : undefined,\n );\n }\n\n if (error instanceof Error) {\n const forked = new Error(error.message);\n forked.name = error.name;\n forked.stack = error.stack;\n if (\"cause\" in error) {\n (forked as Error & { cause?: unknown }).cause = (\n error as Error & { cause?: unknown }\n ).cause;\n }\n\n // 保留 onError 替换错误上的自定义字段(如 code/meta)\n for (const key of Object.keys(error)) {\n if (key === \"name\" || key === \"message\" || key === \"stack\" || key === \"cause\") {\n continue;\n }\n try {\n (forked as Error & Record<string, unknown>)[key] = (\n error as Error & Record<string, unknown>\n )[key];\n } catch {\n // ignore non-writable properties\n }\n }\n\n return forked;\n }\n\n return error;\n};\n\n/**\n * 调用错误回调,返回最终错误。\n */\nexport const invokeOnError = async (\n error: Error,\n context: ErrorContext,\n onError?: (\n error: Error,\n context: ErrorContext,\n ) => Error | void | Promise<Error | void>,\n): Promise<Error> => {\n if (!onError) {\n return error;\n }\n\n try {\n const result = await onError(error, context);\n return result ?? error;\n } catch {\n return error;\n }\n};\n","/**\n * 刷新判定与重试策略辅助。\n *\n * @internal\n */\nimport type { InternalAxiosRequestConfig } from \"axios\";\nimport axios, { AxiosError } from \"axios\";\nimport { DEFAULT_RETRY_DELAY_CAP } from \"../constants\";\nimport type { RequestRetryState } from \"../types/common\";\nimport type { RetryPolicy } from \"../types/http-client-options\";\n\n/**\n * 默认的重试判断逻辑。\n * 网络错误(AxiosError 无 response)或 5xx 状态码时重试。\n * 用户取消 / 非 AxiosError 不重试。\n */\nexport const defaultShouldRetry = (error: unknown): boolean => {\n // 非 AxiosError 不重试(如 onBusinessResponse 抛出的普通 Error)\n if (!axios.isAxiosError(error)) {\n return false;\n }\n\n // 用户取消(AbortController / CancelToken)不重试\n if (axios.isCancel(error) || error.code === AxiosError.ERR_CANCELED) {\n return false;\n }\n\n // 网络错误(无 response)重试\n if (!error.response) {\n return true;\n }\n\n // 5xx 状态码重试\n return error.response.status >= 500;\n};\n\n/**\n * 默认的重试延迟计算。\n * 指数退避:1000 * 2^retryCount,上限 30 秒。\n */\nexport const defaultRetryDelay = (retryCount: number): number => {\n return Math.min(1000 * Math.pow(2, retryCount), DEFAULT_RETRY_DELAY_CAP);\n};\n\n/**\n * 解析重试策略,补齐默认值。\n */\nexport const resolveRetryPolicy = (\n retryPolicy?: RetryPolicy,\n): Required<RetryPolicy> | null => {\n if (!retryPolicy) {\n return null;\n }\n\n const maxRetries = retryPolicy.maxRetries ?? 0;\n\n if (maxRetries <= 0) {\n return null;\n }\n\n return {\n maxRetries,\n shouldRetry: retryPolicy.shouldRetry ?? defaultShouldRetry,\n retryDelay: retryPolicy.retryDelay ?? defaultRetryDelay,\n };\n};\n\n/**\n * 判断是否跳过刷新流程。\n *\n * 匹配规则:\n * - 仅 exact / prefix 路径匹配\n * - 不是任意子串 includes,也不做中间段滑动匹配\n * - 例如 `/auth` 匹配 `/auth`、`/auth/login`\n * - 不匹配 `/user/auth-history`、`/authorization`、`/api/auth/login`\n */\nexport const shouldSkipRefresh = (\n skipRefreshUrls: string[],\n config?: InternalAxiosRequestConfig & RequestRetryState,\n) => {\n const requestUrl = config?.url;\n\n if (!requestUrl) {\n return false;\n }\n\n const normalizedRequestPath = normalizeRequestPath(requestUrl);\n\n return skipRefreshUrls.some((skipUrl) =>\n matchesSkipPath(normalizedRequestPath, skipUrl),\n );\n};\n\nconst normalizeRequestPath = (requestUrl: string): string => {\n // 兼容相对路径、绝对 URL、带 query/hash 的地址\n try {\n const parsed = new URL(requestUrl, \"http://localhost\");\n return parsed.pathname || \"/\";\n } catch {\n const withoutQuery = requestUrl.split(\"?\")[0]?.split(\"#\")[0] ?? requestUrl;\n return withoutQuery.startsWith(\"/\") ? withoutQuery : `/${withoutQuery}`;\n }\n};\n\nconst matchesSkipPath = (requestPath: string, skipUrl: string): boolean => {\n if (!skipUrl) {\n return false;\n }\n\n const normalizedSkip = skipUrl.startsWith(\"/\") ? skipUrl : `/${skipUrl}`;\n const skipPath = normalizedSkip.replace(/\\/+$/, \"\") || \"/\";\n const path = requestPath.replace(/\\/+$/, \"\") || \"/\";\n\n return path === skipPath || path.startsWith(`${skipPath}/`);\n};\n\n/**\n * 默认的刷新失败判断逻辑。\n */\nexport const defaultIsRefreshFailure = (\n error: unknown,\n options: { unauthorizedStatusCode: number; refreshFailureCodes: number[] },\n): boolean => {\n // 非 AxiosError(编程错误 / 业务自定义 Error)默认不视为鉴权失败。\n // 若业务需要“抛 Error 即登出”,请自定义 isRefreshFailure。\n if (!axios.isAxiosError(error)) {\n return false;\n }\n\n // 无 response(网络错误)或 5xx 服务端错误:不代表 token 失效\n if (!error.response || error.response.status >= 500) {\n return false;\n }\n\n const status = error.response.status;\n const data = error.response.data as { code?: number } | undefined;\n\n return (\n status === options.unauthorizedStatusCode ||\n (data?.code !== undefined && options.refreshFailureCodes.includes(data.code))\n );\n};\n","/**\n * token 格式化与归一化辅助。\n *\n * @internal\n */\nimport type { AccessTokenResult } from \"../types/token\";\n\n/**\n * 格式化 token(添加前缀)。\n */\nexport const formatAccessToken = (prefix: string, token: string) => {\n const normalizedPrefix = prefix.trim();\n return normalizedPrefix ? `${normalizedPrefix} ${token}` : token;\n};\n\n/**\n * 标准化 token 结果,提取 token 和 expiresAt。\n */\nexport const normalizeTokenResult = (result: AccessTokenResult) => {\n if (!result || typeof result === \"string\") {\n return { token: result ?? \"\", expiresAt: null };\n }\n\n // 对象形态 token 也可能是 null/undefined,统一归一为空串,避免注入 \"Bearer null\"\n const token = result.token ?? \"\";\n\n // 验证 expiresAt 是否为有效的时间值\n const expiresAtValue = result.expiresAt;\n\n // 处理无效值:null、undefined、空字符串、0\n if (expiresAtValue == null || expiresAtValue === \"\" || expiresAtValue === 0) {\n return { token, expiresAt: null };\n }\n\n const expiresAtDate = new Date(expiresAtValue);\n\n // 检查是否为 Invalid Date\n if (Number.isNaN(expiresAtDate.getTime())) {\n return { token, expiresAt: null };\n }\n\n return {\n token,\n expiresAt: expiresAtDate,\n };\n};\n\n/**\n * 判断 token 是否即将过期。\n */\nexport const isTokenExpiringSoon = (\n expiresAt: Date,\n refreshBufferMs: number,\n): boolean => {\n return Date.now() >= expiresAt.getTime() - refreshBufferMs;\n};\n","import type { AxiosInstance, InternalAxiosRequestConfig } from 'axios';\nimport axios, { AxiosError, AxiosHeaders } from 'axios';\nimport { DEFAULT_MESSAGES, DEFAULT_REFRESH_BUFFER_MS } from './constants';\nimport { createDedupeAdapter } from './create-dedupe-adapter';\nimport { DedupeManager } from './dedupe-manager';\nimport { REFRESH_SKIPPED, TokenRefreshManager } from './token-refresh-manager';\nimport type { ErrorContext, RequestRetryState } from './types/common';\nimport type { HttpClientOptions, ResolvedHttpClientOptions } from './types/http-client-options';\nimport type { AccessTokenResult } from './types/token';\nimport { cloneDeep } from './utils/common';\nimport { cloneError, invokeOnError, normalizeError } from './utils/error';\nimport { defaultIsRefreshFailure, resolveRetryPolicy, shouldSkipRefresh } from './utils/refresh';\nimport { formatAccessToken, isTokenExpiringSoon, normalizeTokenResult } from './utils/token';\n\nexport const createHttpClient = <T extends AccessTokenResult = AccessTokenResult>(\n options: HttpClientOptions<T>\n): AxiosInstance => {\n const resolvedOptions: ResolvedHttpClientOptions<T> = {\n accessTokenHeaderName: 'Authorization',\n accessTokenPrefix: 'Bearer',\n refreshFailureCodes: [],\n unauthorizedStatusCode: 401,\n errorMessages: {},\n isRefreshFailure: (error: unknown) =>\n defaultIsRefreshFailure(error, {\n unauthorizedStatusCode: resolvedOptions.unauthorizedStatusCode,\n refreshFailureCodes: resolvedOptions.refreshFailureCodes,\n }),\n skipRefreshUrls: [],\n refreshBufferMs: DEFAULT_REFRESH_BUFFER_MS,\n shouldRefreshByResponse: () => false,\n ...options,\n };\n\n const refreshManager =\n options.refreshManager ?? new TokenRefreshManager(options.refreshCooldownMs);\n const refreshEnabled = options.refreshAccessToken !== undefined;\n const resolvedRetryPolicy = resolveRetryPolicy(options.retryPolicy);\n\n // 请求合并(in-flight coalesce)\n // 始终准备 manager:客户端默认关闭时,仍允许请求级 { enabled: true } 临时启用\n // 请求级仅可覆盖 enabled,generateKey 只读取客户端级配置\n const clientDedupePolicy = options.dedupePolicy;\n const clientDedupeEnabled = clientDedupePolicy?.enabled === true;\n const dedupeManager = new DedupeManager(clientDedupePolicy?.generateKey);\n\n const instance = axios.create({\n timeout: 15 * 1000,\n ...resolvedOptions.axiosConfig,\n });\n\n // dedupe 放在 adapter 层:覆盖 http() / http.get / http.request 等所有入口。\n // 内部 refresh / retry 仍走 instance.request;失败后 pending 会清理,不会自死锁。\n const originalRequest = instance.request.bind(instance);\n const replayRequest = (config: InternalAxiosRequestConfig & RequestRetryState) =>\n originalRequest(config);\n\n instance.defaults.adapter = createDedupeAdapter({\n underlyingAdapter: instance.defaults.adapter,\n dedupeManager,\n clientDedupeEnabled,\n });\n\n const handleAuthFailure = async (error?: unknown) => {\n await resolvedOptions.onAuthFailure?.(error);\n };\n\n const rejectWithError = async (error: unknown, type: ErrorContext['type']) => {\n const normalized = normalizeError(error);\n const finalError = await invokeOnError(normalized, { type }, resolvedOptions.onError);\n return Promise.reject(finalError);\n };\n\n const refreshAccessToken = async (): Promise<AccessTokenResult | typeof REFRESH_SKIPPED> => {\n const requestRefreshAccessToken = resolvedOptions.refreshAccessToken;\n\n if (!refreshEnabled || !requestRefreshAccessToken) {\n throw new Error(DEFAULT_MESSAGES.refreshDisabled);\n }\n\n const rejectRefreshAuthFailure = async (): Promise<never> => {\n const authError = new Error(\n resolvedOptions.errorMessages?.refreshTokenExpired ?? DEFAULT_MESSAGES.refreshTokenExpired\n );\n await handleAuthFailure(authError);\n throw await invokeOnError(authError, { type: 'refresh' }, resolvedOptions.onError);\n };\n\n // TokenRefreshManager 共享 Promise:成功结果可共享,失败需为每个 waiter 分叉错误实例\n try {\n return await refreshManager.runRefresh(async () => {\n let result: AccessTokenResult;\n\n try {\n result = await requestRefreshAccessToken();\n } catch (error) {\n const normalizedError = normalizeError(error);\n const isAuthFailure = resolvedOptions.isRefreshFailure(error);\n\n if (isAuthFailure) {\n await rejectRefreshAuthFailure();\n }\n\n // 非鉴权失败(如网络错误 / 编程错误),不调用 handleAuthFailure\n throw await invokeOnError(normalizedError, { type: 'refresh' }, resolvedOptions.onError);\n }\n\n const { token } = normalizeTokenResult(result);\n\n // 空 token 视为刷新鉴权失败:不写冷却,不重试业务请求\n if (!token) {\n await rejectRefreshAuthFailure();\n }\n\n return result;\n });\n } catch (error) {\n throw cloneError(error);\n }\n };\n\n const retryAfterRefresh = async (config: InternalAxiosRequestConfig & RequestRetryState) => {\n if (config._retry) {\n const authError = new Error(\n resolvedOptions.errorMessages?.loginExpired ?? DEFAULT_MESSAGES.loginExpired\n );\n await handleAuthFailure(authError);\n throw await invokeOnError(authError, { type: 'refresh' }, resolvedOptions.onError);\n }\n\n config._retry = true;\n\n const refreshResult = await refreshAccessToken();\n\n // 冷却期内跳过刷新时重新获取 token,否则使用刷新结果\n const tokenSource =\n refreshResult === REFRESH_SKIPPED ? await resolvedOptions.getAccessToken() : refreshResult;\n const { token } = normalizeTokenResult(tokenSource);\n\n // 冷却跳过或刷新结果为空 token 时,不再重试原请求\n if (!token) {\n const authError = new Error(\n resolvedOptions.errorMessages?.loginExpired ?? DEFAULT_MESSAGES.loginExpired\n );\n await handleAuthFailure(authError);\n throw await invokeOnError(authError, { type: 'refresh' }, resolvedOptions.onError);\n }\n\n const headers = AxiosHeaders.from(config.headers ?? {});\n headers.set(\n resolvedOptions.accessTokenHeaderName,\n formatAccessToken(resolvedOptions.accessTokenPrefix, token)\n );\n config.headers = headers;\n // 工厂写入的新 token,通用重试时可安全清除后重读 store\n config.__tokenInjected = true;\n // 重试需要重新跑 headersProvider / 请求准备逻辑\n config.__headersPrepared = false;\n\n return replayRequest(config);\n };\n\n const prepareRequestHeaders = async (config: InternalAxiosRequestConfig & RequestRetryState) => {\n if (config.__headersPrepared) {\n return config;\n }\n\n const headersProvider = resolvedOptions.headersProvider;\n const runtimeHeaders = headersProvider ? await headersProvider() : undefined;\n // 仅快照 headersProvider 返回值供 dedupe key 使用;调用方 headers / token 注入不参与\n config.__dedupeProviderHeaders = runtimeHeaders\n ? { ...runtimeHeaders }\n : headersProvider\n ? {}\n : null;\n\n // 先合并调用方 / headersProvider 的 headers,再做大小写无关的 token 判定\n const headers = AxiosHeaders.from(config.headers ?? {});\n // refresh 重试时已写入新 token:保留它,避免 headersProvider 用旧 Authorization 覆盖\n const refreshedAuth = config._retry\n ? headers.get(resolvedOptions.accessTokenHeaderName)\n : undefined;\n\n if (runtimeHeaders) {\n headers.set(runtimeHeaders);\n }\n\n if (refreshedAuth != null) {\n headers.set(resolvedOptions.accessTokenHeaderName, refreshedAuth);\n }\n\n config.headers = headers;\n\n const currentAuthorization = headers.get(resolvedOptions.accessTokenHeaderName);\n\n // 仅在调用方未显式提供 header(undefined/null)时注入 token\n // 空字符串也视为显式控制,不覆盖\n const needToken = currentAuthorization == null;\n\n if (needToken) {\n const tokenResult = await resolvedOptions.getAccessToken();\n const { token, expiresAt } = normalizeTokenResult(tokenResult);\n\n if (token) {\n // 主动刷新:token 即将过期时异步触发刷新,不阻塞当前请求\n if (\n refreshEnabled &&\n expiresAt &&\n !shouldSkipRefresh(resolvedOptions.skipRefreshUrls, config)\n ) {\n const bufferMs = resolvedOptions.refreshBufferMs;\n\n if (bufferMs > 0 && isTokenExpiringSoon(expiresAt, bufferMs)) {\n // fire-and-forget:refreshAccessToken 内部已调用 onError/onAuthFailure\n // 这里仅吞掉 rejection,避免 unhandledrejection,且不阻塞当前请求\n void refreshAccessToken().catch(() => {});\n }\n }\n\n headers.set(\n resolvedOptions.accessTokenHeaderName,\n formatAccessToken(resolvedOptions.accessTokenPrefix, token)\n );\n config.__tokenInjected = true;\n }\n }\n\n config.__headersPrepared = true;\n return config;\n };\n\n instance.interceptors.request.use(\n async (config: InternalAxiosRequestConfig & RequestRetryState) => {\n return prepareRequestHeaders(config);\n },\n (error) => Promise.reject(error)\n );\n\n instance.interceptors.response.use(\n async (response) => {\n const config = response.config as InternalAxiosRequestConfig & RequestRetryState;\n\n if (\n resolvedOptions.shouldRefreshByResponse(response) &&\n refreshEnabled &&\n !shouldSkipRefresh(resolvedOptions.skipRefreshUrls, config)\n ) {\n return retryAfterRefresh(config);\n }\n\n if (resolvedOptions.onBusinessResponse) {\n try {\n const businessResult = await resolvedOptions.onBusinessResponse(response);\n\n if (businessResult instanceof Error) {\n return rejectWithError(businessResult, 'request');\n }\n\n // 仅接受完整 AxiosResponse 形态,避免 {status,data} 业务对象被误替换\n if (\n businessResult &&\n typeof businessResult === 'object' &&\n 'status' in businessResult &&\n 'data' in businessResult &&\n 'config' in businessResult &&\n 'headers' in businessResult &&\n 'statusText' in businessResult\n ) {\n // 替换响应也隔离 data,避免 dedupe 多消费者共享同一引用\n return {\n ...businessResult,\n data: cloneDeep(businessResult.data),\n };\n }\n } catch (businessError) {\n // throw Error / throw 非 Error 与 return Error 对齐,统一进入 onError(request)\n return rejectWithError(businessError, 'request');\n }\n }\n\n return response;\n },\n async (error: AxiosError) => {\n const config = error.config as (InternalAxiosRequestConfig & RequestRetryState) | undefined;\n\n const normalizedError = normalizeError(error);\n\n if (!config) {\n return rejectWithError(normalizedError, 'request');\n }\n\n const status = error.response?.status;\n\n // 鉴权失败优先于通用重试,避免 401 被 shouldRetry 空耗重试次数\n if (status === resolvedOptions.unauthorizedStatusCode) {\n if (!refreshEnabled || shouldSkipRefresh(resolvedOptions.skipRefreshUrls, config)) {\n await handleAuthFailure(normalizedError);\n return rejectWithError(normalizedError, 'request');\n }\n\n try {\n return await retryAfterRefresh(config);\n } catch (refreshError) {\n return Promise.reject(refreshError);\n }\n }\n\n // 通用重试逻辑(仅处理非鉴权失败)\n if (resolvedRetryPolicy) {\n const retryCount = config.__retryCount ?? 0;\n\n try {\n const shouldRetry = resolvedRetryPolicy.shouldRetry(error, retryCount);\n\n if (retryCount < resolvedRetryPolicy.maxRetries && shouldRetry) {\n const rawDelay = resolvedRetryPolicy.retryDelay(retryCount);\n // 非有限 / 负数 delay 归一为 0,避免 timer 警告或异常挂起\n const delay =\n typeof rawDelay === 'number' && Number.isFinite(rawDelay) && rawDelay > 0\n ? rawDelay\n : 0;\n config.__retryCount = retryCount + 1;\n\n // 清除工厂注入的旧 token,让 prepare 重新 getAccessToken / headersProvider\n // 调用方显式 Authorization 不带 __tokenInjected,予以保留\n if (config.__tokenInjected) {\n const headers = AxiosHeaders.from(config.headers ?? {});\n headers.delete(resolvedOptions.accessTokenHeaderName);\n config.headers = headers;\n delete config.__tokenInjected;\n }\n config.__headersPrepared = false;\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n return replayRequest(config);\n }\n } catch (policyError) {\n // shouldRetry / retryDelay 编程错误:停止重试并进入 onError(request)\n return rejectWithError(policyError, 'request');\n }\n }\n\n return rejectWithError(normalizedError, 'request');\n }\n );\n\n return instance;\n};\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_create_http_client = require("../create-http-client-DzgZA6VA.cjs");
3
+ exports.TokenRefreshManager = require_create_http_client.TokenRefreshManager;
4
+ exports.createHttpClient = require_create_http_client.createHttpClient;
@@ -0,0 +1,2 @@
1
+ import { a as RetryPolicy, c as ErrorMessages, d as AccessTokenResult, i as RequestDedupePolicy, l as TokenRefreshManager, n as DedupePolicy, o as BusinessResponseResult, r as HttpClientOptions, s as ErrorContext, t as createHttpClient, u as AccessTokenDetail } from "../create-http-client-BoM9-_Ty.cjs";
2
+ export { type AccessTokenDetail, type AccessTokenResult, type BusinessResponseResult, type DedupePolicy, type ErrorContext, type ErrorMessages, type HttpClientOptions, type RequestDedupePolicy, type RetryPolicy, TokenRefreshManager, createHttpClient };
@@ -0,0 +1,2 @@
1
+ import { a as RetryPolicy, c as ErrorMessages, d as AccessTokenResult, i as RequestDedupePolicy, l as TokenRefreshManager, n as DedupePolicy, o as BusinessResponseResult, r as HttpClientOptions, s as ErrorContext, t as createHttpClient, u as AccessTokenDetail } from "../create-http-client-BoM9-_Ty.mjs";
2
+ export { type AccessTokenDetail, type AccessTokenResult, type BusinessResponseResult, type DedupePolicy, type ErrorContext, type ErrorMessages, type HttpClientOptions, type RequestDedupePolicy, type RetryPolicy, TokenRefreshManager, createHttpClient };
@@ -0,0 +1,2 @@
1
+ import { n as TokenRefreshManager, t as createHttpClient } from "../create-http-client-pzpOS1bC.mjs";
2
+ export { TokenRefreshManager, createHttpClient };
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_create_http_client = require("./create-http-client-DzgZA6VA.cjs");
3
+ exports.createHttpClient = require_create_http_client.createHttpClient;
@@ -0,0 +1,2 @@
1
+ import { t as createHttpClient } from "./create-http-client-BoM9-_Ty.cjs";
2
+ export { createHttpClient };
@@ -0,0 +1,2 @@
1
+ import { t as createHttpClient } from "./create-http-client-BoM9-_Ty.mjs";
2
+ export { createHttpClient };
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { t as createHttpClient } from "./create-http-client-pzpOS1bC.mjs";
2
+ export { createHttpClient };
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "fzkit",
3
+ "version": "0.1.0",
4
+ "description": "Axios HTTP client factory with token injection, refresh, retry and in-flight dedupe",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "fengzai6",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/fengzai6/fzkit.git",
11
+ "directory": "packages/fzkit"
12
+ },
13
+ "homepage": "https://github.com/fengzai6/fzkit/tree/main/packages/fzkit",
14
+ "bugs": {
15
+ "url": "https://github.com/fengzai6/fzkit/issues"
16
+ },
17
+ "keywords": [
18
+ "axios",
19
+ "http-client",
20
+ "token-refresh",
21
+ "retry",
22
+ "dedupe",
23
+ "typescript"
24
+ ],
25
+ "sideEffects": false,
26
+ "exports": {
27
+ ".": {
28
+ "import": {
29
+ "types": "./dist/index.d.mts",
30
+ "default": "./dist/index.mjs"
31
+ },
32
+ "require": {
33
+ "types": "./dist/index.d.cts",
34
+ "default": "./dist/index.cjs"
35
+ }
36
+ },
37
+ "./http-client": {
38
+ "import": {
39
+ "types": "./dist/http-client/index.d.mts",
40
+ "default": "./dist/http-client/index.mjs"
41
+ },
42
+ "require": {
43
+ "types": "./dist/http-client/index.d.cts",
44
+ "default": "./dist/http-client/index.cjs"
45
+ }
46
+ }
47
+ },
48
+ "main": "./dist/index.cjs",
49
+ "module": "./dist/index.mjs",
50
+ "types": "./dist/index.d.mts",
51
+ "files": [
52
+ "dist",
53
+ "README.md",
54
+ "LICENSE"
55
+ ],
56
+ "scripts": {
57
+ "build": "tsdown",
58
+ "dev": "tsdown --watch",
59
+ "test": "vitest run",
60
+ "test:watch": "vitest",
61
+ "type-check": "tsc -p tsconfig.json --noEmit",
62
+ "lint": "tsc -p tsconfig.json --noEmit",
63
+ "clean": "rm -rf dist",
64
+ "check:package": "node scripts/check-package.mjs",
65
+ "prepack": "yarn build"
66
+ },
67
+ "peerDependencies": {
68
+ "axios": "^1.7.0"
69
+ },
70
+ "devDependencies": {
71
+ "axios": "^1.18.1",
72
+ "tsdown": "0.22.5",
73
+ "typescript": "6.0.3",
74
+ "vitest": "^3.2.7"
75
+ },
76
+ "publishConfig": {
77
+ "access": "public",
78
+ "registry": "https://registry.npmjs.org/"
79
+ }
80
+ }