@vlian/framework 1.2.16 → 1.2.19

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.
Files changed (58) hide show
  1. package/dist/analytics.umd.js +1 -1
  2. package/dist/core/router/RouterManager.cjs +52 -3
  3. package/dist/core/router/RouterManager.cjs.map +1 -1
  4. package/dist/core/router/RouterManager.d.ts +5 -0
  5. package/dist/core/router/RouterManager.js +53 -4
  6. package/dist/core/router/RouterManager.js.map +1 -1
  7. package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs +1 -1
  8. package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs.map +1 -1
  9. package/dist/core/router/adapter/react-router/ReactRouterAdapter.js +1 -1
  10. package/dist/core/router/adapter/react-router/ReactRouterAdapter.js.map +1 -1
  11. package/dist/core/router/dev/RouterDevTools.cjs.map +1 -1
  12. package/dist/core/router/dev/RouterDevTools.js.map +1 -1
  13. package/dist/core/router/middleware/RouterMiddlewareManager.cjs +24 -4
  14. package/dist/core/router/middleware/RouterMiddlewareManager.cjs.map +1 -1
  15. package/dist/core/router/middleware/RouterMiddlewareManager.d.ts +1 -0
  16. package/dist/core/router/middleware/RouterMiddlewareManager.js +24 -4
  17. package/dist/core/router/middleware/RouterMiddlewareManager.js.map +1 -1
  18. package/dist/core/router/middleware/types.cjs.map +1 -1
  19. package/dist/core/router/middleware/types.d.ts +1 -1
  20. package/dist/core/router/middleware/types.js.map +1 -1
  21. package/dist/core/router/navigation/RouterNavigation.cjs +69 -14
  22. package/dist/core/router/navigation/RouterNavigation.cjs.map +1 -1
  23. package/dist/core/router/navigation/RouterNavigation.d.ts +3 -0
  24. package/dist/core/router/navigation/RouterNavigation.js +69 -14
  25. package/dist/core/router/navigation/RouterNavigation.js.map +1 -1
  26. package/dist/core/router/performance/RouteCache.cjs +34 -13
  27. package/dist/core/router/performance/RouteCache.cjs.map +1 -1
  28. package/dist/core/router/performance/RouteCache.d.ts +8 -2
  29. package/dist/core/router/performance/RouteCache.js +34 -13
  30. package/dist/core/router/performance/RouteCache.js.map +1 -1
  31. package/dist/core/router/performance/RoutePreloader.cjs +89 -22
  32. package/dist/core/router/performance/RoutePreloader.cjs.map +1 -1
  33. package/dist/core/router/performance/RoutePreloader.d.ts +9 -1
  34. package/dist/core/router/performance/RoutePreloader.js +89 -22
  35. package/dist/core/router/performance/RoutePreloader.js.map +1 -1
  36. package/dist/core/router/types.d.ts +31 -5
  37. package/dist/core/router/types.js.map +1 -1
  38. package/dist/core/router/utils/adapters/react-router/transform.cjs +43 -65
  39. package/dist/core/router/utils/adapters/react-router/transform.cjs.map +1 -1
  40. package/dist/core/router/utils/adapters/react-router/transform.d.ts +1 -1
  41. package/dist/core/router/utils/adapters/react-router/transform.js +43 -60
  42. package/dist/core/router/utils/adapters/react-router/transform.js.map +1 -1
  43. package/dist/core/router/utils/transform.cjs +79 -70
  44. package/dist/core/router/utils/transform.cjs.map +1 -1
  45. package/dist/core/router/utils/transform.d.ts +1 -1
  46. package/dist/core/router/utils/transform.js +80 -71
  47. package/dist/core/router/utils/transform.js.map +1 -1
  48. package/dist/core/router/validation/RouterConfigValidator.d.ts +68 -4
  49. package/dist/core/router/validation/schema.cjs +72 -2
  50. package/dist/core/router/validation/schema.cjs.map +1 -1
  51. package/dist/core/router/validation/schema.d.ts +105 -6
  52. package/dist/core/router/validation/schema.js +72 -2
  53. package/dist/core/router/validation/schema.js.map +1 -1
  54. package/dist/index.umd.js +705 -431
  55. package/dist/index.umd.js.map +1 -1
  56. package/dist/request.umd.js +1 -1
  57. package/dist/state.umd.js +1 -1
  58. package/package.json +1 -1
@@ -48,10 +48,40 @@ const componentImportSchema = _zod.z.union([
48
48
  _zod.z.function(),
49
49
  _zod.z.null()
50
50
  ]);
