@relia-fe/core 0.0.1 → 0.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.
- package/dist/api/index.d.mts +317 -0
- package/dist/api/index.d.ts +317 -0
- package/dist/api/index.js +749 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/index.mjs +700 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +723 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +699 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +30 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/index.ts"],"sourcesContent":["// Providers\n// export * from \"./providers\";\n\n// Hooks\n// export * from \"./hooks\";\n\n// Components\n// export * from \"./components\";\n\n// Utils\nexport * from \"./utils\";\n\n// Theme\n// export * from \"./theme\";","// Re-export commonly used utilities\nexport { omit, pick, debounce, throttle } from \"radash\";\nexport { \n isEmpty, \n isEqual, \n cloneDeep, \n merge, \n get, \n set, \n uniq, \n uniqBy,\n groupBy,\n orderBy,\n sortBy\n} from \"lodash-es\";\n\n// Custom utility functions\nexport const sleep = (ms: number): Promise<void> => \n new Promise(resolve => setTimeout(resolve, ms));\n\nexport const formatCurrency = (\n amount: number, \n currency = 'USD', \n locale = 'en-US'\n): string => {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(amount);\n};\n\nexport const formatDate = (\n date: Date | string | number, \n options?: Intl.DateTimeFormatOptions,\n locale = 'en-US'\n): string => {\n return new Intl.DateTimeFormat(locale, options).format(new Date(date));\n};\n\nexport const generateId = (): string => {\n return Math.random().toString(36).substring(2) + Date.now().toString(36);\n};\n\nexport const copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch (error) {\n console.error('Failed to copy to clipboard:', error);\n return false;\n }\n};"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,oBAA+C;AAC/C,uBAYO;AAGA,IAAM,QAAQ,CAAC,OACpB,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AAEzC,IAAM,iBAAiB,CAC5B,QACA,WAAW,OACX,SAAS,YACE;AACX,SAAO,IAAI,KAAK,aAAa,QAAQ;AAAA,IACnC,OAAO;AAAA,IACP;AAAA,EACF,CAAC,EAAE,OAAO,MAAM;AAClB;AAEO,IAAM,aAAa,CACxB,MACA,SACA,SAAS,YACE;AACX,SAAO,IAAI,KAAK,eAAe,QAAQ,OAAO,EAAE,OAAO,IAAI,KAAK,IAAI,CAAC;AACvE;AAEO,IAAM,aAAa,MAAc;AACtC,SAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,IAAI,KAAK,IAAI,EAAE,SAAS,EAAE;AACzE;AAEO,IAAM,kBAAkB,OAAO,SAAmC;AACvE,MAAI;AACF,UAAM,UAAU,UAAU,UAAU,IAAI;AACxC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,gCAAgC,KAAK;AACnD,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/api/base/request.ts","../src/api/base/definition.ts","../src/api/base/TokenStorageService.ts","../src/api/base/AuthError.ts","../src/api/base/AuthService.ts","../src/api/provider/AuthProvider.tsx","../src/api/hooks/useAuth.ts","../src/api/hooks/useAuthChange.ts","../src/api/hooks/useAuthRequest.ts","../src/api/hooks/useResource.ts","../src/api/hooks/fetcherFactory.ts","../src/api/hooks/useResourceList.ts","../src/api/hooks/useMutation.ts","../src/utils/index.ts"],"sourcesContent":["// API Module (包含 base、hooks、provider)\nexport * from \"./api\";\n\n// Utils\nexport * from \"./utils\";\n\n// Providers\n// export * from \"./providers\";\n\n// Hooks\n// export * from \"./hooks\";\n\n// Components\n// export * from \"./components\";\n\n// Theme\n// export * from \"./theme\";","import axios, {\n AxiosError,\n AxiosHeaders,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n InternalAxiosRequestConfig,\n} from \"axios\";\n\nimport { AuthService } from \"./AuthService\";\n\nexport const isBrowser = typeof window !== \"undefined\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface RetryableRequestConfig extends InternalAxiosRequestConfig {\n _retry?: boolean;\n}\n\n// Re-export for backward compatibility\nexport type { AuthType } from \"./types\";\n\n// ============================================================================\n// URL Utils\n// ============================================================================\n\n/**\n * 判断是否需要移除 baseURL(外部 URL 或 /api/ 路由)\n */\nexport const shouldRemoveBaseURL = (url?: string): boolean => {\n if (!url) return false;\n return url.startsWith(\"http\") || url.startsWith(\"/api/\");\n};\n\n// ============================================================================\n// Auth Utils - 认证工具函数\n// ============================================================================\n\n/**\n * 设置 Authorization header(纯函数,返回新对象)\n */\nexport const setAuthorizationHeader = (\n headers: AxiosHeaders | Record<string, unknown>,\n token: string,\n): AxiosHeaders | Record<string, unknown> => {\n if (headers instanceof AxiosHeaders) {\n const newHeaders = new AxiosHeaders(headers);\n newHeaders.set(\"Authorization\", `TOKEN ${token}`);\n return newHeaders;\n } else {\n return {\n ...headers,\n Authorization: `TOKEN ${token}`,\n };\n }\n};\n\n/**\n * 应用 Authorization header 到请求配置\n */\nexport const applyAuthorizationToConfig = (\n requestConfig: InternalAxiosRequestConfig,\n token: string,\n): InternalAxiosRequestConfig => {\n return {\n ...requestConfig,\n headers: setAuthorizationHeader(\n requestConfig.headers ?? {},\n token,\n ) as AxiosHeaders,\n };\n};\n\n/**\n * 判断是否为 401 错误\n */\nexport const is401Error = (error: unknown): boolean => {\n return (\n !!error &&\n typeof error === \"object\" &&\n \"response\" in error &&\n (error as AxiosError).response?.status === 401\n );\n};\n\nexport interface BaseRequestConfig {\n baseURL: string;\n headers?: Record<string, string>;\n}\n\n/**\n * 创建不带认证的基础请求实例\n */\nexport const createBaseRequest = (config: BaseRequestConfig): AxiosInstance => {\n return axios.create({\n baseURL: config.baseURL,\n headers: {\n \"Content-Type\": \"application/json\",\n ...config.headers,\n },\n });\n};\n\n// 内部使用的默认实例(延迟初始化)\nlet _baseRequest: AxiosInstance | null = null;\n\n/**\n * 获取或创建默认基础请求实例\n */\nexport const getBaseRequest = (): AxiosInstance => {\n if (!_baseRequest) {\n _baseRequest = createBaseRequest({ baseURL: \"\" });\n }\n return _baseRequest;\n};\n\n/**\n * 配置默认基础请求实例\n */\nexport const configureBaseRequest = (config: BaseRequestConfig): void => {\n _baseRequest = createBaseRequest(config);\n};\n\nexport interface CreateAuthRequestConfig {\n authService: AuthService;\n axiosConfig?: AxiosRequestConfig;\n}\n\n/**\n * 创建带鉴权 Axios 实例\n */\nexport const createAuthRequest = (\n config: CreateAuthRequestConfig,\n): AxiosInstance => {\n const { authService, axiosConfig } = config;\n\n /**\n * 请求拦截器 - 统一添加认证 token\n */\n const requestInterceptor = async (\n reqConfig: InternalAxiosRequestConfig,\n ): Promise<InternalAxiosRequestConfig> => {\n let token = authService.getToken();\n\n // 浏览器环境下,无 token 时触发认证\n if (!token && isBrowser) {\n const result = await authService.authenticate(\"request-init\");\n if (result.success && result.token) {\n token = result.token;\n } else {\n throw new Error(\"Authentication required\");\n }\n }\n\n if (!token) {\n throw new Error(\"Authentication required\");\n }\n\n let newConfig = applyAuthorizationToConfig(reqConfig, token);\n if (shouldRemoveBaseURL(newConfig.url)) {\n newConfig = { ...newConfig, baseURL: undefined };\n }\n\n return newConfig;\n };\n\n /**\n * 清理认证数据并重定向\n */\n const clearAuthAndRedirect = (): void => {\n authService.logout();\n if (isBrowser) {\n window.location.replace(\"/\");\n }\n };\n\n /**\n * 处理 401 错误的重试逻辑\n */\n const handle401Retry = async (\n error: AxiosError,\n retryFn: (cfg: RetryableRequestConfig) => Promise<AxiosResponse>,\n ): Promise<AxiosResponse> => {\n const originalConfig = error.config as RetryableRequestConfig;\n\n if (originalConfig._retry) {\n console.warn(\"[Fetcher] Re-authentication retry failed\");\n clearAuthAndRedirect();\n return Promise.reject(error);\n }\n\n originalConfig._retry = true;\n\n const authResult = await authService.authenticate(\"token-refresh\");\n\n if (authResult.success && authResult.token) {\n const newConfig = applyAuthorizationToConfig(\n originalConfig,\n authResult.token,\n );\n console.log(\"[Fetcher] Re-authentication successful, retrying request\");\n return retryFn(newConfig);\n }\n\n console.warn(\"[Fetcher] Re-authentication failed, redirecting to home\");\n clearAuthAndRedirect();\n return Promise.reject(error);\n };\n\n /**\n * 响应拦截器错误处理器\n */\n const responseErrorHandler = async (\n error: unknown,\n retryFn: (cfg: RetryableRequestConfig) => Promise<AxiosResponse>,\n ): Promise<AxiosResponse> => {\n console.error(error);\n\n if (!isBrowser) {\n return Promise.reject(error);\n }\n\n if (is401Error(error)) {\n return handle401Retry(error as AxiosError, retryFn);\n }\n\n return Promise.reject(error);\n };\n\n // 创建实例(合并配置)\n const baseReq = getBaseRequest();\n const instance = axiosConfig ? baseReq.create(axiosConfig) : baseReq.create();\n\n // 注册拦截器\n instance.interceptors.request.use(requestInterceptor, (error) =>\n Promise.reject(error),\n );\n\n instance.interceptors.response.use(\n (response) => response,\n (error) => responseErrorHandler(error, (cfg) => instance.request(cfg)),\n );\n\n return instance;\n};\n","import type { PaginationReq, PaginationResp } from \"./types\";\n\nexport type FetchIdentity<Resp, Req> =\n | ResourceIdentity<Resp, Req>\n | MutationIdentity<Resp, Req>;\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport type ResourceIdentity<Resp = unknown, Req = unknown> = {\n uri: string;\n method?: \"get\";\n host?: string;\n noAuth?: boolean;\n // absoluteUri: string;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport type MutationIdentity<Resp = unknown, Req = unknown> = {\n uri: string;\n method?: \"post\" | \"delete\";\n host?: string;\n noAuth?: boolean;\n // absoluteUri: string;\n};\n\nexport function defineFetch<Resp, Req>(\n uri: string,\n method?: \"get\" | \"post\" | \"delete\",\n option?: {\n host?: string;\n noAuth?: boolean;\n },\n): FetchIdentity<Resp, Req> {\n return {\n uri,\n method,\n host: option?.host,\n // absoluteUri: `${option?.host ?? HOST_PREFIX}${uri}`,\n noAuth: option?.noAuth,\n };\n}\n\nexport function defineResource<Resp, Req = undefined>(\n uri: string,\n option?: {\n host?: string;\n noAuth?: boolean;\n },\n): ResourceIdentity<Resp, Req> {\n return {\n uri,\n method: \"get\",\n host: option?.host,\n // absoluteUri: `${option?.host ?? HOST_PREFIX}${uri}`,\n noAuth: option?.noAuth,\n };\n}\n\nexport function defineResourceList<Resp, Req = undefined>(\n uri: string,\n option?: {\n host?: string;\n noAuth?: boolean;\n },\n): ResourceIdentity<PaginationResp<Resp>, Req & PaginationReq> {\n return {\n uri,\n method: \"get\",\n host: option?.host,\n // absoluteUri: `${option?.host ?? HOST_PREFIX}${uri}`,\n noAuth: option?.noAuth,\n };\n}\n\nexport function defineMutation<Resp, Req>(\n uri: string,\n option?: {\n host?: string;\n noAuth?: boolean;\n method?: \"post\" | \"delete\";\n },\n): MutationIdentity<Resp, Req> {\n return {\n uri,\n method: option?.method ?? \"post\",\n host: option?.host,\n // absoluteUri: `${option?.host ?? HOST_PREFIX}${uri}`,\n noAuth: option?.noAuth,\n };\n}\n","\"use client\";\n\nconst isBrowser = typeof window !== \"undefined\";\nconst STORAGE_KEY = \"auth_tokens\";\n\n/**\n * Token 存储服务接口\n */\nexport interface ITokenStorageService {\n setToken(token: string | undefined, address?: string): void;\n getToken(address?: string): string | null;\n subscribe(listener: () => void): () => void;\n}\n\n/**\n * 默认 Token 存储服务实现(localStorage)\n * 支持多地址 token 存储\n */\nexport class TokenStorageService implements ITokenStorageService {\n private listeners: Set<() => void> = new Set();\n private boundHandleStorage: ((e: StorageEvent) => void) | null = null;\n\n setToken(token: string | undefined, address?: string): void {\n if (!isBrowser) return;\n const key = address?.toLowerCase() ?? \"_default\";\n const map = this.getMap();\n if (token === undefined) {\n delete map[key];\n } else {\n map[key] = token;\n }\n this.saveMap(map);\n }\n\n getToken(address?: string): string | null {\n const key = address?.toLowerCase() ?? \"_default\";\n return this.getMap()[key] ?? null;\n }\n\n private getMap(): Record<string, string> {\n if (!isBrowser) return {};\n try {\n const data = localStorage.getItem(STORAGE_KEY);\n return data ? JSON.parse(data) : {};\n } catch {\n return {};\n }\n }\n\n private saveMap(map: Record<string, string>): void {\n if (!isBrowser) return;\n try {\n if (Object.keys(map).length === 0) {\n localStorage.removeItem(STORAGE_KEY);\n } else {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(map));\n }\n } catch (e) {\n console.error(\"Failed to persist auth tokens\", e);\n }\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n\n // 首次订阅时添加 storage 事件监听\n if (isBrowser && this.listeners.size === 1) {\n this.boundHandleStorage = (e: StorageEvent) => {\n if (e.key === STORAGE_KEY) {\n this.listeners.forEach((l) => l());\n }\n };\n window.addEventListener(\"storage\", this.boundHandleStorage);\n }\n\n return () => {\n this.listeners.delete(listener);\n // 最后一个订阅者取消时移除事件监听\n if (isBrowser && this.listeners.size === 0 && this.boundHandleStorage) {\n window.removeEventListener(\"storage\", this.boundHandleStorage);\n this.boundHandleStorage = null;\n }\n };\n }\n}\n\n/** 默认单例 */\nexport const defaultTokenStorageService = new TokenStorageService();\n","/**\n * 认证错误类型枚举\n */\nexport const enum AuthErrorType {\n /** 认证被取消 */\n CANCELLED = \"cancelled\",\n /** 地址在认证过程中改变 */\n ADDRESS_CHANGED = \"address_changed\",\n /** 未知错误 */\n UNKNOWN = \"unknown\",\n}\n\n/**\n * 通用认证错误类\n */\nexport class AuthError<T extends string = string> extends Error {\n public readonly errorType: AuthErrorType | T;\n\n constructor(message: string, errorType: AuthErrorType | T) {\n super(message);\n this.name = \"AuthError\";\n this.errorType = errorType;\n\n // 保持正确的原型链(TypeScript 继承 Error 的问题)\n Object.setPrototypeOf(this, AuthError.prototype);\n }\n}\n","import type {\n AuthType,\n AuthResult,\n AuthState,\n AuthStateListener,\n} from \"./types\";\nimport {\n ITokenStorageService,\n defaultTokenStorageService,\n} from \"./TokenStorageService\";\nimport { AuthError, AuthErrorType } from \"./AuthError\";\n\ntype RefreshTokenFn = (context: AuthType) => Promise<AuthResult>;\n\nexport interface AuthServiceConfig {\n refreshToken: RefreshTokenFn;\n tokenStorageService?: ITokenStorageService;\n}\n\n/**\n * Authentication service with concurrency control, token storage, and state management\n */\nexport class AuthService {\n private refreshToken: RefreshTokenFn;\n private tokenStorageService: ITokenStorageService;\n private authPromise: Promise<AuthResult> | null = null; // 用于并发控制\n\n // 状态管理\n private state: AuthState = { status: \"idle\" };\n private listeners: Set<AuthStateListener> = new Set();\n\n constructor(config: AuthServiceConfig) {\n this.refreshToken = config.refreshToken;\n this.tokenStorageService =\n config.tokenStorageService ?? defaultTokenStorageService;\n\n // 订阅 storage 变化,实现多 tab 同步\n this.tokenStorageService.subscribe(() => this.handleStorageChange());\n }\n\n /**\n * Authenticate with concurrency control\n * Multiple concurrent calls will share the same Promise\n * Stores token on success\n */\n async authenticate(context: AuthType): Promise<AuthResult> {\n // 并发控制:复用进行中的 Promise\n if (this.state.status === \"authenticating\" && this.authPromise) {\n console.log(\n `[AuthService] Authentication already in progress, reusing Promise`,\n );\n return this.authPromise;\n }\n\n const startAddress = this.state.address;\n this.setState({\n status: \"authenticating\",\n address: startAddress,\n });\n this.authPromise = this.refreshToken(context);\n\n try {\n const result = await this.authPromise;\n const currentAddress = this.state.address;\n\n // 检查认证是否被取消(通过状态判断)\n if (this.state.status !== \"authenticating\") {\n console.log(\n `[AuthService] Authentication was cancelled, ignoring result`,\n );\n throw new AuthError(\"Authentication was cancelled\", AuthErrorType.CANCELLED);\n }\n\n // 认证完成后检查地址是否变化\n if (currentAddress !== startAddress) {\n console.log(\n `[AuthService] Address changed during auth, ignoring result`,\n );\n throw new AuthError(\n \"Address changed during authentication\",\n AuthErrorType.ADDRESS_CHANGED,\n );\n }\n\n // 成功:存储 token\n this.tokenStorageService.setToken(\n result.token,\n currentAddress ?? undefined,\n );\n this.setState({\n status: \"authenticated\",\n address: currentAddress,\n });\n console.log(`[AuthService] Token stored successfully`);\n\n return result;\n } catch (error) {\n const currentAddress = this.state.address;\n\n // 处理 AuthError\n if (error instanceof AuthError) {\n this.setState({\n status: \"unauthenticated\",\n address: currentAddress,\n error: error,\n });\n throw error;\n }\n\n // 处理未知错误\n const authError = new AuthError(\n error instanceof Error ? error.message : \"Unknown error\",\n AuthErrorType.UNKNOWN,\n );\n this.setState({\n status: \"unauthenticated\",\n address: currentAddress,\n error: authError,\n });\n throw authError;\n } finally {\n this.authPromise = null;\n }\n }\n\n /**\n * 重置内部认证状态(私有方法)\n */\n private reset(): void {\n this.authPromise = null;\n }\n\n /**\n * Get current token for the current wallet address\n */\n getToken(): string | null {\n return this.tokenStorageService.getToken(this.state.address ?? undefined);\n }\n\n /**\n * 检查地址是否有有效 token(私有方法)\n */\n private isAddressAuthenticated(address: string | undefined): boolean {\n if (!address) return false;\n return this.tokenStorageService.getToken(address) !== null;\n }\n\n /**\n * Logout: clear token for current address and update state\n */\n logout(): void {\n const address = this.state.address;\n this.tokenStorageService.setToken(undefined, address ?? undefined);\n this.reset();\n this.setState({ status: \"unauthenticated\", address });\n }\n\n /**\n * Get current authentication state\n */\n getState(): AuthState {\n return { ...this.state };\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: AuthStateListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Handle wallet address changes\n * Note: Wallet disconnection should be handled externally by calling logout()\n */\n handleWalletChange(address: string | undefined): void {\n // 地址切换时,如果正在认证旧地址,重置并更新状态\n const isAuthenticating = this.state.status === \"authenticating\";\n if (isAuthenticating && this.state.address !== address) {\n this.reset();\n // 更新状态为新地址,准备重新认证\n this.setState({ status: \"idle\", address });\n }\n\n // 地址已认证\n if (this.isAddressAuthenticated(address)) {\n // 避免重复设置相同状态\n if (\n this.state.status !== \"authenticated\" ||\n this.state.address !== address\n ) {\n this.setState({ status: \"authenticated\", address });\n }\n return;\n }\n\n // 未认证且未在进行中,触发认证\n const isAlreadyAuthForThisAddress =\n this.state.status === \"authenticated\" && this.state.address === address;\n if (!isAuthenticating && !isAlreadyAuthForThisAddress) {\n // 先更新地址,再触发认证\n this.setState({ status: \"idle\", address });\n // 捕获认证错误,避免未处理的 Promise 拒绝\n this.authenticate(\"wallet-connect\").catch(() => {\n // 错误已经在 authenticate 方法中处理并存储到状态中\n // 这里只是为了避免未处理的 Promise 拒绝\n });\n }\n }\n\n /**\n * 处理 StorageChange 事件(用于多选项卡同步)\n * 当 localStorage 在另一个选项卡中发生更改时调用\n */\n private handleStorageChange(): void {\n const address = this.state.address;\n if (!address) return;\n\n const hasToken = this.isAddressAuthenticated(address);\n const currentStatus = this.state.status;\n\n // 其他 tab 登出\n if (!hasToken && currentStatus === \"authenticated\") {\n this.setState({ status: \"unauthenticated\", address });\n }\n // 其他 tab 登录\n else if (hasToken && currentStatus !== \"authenticated\") {\n this.setState({ status: \"authenticated\", address });\n }\n }\n\n /**\n * 更新状态并通知监听者\n */\n private setState(newState: AuthState): void {\n this.state = newState;\n this.listeners.forEach((listener) => listener(newState));\n }\n}\n","\"use client\";\n\nimport { AxiosInstance, AxiosRequestConfig } from \"axios\";\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { SWRConfig, useSWRConfig } from \"swr\";\nimport { AuthService } from \"@/api/base/AuthService\";\nimport { createAuthRequest } from \"@/api/base/request\";\nimport { ITokenStorageService } from \"@/api/base/TokenStorageService\";\nimport type { AuthResult, AuthType as AuthContextType } from \"@/api/base/types\";\nimport { AuthError } from \"@/api/base/AuthError\";\n\nexport type AuthStatus =\n | \"idle\"\n | \"authenticating\"\n | \"authenticated\"\n | \"unauthenticated\";\n\nexport interface AuthProviderInstanceConfig {\n authService: AuthService;\n authRequest: AxiosInstance;\n address?: string;\n}\n\nexport interface AuthProviderFactoryConfig {\n refreshTokenFn: (context: AuthContextType) => Promise<AuthResult>;\n axiosConfig?: AxiosRequestConfig;\n tokenStorageService?: ITokenStorageService;\n address?: string;\n}\n\n/** 联合类型:支持两种配置方式 */\nexport type AuthProviderConfig =\n | AuthProviderInstanceConfig\n | AuthProviderFactoryConfig;\n\n/** 类型守卫:判断是否为实例配置 */\nfunction isInstanceConfig(\n config: AuthProviderConfig,\n): config is AuthProviderInstanceConfig {\n return \"authService\" in config && \"authRequest\" in config;\n}\n\nexport interface UseAuthResult {\n status: AuthStatus;\n error?: AuthError;\n address?: string;\n isAuthenticated: boolean;\n isAuthenticating: boolean;\n authenticate: () => Promise<void>;\n logout: () => void;\n}\n\nexport const AuthContext = createContext<UseAuthResult | null>(null);\nexport const AuthRequestContext = createContext<AxiosInstance | null>(null);\n\ninterface UseAuthInternalProps {\n authService: AuthService;\n address?: string;\n}\n\n/**\n * 管理钱包签名身份验证流程的核心身份验证挂钩\n * AuthService 负责所有认证逻辑和竞态控制,此 hook 只是 React 包装器\n */\nconst useAuthInternal = ({\n authService,\n address,\n}: UseAuthInternalProps): UseAuthResult => {\n const { mutate: globalMutate } = useSWRConfig();\n\n // 订阅 AuthService 状态\n const [authState, setAuthState] = useState(() => authService.getState());\n\n useEffect(() => {\n return authService.subscribe(setAuthState);\n }, [authService]);\n\n // 通知 AuthService 地址变化\n useEffect(() => {\n authService.handleWalletChange(address);\n }, [address, authService]);\n\n // 监听状态和地址变化,触发 SWR 刷新\n const prevStatusRef = useRef<AuthStatus | undefined>(undefined);\n const prevAddressRef = useRef<string | null | undefined>(undefined);\n useEffect(() => {\n const prevStatus = prevStatusRef.current;\n const prevAddress = prevAddressRef.current;\n const currentStatus = authState.status;\n const currentAddress = authState.address;\n\n prevStatusRef.current = currentStatus;\n prevAddressRef.current = currentAddress;\n\n // 变为 authenticated 状态,或者地址变化时刷新\n if (\n (currentStatus === \"authenticated\" && prevStatus !== \"authenticated\") ||\n (currentStatus === \"authenticated\" && currentAddress !== prevAddress)\n ) {\n globalMutate(() => true, undefined, { revalidate: true });\n }\n }, [authState.status, authState.address, globalMutate]);\n\n const authenticate = useCallback(async () => {\n // 如果没有地址,不触发认证\n if (!address) {\n console.warn(\"[Auth] Cannot authenticate without address\");\n return;\n }\n\n // 如果已经在认证中,不重复触发\n if (authState.status === \"authenticating\") {\n console.log(\"[Auth] Authentication already in progress\");\n return;\n }\n\n try {\n await authService.authenticate(\"wallet-connect\");\n } catch (error) {\n // AuthError 已经被 AuthService 处理并存储到状态中\n console.error(\"[Auth] Authentication failed:\", error);\n }\n }, [authService, address, authState.status]);\n\n const logout = useCallback(() => {\n authService.logout();\n }, [authService]);\n\n return {\n status: authState.status,\n error: authState.error,\n address: authState.address,\n isAuthenticated: authState.status === \"authenticated\",\n isAuthenticating: authState.status === \"authenticating\",\n authenticate,\n logout,\n };\n};\n\nexport const AuthProvider = ({\n children,\n ...config\n}: PropsWithChildren<AuthProviderConfig>) => {\n // 使用 useMemo 创建和缓存实例\n const { authService, authRequest, address } = useMemo(() => {\n // 方式1:直接使用传入的实例\n if (isInstanceConfig(config)) {\n return {\n authService: config.authService,\n authRequest: config.authRequest,\n address: config.address,\n };\n }\n\n // 方式2:根据配置创建实例\n const { refreshTokenFn, axiosConfig, tokenStorageService, address } =\n config;\n\n const service = new AuthService({\n refreshToken: refreshTokenFn,\n tokenStorageService,\n });\n\n const request = createAuthRequest({\n authService: service,\n axiosConfig,\n });\n\n return { authService: service, authRequest: request, address };\n }, [config]);\n\n const auth = useAuthInternal({ authService, address });\n\n return (\n <AuthContext.Provider value={auth}>\n <AuthRequestContext.Provider value={authRequest}>\n <SWRConfig\n value={{\n revalidateOnFocus: false,\n shouldRetryOnError: false,\n dedupingInterval: 2000,\n revalidateOnReconnect: false,\n }}\n >\n {children}\n </SWRConfig>\n </AuthRequestContext.Provider>\n </AuthContext.Provider>\n );\n};\n","\"use client\";\n\nimport { useContext } from \"react\";\nimport { AuthContext, UseAuthResult } from \"../provider\";\n\nexport type { AuthStatus, UseAuthResult } from \"../provider\";\n\nexport const useAuth = (): UseAuthResult => {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error(\"useAuth must be used within AuthProvider\");\n }\n return context;\n};\n","\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport { useAuth, AuthStatus } from \"./useAuth\";\nimport { AuthError } from \"@/api/base/AuthError\";\n\nexport type AuthChangeType =\n | { type: \"authenticated\" }\n | { type: \"unauthenticated\"; error?: AuthError }\n | { type: \"error\"; error: AuthError };\n\n/**\n * 监听认证状态变化,通知调用方\n * @param onChange 状态变化时的回调函数\n */\nexport function useAuthChange(onChange: (change: AuthChangeType) => void) {\n const { status, error, address } = useAuth();\n const prevStatusRef = useRef<AuthStatus | undefined>(undefined);\n const prevAddressRef = useRef<string | null | undefined>(undefined);\n\n useEffect(() => {\n const prevStatus = prevStatusRef.current;\n const prevAddress = prevAddressRef.current;\n\n prevStatusRef.current = status;\n prevAddressRef.current = address;\n\n // 变为 authenticated 状态,或者地址变化时触发\n if (\n (status === \"authenticated\" && prevStatus !== \"authenticated\") ||\n (status === \"authenticated\" && address !== prevAddress)\n ) {\n onChange({ type: \"authenticated\" });\n } else if (error && status !== prevStatus) {\n onChange({ type: \"error\", error });\n } else if (\n status === \"unauthenticated\" &&\n prevStatus &&\n prevStatus !== \"idle\"\n ) {\n onChange({ type: \"unauthenticated\", error });\n }\n }, [status, error, address, onChange]);\n}\n","\"use client\";\n\nimport { useContext } from \"react\";\nimport { AxiosInstance } from \"axios\";\nimport { AuthRequestContext } from \"../provider\";\n\n/**\n * Hook for accessing the authenticated axios instance.\n * This hook is for module internal use only and should NOT be exported from api/index.ts\n */\nexport const useAuthRequest = (): AxiosInstance => {\n const context = useContext(AuthRequestContext);\n if (!context) {\n throw new Error(\"useAuthRequest must be used within AuthProvider\");\n }\n return context;\n};\n","\"use client\";\n\nimport type { BaseResponse } from \"@/api/base/types\";\nimport useSWR, { SWRConfiguration } from \"swr\";\nimport { useMemo } from \"react\";\nimport type { ResourceIdentity } from \"@/api/base/definition\";\nimport { useAuthRequest } from \"@/api/hooks/useAuthRequest\";\nimport { createFetcherInterceptor } from \"@/api/hooks/fetcherFactory\";\n\nexport const useResource = <Resp, Req>(\n requestIdentity?: ResourceIdentity<Resp, Req> | null,\n params?: Req,\n option?: SWRConfiguration<BaseResponse<Resp>>,\n) => {\n const authRequest = useAuthRequest();\n const fetcher = useMemo(\n () => createFetcherInterceptor(authRequest),\n [authRequest],\n );\n\n const { data, ...query } = useSWR<BaseResponse<Resp>>(\n requestIdentity && [requestIdentity, params],\n fetcher,\n option,\n );\n return {\n ...query,\n response: data,\n data: data?.data,\n };\n};\n","import { AxiosInstance } from \"axios\";\nimport type { BaseResponse } from \"../base/types\";\nimport { FetchIdentity } from \"../base/definition\";\nimport { getBaseRequest } from \"../base/request\";\n\n// ============================================================================\n// Fetcher Functions - SWR 集成\n// ============================================================================\n\n/**\n * 创建核心请求函数,根据 noAuth 选择实例\n */\nconst createFetchFn = (authRequest: AxiosInstance) => {\n return async <Resp, Req>(\n requestIdentity: FetchIdentity<Resp, Req>,\n payload?: Req,\n ): Promise<BaseResponse<Resp>> => {\n const { method, uri, noAuth } = requestIdentity;\n const instance = noAuth ? getBaseRequest() : authRequest;\n\n if (!method || method === \"get\") {\n const { data } = await instance.get<BaseResponse<Resp>>(uri, {\n params: payload,\n });\n return data;\n }\n\n if (method === \"delete\") {\n const { data } = await instance.delete<BaseResponse<Resp>>(uri, {\n data: payload,\n });\n return data;\n }\n\n const { data } = await instance.post<BaseResponse<Resp>>(uri, payload);\n return data;\n };\n};\n\n// 类型定义\ntype FetcherSingleParams<Resp, Req> = [\n FetchIdentity<Resp, Req>,\n Req | undefined,\n];\ntype FetcherBatchParams = Array<[FetchIdentity<unknown, unknown>, unknown]>;\n\n/**\n * 创建 SWR fetcher(支持单个和批量请求)\n */\nexport const createFetcherInterceptor = (authRequest: AxiosInstance) => {\n const fetchFn = createFetchFn(authRequest);\n\n function fetcherInterceptor<Resp, Req>(\n params: FetcherSingleParams<Resp, Req>,\n ): Promise<BaseResponse<Resp>>;\n function fetcherInterceptor(\n params: FetcherBatchParams,\n ): Promise<BaseResponse<unknown>[]>;\n async function fetcherInterceptor(\n params: FetcherSingleParams<unknown, unknown> | FetcherBatchParams,\n ): Promise<BaseResponse<unknown> | BaseResponse<unknown>[]> {\n if (Array.isArray(params[0])) {\n const multiParams = params as FetcherBatchParams;\n return await Promise.all(\n multiParams.map(([identity, payload]) => fetchFn(identity, payload)),\n );\n }\n\n const [identity, payload] = params as FetcherSingleParams<unknown, unknown>;\n return await fetchFn(identity, payload);\n }\n\n return fetcherInterceptor;\n};\n\n/**\n * 创建 SWR mutation fetcher\n */\nexport const createFetcherMutation = (authRequest: AxiosInstance) => {\n const fetchFn = createFetchFn(authRequest);\n\n return async <Resp, Req>(\n requestIdentity: FetchIdentity<Resp, Req>,\n { arg }: Readonly<{ arg: Req }>,\n ): Promise<BaseResponse<Resp>> => {\n const res = await fetchFn(requestIdentity, arg);\n\n if (!res.success || (res.code !== 0 && res.code !== 10001)) {\n throw Error(res.message);\n }\n return res;\n };\n};\n","\"use client\";\n\nimport type {\n BaseResponse,\n PaginationReq,\n PaginationResp,\n} from \"@/api/base/types\";\nimport useSWR, { SWRConfiguration } from \"swr\";\nimport { useMemo, useState } from \"react\";\nimport type { ResourceIdentity } from \"@/api/base/definition\";\nimport { useAuthRequest } from \"@/api/hooks/useAuthRequest\";\nimport { createFetcherInterceptor } from \"@/api/hooks/fetcherFactory\";\n\nexport const useResourceList = <RespItem, Req extends PaginationReq>(\n requestIdentity?: ResourceIdentity<PaginationResp<RespItem>, Req> | null,\n params?: Req,\n option?: SWRConfiguration<BaseResponse<PaginationResp<RespItem>>> & {\n page?: number;\n size?: number;\n pageMapping?: (pageInfo: {\n page: number;\n size: number;\n }) => Record<string, number>;\n },\n) => {\n const authRequest = useAuthRequest();\n const fetcher = useMemo(\n () => createFetcherInterceptor(authRequest),\n [authRequest],\n );\n\n const [page, setPage] = useState(option?.page ?? 1);\n const [size, setSize] = useState(option?.size ?? 10);\n const pageMapping = option?.pageMapping || ((pageInfo) => pageInfo);\n const keyWithPage = requestIdentity && [\n requestIdentity,\n { ...pageMapping({ page, size }), ...params },\n ];\n\n const { data, ...query } = useSWR<BaseResponse<PaginationResp<RespItem>>>(\n keyWithPage,\n fetcher,\n option,\n );\n\n return {\n ...query,\n response: data,\n list: data?.data?.items,\n pagination: {\n count: (data?.data?.total ?? 0) / size,\n page,\n size,\n setPage,\n setSize,\n },\n };\n};\n","\"use client\";\n\nimport type { BaseResponse } from \"@/api/base/types\";\nimport useSWRMutation, { SWRMutationConfiguration } from \"swr/mutation\";\nimport { useMemo } from \"react\";\nimport type { MutationIdentity } from \"@/api/base/definition\";\nimport { useAuthRequest } from \"@/api/hooks/useAuthRequest\";\nimport { createFetcherMutation } from \"@/api/hooks/fetcherFactory\";\n\nexport const useMutation = <Resp, Req>(\n key: MutationIdentity<Resp, Req>,\n option?: SWRMutationConfiguration<\n BaseResponse<Resp>,\n Error,\n MutationIdentity<Resp, Req>,\n Req\n >,\n) => {\n const authRequest = useAuthRequest();\n const fetcher = useMemo(\n () => createFetcherMutation(authRequest),\n [authRequest],\n );\n\n const { data, error, ...query } = useSWRMutation<\n BaseResponse<Resp>,\n Error,\n MutationIdentity<Resp, Req>,\n Req\n >(key, fetcher, option);\n\n return {\n ...query,\n error,\n response: data,\n data: data?.data,\n };\n};\n","// Re-export commonly used utilities\nexport { omit, pick, debounce, throttle } from \"radash\";\nexport { \n isEmpty, \n isEqual, \n cloneDeep, \n merge, \n get, \n set, \n uniq, \n uniqBy,\n groupBy,\n orderBy,\n sortBy\n} from \"lodash-es\";\n\n// Custom utility functions\nexport const sleep = (ms: number): Promise<void> => \n new Promise(resolve => setTimeout(resolve, ms));\n\nexport const formatCurrency = (\n amount: number, \n currency = 'USD', \n locale = 'en-US'\n): string => {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(amount);\n};\n\nexport const formatDate = (\n date: Date | string | number, \n options?: Intl.DateTimeFormatOptions,\n locale = 'en-US'\n): string => {\n return new Intl.DateTimeFormat(locale, options).format(new Date(date));\n};\n\nexport const generateId = (): string => {\n return Math.random().toString(36).substring(2) + Date.now().toString(36);\n};\n\nexport const copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch (error) {\n console.error('Failed to copy to clipboard:', error);\n return false;\n }\n};"],"mappings":"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","names":["axios","isBrowser","address","import_react","import_react","import_react","import_swr","import_react","data","identity","payload","useSWR","import_swr","import_react","useSWR","import_react","useSWRMutation"]}
|