@route-forge/core 0.0.1
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/README.md +34 -0
- package/dist/codegen.cjs +174 -0
- package/dist/codegen.cjs.map +1 -0
- package/dist/codegen.d.cts +47 -0
- package/dist/codegen.d.ts +47 -0
- package/dist/codegen.js +167 -0
- package/dist/codegen.js.map +1 -0
- package/dist/index.cjs +704 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +151 -0
- package/dist/index.d.ts +151 -0
- package/dist/index.js +690 -0
- package/dist/index.js.map +1 -0
- package/dist/types-UxdZAlmW.d.cts +187 -0
- package/dist/types-UxdZAlmW.d.ts +187 -0
- package/package.json +59 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cache.ts","../src/errors.ts","../src/interceptors.ts","../src/adapters/builtin-http.ts","../src/adapters/axios.ts","../src/adapters/index.ts","../src/forge.ts"],"names":["wrapped"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 按层级隔离的路由表缓存\n * @see .docs/SPEC.md §4.1.2\n *\n * 规则:\n * - 每层级独立条目,互不污染(cache key = `route-forge:${level}`)\n * - TTL 优先用后端响应里的 cache 字段,本地 cache.ttl 仅作兜底\n * - storage: 'memory' | 'sessionStorage' | 'localStorage'\n */\n\nimport type { CacheStorage, LevelRoutesResponse, RouteMeta } from './types.js';\n\ninterface CacheEntry {\n level: string;\n routes: Record<string, RouteMeta>;\n ttl: number | null;\n cachedAt: number;\n}\n\nconst KEY_PREFIX = 'route-forge:';\n\nfunction pickStorage(storage: CacheStorage): Storage | null {\n if (storage === 'memory') return null;\n if (typeof globalThis === 'undefined') return null;\n if (storage === 'sessionStorage') {\n return globalThis.sessionStorage ?? null;\n }\n if (storage === 'localStorage') {\n return globalThis.localStorage ?? null;\n }\n return null;\n}\n\nexport class RouteCache {\n private readonly storage: CacheStorage;\n private readonly fallbackTtl: number;\n private readonly backend: Storage | null;\n private readonly memory = new Map<string, CacheEntry>();\n\n constructor(opts: { storage: CacheStorage; ttl: number }) {\n this.storage = opts.storage;\n this.fallbackTtl = opts.ttl;\n this.backend = pickStorage(opts.storage);\n }\n\n private key(level: string): string {\n return `${KEY_PREFIX}${level}`;\n }\n\n get(level: string): CacheEntry | undefined {\n if (this.storage === 'memory' || !this.backend) {\n return this.getFromMemory(level);\n }\n const raw = this.backend.getItem(this.key(level));\n if (!raw) return undefined;\n try {\n const entry = JSON.parse(raw) as CacheEntry;\n if (this.isExpired(entry)) {\n this.del(level);\n return undefined;\n }\n return entry;\n } catch {\n return undefined;\n }\n }\n\n private getFromMemory(level: string): CacheEntry | undefined {\n const entry = this.memory.get(level);\n if (!entry) return undefined;\n if (this.isExpired(entry)) {\n this.memory.delete(level);\n return undefined;\n }\n return entry;\n }\n\n set(resp: LevelRoutesResponse): void {\n const ttl = resp.cache !== undefined && resp.cache !== null ? resp.cache : this.fallbackTtl;\n const entry: CacheEntry = {\n level: resp.level,\n routes: resp.routes,\n ttl,\n cachedAt: Date.now(),\n };\n if (this.storage === 'memory' || !this.backend) {\n this.memory.set(resp.level, entry);\n return;\n }\n try {\n this.backend.setItem(this.key(resp.level), JSON.stringify(entry));\n } catch {\n // 容量满或被禁用:回退内存\n this.memory.set(resp.level, entry);\n }\n }\n\n del(level: string): void {\n this.memory.delete(level);\n if (this.backend) {\n try {\n this.backend.removeItem(this.key(level));\n } catch {\n /* noop */\n }\n }\n }\n\n clear(): void {\n this.memory.clear();\n if (this.backend) {\n try {\n const toRemove: string[] = [];\n for (let i = 0; i < this.backend.length; i++) {\n const k = this.backend.key(i);\n if (k && k.startsWith(KEY_PREFIX)) toRemove.push(k);\n }\n for (const k of toRemove) this.backend.removeItem(k);\n } catch {\n /* noop */\n }\n }\n }\n\n private isExpired(entry: CacheEntry): boolean {\n if (entry.ttl === null) return false;\n if (entry.ttl === 0) return false; // 0 表示永久\n return Date.now() - entry.cachedAt > entry.ttl * 1000;\n }\n}\n","/**\n * Route Forge 错误基类与具体错误类\n * @see .docs/SPEC.md §6\n */\n\nexport interface ForgeErrorContext {\n [key: string]: unknown;\n}\n\nexport class ForgeError extends Error {\n readonly code: string;\n readonly route?: string;\n readonly level?: string;\n readonly context?: ForgeErrorContext;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n opts: {\n code: string;\n route?: string;\n level?: string;\n context?: ForgeErrorContext;\n cause?: unknown;\n },\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = opts.code;\n if (opts.route !== undefined) this.route = opts.route;\n if (opts.level !== undefined) this.level = opts.level;\n if (opts.context !== undefined) this.context = opts.context;\n if (opts.cause !== undefined) this.cause = opts.cause;\n }\n}\n\n/** RF_FE_001:路由名不存在于已加载层级中 */\nexport class UnknownRouteError extends ForgeError {\n constructor(route: string, level?: string) {\n super(`Route \"${route}\" not found${level ? ` in level \"${level}\"` : ''}`, {\n code: 'RF_FE_001',\n route,\n level,\n });\n }\n}\n\n/** RF_FE_002:路由所在层级未在 levels 声明 */\nexport class UnknownLevelError extends ForgeError {\n constructor(level: string) {\n super(`Level \"${level}\" not declared in options.levels`, {\n code: 'RF_FE_002',\n level,\n });\n }\n}\n\n/** RF_FE_003:路径参数缺失(strict=true 时) */\nexport class MissingRouteParamError extends ForgeError {\n constructor(route: string, missingParams: string[]) {\n super(`Missing path parameter(s) ${missingParams.join(', ')} for route \"${route}\"`, {\n code: 'RF_FE_003',\n route,\n context: { missingParams },\n });\n }\n}\n\n/** RF_FE_004:未登录访问受保护层级 */\nexport class InsufficientAuthError extends ForgeError {\n constructor(level: string) {\n super(`Insufficient auth: level \"${level}\" requires login`, {\n code: 'RF_FE_004',\n level,\n });\n }\n}\n\n/** RF_FE_005:adapter: 'axios' 但未检测到 axios */\nexport class AdapterNotFoundError extends ForgeError {\n constructor(adapter: string) {\n super(`Adapter \"${adapter}\" not available; install axios or use 'builtin'`, {\n code: 'RF_FE_005',\n context: { adapter },\n });\n }\n}\n\n/** RF_FE_006:请求拦截器返回非 RequestConfig */\nexport class InvalidInterceptorReturnError extends ForgeError {\n constructor(route?: string) {\n super(`Request interceptor must return a RequestConfig object`, {\n code: 'RF_FE_006',\n route,\n });\n }\n}\n\n/** RF_FE_007:adapter 抛出的网络错误(DNS、连接超时等) */\nexport class NetworkError extends ForgeError {\n constructor(message: string, route?: string, level?: string, cause?: unknown) {\n super(message, { code: 'RF_FE_007', route, level, cause });\n }\n}\n\n/** RF_FE_008:HTTP 非 2xx 且未被 onRejected 拦截器恢复 */\nexport class HTTPError extends ForgeError {\n constructor(\n message: string,\n opts: { route?: string; level?: string; status?: number; url?: string; method?: string; cause?: unknown },\n ) {\n super(message, {\n code: 'RF_FE_008',\n route: opts.route,\n level: opts.level,\n context: { status: opts.status, url: opts.url, method: opts.method },\n cause: opts.cause,\n });\n }\n}\n","/**\n * 拦截器管理器实现\n * @see .docs/SPEC.md §4.1.3a, §4.1.1\n *\n * 执行顺序约定(对齐 axios):\n * - 请求拦截器:LIFO(后注册先执行),onRejected 与 onFulfilled 同序\n * - 响应拦截器:FIFO(先注册先执行),onRejected 与 onFulfilled 同序\n *\n * 实现策略:\n * - InterceptorManagerImpl.forEach 保持正序迭代(与 use/eject 语义一致)\n * - runRequestInterceptors 收集 handlers 后 reverse() 再串联 Promise 链,实现 LIFO\n * - runResponseInterceptors 直接正序串联,实现 FIFO\n *\n * 串联实现:采用标准 Promise 链语义\n * `Promise.resolve(initial).then(f0, r0).then(f1, r1).then(f2, r2)...`\n * - onFulfilled 抛错 → 下一组 onRejected 接住\n * - onRejected 返回值 → 后续 onFulfilled 继续执行(恢复为正常流程)\n * - onRejected 抛错 → 下一组 onRejected 接住 / 进入调用方 catch\n */\n\nimport type {\n InterceptorHandler,\n InterceptorManager,\n RequestConfig,\n ResponseData,\n} from './types.js';\nimport { InvalidInterceptorReturnError } from './errors.js';\n\nexport class InterceptorManagerImpl<TIn, TOut = TIn> implements InterceptorManager<TIn, TOut> {\n private handlers: InterceptorHandler<TIn, TOut>[] = [];\n private nextId = 0;\n\n use(\n onFulfilled?: (value: TIn) => TOut | Promise<TOut>,\n onRejected?: (error: unknown) => unknown | Promise<unknown>,\n ): number {\n const id = this.nextId++;\n this.handlers.push({ id, onFulfilled, onRejected });\n return id;\n }\n\n eject(id: number): void {\n const idx = this.handlers.findIndex((h) => h.id === id);\n if (idx >= 0) this.handlers.splice(idx, 1);\n }\n\n clear(): void {\n this.handlers = [];\n }\n\n forEach(fn: (handler: InterceptorHandler<TIn, TOut>) => void): void {\n for (const h of this.handlers) fn(h);\n }\n\n /** 测试用:当前注册数量 */\n get size(): number {\n return this.handlers.length;\n }\n}\n\n/**\n * 串联请求拦截器(LIFO,对齐 axios)。\n *\n * - onFulfilled 必须返回对象(RequestConfig);非对象抛 InvalidInterceptorReturnError\n * - onFulfilled 抛错 → 同管理器的 onRejected 链;某段 onRejected 返回值则恢复正序流程\n * - 仍未消化则向上抛,不发请求\n */\nexport async function runRequestInterceptors(\n manager: InterceptorManager<RequestConfig, RequestConfig>,\n initial: RequestConfig,\n): Promise<RequestConfig> {\n const handlers: InterceptorHandler<RequestConfig, RequestConfig>[] = [];\n manager.forEach((h) => handlers.push(h));\n // 请求拦截器 LIFO(对齐 axios):后注册先执行\n handlers.reverse();\n\n let p: Promise<unknown> = Promise.resolve(initial);\n for (const h of handlers) {\n const onF = h.onFulfilled;\n const onR = h.onRejected;\n p = p.then(\n async (v) => {\n if (!onF) return v;\n const result = await onF(v as RequestConfig);\n if (result === null || typeof result !== 'object') {\n throw new InvalidInterceptorReturnError();\n }\n return result;\n },\n (e) => (onR ? onR(e) : Promise.reject(e)),\n );\n }\n return p as Promise<RequestConfig>;\n}\n\n/**\n * 串联响应拦截器(FIFO,对齐 axios)。\n *\n * - HTTP 非 2xx 或任一 onFulfilled 抛错 → onRejected 链;onRejected 返回值则恢复正序流程\n * - 首段 onFulfilled 接收 ResponseData;后续段接收上一段返回值(类型由用户约束)\n * - 末段返回值即 forge.api() 的 resolve 值\n *\n * @param source 已包含 HTTP 错误转换逻辑的 ResponseData Promise\n * (HTTP 非 2xx 时 reject 为 HTTPError;网络层错误 reject 为 NetworkError)\n */\nexport async function runResponseInterceptors(\n manager: InterceptorManager<ResponseData, unknown>,\n source: Promise<ResponseData>,\n): Promise<unknown> {\n const handlers: InterceptorHandler<ResponseData, unknown>[] = [];\n manager.forEach((h) => handlers.push(h));\n\n let p: Promise<unknown> = source;\n for (const h of handlers) {\n const onF = h.onFulfilled;\n const onR = h.onRejected;\n p = p.then(\n (v) => (onF ? onF(v as ResponseData) : v),\n (e) => (onR ? onR(e) : Promise.reject(e)),\n );\n }\n return p;\n}\n\n/**\n * 工厂函数:供自定义 Fetcher 复用同一套拦截器实现\n * @see .docs/SPEC.md §4.3.3\n */\nexport function createInterceptorManager<TIn, TOut = TIn>(): InterceptorManager<TIn, TOut> {\n return new InterceptorManagerImpl<TIn, TOut>();\n}\n","/**\n * 内置类 axios 精简实现(builtin adapter)\n * @see .docs/SPEC.md §4.3.1\n *\n * 设计目标:\n * - API 兼容 axios(use/eject/clear、request/get/post/...)便于业务代码零成本切换\n * - 拦截器执行顺序对齐 axios(请求 LIFO、响应 FIFO),与 SPEC §4.1.3a 一致\n * - 仅实现 Route Forge 调用链需要的能力:拦截器、JSON、超时、取消\n * - 零依赖,仅基于宿主原生 fetch(Node 18+ / 现代浏览器原生支持)\n * - 体积目标:min+gzip < 3KB,仅作为兜底,不追求覆盖 axios 全部 API\n */\n\nimport type { RequestConfig, ResponseData, InterceptorManager } from '../types.js';\nimport {\n createInterceptorManager,\n runRequestInterceptors,\n runResponseInterceptors,\n} from '../interceptors.js';\n\nexport function createBuiltinHttp(forgeInterceptors?: {\n request: InterceptorManager<RequestConfig, RequestConfig>;\n response: InterceptorManager<ResponseData, unknown>;\n}) {\n const requestMgr = forgeInterceptors?.request ?? createInterceptorManager<RequestConfig>();\n const responseMgr = forgeInterceptors?.response ?? createInterceptorManager<ResponseData>();\n\n async function request(config: RequestConfig): Promise<ResponseData> {\n // 1. 执行请求拦截器(LIFO,对齐 axios)\n const finalConfig = await runRequestInterceptors(requestMgr, config);\n\n // 2. 超时控制:timeout > 0 时用 AbortSignal.timeout\n const signal: AbortSignal | undefined =\n finalConfig.timeout && finalConfig.timeout > 0\n ? AbortSignal.timeout(finalConfig.timeout)\n : undefined;\n\n // 3. paramsSerializer:自定义 query 序列化\n let url = finalConfig.url;\n if (finalConfig.paramsSerializer && finalConfig.params) {\n const qs = finalConfig.paramsSerializer(finalConfig.params);\n if (qs) {\n url = url.includes('?') ? `${url}&${qs}` : `${url}?${qs}`;\n }\n }\n\n // 4. 构建 fetchInit\n const fetchInit: RequestInit = {\n method: finalConfig.method,\n headers: new Headers(finalConfig.headers),\n };\n if (signal) fetchInit.signal = signal;\n if (\n finalConfig.body !== undefined &&\n !['GET', 'HEAD'].includes(finalConfig.method.toUpperCase())\n ) {\n fetchInit.body =\n typeof finalConfig.body === 'string'\n ? finalConfig.body\n : JSON.stringify(finalConfig.body);\n }\n\n // 5. 调用 fetch\n const res = await fetch(url, fetchInit);\n const text = await res.text();\n let data: unknown = text;\n const contentType = res.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n data = JSON.parse(text);\n } catch {\n /* 保留原始文本 */\n }\n }\n\n // 6. 构建 ResponseData\n const responseData: ResponseData = {\n route: finalConfig.route,\n level: finalConfig.level,\n method: finalConfig.method,\n url,\n status: res.status,\n headers: res.headers,\n data,\n config: finalConfig,\n };\n\n // 7. 执行响应拦截器(FIFO,对齐 axios);末段返回值即 request() 的 resolve 值\n return runResponseInterceptors(\n responseMgr,\n Promise.resolve(responseData),\n ) as Promise<ResponseData>;\n }\n\n // 便捷方法\n const get = (url: string, config?: Partial<RequestConfig>) =>\n request({ ...config, url, method: 'GET' } as RequestConfig);\n const post = (url: string, config?: Partial<RequestConfig>) =>\n request({ ...config, url, method: 'POST' } as RequestConfig);\n const put = (url: string, config?: Partial<RequestConfig>) =>\n request({ ...config, url, method: 'PUT' } as RequestConfig);\n const patch = (url: string, config?: Partial<RequestConfig>) =>\n request({ ...config, url, method: 'PATCH' } as RequestConfig);\n const del = (url: string, config?: Partial<RequestConfig>) =>\n request({ ...config, url, method: 'DELETE' } as RequestConfig);\n\n return {\n request,\n interceptors: {\n request: requestMgr,\n response: responseMgr,\n },\n runsInterceptors: true,\n get,\n post,\n put,\n patch,\n delete: del,\n };\n}\n","/**\n * 把宿主项目的 axios 实例包装为 Fetcher adapter\n * @see .docs/SPEC.md §4.3.2, §4.3.4\n *\n * 设计约定:\n * - 不接管或修改宿主 axios 已有拦截器/defaults 配置,仅调用其 request 入口\n * - 宿主 axios 的 defaults.baseURL/defaults.headers 自动生效\n * - 宿主已注册的拦截器会先执行;Route Forge 自身拦截器在宿主拦截器之后执行\n * (由 forge.interceptors 注入到宿主 axios 时序)后续阶段填充\n * - 未检测到 axios 时返回 null(让 'auto' 自动降级到 builtin)\n */\n\nimport type { RequestConfig, ResponseData } from '../types.js';\nimport type { ResolvedAdapter } from './index.js';\n\nexport async function wrapAxiosAdapter(): Promise<ResolvedAdapter | null> {\n // ESM 友好的动态探测:尝试 import('axios'),失败则查全局 window.axios\n let axios: any;\n try {\n const mod = await import(/* @vite-ignore */ 'axios');\n axios = mod.default ?? mod;\n } catch {\n if (typeof globalThis !== 'undefined' && (globalThis as any).axios) {\n axios = (globalThis as any).axios;\n }\n }\n if (!axios || typeof axios.request !== 'function') return null;\n\n async function request(config: RequestConfig): Promise<ResponseData> {\n const headers: Record<string, string> = { ...config.headers };\n const res = await axios.request({\n url: config.url,\n method: config.method,\n headers,\n data: config.body,\n // axios 会处理 baseURL/transformRequest 等 defaults\n });\n\n return {\n route: config.route,\n level: config.level,\n method: config.method,\n url: config.url,\n status: res.status,\n headers: new Headers(res.headers ?? {}),\n data: res.data,\n config,\n };\n }\n\n // 不暴露宿主 axios 的 interceptors manager(避免覆盖 Route Forge 的统一时序);\n // Route Forge 调用链由 forge.interceptors 控制,宿主拦截器先执行由 axios 内部保证。\n return { request, interceptors: undefined };\n}\n","/**\n * Adapter 入口\n * @see .docs/SPEC.md §4.3\n *\n * Route Forge 提供三种 adapter:\n * 1. 'auto'(默认):检测到宿主 axios 则用之;否则用内置 builtin adapter\n * 2. 'axios':强制宿主 axios,未安装抛 AdapterNotFoundError\n * 3. 'builtin':强制内置实现\n * 自定义 Fetcher 接口直接传入即可(绕过 auto 检测)。\n */\n\nimport type { Fetcher, InterceptorManager, RequestConfig, ResponseData } from '../types.js';\nimport { AdapterNotFoundError } from '../errors.js';\nimport { createBuiltinHttp } from './builtin-http.js';\nimport { wrapAxiosAdapter } from './axios.js';\n\nexport type ResolvedAdapter = {\n request: (config: RequestConfig) => Promise<ResponseData>;\n interceptors?: Fetcher['interceptors'];\n runsInterceptors?: boolean;\n /**\n * 便捷方法(可选)。\n * - builtin adapter 提供全部 5 个方法\n * - axios / 自定义 Fetcher 可不提供(调用方需先判断存在性)\n * @see .docs/SPEC.md §4.3.1\n */\n get?: (url: string, config?: Partial<RequestConfig>) => Promise<ResponseData>;\n post?: (url: string, config?: Partial<RequestConfig>) => Promise<ResponseData>;\n put?: (url: string, config?: Partial<RequestConfig>) => Promise<ResponseData>;\n patch?: (url: string, config?: Partial<RequestConfig>) => Promise<ResponseData>;\n delete?: (url: string, config?: Partial<RequestConfig>) => Promise<ResponseData>;\n};\n\nexport interface ResolveAdapterOptions {\n adapter: 'auto' | 'axios' | 'builtin' | Fetcher;\n forgeInterceptors?: {\n request: InterceptorManager<RequestConfig, RequestConfig>;\n response: InterceptorManager<ResponseData, unknown>;\n };\n}\n\n/**\n * 解析 adapter 配置;同步阶段尝试 import('axios'),失败则降级。\n * 注意:实际 axios 探测在生产实现里需要 lazy import;此处仅为框架占位。\n */\nexport async function resolveAdapter(opts: ResolveAdapterOptions): Promise<ResolvedAdapter> {\n const { adapter } = opts;\n\n if (adapter && typeof adapter === 'object') {\n return {\n request: (config: RequestConfig) => adapter.request(config),\n interceptors: adapter.interceptors,\n };\n }\n\n if (adapter === 'builtin') {\n return createBuiltinHttp(opts.forgeInterceptors);\n }\n\n if (adapter === 'axios') {\n const wrapped = await wrapAxiosAdapter();\n if (!wrapped) throw new AdapterNotFoundError('axios');\n return wrapped;\n }\n\n // auto: 优先尝试 axios,失败则 builtin\n const wrapped = await wrapAxiosAdapter().catch(() => null);\n if (wrapped) return wrapped;\n return createBuiltinHttp(opts.forgeInterceptors);\n}\n","/**\n * Route Forge 主入口:createRouteForge\n * @see .docs/SPEC.md §4.1.1 ~ §4.1.6\n *\n * 能力清单(v1.0 MVP):\n * - 按层级懒加载与隔离缓存(§4.1.2)\n * - 并发去重(§4.1.4)\n * - 登录态感知(§4.1.5)\n * - 严格模式(§4.1.6)\n * - 通过路由名调用 API(§4.1.3)\n * - 拦截器(§4.1.3a)\n * - Adapter auto 检测 / builtin / axios / 自定义 Fetcher(§4.3)\n */\n\nimport { RouteCache } from './cache.js';\nimport {\n InterceptorManagerImpl,\n createInterceptorManager,\n runRequestInterceptors,\n runResponseInterceptors,\n} from './interceptors.js';\nimport { resolveAdapter } from './adapters/index.js';\nimport {\n AdapterNotFoundError,\n ForgeError,\n HTTPError,\n InsufficientAuthError,\n MissingRouteParamError,\n NetworkError,\n UnknownLevelError,\n UnknownRouteError,\n} from './errors.js';\nimport type {\n ApiCallParams,\n InterceptorManager,\n LevelRoutesResponse,\n RequestConfig,\n ResponseData,\n RouteForge,\n RouteForgeOptions,\n RouteMeta,\n SummaryResponse,\n} from './types.js';\n\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_CACHE_TTL = 3600;\nconst DEFAULT_NAME_SEPARATOR = '.';\n\nexport function createRouteForge(options: RouteForgeOptions): RouteForge {\n if (!options.endpoint) throw new TypeError('options.endpoint is required');\n\n const {\n adapter = 'auto',\n timeout = DEFAULT_TIMEOUT,\n baseURL = '',\n nameSeparator = DEFAULT_NAME_SEPARATOR,\n auth,\n interceptors: declarativeInterceptors,\n cache: cacheOpts = {},\n } = options;\n\n // --- 自动发现(SPEC §4.1.1 + §5.3)---\n const explicitLevels = options.levels;\n const explicitEager = options.eager;\n const explicitStrict = options.strict ?? false;\n const explicitEndpoint = options.endpoint;\n\n // effective* 状态:在摘要端点响应到达后被填充\n let effectiveLevels: string[] = explicitLevels ?? [];\n let effectiveEager: string[] = explicitEager ?? [];\n let effectiveStrict = explicitStrict;\n let effectiveEndpoint = explicitEndpoint;\n\n // 拉取摘要端点(用于 strict_mode / endpoint / levels / eager 自动发现)\n const summaryPromise = (async (): Promise<SummaryResponse | null> => {\n try {\n const summaryUrl = explicitEndpoint; // GET {endpoint} = 摘要端点\n const resp = await fetch(summaryUrl, { method: 'GET' });\n if (!resp.ok) {\n console.warn(\n `[route-forge] summary endpoint ${summaryUrl} unreachable (HTTP ${resp.status}); falling back to explicit options`,\n );\n return null;\n }\n return (await resp.json()) as SummaryResponse;\n } catch (e) {\n if (explicitLevels && explicitLevels.length > 0) {\n console.warn(\n `[route-forge] summary endpoint unreachable: ${(e as Error).message}; using explicit levels`,\n );\n return null;\n }\n // 未传 levels 且摘要端点不可达 → 抛 UnknownLevelError\n throw new UnknownLevelError('(auto-discovery)');\n }\n })();\n\n // 自动发现异步填充(不阻塞 createRouteForge 返回)\n const autoDiscoveryPromise = summaryPromise.then((summary) => {\n if (summary === null) {\n return;\n }\n\n // 1. endpoint 后端权威\n if (summary.config.endpoint_prefix && summary.config.endpoint_prefix !== explicitEndpoint) {\n console.warn(\n `[route-forge] backend endpoint_prefix \"${summary.config.endpoint_prefix}\" overrides frontend endpoint \"${explicitEndpoint}\"`,\n );\n effectiveEndpoint = summary.config.endpoint_prefix;\n }\n\n // 2. strict_mode 后端权威:不能放宽,可收紧\n if (summary.config.strict_mode && !explicitStrict) {\n console.warn(\n '[route-forge] backend strict_mode=true overrides frontend strict=false; forcing strict=true',\n );\n effectiveStrict = true;\n }\n\n // 3. levels 取交集或自动发现\n const backendLevels = Object.keys(summary.levels);\n if (explicitLevels && explicitLevels.length > 0) {\n const intersection = explicitLevels.filter((l) => backendLevels.includes(l));\n const removed = explicitLevels.filter((l) => !backendLevels.includes(l));\n if (removed.length > 0) {\n console.warn(\n `[route-forge] levels not in backend summary and dropped: ${removed.join(', ')}`,\n );\n }\n effectiveLevels = intersection;\n } else {\n effectiveLevels = backendLevels;\n }\n\n // 4. eager 未传时取后端 load:'eager' 层级\n if (!explicitEager) {\n effectiveEager = backendLevels.filter((lvl) => summary.levels[lvl]?.load === 'eager');\n }\n });\n\n // 防止 autoDiscoveryPromise 未被 await 时产生 unhandled rejection\n autoDiscoveryPromise.catch(() => {\n /* 自动发现失败:在 load/api await 时会重新抛出 */\n });\n\n const cacheTtl = cacheOpts.ttl ?? DEFAULT_CACHE_TTL;\n const cacheStorage = cacheOpts.storage ?? 'memory';\n const cache = new RouteCache({ storage: cacheStorage, ttl: cacheTtl });\n\n const requestInterceptors: InterceptorManager<RequestConfig, RequestConfig> = new InterceptorManagerImpl();\n const responseInterceptors: InterceptorManager<ResponseData, unknown> = new InterceptorManagerImpl();\n\n // 声明式拦截器先注册(按数组顺序),随后允许运行时 use() 追加\n if (declarativeInterceptors?.request) {\n for (const pair of declarativeInterceptors.request) {\n const [onFulfilled, onRejected] = pair;\n requestInterceptors.use(onFulfilled, onRejected);\n }\n }\n if (declarativeInterceptors?.response) {\n for (const pair of declarativeInterceptors.response) {\n const [onFulfilled, onRejected] = pair;\n responseInterceptors.use(onFulfilled, onRejected);\n }\n }\n\n const adapterPromise = resolveAdapter({\n adapter,\n forgeInterceptors: { request: requestInterceptors, response: responseInterceptors },\n });\n let adapterResolved = false;\n let adapterObj: Awaited<ReturnType<typeof resolveAdapter>> | null = null;\n\n async function ensureAdapter() {\n if (!adapterResolved) {\n adapterObj = await adapterPromise.catch((e) => {\n if (e instanceof AdapterNotFoundError) throw e;\n // 其他错误降级到 builtin(避免初始化失败)\n return resolveAdapter({ adapter: 'builtin' });\n });\n adapterResolved = true;\n }\n return adapterObj!;\n }\n\n const inflight = new Map<string, Promise<void>>();\n\n function isAuthRequired(level: string): boolean {\n return Boolean(auth?.levels?.[level]);\n }\n\n function assertAuth(level: string): void {\n if (isAuthRequired(level) && auth?.state && !auth.state()) {\n throw new InsufficientAuthError(level);\n }\n }\n\n function assertLevelDeclared(level: string): void {\n if (!effectiveLevels.includes(level)) {\n throw new UnknownLevelError(level);\n }\n }\n\n function buildUrl(level: string): string {\n const base = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL;\n const ep = effectiveEndpoint.startsWith('/') ? effectiveEndpoint : `/${effectiveEndpoint}`;\n return `${base}${ep}/${encodeURIComponent(level)}`;\n }\n\n async function fetchLevel(level: string): Promise<LevelRoutesResponse> {\n const adp = await ensureAdapter();\n const config: RequestConfig = {\n route: `__forge__.load.${level}`,\n level,\n method: 'GET',\n url: buildUrl(level),\n headers: { Accept: 'application/json' },\n params: {},\n timeout,\n meta: {\n name: `__forge__.load.${level}`,\n uri: buildUrl(level),\n methods: ['GET'],\n parameters: [],\n level,\n },\n };\n // 拉取元信息直接走 adapter(不走 forge.interceptors 链,避免与业务调用混淆)\n const resp = await adp.request(config);\n if (!resp || resp.status < 200 || resp.status >= 300) {\n throw new Error(`Failed to load level ${level}: HTTP ${resp?.status}`);\n }\n const data = resp.data as LevelRoutesResponse;\n // 后端可能下发 cache 字段,让 RouteCache 优先采用\n return data;\n }\n\n async function loadOne(level: string): Promise<void> {\n assertLevelDeclared(level);\n assertAuth(level);\n\n // 缓存命中直接返回\n if (cache.get(level)) return;\n\n // inflight 去重\n const existing = inflight.get(level);\n if (existing) return existing;\n\n const p = (async () => {\n try {\n const resp = await fetchLevel(level);\n cache.set(resp);\n } finally {\n inflight.delete(level);\n }\n })();\n inflight.set(level, p);\n return p;\n }\n\n async function load(level: string | string[]): Promise<void> {\n await autoDiscoveryPromise;\n const list = Array.isArray(level) ? level : [level];\n await Promise.all(list.map(loadOne));\n }\n\n function route(name: string, params?: Record<string, unknown>): string {\n // 静态生成 URL:仅查已加载缓存,未加载时 strict 抛 UnknownRouteError\n const meta = findRouteMeta(name);\n if (!meta) {\n if (effectiveStrict) throw new UnknownRouteError(name);\n return '';\n }\n return buildRequestUrl(meta, params ?? {});\n }\n\n function buildRequestUrl(meta: RouteMeta, params: Record<string, unknown>): string {\n let uri = meta.uri;\n for (const p of meta.parameters) {\n const v = params[p];\n if (v === undefined) {\n if (effectiveStrict) throw new MissingRouteParamError(meta.name, [p]);\n uri = uri.replace(`{${p}}`, '');\n } else {\n uri = uri.replace(`{${p}}`, encodeURIComponent(String(v)));\n }\n }\n const base = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL;\n return uri.startsWith('/') ? `${base}${uri}` : `${base}/${uri}`;\n }\n\n function findRouteMeta(name: string): RouteMeta | undefined {\n for (const level of effectiveLevels) {\n const entry = cache.get(level);\n const meta = entry?.routes[name];\n if (meta) {\n return { ...meta, level };\n }\n }\n return undefined;\n }\n\n async function api(name: string, params: ApiCallParams = {}): Promise<unknown> {\n await autoDiscoveryPromise;\n const meta = findRouteMeta(name);\n if (!meta) {\n // 隐式懒加载:路由名不在缓存中,可能是其层级尚未加载\n // 1. 尝试通过 name 分隔符拆出可能的 level 名(如 'admin.users.show' → 'admin')\n const firstSeg = name.split(nameSeparator)[0];\n if (firstSeg && effectiveLevels.includes(firstSeg)) {\n await load(firstSeg);\n }\n // 重新查询\n const reMeta = findRouteMeta(name);\n if (!reMeta) {\n if (effectiveStrict) throw new UnknownRouteError(name);\n return undefined;\n }\n return doApiCall(reMeta, params);\n }\n return doApiCall(meta, params);\n }\n\n async function doApiCall(meta: RouteMeta, params: ApiCallParams): Promise<unknown> {\n assertAuth(meta.level ?? '');\n const { query, body, headers, ...pathParams } = params;\n\n // 校验路径参数\n for (const p of meta.parameters) {\n if (pathParams[p] === undefined) {\n if (effectiveStrict) throw new MissingRouteParamError(meta.name, [p]);\n }\n }\n\n const method = pickMethod(meta);\n const urlWithQuery = appendQuery(buildRequestUrl(meta, pathParams as Record<string, unknown>), query);\n const config: RequestConfig = {\n route: meta.name,\n level: meta.level ?? '',\n method,\n url: urlWithQuery,\n headers: { Accept: 'application/json', ...(headers ?? {}) },\n body,\n params: pathParams as Record<string, unknown>,\n timeout,\n meta,\n };\n\n const adp = await ensureAdapter();\n\n // 5. 请求拦截链(LIFO,对齐 axios);任一段抛错且 onRejected 未消化 → 进入调用方 catch,不发请求\n // builtin adapter 内部已执行 forge 拦截器(同一管理器对象引用,runsInterceptors=true)→ 跳过\n const finalConfig = adp.runsInterceptors\n ? config\n : await runRequestInterceptors(requestInterceptors, config);\n\n // 6. adapter 调用 → 7/8 的错误转换 + 响应拦截链\n // HTTP 非 2xx 转 HTTPError;底层网络错误(非 ForgeError)转 NetworkError\n // 注意:source 始终构造(含错误转换逻辑),runsInterceptors=true 时直接返回 source\n const source: Promise<ResponseData> = adp.request(finalConfig).then(\n (resp) => {\n if (resp.status < 200 || resp.status >= 300) {\n throw new HTTPError(\n `HTTP ${resp.status} for route \"${resp.route}\" (${resp.method} ${resp.url})`,\n {\n route: resp.route,\n level: resp.level,\n status: resp.status,\n url: resp.url,\n method: resp.method,\n },\n );\n }\n return resp;\n },\n (err) => {\n // 已经是 ForgeError(如拦截器内重新抛的)→ 原样抛\n if (err instanceof ForgeError) throw err;\n throw new NetworkError(\n err instanceof Error ? err.message : String(err),\n meta.name,\n meta.level,\n err,\n );\n },\n );\n\n // 响应拦截链(FIFO,对齐 axios);末段返回值即 api() resolve 值\n // builtin adapter 内部已执行 forge 响应拦截器(runsInterceptors=true)→ 直接返回 source\n if (adp.runsInterceptors) return source;\n return runResponseInterceptors(responseInterceptors, source);\n }\n\n function invalidate(level?: string): void {\n if (level) cache.del(level);\n else cache.clear();\n }\n\n // eager 层级自动加载(不阻塞 createRouteForge 返回;在自动发现完成后触发)\n void autoDiscoveryPromise\n .then(() => {\n if (effectiveEager.length > 0) {\n void Promise.all(effectiveEager.map((lvl) => load(lvl))).catch((e) => {\n console.warn(`[route-forge] eager load failed: ${(e as Error).message}`);\n });\n }\n })\n .catch(() => {\n /* 自动发现失败时不触发 eager */\n });\n\n return {\n api,\n load,\n route,\n invalidate,\n interceptors: {\n request: requestInterceptors,\n response: responseInterceptors,\n },\n };\n}\n\nfunction pickMethod(meta: RouteMeta): string {\n const m = meta.methods.find((x) => x.toUpperCase() !== 'HEAD');\n return (m ?? meta.methods[0] ?? 'GET').toUpperCase();\n}\n\nfunction appendQuery(url: string, query?: Record<string, unknown>): string {\n if (!query) return url;\n const usp = new URLSearchParams();\n for (const [k, v] of Object.entries(query)) {\n if (v === undefined || v === null) continue;\n usp.append(k, String(v));\n }\n const qs = usp.toString();\n if (!qs) return url;\n return url.includes('?') ? `${url}&${qs}` : `${url}?${qs}`;\n}\n\n// 显式重导出,便于业务代码按需导入工具件\nexport { createInterceptorManager } from './interceptors.js';\nexport { RouteCache } from './cache.js';\nexport { ForgeError } from './errors.js';\n"]}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @route-forge/core 核心类型定义
|
|
3
|
+
* @see .docs/SPEC.md §4.1.3a, §4.1.1
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 路由元信息(后端 /_forge/routes/{level} 返回的单条路由结构)
|
|
7
|
+
*/
|
|
8
|
+
interface RouteMeta {
|
|
9
|
+
/** 路由名,如 'admin.users.show' */
|
|
10
|
+
name: string;
|
|
11
|
+
/** 路由 URI 模板,如 'admin/users/{user}' */
|
|
12
|
+
uri: string;
|
|
13
|
+
/** 支持的 HTTP 方法集合,如 ['GET','HEAD'] */
|
|
14
|
+
methods: string[];
|
|
15
|
+
/** 路径参数名列表,如 ['user'] */
|
|
16
|
+
parameters: string[];
|
|
17
|
+
/** 所属层级(前端填充,便于隔离缓存) */
|
|
18
|
+
level?: string;
|
|
19
|
+
/** 后端下发的缓存 TTL(秒),优先级高于本地 cache.ttl */
|
|
20
|
+
cache?: number | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 某层级下的全部路由元信息响应
|
|
24
|
+
*/
|
|
25
|
+
interface LevelRoutesResponse {
|
|
26
|
+
level: string;
|
|
27
|
+
routes: Record<string, RouteMeta>;
|
|
28
|
+
/** 后端可选下发该层级缓存 TTL */
|
|
29
|
+
cache?: number | null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 摘要端点响应(SPEC §3.1.6)
|
|
33
|
+
* GET /_forge/routes 返回此结构
|
|
34
|
+
*/
|
|
35
|
+
interface SummaryResponse {
|
|
36
|
+
levels: Record<string, {
|
|
37
|
+
description: string;
|
|
38
|
+
load: 'lazy' | 'eager';
|
|
39
|
+
cache: number | null;
|
|
40
|
+
route_count: number;
|
|
41
|
+
}>;
|
|
42
|
+
config: {
|
|
43
|
+
strict_mode: boolean;
|
|
44
|
+
endpoint_prefix: string;
|
|
45
|
+
};
|
|
46
|
+
unassigned: Array<{
|
|
47
|
+
name: string;
|
|
48
|
+
uri: string;
|
|
49
|
+
methods: string[];
|
|
50
|
+
parameters: string[];
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 请求拦截器接收/返回的配置对象(可变,返回修改后的版本)
|
|
55
|
+
*/
|
|
56
|
+
interface RequestConfig {
|
|
57
|
+
route: string;
|
|
58
|
+
level: string;
|
|
59
|
+
method: string;
|
|
60
|
+
url: string;
|
|
61
|
+
headers: Record<string, string>;
|
|
62
|
+
body?: unknown;
|
|
63
|
+
params: Record<string, unknown>;
|
|
64
|
+
meta: RouteMeta;
|
|
65
|
+
/** 请求超时毫秒数 */
|
|
66
|
+
timeout?: number;
|
|
67
|
+
/** 自定义 query 序列化函数 */
|
|
68
|
+
paramsSerializer?: (params: Record<string, unknown>) => string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 响应拦截器首段接收的完整数据对象
|
|
72
|
+
*/
|
|
73
|
+
interface ResponseData {
|
|
74
|
+
route: string;
|
|
75
|
+
level: string;
|
|
76
|
+
method: string;
|
|
77
|
+
url: string;
|
|
78
|
+
status: number;
|
|
79
|
+
headers: Headers;
|
|
80
|
+
data: unknown;
|
|
81
|
+
config: RequestConfig;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* forge.api(name, params) 调用参数
|
|
85
|
+
*/
|
|
86
|
+
interface ApiCallParams {
|
|
87
|
+
/** 路径参数:填充到 URI 模板的 {name} 占位符 */
|
|
88
|
+
[paramName: string]: unknown;
|
|
89
|
+
/** 查询参数,序列化到 URL query string */
|
|
90
|
+
query?: Record<string, unknown>;
|
|
91
|
+
/** 请求体,按 method 决定是否发送 */
|
|
92
|
+
body?: unknown;
|
|
93
|
+
/** 自定义请求头(与拦截器叠加) */
|
|
94
|
+
headers?: Record<string, string>;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 缓存存储介质
|
|
98
|
+
*/
|
|
99
|
+
type CacheStorage = 'memory' | 'sessionStorage' | 'localStorage';
|
|
100
|
+
/**
|
|
101
|
+
* Adapter 选择值
|
|
102
|
+
*/
|
|
103
|
+
type AdapterOption = 'auto' | 'axios' | 'builtin' | Fetcher;
|
|
104
|
+
/**
|
|
105
|
+
* Fetcher 接口(自定义 adapter)
|
|
106
|
+
* @see .docs/SPEC.md §4.3.3
|
|
107
|
+
*/
|
|
108
|
+
interface Fetcher {
|
|
109
|
+
request(config: RequestConfig): Promise<ResponseData>;
|
|
110
|
+
interceptors?: {
|
|
111
|
+
request?: InterceptorManager<RequestConfig, RequestConfig>;
|
|
112
|
+
response?: InterceptorManager<ResponseData, unknown>;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 拦截器管理器接口(与 axios use/eject/clear API 一致)
|
|
117
|
+
*
|
|
118
|
+
* 双类型参数说明(对应 SPEC §4.1.3a):
|
|
119
|
+
* - 请求拦截:TIn = TOut = RequestConfig(不可变换类型,仅修改字段)
|
|
120
|
+
* - 响应拦截:TIn = ResponseData, TOut = unknown(首段接收 ResponseData,
|
|
121
|
+
* 后续段接收上一段返回值,返回类型由用户自行约束)
|
|
122
|
+
*/
|
|
123
|
+
interface InterceptorManager<TIn, TOut = TIn> {
|
|
124
|
+
use(onFulfilled?: (value: TIn) => TOut | Promise<TOut>, onRejected?: (error: unknown) => unknown | Promise<unknown>): number;
|
|
125
|
+
eject(id: number): void;
|
|
126
|
+
clear(): void;
|
|
127
|
+
/** 内部使用:当前已注册拦截器快照 */
|
|
128
|
+
forEach(fn: (handler: InterceptorHandler<TIn, TOut>) => void): void;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 单个拦截器内部结构
|
|
132
|
+
*/
|
|
133
|
+
interface InterceptorHandler<TIn, TOut = TIn> {
|
|
134
|
+
id: number;
|
|
135
|
+
onFulfilled?: (value: TIn) => TOut | Promise<TOut>;
|
|
136
|
+
onRejected?: (error: unknown) => unknown | Promise<unknown>;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* forge 顶层 API 形状
|
|
140
|
+
*/
|
|
141
|
+
interface RouteForge {
|
|
142
|
+
/** 通过路由名调用 API */
|
|
143
|
+
api(name: string, params?: ApiCallParams): Promise<unknown>;
|
|
144
|
+
/** 拉取一个或多个层级(自动并发去重) */
|
|
145
|
+
load(level: string | string[]): Promise<void>;
|
|
146
|
+
/** 仅生成 URL,不发请求 */
|
|
147
|
+
route(name: string, params?: Record<string, unknown>): string;
|
|
148
|
+
/** 失效指定层级缓存;不传参失效全部 */
|
|
149
|
+
invalidate(level?: string): void;
|
|
150
|
+
/** 拦截器入口(请求 / 响应) */
|
|
151
|
+
interceptors: {
|
|
152
|
+
request: InterceptorManager<RequestConfig, RequestConfig>;
|
|
153
|
+
response: InterceptorManager<ResponseData, unknown>;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* createRouteForge 配置项
|
|
158
|
+
* @see .docs/SPEC.md §5.2
|
|
159
|
+
*/
|
|
160
|
+
interface RouteForgeOptions {
|
|
161
|
+
endpoint: string;
|
|
162
|
+
/**
|
|
163
|
+
* 层级列表。未传时从摘要端点自动发现(SPEC §4.1.1)。
|
|
164
|
+
* 显式传入时取与后端摘要响应 levels 键的交集(前端不能声明后端不存在的层级,SPEC §5.3)。
|
|
165
|
+
*/
|
|
166
|
+
levels?: string[];
|
|
167
|
+
eager?: string[];
|
|
168
|
+
adapter?: AdapterOption;
|
|
169
|
+
cache?: {
|
|
170
|
+
ttl?: number;
|
|
171
|
+
storage?: CacheStorage;
|
|
172
|
+
};
|
|
173
|
+
auth?: {
|
|
174
|
+
state?: () => boolean;
|
|
175
|
+
levels?: Record<string, boolean>;
|
|
176
|
+
};
|
|
177
|
+
interceptors?: {
|
|
178
|
+
request?: Array<[((c: RequestConfig) => RequestConfig | Promise<RequestConfig>) | undefined, ((e: unknown) => unknown | Promise<unknown>) | undefined]>;
|
|
179
|
+
response?: Array<[((r: ResponseData) => unknown | Promise<unknown>) | undefined, ((e: unknown) => unknown | Promise<unknown>) | undefined]>;
|
|
180
|
+
};
|
|
181
|
+
strict?: boolean;
|
|
182
|
+
timeout?: number;
|
|
183
|
+
baseURL?: string;
|
|
184
|
+
nameSeparator?: string;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export type { AdapterOption as A, CacheStorage as C, Fetcher as F, InterceptorManager as I, LevelRoutesResponse as L, RouteMeta as R, SummaryResponse as S, InterceptorHandler as a, RouteForgeOptions as b, RouteForge as c, ApiCallParams as d, RequestConfig as e, ResponseData as f };
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @route-forge/core 核心类型定义
|
|
3
|
+
* @see .docs/SPEC.md §4.1.3a, §4.1.1
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 路由元信息(后端 /_forge/routes/{level} 返回的单条路由结构)
|
|
7
|
+
*/
|
|
8
|
+
interface RouteMeta {
|
|
9
|
+
/** 路由名,如 'admin.users.show' */
|
|
10
|
+
name: string;
|
|
11
|
+
/** 路由 URI 模板,如 'admin/users/{user}' */
|
|
12
|
+
uri: string;
|
|
13
|
+
/** 支持的 HTTP 方法集合,如 ['GET','HEAD'] */
|
|
14
|
+
methods: string[];
|
|
15
|
+
/** 路径参数名列表,如 ['user'] */
|
|
16
|
+
parameters: string[];
|
|
17
|
+
/** 所属层级(前端填充,便于隔离缓存) */
|
|
18
|
+
level?: string;
|
|
19
|
+
/** 后端下发的缓存 TTL(秒),优先级高于本地 cache.ttl */
|
|
20
|
+
cache?: number | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 某层级下的全部路由元信息响应
|
|
24
|
+
*/
|
|
25
|
+
interface LevelRoutesResponse {
|
|
26
|
+
level: string;
|
|
27
|
+
routes: Record<string, RouteMeta>;
|
|
28
|
+
/** 后端可选下发该层级缓存 TTL */
|
|
29
|
+
cache?: number | null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 摘要端点响应(SPEC §3.1.6)
|
|
33
|
+
* GET /_forge/routes 返回此结构
|
|
34
|
+
*/
|
|
35
|
+
interface SummaryResponse {
|
|
36
|
+
levels: Record<string, {
|
|
37
|
+
description: string;
|
|
38
|
+
load: 'lazy' | 'eager';
|
|
39
|
+
cache: number | null;
|
|
40
|
+
route_count: number;
|
|
41
|
+
}>;
|
|
42
|
+
config: {
|
|
43
|
+
strict_mode: boolean;
|
|
44
|
+
endpoint_prefix: string;
|
|
45
|
+
};
|
|
46
|
+
unassigned: Array<{
|
|
47
|
+
name: string;
|
|
48
|
+
uri: string;
|
|
49
|
+
methods: string[];
|
|
50
|
+
parameters: string[];
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 请求拦截器接收/返回的配置对象(可变,返回修改后的版本)
|
|
55
|
+
*/
|
|
56
|
+
interface RequestConfig {
|
|
57
|
+
route: string;
|
|
58
|
+
level: string;
|
|
59
|
+
method: string;
|
|
60
|
+
url: string;
|
|
61
|
+
headers: Record<string, string>;
|
|
62
|
+
body?: unknown;
|
|
63
|
+
params: Record<string, unknown>;
|
|
64
|
+
meta: RouteMeta;
|
|
65
|
+
/** 请求超时毫秒数 */
|
|
66
|
+
timeout?: number;
|
|
67
|
+
/** 自定义 query 序列化函数 */
|
|
68
|
+
paramsSerializer?: (params: Record<string, unknown>) => string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 响应拦截器首段接收的完整数据对象
|
|
72
|
+
*/
|
|
73
|
+
interface ResponseData {
|
|
74
|
+
route: string;
|
|
75
|
+
level: string;
|
|
76
|
+
method: string;
|
|
77
|
+
url: string;
|
|
78
|
+
status: number;
|
|
79
|
+
headers: Headers;
|
|
80
|
+
data: unknown;
|
|
81
|
+
config: RequestConfig;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* forge.api(name, params) 调用参数
|
|
85
|
+
*/
|
|
86
|
+
interface ApiCallParams {
|
|
87
|
+
/** 路径参数:填充到 URI 模板的 {name} 占位符 */
|
|
88
|
+
[paramName: string]: unknown;
|
|
89
|
+
/** 查询参数,序列化到 URL query string */
|
|
90
|
+
query?: Record<string, unknown>;
|
|
91
|
+
/** 请求体,按 method 决定是否发送 */
|
|
92
|
+
body?: unknown;
|
|
93
|
+
/** 自定义请求头(与拦截器叠加) */
|
|
94
|
+
headers?: Record<string, string>;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 缓存存储介质
|
|
98
|
+
*/
|
|
99
|
+
type CacheStorage = 'memory' | 'sessionStorage' | 'localStorage';
|
|
100
|
+
/**
|
|
101
|
+
* Adapter 选择值
|
|
102
|
+
*/
|
|
103
|
+
type AdapterOption = 'auto' | 'axios' | 'builtin' | Fetcher;
|
|
104
|
+
/**
|
|
105
|
+
* Fetcher 接口(自定义 adapter)
|
|
106
|
+
* @see .docs/SPEC.md §4.3.3
|
|
107
|
+
*/
|
|
108
|
+
interface Fetcher {
|
|
109
|
+
request(config: RequestConfig): Promise<ResponseData>;
|
|
110
|
+
interceptors?: {
|
|
111
|
+
request?: InterceptorManager<RequestConfig, RequestConfig>;
|
|
112
|
+
response?: InterceptorManager<ResponseData, unknown>;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 拦截器管理器接口(与 axios use/eject/clear API 一致)
|
|
117
|
+
*
|
|
118
|
+
* 双类型参数说明(对应 SPEC §4.1.3a):
|
|
119
|
+
* - 请求拦截:TIn = TOut = RequestConfig(不可变换类型,仅修改字段)
|
|
120
|
+
* - 响应拦截:TIn = ResponseData, TOut = unknown(首段接收 ResponseData,
|
|
121
|
+
* 后续段接收上一段返回值,返回类型由用户自行约束)
|
|
122
|
+
*/
|
|
123
|
+
interface InterceptorManager<TIn, TOut = TIn> {
|
|
124
|
+
use(onFulfilled?: (value: TIn) => TOut | Promise<TOut>, onRejected?: (error: unknown) => unknown | Promise<unknown>): number;
|
|
125
|
+
eject(id: number): void;
|
|
126
|
+
clear(): void;
|
|
127
|
+
/** 内部使用:当前已注册拦截器快照 */
|
|
128
|
+
forEach(fn: (handler: InterceptorHandler<TIn, TOut>) => void): void;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 单个拦截器内部结构
|
|
132
|
+
*/
|
|
133
|
+
interface InterceptorHandler<TIn, TOut = TIn> {
|
|
134
|
+
id: number;
|
|
135
|
+
onFulfilled?: (value: TIn) => TOut | Promise<TOut>;
|
|
136
|
+
onRejected?: (error: unknown) => unknown | Promise<unknown>;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* forge 顶层 API 形状
|
|
140
|
+
*/
|
|
141
|
+
interface RouteForge {
|
|
142
|
+
/** 通过路由名调用 API */
|
|
143
|
+
api(name: string, params?: ApiCallParams): Promise<unknown>;
|
|
144
|
+
/** 拉取一个或多个层级(自动并发去重) */
|
|
145
|
+
load(level: string | string[]): Promise<void>;
|
|
146
|
+
/** 仅生成 URL,不发请求 */
|
|
147
|
+
route(name: string, params?: Record<string, unknown>): string;
|
|
148
|
+
/** 失效指定层级缓存;不传参失效全部 */
|
|
149
|
+
invalidate(level?: string): void;
|
|
150
|
+
/** 拦截器入口(请求 / 响应) */
|
|
151
|
+
interceptors: {
|
|
152
|
+
request: InterceptorManager<RequestConfig, RequestConfig>;
|
|
153
|
+
response: InterceptorManager<ResponseData, unknown>;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* createRouteForge 配置项
|
|
158
|
+
* @see .docs/SPEC.md §5.2
|
|
159
|
+
*/
|
|
160
|
+
interface RouteForgeOptions {
|
|
161
|
+
endpoint: string;
|
|
162
|
+
/**
|
|
163
|
+
* 层级列表。未传时从摘要端点自动发现(SPEC §4.1.1)。
|
|
164
|
+
* 显式传入时取与后端摘要响应 levels 键的交集(前端不能声明后端不存在的层级,SPEC §5.3)。
|
|
165
|
+
*/
|
|
166
|
+
levels?: string[];
|
|
167
|
+
eager?: string[];
|
|
168
|
+
adapter?: AdapterOption;
|
|
169
|
+
cache?: {
|
|
170
|
+
ttl?: number;
|
|
171
|
+
storage?: CacheStorage;
|
|
172
|
+
};
|
|
173
|
+
auth?: {
|
|
174
|
+
state?: () => boolean;
|
|
175
|
+
levels?: Record<string, boolean>;
|
|
176
|
+
};
|
|
177
|
+
interceptors?: {
|
|
178
|
+
request?: Array<[((c: RequestConfig) => RequestConfig | Promise<RequestConfig>) | undefined, ((e: unknown) => unknown | Promise<unknown>) | undefined]>;
|
|
179
|
+
response?: Array<[((r: ResponseData) => unknown | Promise<unknown>) | undefined, ((e: unknown) => unknown | Promise<unknown>) | undefined]>;
|
|
180
|
+
};
|
|
181
|
+
strict?: boolean;
|
|
182
|
+
timeout?: number;
|
|
183
|
+
baseURL?: string;
|
|
184
|
+
nameSeparator?: string;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export type { AdapterOption as A, CacheStorage as C, Fetcher as F, InterceptorManager as I, LevelRoutesResponse as L, RouteMeta as R, SummaryResponse as S, InterceptorHandler as a, RouteForgeOptions as b, RouteForge as c, ApiCallParams as d, RequestConfig as e, ResponseData as f };
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@route-forge/core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "框架无关的命名路由客户端核心:分级懒加载、隔离缓存、并发去重、登录态感知、拦截器",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "阿杰很厉害 <506907958@qq.com>",
|
|
7
|
+
"homepage": "https://github.com/xyj2156/route-forge",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/xyj2156/route-forge.git",
|
|
11
|
+
"directory": "packages/core"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/xyj2156/route-forge/issues"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"main": "./dist/index.cjs",
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"require": "./dist/index.cjs"
|
|
26
|
+
},
|
|
27
|
+
"./package.json": "./package.json"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsup",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:watch": "vitest",
|
|
37
|
+
"lint": "tsc --noEmit",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"clean": "rimraf dist .turbo"
|
|
40
|
+
},
|
|
41
|
+
"bin": {
|
|
42
|
+
"route-forge-codegen": "./dist/codegen.js"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"vitest": "^1.4.0"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"axios": "^1.6.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependenciesMeta": {
|
|
52
|
+
"axios": {
|
|
53
|
+
"optional": true
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
}
|
|
59
|
+
}
|