51
+ const routerOptionsSchema = _zod.z.object({
52
+ basename: _zod.z.string().optional(),
53
+ future: _zod.z.record(_zod.z.string(), _zod.z.union([
54
+ _zod.z.boolean(),
55
+ _zod.z.string(),
56
+ _zod.z.number()
57
+ ])).optional(),
58
+ hydrationData: _zod.z.unknown().optional(),
59
+ window: _zod.z.unknown().optional(),
60
+ initialEntries: _zod.z.array(_zod.z.string()).optional(),
61
+ initialIndex: _zod.z.number().int().nonnegative().optional()
62
+ }).passthrough();
63
+ const transformOptionsSchema = _zod.z.object({
64
+ pathValidation: _zod.z.object({
65
+ enablePathValidation: _zod.z.boolean().optional(),
66
+ allowedPathPrefixes: _zod.z.array(_zod.z.string().min(1)).optional(),
67
+ maxPathLength: _zod.z.number().int().positive().optional(),
68
+ allowAbsolutePaths: _zod.z.boolean().optional()
69
+ }).optional(),
70
+ performance: _zod.z.object({
71
+ enableCache: _zod.z.boolean().optional(),
72
+ cacheTTL: _zod.z.number().int().positive().optional(),
73
+ maxCacheSize: _zod.z.number().int().positive().optional(),
74
+ maxRecursionDepth: _zod.z.number().int().positive().optional(),
75
+ enableParallelProcessing: _zod.z.boolean().optional(),
76
+ parallelBatchSize: _zod.z.number().int().positive().optional()
77
+ }).optional(),
78
+ enableDebugLog: _zod.z.boolean().optional()
79
+ }).passthrough();
51
80
  const routeConfigSchema = _zod.z.lazy(()=>_zod.z.object({
52
81
  layout: componentImportSchema.optional().nullable(),
53
82
  page: componentImportSchema.optional().nullable(),
54
83
  loading: componentImportSchema.optional().nullable(),
84
+ error: componentImportSchema.optional().nullable(),
55
85
  errors: componentImportSchema.optional().nullable(),
56
86
  name: _zod.z.string().min(1, '路由名称不能为空'),
57
87
  path: _zod.z.string().optional(),
@@ -74,12 +104,52 @@ const routerConfigSchema = _zod.z.object({
74
104
  'hash',
75
105
  'memory'
76
106
  ]).optional(),
77
- options: _zod.z.any().optional(),
107
+ options: routerOptionsSchema.optional(),
78
108
  pathResolve: _zod.z.object({
79
109
  basePath: _zod.z.string().optional(),
80
110
  pathAliases: _zod.z.record(_zod.z.string(), _zod.z.string()).optional()
81
111
  }).optional(),
82
- transformOptions: _zod.z.any().optional()
112
+ transformOptions: transformOptionsSchema.optional(),
113
+ preload: _zod.z.object({
114
+ strategy: _zod.z.enum([
115
+ 'none',
116
+ 'next-level',
117
+ 'all',
118
+ 'visible'
119
+ ]).optional(),
120
+ delay: _zod.z.number().int().positive().optional(),
121
+ priorityThreshold: _zod.z.number().int().nonnegative().optional(),
122
+ timeout: _zod.z.number().int().positive().optional()
123
+ }).optional(),
124
+ enableHydrateFallback: _zod.z.boolean().optional()
125
+ }).superRefine((config, ctx)=>{
126
+ if (!Array.isArray(config.routes)) {
127
+ return;
128
+ }
129
+ const routeNameMap = new Map();
130
+ const walk = (routes, parentPath)=>{
131
+ routes.forEach((route, index)=>{
132
+ const currentPath = `${parentPath}[${index}]`;
133
+ const existingPath = routeNameMap.get(route.name);
134
+ if (existingPath) {
135
+ ctx.addIssue({
136
+ code: _zod.z.ZodIssueCode.custom,
137
+ path: [
138
+ 'routes',
139
+ index,
140
+ 'name'
141
+ ],
142
+ message: `路由名称重复: "${route.name}",首次定义位置 ${existingPath}`
143
+ });
144
+ } else {
145
+ routeNameMap.set(route.name, currentPath);
146
+ }
147
+ if (Array.isArray(route.children) && route.children.length > 0) {
148
+ walk(route.children, `${currentPath}.children`);
149
+ }
150
+ });
151
+ };
152
+ walk(config.routes, 'routes');
83
153
  });
84
154
  function validateRouterConfig(config) {
85
155
  return routerConfigSchema.parse(config);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/router/validation/schema.ts"],"sourcesContent":["/**\n * 路由配置验证 Schema(使用 Zod)\n */\n\nimport { z } from 'zod';\n\n/**\n * RouteItemHandle Schema\n */\nexport const routeItemHandleSchema = z.object({\n title: z.string().min(1, '路由标题不能为空'),\n i18nKey: z.string().optional(),\n order: z.number().int('排序值必须是整数'),\n icon: z.string().optional(),\n hideInMenu: z.boolean().optional(),\n hideFooter: z.boolean().optional(),\n keepAlive: z.boolean().optional(),\n needLogin: z.boolean().optional(),\n roles: z.array(z.string()).optional(),\n name: z.string().optional(),\n}).passthrough(); // 允许其他自定义字段\n\n/**\n * ComponentImport Schema\n * 可以是字符串路径或函数\n */\nexport const componentImportSchema = z.union([\n z.string().min(1, '组件路径不能为空'),\n z.function(),\n z.null(),\n]);\n\n/**\n * RouteConfig Schema\n */\nexport const routeConfigSchema: z.ZodType<any> = z.lazy(() =>\n z.object({\n layout: componentImportSchema.optional().nullable(),\n page: componentImportSchema.optional().nullable(),\n loading: componentImportSchema.optional().nullable(),\n errors: componentImportSchema.optional().nullable(),\n name: z.string().min(1, '路由名称不能为空'),\n path: z.string().optional(),\n isGroup: z.boolean().optional(),\n enableRedirection: z.boolean().optional(),\n handle: routeItemHandleSchema,\n children: z.array(routeConfigSchema).optional(),\n })\n);\n\n/**\n * RouterConfig Schema\n */\nexport const routerConfigSchema = z.object({\n enabled: z.union([z.boolean(), z.literal('disabled')]).optional(),\n routes: z\n .union([\n z.array(routeConfigSchema),\n z.function(),\n ])\n .optional(),\n mode: z.enum(['browser', 'hash', 'memory']).optional(),\n options: z.any().optional(), // react-router-dom 的选项类型较复杂,使用 any\n pathResolve: z\n .object({\n basePath: z.string().optional(),\n pathAliases: z.record(z.string(), z.string()).optional(),\n })\n .optional(),\n transformOptions: z.any().optional(), // TransformOptions 类型较复杂,使用 any\n});\n\n/**\n * 验证路由配置\n * \n * @param config - 要验证的路由配置\n * @returns 验证后的路由配置\n * @throws z.ZodError 如果配置验证失败\n */\nexport function validateRouterConfig(config: unknown) {\n return routerConfigSchema.parse(config);\n}\n\n/**\n * 安全验证路由配置(不抛出异常)\n * \n * @param config - 要验证的路由配置\n * @returns 验证结果\n */\nexport function safeValidateRouterConfig(config: unknown) {\n return routerConfigSchema.safeParse(config);\n}\n"],"names":["componentImportSchema","routeConfigSchema","routeItemHandleSchema","routerConfigSchema","safeValidateRouterConfig","validateRouterConfig","z","object","title","string","min","i18nKey","optional","order","number","int","icon","hideInMenu","boolean","hideFooter","keepAlive","needLogin","roles","array","name","passthrough","union","function","null","lazy","layout","nullable","page","loading","errors","path","isGroup","enableRedirection","handle","children","enabled","literal","routes","mode","enum","options","any","pathResolve","basePath","pathAliases","record","transformOptions","config","parse","safeParse"],"mappings":"AAAA;;CAEC;;;;;;;;;;;QAwBYA;eAAAA;;QASAC;eAAAA;;QA1BAC;eAAAA;;QA4CAC;eAAAA;;QAoCGC;eAAAA;;QAVAC;eAAAA;;;qBA3EE;AAKX,MAAMH,wBAAwBI,MAAC,CAACC,MAAM,CAAC;IAC5CC,OAAOF,MAAC,CAACG,MAAM,GAAGC,GAAG,CAAC,GAAG;IACzBC,SAASL,MAAC,CAACG,MAAM,GAAGG,QAAQ;IAC5BC,OAAOP,MAAC,CAACQ,MAAM,GAAGC,GAAG,CAAC;IACtBC,MAAMV,MAAC,CAACG,MAAM,GAAGG,QAAQ;IACzBK,YAAYX,MAAC,CAACY,OAAO,GAAGN,QAAQ;IAChCO,YAAYb,MAAC,CAACY,OAAO,GAAGN,QAAQ;IAChCQ,WAAWd,MAAC,CAACY,OAAO,GAAGN,QAAQ;IAC/BS,WAAWf,MAAC,CAACY,OAAO,GAAGN,QAAQ;IAC/BU,OAAOhB,MAAC,CAACiB,KAAK,CAACjB,MAAC,CAACG,MAAM,IAAIG,QAAQ;IACnCY,MAAMlB,MAAC,CAACG,MAAM,GAAGG,QAAQ;AAC3B,GAAGa,WAAW,IAAI,YAAY;AAMvB,MAAMzB,wBAAwBM,MAAC,CAACoB,KAAK,CAAC;IAC3CpB,MAAC,CAACG,MAAM,GAAGC,GAAG,CAAC,GAAG;IAClBJ,MAAC,CAACqB,QAAQ;IACVrB,MAAC,CAACsB,IAAI;CACP;AAKM,MAAM3B,oBAAoCK,MAAC,CAACuB,IAAI,CAAC,IACtDvB,MAAC,CAACC,MAAM,CAAC;QACPuB,QAAQ9B,sBAAsBY,QAAQ,GAAGmB,QAAQ;QACjDC,MAAMhC,sBAAsBY,QAAQ,GAAGmB,QAAQ;QAC/CE,SAASjC,sBAAsBY,QAAQ,GAAGmB,QAAQ;QAClDG,QAAQlC,sBAAsBY,QAAQ,GAAGmB,QAAQ;QACjDP,MAAMlB,MAAC,CAACG,MAAM,GAAGC,GAAG,CAAC,GAAG;QACxByB,MAAM7B,MAAC,CAACG,MAAM,GAAGG,QAAQ;QACzBwB,SAAS9B,MAAC,CAACY,OAAO,GAAGN,QAAQ;QAC7ByB,mBAAmB/B,MAAC,CAACY,OAAO,GAAGN,QAAQ;QACvC0B,QAAQpC;QACRqC,UAAUjC,MAAC,CAACiB,KAAK,CAACtB,mBAAmBW,QAAQ;IAC/C;AAMK,MAAMT,qBAAqBG,MAAC,CAACC,MAAM,CAAC;IACzCiC,SAASlC,MAAC,CAACoB,KAAK,CAAC;QAACpB,MAAC,CAACY,OAAO;QAAIZ,MAAC,CAACmC,OAAO,CAAC;KAAY,EAAE7B,QAAQ;IAC/D8B,QAAQpC,MAAC,CACNoB,KAAK,CAAC;QACLpB,MAAC,CAACiB,KAAK,CAACtB;QACRK,MAAC,CAACqB,QAAQ;KACX,EACAf,QAAQ;IACX+B,MAAMrC,MAAC,CAACsC,IAAI,CAAC;QAAC;QAAW;QAAQ;KAAS,EAAEhC,QAAQ;IACpDiC,SAASvC,MAAC,CAACwC,GAAG,GAAGlC,QAAQ;IACzBmC,aAAazC,MAAC,CACXC,MAAM,CAAC;QACNyC,UAAU1C,MAAC,CAACG,MAAM,GAAGG,QAAQ;QAC7BqC,aAAa3C,MAAC,CAAC4C,MAAM,CAAC5C,MAAC,CAACG,MAAM,IAAIH,MAAC,CAACG,MAAM,IAAIG,QAAQ;IACxD,GACCA,QAAQ;IACXuC,kBAAkB7C,MAAC,CAACwC,GAAG,GAAGlC,QAAQ;AACpC;AASO,SAASP,qBAAqB+C,MAAe;IAClD,OAAOjD,mBAAmBkD,KAAK,CAACD;AAClC;AAQO,SAAShD,yBAAyBgD,MAAe;IACtD,OAAOjD,mBAAmBmD,SAAS,CAACF;AACtC"}
1
+ {"version":3,"sources":["../../../../src/core/router/validation/schema.ts"],"sourcesContent":["/**\n * 路由配置验证 Schema(使用 Zod)\n */\n\nimport { z } from 'zod';\n\n/**\n * RouteItemHandle Schema\n */\nexport const routeItemHandleSchema = z.object({\n title: z.string().min(1, '路由标题不能为空'),\n i18nKey: z.string().optional(),\n order: z.number().int('排序值必须是整数'),\n icon: z.string().optional(),\n hideInMenu: z.boolean().optional(),\n hideFooter: z.boolean().optional(),\n keepAlive: z.boolean().optional(),\n needLogin: z.boolean().optional(),\n roles: z.array(z.string()).optional(),\n name: z.string().optional(),\n}).passthrough(); // 允许其他自定义字段\n\n/**\n * ComponentImport Schema\n * 可以是字符串路径或函数\n */\nexport const componentImportSchema = z.union([\n z.string().min(1, '组件路径不能为空'),\n z.function(),\n z.null(),\n]);\n\nconst routerOptionsSchema = z\n .object({\n basename: z.string().optional(),\n future: z.record(z.string(), z.union([z.boolean(), z.string(), z.number()])).optional(),\n hydrationData: z.unknown().optional(),\n window: z.unknown().optional(),\n initialEntries: z.array(z.string()).optional(),\n initialIndex: z.number().int().nonnegative().optional(),\n })\n .passthrough();\n\nconst transformOptionsSchema = z\n .object({\n pathValidation: z\n .object({\n enablePathValidation: z.boolean().optional(),\n allowedPathPrefixes: z.array(z.string().min(1)).optional(),\n maxPathLength: z.number().int().positive().optional(),\n allowAbsolutePaths: z.boolean().optional(),\n })\n .optional(),\n performance: z\n .object({\n enableCache: z.boolean().optional(),\n cacheTTL: z.number().int().positive().optional(),\n maxCacheSize: z.number().int().positive().optional(),\n maxRecursionDepth: z.number().int().positive().optional(),\n enableParallelProcessing: z.boolean().optional(),\n parallelBatchSize: z.number().int().positive().optional(),\n })\n .optional(),\n enableDebugLog: z.boolean().optional(),\n })\n .passthrough();\n\n/**\n * RouteConfig Schema\n */\nexport const routeConfigSchema: z.ZodType<any> = z.lazy(() =>\n z.object({\n layout: componentImportSchema.optional().nullable(),\n page: componentImportSchema.optional().nullable(),\n loading: componentImportSchema.optional().nullable(),\n error: componentImportSchema.optional().nullable(),\n errors: componentImportSchema.optional().nullable(),\n name: z.string().min(1, '路由名称不能为空'),\n path: z.string().optional(),\n isGroup: z.boolean().optional(),\n enableRedirection: z.boolean().optional(),\n handle: routeItemHandleSchema,\n children: z.array(routeConfigSchema).optional(),\n })\n);\n\n/**\n * RouterConfig Schema\n */\nexport const routerConfigSchema = z.object({\n enabled: z.union([z.boolean(), z.literal('disabled')]).optional(),\n routes: z\n .union([\n z.array(routeConfigSchema),\n z.function(),\n ])\n .optional(),\n mode: z.enum(['browser', 'hash', 'memory']).optional(),\n options: routerOptionsSchema.optional(),\n pathResolve: z\n .object({\n basePath: z.string().optional(),\n pathAliases: z.record(z.string(), z.string()).optional(),\n })\n .optional(),\n transformOptions: transformOptionsSchema.optional(),\n preload: z\n .object({\n strategy: z.enum(['none', 'next-level', 'all', 'visible']).optional(),\n delay: z.number().int().positive().optional(),\n priorityThreshold: z.number().int().nonnegative().optional(),\n timeout: z.number().int().positive().optional(),\n })\n .optional(),\n enableHydrateFallback: z.boolean().optional(),\n}).superRefine((config, ctx) => {\n if (!Array.isArray(config.routes)) {\n return;\n }\n\n const routeNameMap = new Map<string, string>();\n\n const walk = (routes: Array<z.infer<typeof routeConfigSchema>>, parentPath: string): void => {\n routes.forEach((route, index) => {\n const currentPath = `${parentPath}[${index}]`;\n const existingPath = routeNameMap.get(route.name);\n if (existingPath) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['routes', index, 'name'],\n message: `路由名称重复: \"${route.name}\",首次定义位置 ${existingPath}`,\n });\n } else {\n routeNameMap.set(route.name, currentPath);\n }\n\n if (Array.isArray(route.children) && route.children.length > 0) {\n walk(route.children as Array<z.infer<typeof routeConfigSchema>>, `${currentPath}.children`);\n }\n });\n };\n\n walk(config.routes, 'routes');\n});\n\n/**\n * 验证路由配置\n * \n * @param config - 要验证的路由配置\n * @returns 验证后的路由配置\n * @throws z.ZodError 如果配置验证失败\n */\nexport function validateRouterConfig(config: unknown) {\n return routerConfigSchema.parse(config);\n}\n\n/**\n * 安全验证路由配置(不抛出异常)\n * \n * @param config - 要验证的路由配置\n * @returns 验证结果\n */\nexport function safeValidateRouterConfig(config: unknown) {\n return routerConfigSchema.safeParse(config);\n}\n"],"names":["componentImportSchema","routeConfigSchema","routeItemHandleSchema","routerConfigSchema","safeValidateRouterConfig","validateRouterConfig","z","object","title","string","min","i18nKey","optional","order","number","int","icon","hideInMenu","boolean","hideFooter","keepAlive","needLogin","roles","array","name","passthrough","union","function","null","routerOptionsSchema","basename","future","record","hydrationData","unknown","window","initialEntries","initialIndex","nonnegative","transformOptionsSchema","pathValidation","enablePathValidation","allowedPathPrefixes","maxPathLength","positive","allowAbsolutePaths","performance","enableCache","cacheTTL","maxCacheSize","maxRecursionDepth","enableParallelProcessing","parallelBatchSize","enableDebugLog","lazy","layout","nullable","page","loading","error","errors","path","isGroup","enableRedirection","handle","children","enabled","literal","routes","mode","enum","options","pathResolve","basePath","pathAliases","transformOptions","preload","strategy","delay","priorityThreshold","timeout","enableHydrateFallback","superRefine","config","ctx","Array","isArray","routeNameMap","Map","walk","parentPath","forEach","route","index","currentPath","existingPath","get","addIssue","code","ZodIssueCode","custom","message","set","length","parse","safeParse"],"mappings":"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"}
@@ -37,12 +37,47 @@ export declare const routerConfigSchema: z.ZodObject<{
37
37
  browser: "browser";
38
38
  memory: "memory";
39
39
  }>>;
40
- options: z.ZodOptional<z.ZodAny>;
40
+ options: z.ZodOptional<z.ZodObject<{
41
+ basename: z.ZodOptional<z.ZodString>;
42
+ future: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString, z.ZodNumber]>>>;
43
+ hydrationData: z.ZodOptional<z.ZodUnknown>;
44
+ window: z.ZodOptional<z.ZodUnknown>;
45
+ initialEntries: z.ZodOptional<z.ZodArray<z.ZodString>>;
46
+ initialIndex: z.ZodOptional<z.ZodNumber>;
47
+ }, z.core.$loose>>;
41
48
  pathResolve: z.ZodOptional<z.ZodObject<{
42
49
  basePath: z.ZodOptional<z.ZodString>;
43
50
  pathAliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
44
51
  }, z.core.$strip>>;
45
- transformOptions: z.ZodOptional<z.ZodAny>;
52
+ transformOptions: z.ZodOptional<z.ZodObject<{
53
+ pathValidation: z.ZodOptional<z.ZodObject<{
54
+ enablePathValidation: z.ZodOptional<z.ZodBoolean>;
55
+ allowedPathPrefixes: z.ZodOptional<z.ZodArray<z.ZodString>>;
56
+ maxPathLength: z.ZodOptional<z.ZodNumber>;
57
+ allowAbsolutePaths: z.ZodOptional<z.ZodBoolean>;
58
+ }, z.core.$strip>>;
59
+ performance: z.ZodOptional<z.ZodObject<{
60
+ enableCache: z.ZodOptional<z.ZodBoolean>;
61
+ cacheTTL: z.ZodOptional<z.ZodNumber>;
62
+ maxCacheSize: z.ZodOptional<z.ZodNumber>;
63
+ maxRecursionDepth: z.ZodOptional<z.ZodNumber>;
64
+ enableParallelProcessing: z.ZodOptional<z.ZodBoolean>;
65
+ parallelBatchSize: z.ZodOptional<z.ZodNumber>;
66
+ }, z.core.$strip>>;
67
+ enableDebugLog: z.ZodOptional<z.ZodBoolean>;
68
+ }, z.core.$loose>>;
69
+ preload: z.ZodOptional<z.ZodObject<{
70
+ strategy: z.ZodOptional<z.ZodEnum<{
71
+ none: "none";
72
+ visible: "visible";
73
+ all: "all";
74
+ "next-level": "next-level";
75
+ }>>;
76
+ delay: z.ZodOptional<z.ZodNumber>;
77
+ priorityThreshold: z.ZodOptional<z.ZodNumber>;
78
+ timeout: z.ZodOptional<z.ZodNumber>;
79
+ }, z.core.$strip>>;
80
+ enableHydrateFallback: z.ZodOptional<z.ZodBoolean>;
46
81
  }, z.core.$strip>;
