@route-forge/core 0.1.1 → 0.3.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.
@@ -14,6 +14,8 @@ interface RouteMeta {
14
14
  methods: string[];
15
15
  /** 路径参数名列表,如 ['user'] */
16
16
  parameters: string[];
17
+ /** 路径参数默认值(Laravel ->defaults()),key 为参数名,value 为默认值 */
18
+ parameter_defaults?: Record<string, unknown>;
17
19
  /** 所属层级(前端填充,便于隔离缓存) */
18
20
  level?: string;
19
21
  /** 后端下发的缓存 TTL(秒),优先级高于本地 cache.ttl */
@@ -42,12 +44,15 @@ interface SummaryResponse {
42
44
  config: {
43
45
  strict_mode: boolean;
44
46
  endpoint_prefix: string;
47
+ /** 后端下发的 URL 前缀,生成 URL 时自动拼接到路由 URI 前面(SPEC §3.1.6) */
48
+ url_prefix?: string;
45
49
  };
46
50
  unassigned: Array<{
47
51
  name: string;
48
52
  uri: string;
49
53
  methods: string[];
50
54
  parameters: string[];
55
+ parameter_defaults?: Record<string, unknown>;
51
56
  }>;
52
57
  }
53
58
  /**
@@ -81,11 +86,24 @@ interface ResponseData {
81
86
  config: RequestConfig;
82
87
  }
83
88
  /**
84
- * forge.api(name, params) 调用参数
89
+ * forge.api(level, name, params) 调用参数
90
+ *
91
+ * 参数解析规则(智能消解):
92
+ * 1. `params` — 显式指定路径参数,优先级最高
93
+ * 2. 平铺的 string | number 值 — 作为路径参数(含与 query/body/headers 同名的 key)
94
+ * 3. `query` (对象) — 查询参数,序列化到 URL query string
95
+ * 4. `body` (非 string/number) — 请求体
96
+ * 5. `headers` (对象) — 自定义请求头
97
+ *
98
+ * 当路径参数名与 query/body/headers 冲突时:
99
+ * - 值为 string | number → 智能识别为路径参数
100
+ * - 同时提供 params 显式指定 → params 优先,固定 key 按原定义处理
85
101
  */
86
102
  interface ApiCallParams {
87
103
  /** 路径参数:填充到 URI 模板的 {name} 占位符 */
88
104
  [paramName: string]: unknown;
105
+ /** 显式指定路径参数(优先级最高,解决路径参数名与 query/body/headers 冲突的场景) */
106
+ params?: Record<string, unknown>;
89
107
  /** 查询参数,序列化到 URL query string */
90
108
  query?: Record<string, unknown>;
91
109
  /** 请求体,按 method 决定是否发送 */
@@ -139,14 +157,27 @@ interface InterceptorHandler<TIn, TOut = TIn> {
139
157
  * forge 顶层 API 形状
140
158
  */
141
159
  interface RouteForge {
142
- /** 通过路由名调用 API */
143
- api(name: string, params?: ApiCallParams): Promise<unknown>;
160
+ /** 通过层级 + 路由名调用 API;level 用于确定加载哪个层级的路由元信息 */
161
+ api(level: string, name: string, params?: ApiCallParams): Promise<unknown>;
144
162
  /** 拉取一个或多个层级(自动并发去重) */
145
163
  load(level: string | string[]): Promise<void>;
146
- /** 仅生成 URL,不发请求 */
147
- route(name: string, params?: Record<string, unknown>): string;
164
+ /** 仅生成 URL,不发请求;level 用于定位路由所在的层级缓存 */
165
+ route(level: string, name: string, params?: Record<string, unknown>): string;
166
+ /** route() 的语义别名,适用于链接生成等场景 */
167
+ url(level: string, name: string, params?: Record<string, unknown>): string;
148
168
  /** 失效指定层级缓存;不传参失效全部 */
149
169
  invalidate(level?: string): void;
170
+ /** 检查指定层级路由是否已加载并缓存;不传参检查全部 */
171
+ isLoaded(level?: string): boolean;
172
+ /** 检查指定层级下某条路由是否存在(需该层级缓存已加载) */
173
+ hasRoute(level: string, name: string): boolean;
174
+ /**
175
+ * 获取路由元信息快照(深拷贝,修改返回值不影响内部缓存)。
176
+ * - getRoutes(level):返回指定层级下全部路由
177
+ * - getRoutes():返回全部层级的路由(按 level 分组)
178
+ */
179
+ getRoutes(level: string): Record<string, RouteMeta>;
180
+ getRoutes(): Record<string, Record<string, RouteMeta>>;
150
181
  /** 拦截器入口(请求 / 响应) */
151
182
  interceptors: {
152
183
  request: InterceptorManager<RequestConfig, RequestConfig>;
@@ -181,7 +212,40 @@ interface RouteForgeOptions {
181
212
  strict?: boolean;
182
213
  timeout?: number;
183
214
  baseURL?: string;
184
- nameSeparator?: string;
185
215
  }
216
+ /**
217
+ * 二级路由类型映射(可由 codegen 生成或通过 module augmentation 增强)
218
+ *
219
+ * @example
220
+ * declare module '@route-forge/core' {
221
+ * interface ForgeRouteMap {
222
+ * admin: {
223
+ * 'users.show': { method: 'GET'; params: { user: string | number }; response: User };
224
+ * 'users.index': { method: 'GET'; params: {}; response: User[] };
225
+ * };
226
+ * public: {
227
+ * 'login.show': { method: 'GET'; params: {}; response: unknown };
228
+ * };
229
+ * }
230
+ * }
231
+ */
232
+ interface ForgeRouteMap {
233
+ }
234
+ /** 从 ForgeRouteMap 推断指定层级下的路由名;未定义时回退 string */
235
+ type ForgeRouteName<L extends string> = [
236
+ keyof ForgeRouteMap
237
+ ] extends [never] ? string : L extends keyof ForgeRouteMap ? keyof ForgeRouteMap[L] & string : string;
238
+ /** 从 ForgeRouteMap 推断指定路由的 params 类型;未定义时回退 ApiCallParams */
239
+ type ForgeApiParams<L extends string, N extends string> = [
240
+ keyof ForgeRouteMap
241
+ ] extends [never] ? ApiCallParams : L extends keyof ForgeRouteMap ? N extends keyof ForgeRouteMap[L] ? (ForgeRouteMap[L][N] extends {
242
+ params: infer P;
243
+ } ? P & ApiCallParams : ApiCallParams) : ApiCallParams : ApiCallParams;
244
+ /** 从 ForgeRouteMap 推断指定路由的响应类型;未定义时回退 unknown */
245
+ type ForgeApiResponse<L extends string, N extends string> = [
246
+ keyof ForgeRouteMap
247
+ ] extends [never] ? unknown : L extends keyof ForgeRouteMap ? N extends keyof ForgeRouteMap[L] ? (ForgeRouteMap[L][N] extends {
248
+ response: infer R;
249
+ } ? R : unknown) : unknown : unknown;
186
250
 
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 };
251
+ 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, ForgeApiParams as e, ForgeApiResponse as f, ForgeRouteMap as g, ForgeRouteName as h, RequestConfig as i, ResponseData as j };
@@ -14,6 +14,8 @@ interface RouteMeta {
14
14
  methods: string[];
15
15
  /** 路径参数名列表,如 ['user'] */
16
16
  parameters: string[];
17
+ /** 路径参数默认值(Laravel ->defaults()),key 为参数名,value 为默认值 */
18
+ parameter_defaults?: Record<string, unknown>;
17
19
  /** 所属层级(前端填充,便于隔离缓存) */
18
20
  level?: string;
19
21
  /** 后端下发的缓存 TTL(秒),优先级高于本地 cache.ttl */
@@ -42,12 +44,15 @@ interface SummaryResponse {
42
44
  config: {
43
45
  strict_mode: boolean;
44
46
  endpoint_prefix: string;
47
+ /** 后端下发的 URL 前缀,生成 URL 时自动拼接到路由 URI 前面(SPEC §3.1.6) */
48
+ url_prefix?: string;
45
49
  };
46
50
  unassigned: Array<{
47
51
  name: string;
48
52
  uri: string;
49
53
  methods: string[];
50
54
  parameters: string[];
55
+ parameter_defaults?: Record<string, unknown>;
51
56
  }>;
52
57
  }
53
58
  /**
@@ -81,11 +86,24 @@ interface ResponseData {
81
86
  config: RequestConfig;
82
87
  }
83
88
  /**
84
- * forge.api(name, params) 调用参数
89
+ * forge.api(level, name, params) 调用参数
90
+ *
91
+ * 参数解析规则(智能消解):
92
+ * 1. `params` — 显式指定路径参数,优先级最高
93
+ * 2. 平铺的 string | number 值 — 作为路径参数(含与 query/body/headers 同名的 key)
94
+ * 3. `query` (对象) — 查询参数,序列化到 URL query string
95
+ * 4. `body` (非 string/number) — 请求体
96
+ * 5. `headers` (对象) — 自定义请求头
97
+ *
98
+ * 当路径参数名与 query/body/headers 冲突时:
99
+ * - 值为 string | number → 智能识别为路径参数
100
+ * - 同时提供 params 显式指定 → params 优先,固定 key 按原定义处理
85
101
  */
86
102
  interface ApiCallParams {
87
103
  /** 路径参数:填充到 URI 模板的 {name} 占位符 */
88
104
  [paramName: string]: unknown;
105
+ /** 显式指定路径参数(优先级最高,解决路径参数名与 query/body/headers 冲突的场景) */
106
+ params?: Record<string, unknown>;
89
107
  /** 查询参数,序列化到 URL query string */
90
108
  query?: Record<string, unknown>;
91
109
  /** 请求体,按 method 决定是否发送 */
@@ -139,14 +157,27 @@ interface InterceptorHandler<TIn, TOut = TIn> {
139
157
  * forge 顶层 API 形状
140
158
  */
141
159
  interface RouteForge {
142
- /** 通过路由名调用 API */
143
- api(name: string, params?: ApiCallParams): Promise<unknown>;
160
+ /** 通过层级 + 路由名调用 API;level 用于确定加载哪个层级的路由元信息 */
161
+ api(level: string, name: string, params?: ApiCallParams): Promise<unknown>;
144
162
  /** 拉取一个或多个层级(自动并发去重) */
145
163
  load(level: string | string[]): Promise<void>;
146
- /** 仅生成 URL,不发请求 */
147
- route(name: string, params?: Record<string, unknown>): string;
164
+ /** 仅生成 URL,不发请求;level 用于定位路由所在的层级缓存 */
165
+ route(level: string, name: string, params?: Record<string, unknown>): string;
166
+ /** route() 的语义别名,适用于链接生成等场景 */
167
+ url(level: string, name: string, params?: Record<string, unknown>): string;
148
168
  /** 失效指定层级缓存;不传参失效全部 */
149
169
  invalidate(level?: string): void;
170
+ /** 检查指定层级路由是否已加载并缓存;不传参检查全部 */
171
+ isLoaded(level?: string): boolean;
172
+ /** 检查指定层级下某条路由是否存在(需该层级缓存已加载) */
173
+ hasRoute(level: string, name: string): boolean;
174
+ /**
175
+ * 获取路由元信息快照(深拷贝,修改返回值不影响内部缓存)。
176
+ * - getRoutes(level):返回指定层级下全部路由
177
+ * - getRoutes():返回全部层级的路由(按 level 分组)
178
+ */
179
+ getRoutes(level: string): Record<string, RouteMeta>;
180
+ getRoutes(): Record<string, Record<string, RouteMeta>>;
150
181
  /** 拦截器入口(请求 / 响应) */
151
182
  interceptors: {
152
183
  request: InterceptorManager<RequestConfig, RequestConfig>;
@@ -181,7 +212,40 @@ interface RouteForgeOptions {
181
212
  strict?: boolean;
182
213
  timeout?: number;
183
214
  baseURL?: string;
184
- nameSeparator?: string;
185
215
  }
216
+ /**
217
+ * 二级路由类型映射(可由 codegen 生成或通过 module augmentation 增强)
218
+ *
219
+ * @example
220
+ * declare module '@route-forge/core' {
221
+ * interface ForgeRouteMap {
222
+ * admin: {
223
+ * 'users.show': { method: 'GET'; params: { user: string | number }; response: User };
224
+ * 'users.index': { method: 'GET'; params: {}; response: User[] };
225
+ * };
226
+ * public: {
227
+ * 'login.show': { method: 'GET'; params: {}; response: unknown };
228
+ * };
229
+ * }
230
+ * }
231
+ */
232
+ interface ForgeRouteMap {
233
+ }
234
+ /** 从 ForgeRouteMap 推断指定层级下的路由名;未定义时回退 string */
235
+ type ForgeRouteName<L extends string> = [
236
+ keyof ForgeRouteMap
237
+ ] extends [never] ? string : L extends keyof ForgeRouteMap ? keyof ForgeRouteMap[L] & string : string;
238
+ /** 从 ForgeRouteMap 推断指定路由的 params 类型;未定义时回退 ApiCallParams */
239
+ type ForgeApiParams<L extends string, N extends string> = [
240
+ keyof ForgeRouteMap
241
+ ] extends [never] ? ApiCallParams : L extends keyof ForgeRouteMap ? N extends keyof ForgeRouteMap[L] ? (ForgeRouteMap[L][N] extends {
242
+ params: infer P;
243
+ } ? P & ApiCallParams : ApiCallParams) : ApiCallParams : ApiCallParams;
244
+ /** 从 ForgeRouteMap 推断指定路由的响应类型;未定义时回退 unknown */
245
+ type ForgeApiResponse<L extends string, N extends string> = [
246
+ keyof ForgeRouteMap
247
+ ] extends [never] ? unknown : L extends keyof ForgeRouteMap ? N extends keyof ForgeRouteMap[L] ? (ForgeRouteMap[L][N] extends {
248
+ response: infer R;
249
+ } ? R : unknown) : unknown : unknown;
186
250
 
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 };
251
+ 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, ForgeApiParams as e, ForgeApiResponse as f, ForgeRouteMap as g, ForgeRouteName as h, RequestConfig as i, ResponseData as j };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@route-forge/core",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "框架无关的命名路由客户端核心:分级懒加载、隔离缓存、并发去重、登录态感知、拦截器",
5
5
  "license": "MIT",
6
6
  "author": "阿杰很厉害 <506907958@qq.com>",
@@ -50,6 +50,7 @@
50
50
  },
51
51
  "scripts": {
52
52
  "build": "tsup",
53
+ "dev": "tsup --watch",
53
54
  "test": "vitest run",
54
55
  "test:watch": "vitest",
55
56
  "lint": "tsc --noEmit",