47
82
  /**
48
83
  * 验证路由配置
@@ -55,12 +90,44 @@ export declare function validateRouterConfig(config: unknown): {
55
90
  enabled?: boolean | "disabled" | undefined;
56
91
  routes?: any[] | z.core.$InferOuterFunctionType<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut> | undefined;
57
92
  mode?: "hash" | "browser" | "memory" | undefined;
58
- options?: any;
93
+ options?: {
94
+ [x: string]: unknown;
95
+ basename?: string | undefined;
96
+ future?: Record<string, string | number | boolean> | undefined;
97
+ hydrationData?: unknown;
98
+ window?: unknown;
99
+ initialEntries?: string[] | undefined;
100
+ initialIndex?: number | undefined;
101
+ } | undefined;
59
102
  pathResolve?: {
60
103
  basePath?: string | undefined;
61
104
  pathAliases?: Record<string, string> | undefined;
62
105
  } | undefined;
63
- transformOptions?: any;
106
+ transformOptions?: {
107
+ [x: string]: unknown;
108
+ pathValidation?: {
109
+ enablePathValidation?: boolean | undefined;
110
+ allowedPathPrefixes?: string[] | undefined;
111
+ maxPathLength?: number | undefined;
112
+ allowAbsolutePaths?: boolean | undefined;
113
+ } | undefined;
114
+ performance?: {
115
+ enableCache?: boolean | undefined;
116
+ cacheTTL?: number | undefined;
117
+ maxCacheSize?: number | undefined;
118
+ maxRecursionDepth?: number | undefined;
119
+ enableParallelProcessing?: boolean | undefined;
120
+ parallelBatchSize?: number | undefined;
121
+ } | undefined;
122
+ enableDebugLog?: boolean | undefined;
123
+ } | undefined;
124
+ preload?: {
125
+ strategy?: "none" | "visible" | "all" | "next-level" | undefined;
126
+ delay?: number | undefined;
127
+ priorityThreshold?: number | undefined;
128
+ timeout?: number | undefined;
129
+ } | undefined;
130
+ enableHydrateFallback?: boolean | undefined;
64
131
  };
65
132
  /**
66
133
  * 安全验证路由配置(不抛出异常)
@@ -72,10 +139,42 @@ export declare function safeValidateRouterConfig(config: unknown): z.ZodSafePars
72
139
  enabled?: boolean | "disabled" | undefined;
73
140
  routes?: any[] | z.core.$InferOuterFunctionType<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut> | undefined;
74
141
  mode?: "hash" | "browser" | "memory" | undefined;
75
- options?: any;
142
+ options?: {
143
+ [x: string]: unknown;
144
+ basename?: string | undefined;
145
+ future?: Record<string, string | number | boolean> | undefined;
146
+ hydrationData?: unknown;
147
+ window?: unknown;
148
+ initialEntries?: string[] | undefined;
149
+ initialIndex?: number | undefined;
150
+ } | undefined;
76
151
  pathResolve?: {
77
152
  basePath?: string | undefined;
78
153
  pathAliases?: Record<string, string> | undefined;
79
154
  } | undefined;
80
- transformOptions?: any;
155
+ transformOptions?: {
156
+ [x: string]: unknown;
157
+ pathValidation?: {
158
+ enablePathValidation?: boolean | undefined;
159
+ allowedPathPrefixes?: string[] | undefined;
160
+ maxPathLength?: number | undefined;
161
+ allowAbsolutePaths?: boolean | undefined;
162
+ } | undefined;
163
+ performance?: {
164
+ enableCache?: boolean | undefined;
165
+ cacheTTL?: number | undefined;
166
+ maxCacheSize?: number | undefined;
167
+ maxRecursionDepth?: number | undefined;
168
+ enableParallelProcessing?: boolean | undefined;
169
+ parallelBatchSize?: number | undefined;
170
+ } | undefined;
171
+ enableDebugLog?: boolean | undefined;
172
+ } | undefined;
173
+ preload?: {
174
+ strategy?: "none" | "visible" | "all" | "next-level" | undefined;
175
+ delay?: number | undefined;
176
+ priorityThreshold?: number | undefined;
177
+ timeout?: number | undefined;
178
+ } | undefined;
179
+ enableHydrateFallback?: boolean | undefined;
81
180
  }>;
@@ -23,12 +23,42 @@
23
23
  z.function(),
24
24
  z.null()
25
25
  ]);
26
+ const routerOptionsSchema = z.object({
27
+ basename: z.string().optional(),
28
+ future: z.record(z.string(), z.union([
29
+ z.boolean(),
30
+ z.string(),
31
+ z.number()
32
+ ])).optional(),
33
+ hydrationData: z.unknown().optional(),
34
+ window: z.unknown().optional(),
35
+ initialEntries: z.array(z.string()).optional(),
36
+ initialIndex: z.number().int().nonnegative().optional()
37
+ }).passthrough();
38
+ const transformOptionsSchema = z.object({
39
+ pathValidation: z.object({
40
+ enablePathValidation: z.boolean().optional(),
41
+ allowedPathPrefixes: z.array(z.string().min(1)).optional(),
42
+ maxPathLength: z.number().int().positive().optional(),
43
+ allowAbsolutePaths: z.boolean().optional()
44
+ }).optional(),
45
+ performance: z.object({
46
+ enableCache: z.boolean().optional(),
47
+ cacheTTL: z.number().int().positive().optional(),
48
+ maxCacheSize: z.number().int().positive().optional(),
49
+ maxRecursionDepth: z.number().int().positive().optional(),
50
+ enableParallelProcessing: z.boolean().optional(),
51
+ parallelBatchSize: z.number().int().positive().optional()
52
+ }).optional(),
53
+ enableDebugLog: z.boolean().optional()
54
+ }).passthrough();
26
55
  /**
27
56
  * RouteConfig Schema
28
57
  */ export const routeConfigSchema = z.lazy(()=>z.object({
29
58
  layout: componentImportSchema.optional().nullable(),
30
59
  page: componentImportSchema.optional().nullable(),
31
60
  loading: componentImportSchema.optional().nullable(),
61
+ error: componentImportSchema.optional().nullable(),
32
62
  errors: componentImportSchema.optional().nullable(),
33
63
  name: z.string().min(1, '路由名称不能为空'),
34
64
  path: z.string().optional(),
@@ -53,12 +83,52 @@
53
83
  'hash',
54
84
  'memory'
55
85
  ]).optional(),
56
- options: z.any().optional(),
86
+ options: routerOptionsSchema.optional(),
57
87
  pathResolve: z.object({
58
88
  basePath: z.string().optional(),
59
89
  pathAliases: z.record(z.string(), z.string()).optional()
60
90
  }).optional(),
61
- transformOptions: z.any().optional()
91
+ transformOptions: transformOptionsSchema.optional(),
92
+ preload: z.object({
93
+ strategy: z.enum([
94
+ 'none',
95
+ 'next-level',
96
+ 'all',
97
+ 'visible'
98
+ ]).optional(),
99
+ delay: z.number().int().positive().optional(),
100
+ priorityThreshold: z.number().int().nonnegative().optional(),
101
+ timeout: z.number().int().positive().optional()
102
+ }).optional(),
103
+ enableHydrateFallback: z.boolean().optional()
104
+ }).superRefine((config, ctx)=>{
105
+ if (!Array.isArray(config.routes)) {
106
+ return;
107
+ }
108
+ const routeNameMap = new Map();
109
+ const walk = (routes, parentPath)=>{
110
+ routes.forEach((route, index)=>{
111
+ const currentPath = `${parentPath}[${index}]`;
112
+ const existingPath = routeNameMap.get(route.name);
113
+ if (existingPath) {
114
+ ctx.addIssue({
115
+ code: z.ZodIssueCode.custom,
116
+ path: [
117
+ 'routes',
118
+ index,
119
+ 'name'
120
+ ],
121
+ message: `路由名称重复: "${route.name}",首次定义位置 ${existingPath}`
122
+ });
123
+ } else {
124
+ routeNameMap.set(route.name, currentPath);
125
+ }
126
+ if (Array.isArray(route.children) && route.children.length > 0) {
127
+ walk(route.children, `${currentPath}.children`);
128
+ }
129
+ });
130
+ };
131
+ walk(config.routes, 'routes');
62
132
  });
63
133
  /**
64
134
  * 验证路由配置
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/router/validation/schema.ts"],"sourcesContent":["/**\n * 路由配置验证 Schema(使用 Zod)\n */\n\nimport { z } from 'zod';\n\n/**\n * RouteItemHandle Schema\n */\nexport const routeItemHandleSchema = z.object({\n title: z.string().min(1, '路由标题不能为空'),\n i18nKey: z.string().optional(),\n order: z.number().int('排序值必须是整数'),\n icon: z.string().optional(),\n hideInMenu: z.boolean().optional(),\n hideFooter: z.boolean().optional(),\n keepAlive: z.boolean().optional(),\n needLogin: z.boolean().optional(),\n roles: z.array(z.string()).optional(),\n name: z.string().optional(),\n}).passthrough(); // 允许其他自定义字段\n\n/**\n * ComponentImport Schema\n * 可以是字符串路径或函数\n */\nexport const componentImportSchema = z.union([\n z.string().min(1, '组件路径不能为空'),\n z.function(),\n z.null(),\n]);\n\n/**\n * RouteConfig Schema\n */\nexport const routeConfigSchema: z.ZodType<any> = z.lazy(() =>\n z.object({\n layout: componentImportSchema.optional().nullable(),\n page: componentImportSchema.optional().nullable(),\n loading: componentImportSchema.optional().nullable(),\n errors: componentImportSchema.optional().nullable(),\n name: z.string().min(1, '路由名称不能为空'),\n path: z.string().optional(),\n isGroup: z.boolean().optional(),\n enableRedirection: z.boolean().optional(),\n handle: routeItemHandleSchema,\n children: z.array(routeConfigSchema).optional(),\n })\n);\n\n/**\n * RouterConfig Schema\n */\nexport const routerConfigSchema = z.object({\n enabled: z.union([z.boolean(), z.literal('disabled')]).optional(),\n routes: z\n .union([\n z.array(routeConfigSchema),\n z.function(),\n ])\n .optional(),\n mode: z.enum(['browser', 'hash', 'memory']).optional(),\n options: z.any().optional(), // react-router-dom 的选项类型较复杂,使用 any\n pathResolve: z\n .object({\n basePath: z.string().optional(),\n pathAliases: z.record(z.string(), z.string()).optional(),\n })\n .optional(),\n transformOptions: z.any().optional(), // TransformOptions 类型较复杂,使用 any\n});\n\n/**\n * 验证路由配置\n * \n * @param config - 要验证的路由配置\n * @returns 验证后的路由配置\n * @throws z.ZodError 如果配置验证失败\n */\nexport function validateRouterConfig(config: unknown) {\n return routerConfigSchema.parse(config);\n}\n\n/**\n * 安全验证路由配置(不抛出异常)\n * \n * @param config - 要验证的路由配置\n * @returns 验证结果\n */\nexport function safeValidateRouterConfig(config: unknown) {\n return routerConfigSchema.safeParse(config);\n}\n"],"names":["z","routeItemHandleSchema","object","title","string","min","i18nKey","optional","order","number","int","icon","hideInMenu","boolean","hideFooter","keepAlive","needLogin","roles","array","name","passthrough","componentImportSchema","union","function","null","routeConfigSchema","lazy","layout","nullable","page","loading","errors","path","isGroup","enableRedirection","handle","children","routerConfigSchema","enabled","literal","routes","mode","enum","options","any","pathResolve","basePath","pathAliases","record","transformOptions","validateRouterConfig","config","parse","safeValidateRouterConfig","safeParse"],"mappings":"AAAA;;CAEC,GAED,SAASA,CAAC,QAAQ,MAAM;AAExB;;CAEC,GACD,OAAO,MAAMC,wBAAwBD,EAAEE,MAAM,CAAC;IAC5CC,OAAOH,EAAEI,MAAM,GAAGC,GAAG,CAAC,GAAG;IACzBC,SAASN,EAAEI,MAAM,GAAGG,QAAQ;IAC5BC,OAAOR,EAAES,MAAM,GAAGC,GAAG,CAAC;IACtBC,MAAMX,EAAEI,MAAM,GAAGG,QAAQ;IACzBK,YAAYZ,EAAEa,OAAO,GAAGN,QAAQ;IAChCO,YAAYd,EAAEa,OAAO,GAAGN,QAAQ;IAChCQ,WAAWf,EAAEa,OAAO,GAAGN,QAAQ;IAC/BS,WAAWhB,EAAEa,OAAO,GAAGN,QAAQ;IAC/BU,OAAOjB,EAAEkB,KAAK,CAAClB,EAAEI,MAAM,IAAIG,QAAQ;IACnCY,MAAMnB,EAAEI,MAAM,GAAGG,QAAQ;AAC3B,GAAGa,WAAW,GAAG,CAAC,YAAY;AAE9B;;;CAGC,GACD,OAAO,MAAMC,wBAAwBrB,EAAEsB,KAAK,CAAC;IAC3CtB,EAAEI,MAAM,GAAGC,GAAG,CAAC,GAAG;IAClBL,EAAEuB,QAAQ;IACVvB,EAAEwB,IAAI;CACP,EAAE;AAEH;;CAEC,GACD,OAAO,MAAMC,oBAAoCzB,EAAE0B,IAAI,CAAC,IACtD1B,EAAEE,MAAM,CAAC;QACPyB,QAAQN,sBAAsBd,QAAQ,GAAGqB,QAAQ;QACjDC,MAAMR,sBAAsBd,QAAQ,GAAGqB,QAAQ;QAC/CE,SAAST,sBAAsBd,QAAQ,GAAGqB,QAAQ;QAClDG,QAAQV,sBAAsBd,QAAQ,GAAGqB,QAAQ;QACjDT,MAAMnB,EAAEI,MAAM,GAAGC,GAAG,CAAC,GAAG;QACxB2B,MAAMhC,EAAEI,MAAM,GAAGG,QAAQ;QACzB0B,SAASjC,EAAEa,OAAO,GAAGN,QAAQ;QAC7B2B,mBAAmBlC,EAAEa,OAAO,GAAGN,QAAQ;QACvC4B,QAAQlC;QACRmC,UAAUpC,EAAEkB,KAAK,CAACO,mBAAmBlB,QAAQ;IAC/C,IACA;AAEF;;CAEC,GACD,OAAO,MAAM8B,qBAAqBrC,EAAEE,MAAM,CAAC;IACzCoC,SAAStC,EAAEsB,KAAK,CAAC;QAACtB,EAAEa,OAAO;QAAIb,EAAEuC,OAAO,CAAC;KAAY,EAAEhC,QAAQ;IAC/DiC,QAAQxC,EACLsB,KAAK,CAAC;QACLtB,EAAEkB,KAAK,CAACO;QACRzB,EAAEuB,QAAQ;KACX,EACAhB,QAAQ;IACXkC,MAAMzC,EAAE0C,IAAI,CAAC;QAAC;QAAW;QAAQ;KAAS,EAAEnC,QAAQ;IACpDoC,SAAS3C,EAAE4C,GAAG,GAAGrC,QAAQ;IACzBsC,aAAa7C,EACVE,MAAM,CAAC;QACN4C,UAAU9C,EAAEI,MAAM,GAAGG,QAAQ;QAC7BwC,aAAa/C,EAAEgD,MAAM,CAAChD,EAAEI,MAAM,IAAIJ,EAAEI,MAAM,IAAIG,QAAQ;IACxD,GACCA,QAAQ;IACX0C,kBAAkBjD,EAAE4C,GAAG,GAAGrC,QAAQ;AACpC,GAAG;AAEH;;;;;;CAMC,GACD,OAAO,SAAS2C,qBAAqBC,MAAe;IAClD,OAAOd,mBAAmBe,KAAK,CAACD;AAClC;AAEA;;;;;CAKC,GACD,OAAO,SAASE,yBAAyBF,MAAe;IACtD,OAAOd,mBAAmBiB,SAAS,CAACH;AACtC"}
1
+ {"version":3,"sources":["../../../../src/core/router/validation/schema.ts"],"sourcesContent":["/**\n * 路由配置验证 Schema(使用 Zod)\n */\n\nimport { z } from 'zod';\n\n/**\n * RouteItemHandle Schema\n */\nexport const routeItemHandleSchema = z.object({\n title: z.string().min(1, '路由标题不能为空'),\n i18nKey: z.string().optional(),\n order: z.number().int('排序值必须是整数'),\n icon: z.string().optional(),\n hideInMenu: z.boolean().optional(),\n hideFooter: z.boolean().optional(),\n keepAlive: z.boolean().optional(),\n needLogin: z.boolean().optional(),\n roles: z.array(z.string()).optional(),\n name: z.string().optional(),\n}).passthrough(); // 允许其他自定义字段\n\n/**\n * ComponentImport Schema\n * 可以是字符串路径或函数\n */\nexport const componentImportSchema = z.union([\n z.string().min(1, '组件路径不能为空'),\n z.function(),\n z.null(),\n]);\n\nconst routerOptionsSchema = z\n .object({\n basename: z.string().optional(),\n future: z.record(z.string(), z.union([z.boolean(), z.string(), z.number()])).optional(),\n hydrationData: z.unknown().optional(),\n window: z.unknown().optional(),\n initialEntries: z.array(z.string()).optional(),\n initialIndex: z.number().int().nonnegative().optional(),\n })\n .passthrough();\n\nconst transformOptionsSchema = z\n .object({\n pathValidation: z\n .object({\n enablePathValidation: z.boolean().optional(),\n allowedPathPrefixes: z.array(z.string().min(1)).optional(),\n maxPathLength: z.number().int().positive().optional(),\n allowAbsolutePaths: z.boolean().optional(),\n })\n .optional(),\n performance: z\n .object({\n enableCache: z.boolean().optional(),\n cacheTTL: z.number().int().positive().optional(),\n maxCacheSize: z.number().int().positive().optional(),\n maxRecursionDepth: z.number().int().positive().optional(),\n enableParallelProcessing: z.boolean().optional(),\n parallelBatchSize: z.number().int().positive().optional(),\n })\n .optional(),\n enableDebugLog: z.boolean().optional(),\n })\n .passthrough();\n\n/**\n * RouteConfig Schema\n */\nexport const routeConfigSchema: z.ZodType<any> = z.lazy(() =>\n z.object({\n layout: componentImportSchema.optional().nullable(),\n page: componentImportSchema.optional().nullable(),\n loading: componentImportSchema.optional().nullable(),\n error: componentImportSchema.optional().nullable(),\n errors: componentImportSchema.optional().nullable(),\n name: z.string().min(1, '路由名称不能为空'),\n path: z.string().optional(),\n isGroup: z.boolean().optional(),\n enableRedirection: z.boolean().optional(),\n handle: routeItemHandleSchema,\n children: z.array(routeConfigSchema).optional(),\n })\n);\n\n/**\n * RouterConfig Schema\n */\nexport const routerConfigSchema = z.object({\n enabled: z.union([z.boolean(), z.literal('disabled')]).optional(),\n routes: z\n .union([\n z.array(routeConfigSchema),\n z.function(),\n ])\n .optional(),\n mode: z.enum(['browser', 'hash', 'memory']).optional(),\n options: routerOptionsSchema.optional(),\n pathResolve: z\n .object({\n basePath: z.string().optional(),\n pathAliases: z.record(z.string(), z.string()).optional(),\n })\n .optional(),\n transformOptions: transformOptionsSchema.optional(),\n preload: z\n .object({\n strategy: z.enum(['none', 'next-level', 'all', 'visible']).optional(),\n delay: z.number().int().positive().optional(),\n priorityThreshold: z.number().int().nonnegative().optional(),\n timeout: z.number().int().positive().optional(),\n })\n .optional(),\n enableHydrateFallback: z.boolean().optional(),\n}).superRefine((config, ctx) => {\n if (!Array.isArray(config.routes)) {\n return;\n }\n\n const routeNameMap = new Map<string, string>();\n\n const walk = (routes: Array<z.infer<typeof routeConfigSchema>>, parentPath: string): void => {\n routes.forEach((route, index) => {\n const currentPath = `${parentPath}[${index}]`;\n const existingPath = routeNameMap.get(route.name);\n if (existingPath) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['routes', index, 'name'],\n message: `路由名称重复: \"${route.name}\",首次定义位置 ${existingPath}`,\n });\n } else {\n routeNameMap.set(route.name, currentPath);\n }\n\n if (Array.isArray(route.children) && route.children.length > 0) {\n walk(route.children as Array<z.infer<typeof routeConfigSchema>>, `${currentPath}.children`);\n }\n });\n };\n\n walk(config.routes, 'routes');\n});\n\n/**\n * 验证路由配置\n * \n * @param config - 要验证的路由配置\n * @returns 验证后的路由配置\n * @throws z.ZodError 如果配置验证失败\n */\nexport function validateRouterConfig(config: unknown) {\n return routerConfigSchema.parse(config);\n}\n\n/**\n * 安全验证路由配置(不抛出异常)\n * \n * @param config - 要验证的路由配置\n * @returns 验证结果\n */\nexport function safeValidateRouterConfig(config: unknown) {\n return routerConfigSchema.safeParse(config);\n}\n"],"names":["z","routeItemHandleSchema","object","title","string","min","i18nKey","optional","order","number","int","icon","hideInMenu","boolean","hideFooter","keepAlive","needLogin","roles","array","name","passthrough","componentImportSchema","union","function","null","routerOptionsSchema","basename","future","record","hydrationData","unknown","window","initialEntries","initialIndex","nonnegative","transformOptionsSchema","pathValidation","enablePathValidation","allowedPathPrefixes","maxPathLength","positive","allowAbsolutePaths","performance","enableCache","cacheTTL","maxCacheSize","maxRecursionDepth","enableParallelProcessing","parallelBatchSize","enableDebugLog","routeConfigSchema","lazy","layout","nullable","page","loading","error","errors","path","isGroup","enableRedirection","handle","children","routerConfigSchema","enabled","literal","routes","mode","enum","options","pathResolve","basePath","pathAliases","transformOptions","preload","strategy","delay","priorityThreshold","timeout","enableHydrateFallback","superRefine","config","ctx","Array","isArray","routeNameMap","Map","walk","parentPath","forEach","route","index","currentPath","existingPath","get","addIssue","code","ZodIssueCode","custom","message","set","length","validateRouterConfig","parse","safeValidateRouterConfig","safeParse"],"mappings":"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"}