@vlian/framework 1.2.57 → 1.2.60
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 +15 -3
- package/dist/analytics/index.cjs +1 -24
- package/dist/analytics/index.js +1 -3
- package/dist/analytics.umd.js +8 -208
- package/dist/components/LocaleSwitch.cjs +1 -118
- package/dist/components/LocaleSwitch.js +1 -103
- package/dist/components/ThemeSwitch.cjs +1 -117
- package/dist/components/ThemeSwitch.js +1 -102
- package/dist/components/index.cjs +1 -22
- package/dist/components/index.js +1 -4
- package/dist/components/persistence.cjs +1 -60
- package/dist/components/persistence.js +1 -39
- package/dist/core/Test.cjs +1 -66
- package/dist/core/Test.js +1 -15
- package/dist/core/app/AppContext.cjs +1 -350
- package/dist/core/app/AppContext.js +1 -339
- package/dist/core/app/AppContext.types.cjs +1 -6
- package/dist/core/app/AppContext.types.js +1 -5
- package/dist/core/app/BasicLayout.cjs +1 -124
- package/dist/core/app/BasicLayout.js +1 -74
- package/dist/core/app/DefaultApp.cjs +1 -152
- package/dist/core/app/DefaultApp.js +1 -143
- package/dist/core/app/index.cjs +1 -43
- package/dist/core/app/index.js +1 -7
- package/dist/core/config/AppConfig.cjs +1 -141
- package/dist/core/config/AppConfig.js +1 -133
- package/dist/core/config/ConfigLoader.cjs +1 -325
- package/dist/core/config/ConfigLoader.js +1 -311
- package/dist/core/config/ConfigValidator.cjs +2 -135
- package/dist/core/config/ConfigValidator.js +2 -121
- package/dist/core/config/index.cjs +1 -30
- package/dist/core/config/index.js +1 -7
- package/dist/core/dev/DevTools.cjs +1 -228
- package/dist/core/dev/DevTools.js +1 -210
- package/dist/core/error/ErrorBoundary.cjs +1 -403
- package/dist/core/error/ErrorBoundary.js +1 -399
- package/dist/core/error/ErrorHandler.cjs +1 -277
- package/dist/core/error/ErrorHandler.js +1 -261
- package/dist/core/error/index.cjs +1 -36
- package/dist/core/error/index.js +1 -6
- package/dist/core/event/AppEventBus.cjs +1 -446
- package/dist/core/event/AppEventBus.js +1 -438
- package/dist/core/event/frameworkEvents.cjs +1 -143
- package/dist/core/event/frameworkEvents.js +1 -135
- package/dist/core/event/hooks.cjs +1 -71
- package/dist/core/event/hooks.js +1 -95
- package/dist/core/event/index.cjs +1 -43
- package/dist/core/event/index.js +1 -10
- package/dist/core/event/types.cjs +1 -64
- package/dist/core/event/types.js +1 -56
- package/dist/core/event/useEventBus.cjs +1 -27
- package/dist/core/event/useEventBus.js +1 -39
- package/dist/core/index.cjs +1 -142
- package/dist/core/index.js +1 -69
- package/dist/core/initialization/InitializationErrorThrower.cjs +1 -77
- package/dist/core/initialization/InitializationErrorThrower.js +1 -30
- package/dist/core/initialization/index.cjs +1 -28
- package/dist/core/initialization/index.js +1 -7
- package/dist/core/initialization/initialization.cjs +1 -66
- package/dist/core/initialization/initialization.js +1 -78
- package/dist/core/initialization/initializationErrorState.cjs +1 -68
- package/dist/core/initialization/initializationErrorState.js +1 -60
- package/dist/core/kernel/defaultAdapters.cjs +1 -186
- package/dist/core/kernel/defaultAdapters.js +1 -176
- package/dist/core/kernel/errors.cjs +1 -71
- package/dist/core/kernel/errors.js +1 -53
- package/dist/core/kernel/index.cjs +1 -22
- package/dist/core/kernel/index.js +1 -4
- package/dist/core/kernel/startKernel.cjs +1 -202
- package/dist/core/kernel/startKernel.js +1 -192
- package/dist/core/kernel/types.cjs +1 -6
- package/dist/core/kernel/types.js +1 -3
- package/dist/core/middleware.cjs +1 -75
- package/dist/core/middleware.js +1 -61
- package/dist/core/plugin/PluginEventBus.cjs +1 -300
- package/dist/core/plugin/PluginEventBus.js +1 -286
- package/dist/core/plugin/PluginSandbox.cjs +1 -139
- package/dist/core/plugin/PluginSandbox.js +1 -125
- package/dist/core/plugin.cjs +1 -496
- package/dist/core/plugin.js +1 -438
- package/dist/core/router/RouterManager.cjs +1 -288
- package/dist/core/router/RouterManager.js +1 -272
- package/dist/core/router/adapter/AdapterManager.cjs +1 -237
- package/dist/core/router/adapter/AdapterManager.js +1 -221
- package/dist/core/router/adapter/index.cjs +1 -24
- package/dist/core/router/adapter/index.js +1 -7
- package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs +1 -130
- package/dist/core/router/adapter/react-router/ReactRouterAdapter.js +1 -116
- package/dist/core/router/adapter/react-router/index.cjs +1 -22
- package/dist/core/router/adapter/react-router/index.js +1 -5
- package/dist/core/router/adapter/types.cjs +1 -8
- package/dist/core/router/adapter/types.js +1 -7
- package/dist/core/router/dev/RouterDevTools.cjs +1 -262
- package/dist/core/router/dev/RouterDevTools.js +1 -211
- package/dist/core/router/dev/index.cjs +1 -22
- package/dist/core/router/dev/index.js +1 -5
- package/dist/core/router/dynamic/DynamicRouteManager.cjs +1 -195
- package/dist/core/router/dynamic/DynamicRouteManager.js +1 -179
- package/dist/core/router/dynamic/index.cjs +1 -22
- package/dist/core/router/dynamic/index.js +1 -5
- package/dist/core/router/errors/RouterError.cjs +1 -63
- package/dist/core/router/errors/RouterError.js +1 -48
- package/dist/core/router/errors/index.cjs +1 -22
- package/dist/core/router/errors/index.js +1 -5
- package/dist/core/router/index.cjs +1 -38
- package/dist/core/router/index.js +1 -32
- package/dist/core/router/lifecycle/RouterLifecycleManager.cjs +1 -146
- package/dist/core/router/lifecycle/RouterLifecycleManager.js +1 -130
- package/dist/core/router/lifecycle/index.cjs +1 -22
- package/dist/core/router/lifecycle/index.js +1 -5
- package/dist/core/router/middleware/RouterMiddlewareManager.cjs +1 -195
- package/dist/core/router/middleware/RouterMiddlewareManager.js +1 -179
- package/dist/core/router/middleware/auth.cjs +1 -68
- package/dist/core/router/middleware/auth.js +1 -63
- package/dist/core/router/middleware/index.cjs +1 -24
- package/dist/core/router/middleware/index.js +1 -7
- package/dist/core/router/middleware/types.cjs +1 -8
- package/dist/core/router/middleware/types.js +1 -7
- package/dist/core/router/monitoring/RouterMonitoring.cjs +1 -229
- package/dist/core/router/monitoring/RouterMonitoring.js +1 -213
- package/dist/core/router/monitoring/index.cjs +1 -22
- package/dist/core/router/monitoring/index.js +1 -5
- package/dist/core/router/navigation/RouterNavigation.cjs +1 -241
- package/dist/core/router/navigation/RouterNavigation.js +1 -192
- package/dist/core/router/navigation/index.cjs +1 -22
- package/dist/core/router/navigation/index.js +1 -5
- package/dist/core/router/performance/RouteCache.cjs +1 -307
- package/dist/core/router/performance/RouteCache.js +1 -291
- package/dist/core/router/performance/RoutePreloader.cjs +1 -294
- package/dist/core/router/performance/RoutePreloader.js +1 -277
- package/dist/core/router/performance/index.cjs +1 -23
- package/dist/core/router/performance/index.js +1 -6
- package/dist/core/router/plugin/RouterPluginManager.cjs +1 -264
- package/dist/core/router/plugin/RouterPluginManager.js +1 -248
- package/dist/core/router/plugin/index.cjs +1 -23
- package/dist/core/router/plugin/index.js +1 -6
- package/dist/core/router/plugin/types.cjs +1 -41
- package/dist/core/router/plugin/types.js +1 -33
- package/dist/core/router/types.cjs +1 -6
- package/dist/core/router/types.js +1 -5
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs +1 -131
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js +1 -121
- package/dist/core/router/utils/adapters/react-router/transform.cjs +1 -252
- package/dist/core/router/utils/adapters/react-router/transform.js +1 -242
- package/dist/core/router/utils/transform.cjs +1 -782
- package/dist/core/router/utils/transform.js +1 -791
- package/dist/core/router/validation/RouterConfigValidator.cjs +2 -85
- package/dist/core/router/validation/RouterConfigValidator.js +2 -77
- package/dist/core/router/validation/index.cjs +1 -23
- package/dist/core/router/validation/index.js +1 -6
- package/dist/core/router/validation/schema.cjs +1 -161
- package/dist/core/router/validation/schema.js +1 -151
- package/dist/core/router/version/RouteVersionManager.cjs +1 -207
- package/dist/core/router/version/RouteVersionManager.js +1 -191
- package/dist/core/router/version/index.cjs +1 -22
- package/dist/core/router/version/index.js +1 -5
- package/dist/core/splash/SplashScreen.cjs +1 -343
- package/dist/core/splash/SplashScreen.js +1 -293
- package/dist/core/splash/index.cjs +1 -24
- package/dist/core/splash/index.js +1 -6
- package/dist/core/splash/splashScreenUtils.cjs +1 -40
- package/dist/core/splash/splashScreenUtils.js +1 -30
- package/dist/core/startup/AppInstance.cjs +1 -241
- package/dist/core/startup/AppInstance.js +1 -226
- package/dist/core/startup/environment.cjs +1 -171
- package/dist/core/startup/environment.js +1 -154
- package/dist/core/startup/index.cjs +1 -25
- package/dist/core/startup/index.js +1 -8
- package/dist/core/startup/initializeServices.cjs +1 -228
- package/dist/core/startup/initializeServices.js +1 -188
- package/dist/core/startup/performanceTracker.cjs +1 -181
- package/dist/core/startup/performanceTracker.js +1 -167
- package/dist/core/startup/renderApp.cjs +1 -316
- package/dist/core/startup/renderApp.js +1 -267
- package/dist/core/startup/startApp.cjs +1 -319
- package/dist/core/startup/startApp.js +1 -315
- package/dist/core/types.cjs +1 -6
- package/dist/core/types.js +1 -5
- package/dist/index.cjs +1 -54
- package/dist/index.js +1 -11
- package/dist/index.umd.cjs +1 -29
- package/dist/index.umd.js +362 -13233
- package/dist/kernel/constants.cjs +1 -67
- package/dist/kernel/constants.js +1 -43
- package/dist/kernel/index.cjs +1 -40
- package/dist/kernel/index.js +1 -4
- package/dist/kernel/kernel.cjs +1 -297
- package/dist/kernel/kernel.js +1 -273
- package/dist/kernel/manager/cacheManager.cjs +1 -48
- package/dist/kernel/manager/cacheManager.js +1 -38
- package/dist/kernel/manager/i18n/I18nManager.cjs +1 -93
- package/dist/kernel/manager/i18n/I18nManager.js +1 -83
- package/dist/kernel/manager/i18n/i18n.persistence.cjs +1 -62
- package/dist/kernel/manager/i18n/i18n.persistence.js +1 -41
- package/dist/kernel/manager/i18n/i18n.schema.cjs +1 -88
- package/dist/kernel/manager/i18n/i18n.schema.js +1 -64
- package/dist/kernel/manager/i18n/index.cjs +1 -13
- package/dist/kernel/manager/i18n/index.js +1 -3
- package/dist/kernel/manager/i18nManager.cjs +1 -13
- package/dist/kernel/manager/i18nManager.js +1 -3
- package/dist/kernel/manager/index.cjs +1 -30
- package/dist/kernel/manager/index.js +1 -6
- package/dist/kernel/manager/logger/LoggerManager.cjs +1 -109
- package/dist/kernel/manager/logger/LoggerManager.js +1 -99
- package/dist/kernel/manager/logger/index.cjs +1 -13
- package/dist/kernel/manager/logger/index.js +1 -3
- package/dist/kernel/manager/logger/logger.persistence.cjs +1 -64
- package/dist/kernel/manager/logger/logger.persistence.js +1 -43
- package/dist/kernel/manager/logger/logger.schema.cjs +1 -76
- package/dist/kernel/manager/logger/logger.schema.js +1 -55
- package/dist/kernel/manager/loggerManager.cjs +1 -13
- package/dist/kernel/manager/loggerManager.js +1 -3
- package/dist/kernel/manager/theme/ThemeManager.cjs +1 -86
- package/dist/kernel/manager/theme/ThemeManager.js +1 -76
- package/dist/kernel/manager/theme/index.cjs +1 -13
- package/dist/kernel/manager/theme/index.js +1 -3
- package/dist/kernel/manager/theme/theme.dom.cjs +1 -63
- package/dist/kernel/manager/theme/theme.dom.js +1 -45
- package/dist/kernel/manager/theme/theme.persistence.cjs +1 -59
- package/dist/kernel/manager/theme/theme.persistence.js +1 -38
- package/dist/kernel/manager/theme/theme.schema.cjs +1 -124
- package/dist/kernel/manager/theme/theme.schema.js +1 -97
- package/dist/kernel/manager/themeManager.cjs +1 -13
- package/dist/kernel/manager/themeManager.js +1 -3
- package/dist/kernel/types.cjs +1 -6
- package/dist/kernel/types.js +1 -3
- package/dist/library/index.cjs +1 -21
- package/dist/library/index.js +1 -4
- package/dist/library/locale/index.cjs +1 -41
- package/dist/library/locale/index.js +1 -12
- package/dist/library/locale/langs/en-us/index.cjs +1 -34
- package/dist/library/locale/langs/en-us/index.js +1 -24
- package/dist/library/locale/langs/zh-cn/index.cjs +1 -34
- package/dist/library/locale/langs/zh-cn/index.js +1 -24
- package/dist/library/locale/types.cjs +1 -6
- package/dist/library/locale/types.js +1 -3
- package/dist/library/storage/cache.cjs +1 -245
- package/dist/library/storage/cache.js +1 -237
- package/dist/library/storage/encryption.cjs +1 -149
- package/dist/library/storage/encryption.js +1 -141
- package/dist/library/storage/index.cjs +1 -126
- package/dist/library/storage/index.js +1 -106
- package/dist/state/StateManager.cjs +1 -168
- package/dist/state/StateManager.js +1 -160
- package/dist/state/adapters/AdapterFactory.cjs +1 -91
- package/dist/state/adapters/AdapterFactory.js +1 -85
- package/dist/state/adapters/DefaultAdapter.cjs +1 -77
- package/dist/state/adapters/DefaultAdapter.js +1 -71
- package/dist/state/adapters/ReduxAdapter.cjs +1 -445
- package/dist/state/adapters/ReduxAdapter.js +1 -439
- package/dist/state/adapters/ZustandAdapter.cjs +1 -71
- package/dist/state/adapters/ZustandAdapter.js +1 -70
- package/dist/state/adapters/index.cjs +1 -46
- package/dist/state/adapters/index.js +1 -9
- package/dist/state/adapters/types.cjs +1 -22
- package/dist/state/adapters/types.js +1 -5
- package/dist/state/core/DerivedStateInstance.cjs +1 -176
- package/dist/state/core/DerivedStateInstance.js +1 -173
- package/dist/state/core/StateInstance.cjs +1 -172
- package/dist/state/core/StateInstance.js +1 -168
- package/dist/state/core/StateRegistry.cjs +1 -112
- package/dist/state/core/StateRegistry.js +1 -106
- package/dist/state/core/StateScope.cjs +1 -139
- package/dist/state/core/StateScope.js +1 -133
- package/dist/state/core/index.cjs +1 -32
- package/dist/state/core/index.js +1 -8
- package/dist/state/index.cjs +1 -32
- package/dist/state/index.js +1 -12
- package/dist/state/types.cjs +1 -14
- package/dist/state/types.js +1 -13
- package/dist/state.umd.js +22 -1395
- package/dist/types.cjs +1 -6
- package/dist/types.js +1 -3
- package/dist/utils/analytics.cjs +1 -219
- package/dist/utils/analytics.js +1 -204
- package/dist/utils/configSecurity.cjs +3 -184
- package/dist/utils/configSecurity.js +3 -176
- package/dist/utils/csrf.cjs +1 -20
- package/dist/utils/csrf.js +1 -3
- package/dist/utils/errors/ErrorCodes.cjs +1 -27
- package/dist/utils/errors/ErrorCodes.js +1 -3
- package/dist/utils/errors.cjs +1 -113
- package/dist/utils/errors.js +1 -18
- package/dist/utils/index.cjs +1 -137
- package/dist/utils/index.js +1 -48
- package/dist/utils/logger.cjs +1 -27
- package/dist/utils/logger.js +1 -3
- package/dist/utils/logger.types.cjs +1 -13
- package/dist/utils/logger.types.js +1 -3
- package/dist/utils/monitoring.cjs +1 -20
- package/dist/utils/monitoring.js +1 -3
- package/dist/utils/performance.cjs +1 -24
- package/dist/utils/performance.js +1 -3
- package/dist/utils/resourceLoader.cjs +1 -24
- package/dist/utils/resourceLoader.js +1 -3
- package/dist/utils/runtimeSecurity.cjs +1 -13
- package/dist/utils/runtimeSecurity.js +1 -3
- package/dist/utils/security.cjs +1 -21
- package/dist/utils/security.js +1 -3
- package/dist/utils/traceId.cjs +1 -39
- package/dist/utils/traceId.js +1 -3
- package/dist/utils/validation.cjs +1 -21
- package/dist/utils/validation.js +1 -3
- package/package.json +9 -6
- package/dist/analytics/index.cjs.map +0 -1
- package/dist/analytics/index.js.map +0 -1
- package/dist/analytics.umd.js.map +0 -1
- package/dist/components/LocaleSwitch.cjs.map +0 -1
- package/dist/components/LocaleSwitch.js.map +0 -1
- package/dist/components/ThemeSwitch.cjs.map +0 -1
- package/dist/components/ThemeSwitch.js.map +0 -1
- package/dist/components/index.cjs.map +0 -1
- package/dist/components/index.js.map +0 -1
- package/dist/components/persistence.cjs.map +0 -1
- package/dist/components/persistence.js.map +0 -1
- package/dist/core/Test.cjs.map +0 -1
- package/dist/core/Test.js.map +0 -1
- package/dist/core/app/AppContext.cjs.map +0 -1
- package/dist/core/app/AppContext.js.map +0 -1
- package/dist/core/app/AppContext.types.cjs.map +0 -1
- package/dist/core/app/AppContext.types.js.map +0 -1
- package/dist/core/app/BasicLayout.cjs.map +0 -1
- package/dist/core/app/BasicLayout.js.map +0 -1
- package/dist/core/app/DefaultApp.cjs.map +0 -1
- package/dist/core/app/DefaultApp.js.map +0 -1
- package/dist/core/app/index.cjs.map +0 -1
- package/dist/core/app/index.js.map +0 -1
- package/dist/core/config/AppConfig.cjs.map +0 -1
- package/dist/core/config/AppConfig.js.map +0 -1
- package/dist/core/config/ConfigLoader.cjs.map +0 -1
- package/dist/core/config/ConfigLoader.js.map +0 -1
- package/dist/core/config/ConfigValidator.cjs.map +0 -1
- package/dist/core/config/ConfigValidator.js.map +0 -1
- package/dist/core/config/index.cjs.map +0 -1
- package/dist/core/config/index.js.map +0 -1
- package/dist/core/dev/DevTools.cjs.map +0 -1
- package/dist/core/dev/DevTools.js.map +0 -1
- package/dist/core/error/ErrorBoundary.cjs.map +0 -1
- package/dist/core/error/ErrorBoundary.js.map +0 -1
- package/dist/core/error/ErrorHandler.cjs.map +0 -1
- package/dist/core/error/ErrorHandler.js.map +0 -1
- package/dist/core/error/index.cjs.map +0 -1
- package/dist/core/error/index.js.map +0 -1
- package/dist/core/event/AppEventBus.cjs.map +0 -1
- package/dist/core/event/AppEventBus.js.map +0 -1
- package/dist/core/event/frameworkEvents.cjs.map +0 -1
- package/dist/core/event/frameworkEvents.js.map +0 -1
- package/dist/core/event/hooks.cjs.map +0 -1
- package/dist/core/event/hooks.js.map +0 -1
- package/dist/core/event/index.cjs.map +0 -1
- package/dist/core/event/index.js.map +0 -1
- package/dist/core/event/types.cjs.map +0 -1
- package/dist/core/event/types.js.map +0 -1
- package/dist/core/event/useEventBus.cjs.map +0 -1
- package/dist/core/event/useEventBus.js.map +0 -1
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/core/initialization/InitializationErrorThrower.cjs.map +0 -1
- package/dist/core/initialization/InitializationErrorThrower.js.map +0 -1
- package/dist/core/initialization/index.cjs.map +0 -1
- package/dist/core/initialization/index.js.map +0 -1
- package/dist/core/initialization/initialization.cjs.map +0 -1
- package/dist/core/initialization/initialization.js.map +0 -1
- package/dist/core/initialization/initializationErrorState.cjs.map +0 -1
- package/dist/core/initialization/initializationErrorState.js.map +0 -1
- package/dist/core/kernel/defaultAdapters.cjs.map +0 -1
- package/dist/core/kernel/defaultAdapters.js.map +0 -1
- package/dist/core/kernel/errors.cjs.map +0 -1
- package/dist/core/kernel/errors.js.map +0 -1
- package/dist/core/kernel/index.cjs.map +0 -1
- package/dist/core/kernel/index.js.map +0 -1
- package/dist/core/kernel/startKernel.cjs.map +0 -1
- package/dist/core/kernel/startKernel.js.map +0 -1
- package/dist/core/kernel/types.cjs.map +0 -1
- package/dist/core/kernel/types.js.map +0 -1
- package/dist/core/middleware.cjs.map +0 -1
- package/dist/core/middleware.js.map +0 -1
- package/dist/core/plugin/PluginEventBus.cjs.map +0 -1
- package/dist/core/plugin/PluginEventBus.js.map +0 -1
- package/dist/core/plugin/PluginSandbox.cjs.map +0 -1
- package/dist/core/plugin/PluginSandbox.js.map +0 -1
- package/dist/core/plugin.cjs.map +0 -1
- package/dist/core/plugin.js.map +0 -1
- package/dist/core/router/RouterManager.cjs.map +0 -1
- package/dist/core/router/RouterManager.js.map +0 -1
- package/dist/core/router/adapter/AdapterManager.cjs.map +0 -1
- package/dist/core/router/adapter/AdapterManager.js.map +0 -1
- package/dist/core/router/adapter/index.cjs.map +0 -1
- package/dist/core/router/adapter/index.js.map +0 -1
- package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs.map +0 -1
- package/dist/core/router/adapter/react-router/ReactRouterAdapter.js.map +0 -1
- package/dist/core/router/adapter/react-router/index.cjs.map +0 -1
- package/dist/core/router/adapter/react-router/index.js.map +0 -1
- package/dist/core/router/adapter/types.cjs.map +0 -1
- package/dist/core/router/adapter/types.js.map +0 -1
- package/dist/core/router/dev/RouterDevTools.cjs.map +0 -1
- package/dist/core/router/dev/RouterDevTools.js.map +0 -1
- package/dist/core/router/dev/index.cjs.map +0 -1
- package/dist/core/router/dev/index.js.map +0 -1
- package/dist/core/router/dynamic/DynamicRouteManager.cjs.map +0 -1
- package/dist/core/router/dynamic/DynamicRouteManager.js.map +0 -1
- package/dist/core/router/dynamic/index.cjs.map +0 -1
- package/dist/core/router/dynamic/index.js.map +0 -1
- package/dist/core/router/errors/RouterError.cjs.map +0 -1
- package/dist/core/router/errors/RouterError.js.map +0 -1
- package/dist/core/router/errors/index.cjs.map +0 -1
- package/dist/core/router/errors/index.js.map +0 -1
- package/dist/core/router/index.cjs.map +0 -1
- package/dist/core/router/index.js.map +0 -1
- package/dist/core/router/lifecycle/RouterLifecycleManager.cjs.map +0 -1
- package/dist/core/router/lifecycle/RouterLifecycleManager.js.map +0 -1
- package/dist/core/router/lifecycle/index.cjs.map +0 -1
- package/dist/core/router/lifecycle/index.js.map +0 -1
- package/dist/core/router/middleware/RouterMiddlewareManager.cjs.map +0 -1
- package/dist/core/router/middleware/RouterMiddlewareManager.js.map +0 -1
- package/dist/core/router/middleware/auth.cjs.map +0 -1
- package/dist/core/router/middleware/auth.js.map +0 -1
- package/dist/core/router/middleware/index.cjs.map +0 -1
- package/dist/core/router/middleware/index.js.map +0 -1
- package/dist/core/router/middleware/types.cjs.map +0 -1
- package/dist/core/router/middleware/types.js.map +0 -1
- package/dist/core/router/monitoring/RouterMonitoring.cjs.map +0 -1
- package/dist/core/router/monitoring/RouterMonitoring.js.map +0 -1
- package/dist/core/router/monitoring/index.cjs.map +0 -1
- package/dist/core/router/monitoring/index.js.map +0 -1
- package/dist/core/router/navigation/RouterNavigation.cjs.map +0 -1
- package/dist/core/router/navigation/RouterNavigation.js.map +0 -1
- package/dist/core/router/navigation/index.cjs.map +0 -1
- package/dist/core/router/navigation/index.js.map +0 -1
- package/dist/core/router/performance/RouteCache.cjs.map +0 -1
- package/dist/core/router/performance/RouteCache.js.map +0 -1
- package/dist/core/router/performance/RoutePreloader.cjs.map +0 -1
- package/dist/core/router/performance/RoutePreloader.js.map +0 -1
- package/dist/core/router/performance/index.cjs.map +0 -1
- package/dist/core/router/performance/index.js.map +0 -1
- package/dist/core/router/plugin/RouterPluginManager.cjs.map +0 -1
- package/dist/core/router/plugin/RouterPluginManager.js.map +0 -1
- package/dist/core/router/plugin/index.cjs.map +0 -1
- package/dist/core/router/plugin/index.js.map +0 -1
- package/dist/core/router/plugin/types.cjs.map +0 -1
- package/dist/core/router/plugin/types.js.map +0 -1
- package/dist/core/router/types.cjs.map +0 -1
- package/dist/core/router/types.js.map +0 -1
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs.map +0 -1
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js.map +0 -1
- package/dist/core/router/utils/adapters/react-router/transform.cjs.map +0 -1
- package/dist/core/router/utils/adapters/react-router/transform.js.map +0 -1
- package/dist/core/router/utils/transform.cjs.map +0 -1
- package/dist/core/router/utils/transform.js.map +0 -1
- package/dist/core/router/validation/RouterConfigValidator.cjs.map +0 -1
- package/dist/core/router/validation/RouterConfigValidator.js.map +0 -1
- package/dist/core/router/validation/index.cjs.map +0 -1
- package/dist/core/router/validation/index.js.map +0 -1
- package/dist/core/router/validation/schema.cjs.map +0 -1
- package/dist/core/router/validation/schema.js.map +0 -1
- package/dist/core/router/version/RouteVersionManager.cjs.map +0 -1
- package/dist/core/router/version/RouteVersionManager.js.map +0 -1
- package/dist/core/router/version/index.cjs.map +0 -1
- package/dist/core/router/version/index.js.map +0 -1
- package/dist/core/splash/SplashScreen.cjs.map +0 -1
- package/dist/core/splash/SplashScreen.js.map +0 -1
- package/dist/core/splash/index.cjs.map +0 -1
- package/dist/core/splash/index.js.map +0 -1
- package/dist/core/splash/splashScreenUtils.cjs.map +0 -1
- package/dist/core/splash/splashScreenUtils.js.map +0 -1
- package/dist/core/startup/AppInstance.cjs.map +0 -1
- package/dist/core/startup/AppInstance.js.map +0 -1
- package/dist/core/startup/environment.cjs.map +0 -1
- package/dist/core/startup/environment.js.map +0 -1
- package/dist/core/startup/index.cjs.map +0 -1
- package/dist/core/startup/index.js.map +0 -1
- package/dist/core/startup/initializeServices.cjs.map +0 -1
- package/dist/core/startup/initializeServices.js.map +0 -1
- package/dist/core/startup/performanceTracker.cjs.map +0 -1
- package/dist/core/startup/performanceTracker.js.map +0 -1
- package/dist/core/startup/renderApp.cjs.map +0 -1
- package/dist/core/startup/renderApp.js.map +0 -1
- package/dist/core/startup/startApp.cjs.map +0 -1
- package/dist/core/startup/startApp.js.map +0 -1
- package/dist/core/types.cjs.map +0 -1
- package/dist/core/types.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.umd.cjs.map +0 -1
- package/dist/index.umd.js.map +0 -1
- package/dist/kernel/constants.cjs.map +0 -1
- package/dist/kernel/constants.js.map +0 -1
- package/dist/kernel/index.cjs.map +0 -1
- package/dist/kernel/index.js.map +0 -1
- package/dist/kernel/kernel.cjs.map +0 -1
- package/dist/kernel/kernel.js.map +0 -1
- package/dist/kernel/manager/cacheManager.cjs.map +0 -1
- package/dist/kernel/manager/cacheManager.js.map +0 -1
- package/dist/kernel/manager/i18n/I18nManager.cjs.map +0 -1
- package/dist/kernel/manager/i18n/I18nManager.js.map +0 -1
- package/dist/kernel/manager/i18n/i18n.persistence.cjs.map +0 -1
- package/dist/kernel/manager/i18n/i18n.persistence.js.map +0 -1
- package/dist/kernel/manager/i18n/i18n.schema.cjs.map +0 -1
- package/dist/kernel/manager/i18n/i18n.schema.js.map +0 -1
- package/dist/kernel/manager/i18n/index.cjs.map +0 -1
- package/dist/kernel/manager/i18n/index.js.map +0 -1
- package/dist/kernel/manager/i18nManager.cjs.map +0 -1
- package/dist/kernel/manager/i18nManager.js.map +0 -1
- package/dist/kernel/manager/index.cjs.map +0 -1
- package/dist/kernel/manager/index.js.map +0 -1
- package/dist/kernel/manager/logger/LoggerManager.cjs.map +0 -1
- package/dist/kernel/manager/logger/LoggerManager.js.map +0 -1
- package/dist/kernel/manager/logger/index.cjs.map +0 -1
- package/dist/kernel/manager/logger/index.js.map +0 -1
- package/dist/kernel/manager/logger/logger.persistence.cjs.map +0 -1
- package/dist/kernel/manager/logger/logger.persistence.js.map +0 -1
- package/dist/kernel/manager/logger/logger.schema.cjs.map +0 -1
- package/dist/kernel/manager/logger/logger.schema.js.map +0 -1
- package/dist/kernel/manager/loggerManager.cjs.map +0 -1
- package/dist/kernel/manager/loggerManager.js.map +0 -1
- package/dist/kernel/manager/persistence.cjs +0 -78
- package/dist/kernel/manager/persistence.cjs.map +0 -1
- package/dist/kernel/manager/persistence.d.ts +0 -3
- package/dist/kernel/manager/persistence.js +0 -60
- package/dist/kernel/manager/persistence.js.map +0 -1
- package/dist/kernel/manager/theme/ThemeManager.cjs.map +0 -1
- package/dist/kernel/manager/theme/ThemeManager.js.map +0 -1
- package/dist/kernel/manager/theme/index.cjs.map +0 -1
- package/dist/kernel/manager/theme/index.js.map +0 -1
- package/dist/kernel/manager/theme/theme.dom.cjs.map +0 -1
- package/dist/kernel/manager/theme/theme.dom.js.map +0 -1
- package/dist/kernel/manager/theme/theme.persistence.cjs.map +0 -1
- package/dist/kernel/manager/theme/theme.persistence.js.map +0 -1
- package/dist/kernel/manager/theme/theme.schema.cjs.map +0 -1
- package/dist/kernel/manager/theme/theme.schema.js.map +0 -1
- package/dist/kernel/manager/themeManager.cjs.map +0 -1
- package/dist/kernel/manager/themeManager.js.map +0 -1
- package/dist/kernel/types.cjs.map +0 -1
- package/dist/kernel/types.js.map +0 -1
- package/dist/library/index.cjs.map +0 -1
- package/dist/library/index.js.map +0 -1
- package/dist/library/locale/index.cjs.map +0 -1
- package/dist/library/locale/index.js.map +0 -1
- package/dist/library/locale/langs/en-us/index.cjs.map +0 -1
- package/dist/library/locale/langs/en-us/index.js.map +0 -1
- package/dist/library/locale/langs/zh-cn/index.cjs.map +0 -1
- package/dist/library/locale/langs/zh-cn/index.js.map +0 -1
- package/dist/library/locale/types.cjs.map +0 -1
- package/dist/library/locale/types.js.map +0 -1
- package/dist/library/storage/cache.cjs.map +0 -1
- package/dist/library/storage/cache.js.map +0 -1
- package/dist/library/storage/encryption.cjs.map +0 -1
- package/dist/library/storage/encryption.js.map +0 -1
- package/dist/library/storage/index.cjs.map +0 -1
- package/dist/library/storage/index.js.map +0 -1
- package/dist/request/adapter/RequestAdapter.d.ts +0 -85
- package/dist/request/adapter/RequestAdapter.js +0 -70
- package/dist/request/adapter/RequestAdapter.js.map +0 -1
- package/dist/request/adapter/axiosAdapter.d.ts +0 -10
- package/dist/request/adapter/axiosAdapter.js +0 -115
- package/dist/request/adapter/axiosAdapter.js.map +0 -1
- package/dist/request/adapter/fetchAdapter.d.ts +0 -10
- package/dist/request/adapter/fetchAdapter.js +0 -126
- package/dist/request/adapter/fetchAdapter.js.map +0 -1
- package/dist/request/adapter/index.d.ts +0 -9
- package/dist/request/adapter/index.js +0 -14
- package/dist/request/adapter/index.js.map +0 -1
- package/dist/request/adapter/kyAdapter.d.ts +0 -10
- package/dist/request/adapter/kyAdapter.js +0 -142
- package/dist/request/adapter/kyAdapter.js.map +0 -1
- package/dist/request/adapter/undiciAdapter.d.ts +0 -10
- package/dist/request/adapter/undiciAdapter.js +0 -164
- package/dist/request/adapter/undiciAdapter.js.map +0 -1
- package/dist/request/adapter.d.ts +0 -1
- package/dist/request/core/RequestClient.d.ts +0 -134
- package/dist/request/core/RequestClient.js +0 -509
- package/dist/request/core/RequestClient.js.map +0 -1
- package/dist/request/core/index.d.ts +0 -5
- package/dist/request/core/index.js +0 -5
- package/dist/request/core/index.js.map +0 -1
- package/dist/request/core.d.ts +0 -1
- package/dist/request/index.d.ts +0 -1
- package/dist/request/index.js +0 -50
- package/dist/request/index.js.map +0 -1
- package/dist/request/plugin/RequestPlugin.d.ts +0 -170
- package/dist/request/plugin/RequestPlugin.js +0 -203
- package/dist/request/plugin/RequestPlugin.js.map +0 -1
- package/dist/request/plugin/cache.d.ts +0 -33
- package/dist/request/plugin/cache.js +0 -264
- package/dist/request/plugin/cache.js.map +0 -1
- package/dist/request/plugin/csrfPlugin.d.ts +0 -21
- package/dist/request/plugin/csrfPlugin.js +0 -44
- package/dist/request/plugin/csrfPlugin.js.map +0 -1
- package/dist/request/plugin/index.d.ts +0 -11
- package/dist/request/plugin/index.js +0 -12
- package/dist/request/plugin/index.js.map +0 -1
- package/dist/request/plugin/monitoring.d.ts +0 -112
- package/dist/request/plugin/monitoring.js +0 -205
- package/dist/request/plugin/monitoring.js.map +0 -1
- package/dist/request/plugin/queue.d.ts +0 -91
- package/dist/request/plugin/queue.js +0 -156
- package/dist/request/plugin/queue.js.map +0 -1
- package/dist/request/plugin/retry.d.ts +0 -34
- package/dist/request/plugin/retry.js +0 -93
- package/dist/request/plugin/retry.js.map +0 -1
- package/dist/request/plugin/validation.d.ts +0 -26
- package/dist/request/plugin/validation.js +0 -116
- package/dist/request/plugin/validation.js.map +0 -1
- package/dist/request/plugin.d.ts +0 -1
- package/dist/request/runtime/RequestContext.d.ts +0 -50
- package/dist/request/runtime/RequestContext.js +0 -86
- package/dist/request/runtime/RequestContext.js.map +0 -1
- package/dist/request/runtime/index.d.ts +0 -4
- package/dist/request/runtime/index.js +0 -5
- package/dist/request/runtime/index.js.map +0 -1
- package/dist/request/runtime.d.ts +0 -1
- package/dist/request/types.d.ts +0 -1
- package/dist/request/types.js +0 -97
- package/dist/request/types.js.map +0 -1
- package/dist/request/utils/RequestQueueManager.d.ts +0 -74
- package/dist/request/utils/RequestQueueManager.js +0 -160
- package/dist/request/utils/RequestQueueManager.js.map +0 -1
- package/dist/request/utils/dependencyCheck.d.ts +0 -63
- package/dist/request/utils/dependencyCheck.js +0 -192
- package/dist/request/utils/dependencyCheck.js.map +0 -1
- package/dist/request/utils/index.d.ts +0 -5
- package/dist/request/utils/index.js +0 -6
- package/dist/request/utils/index.js.map +0 -1
- package/dist/request/utils.d.ts +0 -1
- package/dist/state/StateManager.cjs.map +0 -1
- package/dist/state/StateManager.js.map +0 -1
- package/dist/state/adapters/AdapterFactory.cjs.map +0 -1
- package/dist/state/adapters/AdapterFactory.js.map +0 -1
- package/dist/state/adapters/DefaultAdapter.cjs.map +0 -1
- package/dist/state/adapters/DefaultAdapter.js.map +0 -1
- package/dist/state/adapters/ReduxAdapter.cjs.map +0 -1
- package/dist/state/adapters/ReduxAdapter.js.map +0 -1
- package/dist/state/adapters/ZustandAdapter.cjs.map +0 -1
- package/dist/state/adapters/ZustandAdapter.js.map +0 -1
- package/dist/state/adapters/index.cjs.map +0 -1
- package/dist/state/adapters/index.js.map +0 -1
- package/dist/state/adapters/types.cjs.map +0 -1
- package/dist/state/adapters/types.js.map +0 -1
- package/dist/state/core/DerivedStateInstance.cjs.map +0 -1
- package/dist/state/core/DerivedStateInstance.js.map +0 -1
- package/dist/state/core/StateInstance.cjs.map +0 -1
- package/dist/state/core/StateInstance.js.map +0 -1
- package/dist/state/core/StateRegistry.cjs.map +0 -1
- package/dist/state/core/StateRegistry.js.map +0 -1
- package/dist/state/core/StateScope.cjs.map +0 -1
- package/dist/state/core/StateScope.js.map +0 -1
- package/dist/state/core/index.cjs.map +0 -1
- package/dist/state/core/index.js.map +0 -1
- package/dist/state/index.cjs.map +0 -1
- package/dist/state/index.js.map +0 -1
- package/dist/state/types.cjs.map +0 -1
- package/dist/state/types.js.map +0 -1
- package/dist/state.umd.js.map +0 -1
- package/dist/types.cjs.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/analytics.cjs.map +0 -1
- package/dist/utils/analytics.js.map +0 -1
- package/dist/utils/configSecurity.cjs.map +0 -1
- package/dist/utils/configSecurity.js.map +0 -1
- package/dist/utils/csrf.cjs.map +0 -1
- package/dist/utils/csrf.js.map +0 -1
- package/dist/utils/errors/ErrorCodes.cjs.map +0 -1
- package/dist/utils/errors/ErrorCodes.js.map +0 -1
- package/dist/utils/errors.cjs.map +0 -1
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/index.cjs.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.cjs.map +0 -1
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/logger.types.cjs.map +0 -1
- package/dist/utils/logger.types.js.map +0 -1
- package/dist/utils/monitoring.cjs.map +0 -1
- package/dist/utils/monitoring.js.map +0 -1
- package/dist/utils/performance.cjs.map +0 -1
- package/dist/utils/performance.js.map +0 -1
- package/dist/utils/resourceLoader.cjs.map +0 -1
- package/dist/utils/resourceLoader.js.map +0 -1
- package/dist/utils/runtimeSecurity.cjs.map +0 -1
- package/dist/utils/runtimeSecurity.js.map +0 -1
- package/dist/utils/security.cjs.map +0 -1
- package/dist/utils/security.js.map +0 -1
- package/dist/utils/traceId.cjs.map +0 -1
- package/dist/utils/traceId.js.map +0 -1
- package/dist/utils/validation.cjs.map +0 -1
- package/dist/utils/validation.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/router/plugin/types.ts"],"sourcesContent":["/**\n * 路由插件类型定义\n */\n\nimport type { RouterConfig, RouteConfig } from '../types';\nimport type { RouterMiddlewareContext } from '../middleware/types';\n\n/**\n * 插件生命周期阶段\n */\nexport enum PluginLifecycleStage {\n /**\n * 插件注册阶段\n */\n REGISTER = 'register',\n\n /**\n * 路由初始化前\n */\n BEFORE_INIT = 'before-init',\n\n /**\n * 路由初始化后\n */\n AFTER_INIT = 'after-init',\n\n /**\n * 路由转换前\n */\n BEFORE_TRANSFORM = 'before-transform',\n\n /**\n * 路由转换后\n */\n AFTER_TRANSFORM = 'after-transform',\n\n /**\n * 路由匹配前\n */\n BEFORE_MATCH = 'before-match',\n\n /**\n * 路由匹配后\n */\n AFTER_MATCH = 'after-match',\n\n /**\n * 插件销毁阶段\n */\n DESTROY = 'destroy',\n}\n\n/**\n * 插件上下文\n */\nexport interface PluginContext {\n /**\n * 路由配置\n */\n config: RouterConfig;\n\n /**\n * 转换后的路由\n */\n routes?: RouteConfig[];\n\n /**\n * 中间件上下文(在路由匹配时可用)\n */\n middlewareContext?: RouterMiddlewareContext;\n\n /**\n * 插件元数据\n */\n meta?: Record<string, unknown>;\n}\n\n/**\n * 插件钩子函数\n */\nexport type PluginHook = (context: PluginContext) => void | Promise<void>;\n\n/**\n * 路由插件接口\n */\nexport interface RouterPlugin {\n /**\n * 插件名称(唯一标识)\n */\n name: string;\n\n /**\n * 插件版本\n */\n version?: string;\n\n /**\n * 插件描述\n */\n description?: string;\n\n /**\n * 插件优先级(数字越小优先级越高)\n * @default 100\n */\n priority?: number;\n\n /**\n * 是否启用\n * @default true\n */\n enabled?: boolean;\n\n /**\n * 插件依赖(其他插件名称列表)\n */\n dependencies?: string[];\n\n /**\n * 插件配置\n */\n config?: Record<string, unknown>;\n\n /**\n * 生命周期钩子\n */\n hooks?: {\n /**\n * 插件注册时调用\n */\n onRegister?: PluginHook;\n\n /**\n * 路由初始化前调用\n */\n onBeforeInit?: PluginHook;\n\n /**\n * 路由初始化后调用\n */\n onAfterInit?: PluginHook;\n\n /**\n * 路由转换前调用\n */\n onBeforeTransform?: PluginHook;\n\n /**\n * 路由转换后调用\n */\n onAfterTransform?: PluginHook;\n\n /**\n * 路由匹配前调用\n */\n onBeforeMatch?: PluginHook;\n\n /**\n * 路由匹配后调用\n */\n onAfterMatch?: PluginHook;\n\n /**\n * 插件销毁时调用\n */\n onDestroy?: PluginHook;\n };\n}\n\n/**\n * 插件注册选项\n */\nexport interface PluginRegisterOptions {\n /**\n * 是否覆盖已存在的插件\n * @default false\n */\n overwrite?: boolean;\n\n /**\n * 插件配置\n */\n config?: Record<string, unknown>;\n}\n"],"names":["PluginLifecycleStage"],"mappings":"AAAA;;CAEC;;;;+BAQWA;;;eAAAA;;;AAAL,IAAA,AAAKA,8CAAAA;IACV;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;WAtCSA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/router/plugin/types.ts"],"sourcesContent":["/**\n * 路由插件类型定义\n */\n\nimport type { RouterConfig, RouteConfig } from '../types';\nimport type { RouterMiddlewareContext } from '../middleware/types';\n\n/**\n * 插件生命周期阶段\n */\nexport enum PluginLifecycleStage {\n /**\n * 插件注册阶段\n */\n REGISTER = 'register',\n\n /**\n * 路由初始化前\n */\n BEFORE_INIT = 'before-init',\n\n /**\n * 路由初始化后\n */\n AFTER_INIT = 'after-init',\n\n /**\n * 路由转换前\n */\n BEFORE_TRANSFORM = 'before-transform',\n\n /**\n * 路由转换后\n */\n AFTER_TRANSFORM = 'after-transform',\n\n /**\n * 路由匹配前\n */\n BEFORE_MATCH = 'before-match',\n\n /**\n * 路由匹配后\n */\n AFTER_MATCH = 'after-match',\n\n /**\n * 插件销毁阶段\n */\n DESTROY = 'destroy',\n}\n\n/**\n * 插件上下文\n */\nexport interface PluginContext {\n /**\n * 路由配置\n */\n config: RouterConfig;\n\n /**\n * 转换后的路由\n */\n routes?: RouteConfig[];\n\n /**\n * 中间件上下文(在路由匹配时可用)\n */\n middlewareContext?: RouterMiddlewareContext;\n\n /**\n * 插件元数据\n */\n meta?: Record<string, unknown>;\n}\n\n/**\n * 插件钩子函数\n */\nexport type PluginHook = (context: PluginContext) => void | Promise<void>;\n\n/**\n * 路由插件接口\n */\nexport interface RouterPlugin {\n /**\n * 插件名称(唯一标识)\n */\n name: string;\n\n /**\n * 插件版本\n */\n version?: string;\n\n /**\n * 插件描述\n */\n description?: string;\n\n /**\n * 插件优先级(数字越小优先级越高)\n * @default 100\n */\n priority?: number;\n\n /**\n * 是否启用\n * @default true\n */\n enabled?: boolean;\n\n /**\n * 插件依赖(其他插件名称列表)\n */\n dependencies?: string[];\n\n /**\n * 插件配置\n */\n config?: Record<string, unknown>;\n\n /**\n * 生命周期钩子\n */\n hooks?: {\n /**\n * 插件注册时调用\n */\n onRegister?: PluginHook;\n\n /**\n * 路由初始化前调用\n */\n onBeforeInit?: PluginHook;\n\n /**\n * 路由初始化后调用\n */\n onAfterInit?: PluginHook;\n\n /**\n * 路由转换前调用\n */\n onBeforeTransform?: PluginHook;\n\n /**\n * 路由转换后调用\n */\n onAfterTransform?: PluginHook;\n\n /**\n * 路由匹配前调用\n */\n onBeforeMatch?: PluginHook;\n\n /**\n * 路由匹配后调用\n */\n onAfterMatch?: PluginHook;\n\n /**\n * 插件销毁时调用\n */\n onDestroy?: PluginHook;\n };\n}\n\n/**\n * 插件注册选项\n */\nexport interface PluginRegisterOptions {\n /**\n * 是否覆盖已存在的插件\n * @default false\n */\n overwrite?: boolean;\n\n /**\n * 插件配置\n */\n config?: Record<string, unknown>;\n}\n"],"names":["PluginLifecycleStage"],"mappings":"AAAA;;CAEC,GAKD;;CAEC,GACD,OAAO,IAAA,AAAKA,8CAAAA;IACV;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;IAGD;;GAEC;WAtCSA;MAwCX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/router/types.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/router/types.ts"],"sourcesContent":["import type { AppInstance } from '../startup/AppInstance';\nimport type { createBrowserRouter, createMemoryRouter } from 'react-router-dom';\nimport type { TransformOptions } from './utils/transform';\nimport type { PreloadConfig } from './performance/RoutePreloader';\n\nexport type RouteItemHandle = {\n title: string,\n i18nKey?: string,\n order: number,\n icon?: string,\n // 在菜单中隐藏\n hideInMenu?: boolean,\n // 隐藏尾部\n hideFooter?: boolean,\n // 保活\n keepAlive?: boolean,\n // 是否需要的登录\n needLogin?: boolean,\n // 角色\n roles?: Array<string>,\n // 路由名称,唯一Key\n name?: string,\n // 其他\n [key: string]: unknown,\n}\nexport type RouteItem = {\n // 布局 布局对象的key或动态导入函数\n layout?: string | ComponentImport | null,\n // 页面 页面对象的key或动态导入函数\n page?: string | ComponentImport | null,\n // loading 加载对象的key或动态导入函数\n loading?: string | ComponentImport | null,\n // 错误 组件的key或动态导入函数\n errors?: string | ComponentImport | null,\n // 错误(兼容字段)组件的key或动态导入函数\n error?: string | ComponentImport | null,\n // 路由名称,唯一Key\n name: string,\n // 路由\n path: string | undefined,\n // 是否分组路由\n isGroup?: boolean,\n // 是否开启重定向\n enableRedirection?: boolean,\n // 额外参数\n handle: RouteItemHandle,\n children?: RouteItem[]\n}\n\nexport type RouteMapType = Record<string, () => Promise<any>>;\n\n/**\n * DOM 路由选项类型(从 createBrowserRouter 和 createHashRouter 的参数类型提取)\n */\nexport type DOMRouterOpts = Parameters<typeof createBrowserRouter>[1];\n\n/**\n * Memory 路由选项类型(从 createMemoryRouter 的参数类型提取)\n */\nexport type MemoryRouterOpts = Parameters<typeof createMemoryRouter>[1];\n\n/**\n * 路由元数据(兼容 RouteItemHandle)\n * \n * @deprecated 建议直接使用 RouteItem 和 RouteItemHandle\n */\nexport interface RouteMeta {\n /**\n * 路由标题\n */\n title?: string;\n\n /**\n * 图标\n */\n icon?: string;\n\n /**\n * 排序\n */\n order?: number;\n\n /**\n * 权限标识\n */\n auth?: string | string[];\n\n /**\n * 是否在菜单中隐藏\n */\n hideInMenu?: boolean;\n\n /**\n * 是否启用 KeepAlive\n */\n keepAlive?: boolean;\n\n /**\n * 是否需要登录\n */\n needLogin?: boolean;\n\n /**\n * 角色列表\n */\n roles?: string[];\n\n /**\n * 路由名称(唯一标识)\n */\n name?: string;\n\n /**\n * 其他自定义元数据\n */\n [key: string]: unknown;\n}\n\n/**\n * 动态导入函数类型\n * \n * 用于懒加载组件,返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\nexport type ComponentImport = () => Promise<any>;\n\n/**\n * 路由配置项\n * \n * 与 RouteItem 的区别:\n * - layout、page、loading、error/errors 可以是组件路径字符串(如 \"@/pages/index.ts\")或动态导入函数\n * - 如果使用字符串,系统会自动转换为动态导入函数\n * - 如果使用函数,则直接使用,无需转换\n * - 对应的组件必须默认导出(export default xxxx)\n */\nexport interface RouteConfig {\n /**\n * 布局组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/layout.tsx\" 或 \"../../pages/layout.tsx\"\n * 函数示例: () => import(\"@/pages/layout.tsx\")\n * 组件必须默认导出\n */\n layout?: string | ComponentImport | null;\n\n /**\n * 页面组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/index.tsx\" 或 \"../../pages/index.tsx\"\n * 函数示例: () => import(\"@/pages/index.tsx\")\n * 组件必须默认导出\n */\n page?: string | ComponentImport | null;\n\n /**\n * 加载组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/components/Loading.tsx\"\n * 函数示例: () => import(\"@/components/Loading.tsx\")\n * 组件必须默认导出\n */\n loading?: string | ComponentImport | null;\n\n /**\n * 错误组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/error.tsx\"\n * 函数示例: () => import(\"@/pages/error.tsx\")\n * 组件必须默认导出\n */\n errors?: string | ComponentImport | null;\n\n /**\n * 错误组件路径(字符串)或动态导入函数(兼容字段,优先级高于 errors)\n *\n * 字符串示例: \"@/pages/error.tsx\"\n * 函数示例: () => import(\"@/pages/error.tsx\")\n * 组件必须默认导出\n */\n error?: string | ComponentImport | null;\n\n /**\n * 路由名称(唯一标识)\n */\n name: string;\n\n /**\n * 路由路径\n */\n path: string | undefined;\n\n /**\n * 是否为路由组\n */\n isGroup?: boolean;\n\n /**\n * 是否启用重定向\n */\n enableRedirection?: boolean;\n\n /**\n * 路由元数据\n */\n handle: {\n title: string;\n i18nKey?: string;\n order: number;\n icon?: string;\n hideInMenu?: boolean;\n hideFooter?: boolean;\n keepAlive?: boolean;\n needLogin?: boolean;\n roles?: Array<string>;\n name?: string;\n [key: string]: unknown;\n };\n\n /**\n * 子路由配置\n */\n children?: RouteConfig[];\n}\n\n/**\n * 路由位置信息\n */\nexport interface RouteLocation {\n /**\n * 路径\n */\n path: string;\n\n /**\n * 路径参数\n */\n params?: Record<string, unknown>;\n\n /**\n * 查询参数\n */\n query?: Record<string, unknown>;\n\n /**\n * 路由元数据\n */\n meta?: RouteMeta;\n}\n\n/**\n * 导航选项\n */\nexport interface NavigateOptions {\n /**\n * 是否替换当前历史记录\n */\n replace?: boolean;\n\n /**\n * 状态数据\n */\n state?: unknown;\n\n /**\n * 查询参数\n */\n query?: Record<string, unknown>;\n}\n\n/**\n * 路由生命周期钩子\n */\nexport interface RouteLifecycleHooks {\n /**\n * 路由跳转前钩子\n * \n * @param to - 目标路由\n * @param from - 来源路由\n * @returns 如果返回字符串,则跳转到该路径;如果返回 false,则阻止跳转;返回 true 或 undefined 则继续跳转\n */\n beforeEach?: (to: RouteLocation, from?: RouteLocation) => string | false | void | Promise<string | false | void>;\n\n /**\n * 路由跳转后钩子\n * \n * @param to - 目标路由\n * @param from - 来源路由\n */\n afterEach?: (to: RouteLocation, from?: RouteLocation) => void | Promise<void>;\n}\n\n/**\n * 路由模式\n * \n * 对应 react-router-dom 的路由模式:\n * - `browser`: 使用 BrowserRouter(createBrowserRouter)\n * - `hash`: 使用 HashRouter(createHashRouter)\n * - `memory`: 使用 MemoryRouter(createMemoryRouter)\n */\nexport type RouterMode = 'browser' | 'hash' | 'memory';\n\n/**\n * 应用路由接口\n * \n * 这是框架核心依赖的抽象接口,所有路由实现都必须实现此接口\n */\nexport interface AppRouter {\n /**\n * 挂载到应用实例\n * \n * @param app - 应用实例\n */\n mount(app: AppInstance): void;\n\n /**\n * 路由跳转\n * \n * @param to - 目标路径或路由名称\n * @param options - 导航选项\n */\n navigate(to: string, options?: NavigateOptions): void;\n\n /**\n * 获取当前路由信息\n * \n * @returns 当前路由位置信息\n */\n getCurrentRoute(): RouteLocation;\n\n /**\n * 销毁路由实例(可选)\n */\n destroy?(): void;\n}\n\n/**\n * 路径解析配置\n */\nexport interface PathResolveConfig {\n /**\n * 项目根目录路径\n * \n * 用于解析相对路径的基准目录。\n * 如果不提供,将使用调用框架的项目根目录(通常为 process.cwd())。\n * \n * 注意:路径解析主要由构建工具(如 Vite、Webpack)处理,\n * 此配置主要用于文档和错误提示。\n * \n * @example\n * ```typescript\n * router: {\n * pathResolve: {\n * basePath: '/path/to/project',\n * },\n * }\n * ```\n */\n basePath?: string;\n\n /**\n * 路径别名映射\n * \n * 用于将路径别名(如 @/)映射到实际路径。\n * 如果不提供,将使用构建工具的配置(如 vite.config.ts 中的 resolve.alias)。\n * \n * 注意:路径别名解析主要由构建工具处理,\n * 此配置主要用于文档和错误提示。\n * \n * @example\n * ```typescript\n * router: {\n * pathResolve: {\n * pathAliases: {\n * '@': './src',\n * '@components': './src/components',\n * },\n * },\n * }\n * ```\n */\n pathAliases?: Record<string, string>;\n}\n\n/**\n * 路由配置选项\n */\nexport interface RouterConfig {\n /**\n * 是否启用路由\n * \n * - `true`: 启用内置路由(默认)\n * - `false`: 禁用内置路由,使用自定义路由\n * - `'disabled'`: 完全禁用路由\n * \n * @default true\n */\n enabled?: boolean | 'disabled';\n\n /**\n * 路由配置列表\n * \n * 使用 RouteConfig 类型\n * \n * 注意:RouteConfig 中的 layout、page、loading、error/errors 可以是:\n * - 组件路径字符串:系统会自动转换为动态导入函数\n * - 动态导入函数:直接使用,无需转换\n * \n * 路径字符串可以是:\n * - 相对路径:如 `\"./pages/index.tsx\"`、`\"../components/Layout.tsx\"`\n * - 路径别名:如 `\"@/pages/index.tsx\"`(需要在构建工具中配置,如 vite.config.ts)\n * - 绝对路径:如 `\"/src/pages/index.tsx\"`(不推荐)\n * \n * 动态导入函数示例:\n * - `() => import(\"./pages/index.tsx\")`\n * - `() => import(\"@/pages/index.tsx\")`\n * \n * 路径解析由构建工具(如 Vite、Webpack)处理,框架会在运行时验证组件是否有默认导出。\n */\n routes?: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>);\n\n /**\n * 路由模式\n * \n * - `browser`: 使用 BrowserRouter(createBrowserRouter)- 默认\n * - `hash`: 使用 HashRouter(createHashRouter)\n * - `memory`: 使用 MemoryRouter(createMemoryRouter)\n * \n * @default 'browser'\n */\n mode?: RouterMode;\n\n /**\n * 路由选项\n * \n * 传递给 react-router-dom 的路由创建方法的选项\n * - `browser` 和 `hash` 模式使用 `DOMRouterOpts`\n * - `memory` 模式使用 `MemoryRouterOpts`\n */\n options?: DOMRouterOpts | MemoryRouterOpts;\n\n /**\n * 路径解析配置\n * \n * 用于配置路径解析选项,主要用于文档和错误提示。\n * 实际的路径解析由构建工具(如 Vite、Webpack)处理。\n */\n pathResolve?: PathResolveConfig;\n\n /**\n * 转换选项\n * \n * 用于配置转换选项,主要用于转换路由配置。\n */\n transformOptions?: TransformOptions;\n\n /**\n * 路由预加载配置\n *\n * 默认策略为 `none`,即按需懒加载路由组件。\n * 如需预加载,可显式配置 `strategy` 为 `next-level` / `visible` / `all`。\n */\n preload?: PreloadConfig;\n\n /**\n * 路由生命周期钩子\n */\n hooks?: RouteLifecycleHooks;\n\n /**\n * 是否启用配置验证(默认 true)\n * \n * 如果为 false,将跳过路由配置的 Zod 验证\n */\n enableValidation?: boolean;\n\n /**\n * 默认路由错误组件\n * \n * 当路由配置中的 `error`/`errors` 为空时,将使用此组件作为错误边界。\n * 如果不提供,将使用框架内置的 `RouteErrorBoundary` 组件。\n * \n * 组件必须使用默认导出(export default)。\n * \n * @example\n * ```typescript\n * router: {\n * defaultRouteErrorComponent: () => import('./components/CustomErrorBoundary'),\n * routes: [\n * {\n * name: 'home',\n * path: '/',\n * page: './pages/Home',\n * // error/errors 为空时,将使用 defaultRouteErrorComponent\n * },\n * ],\n * },\n * ```\n */\n defaultRouteErrorComponent?: ComponentImport;\n\n /**\n * 默认路由加载组件\n * \n * 当路由配置中的 `loading` 为空时,将使用此组件作为加载指示器。\n * 如果不提供,将使用框架内置 Loading 组件。\n * \n * 组件必须使用默认导出(export default)。\n * \n * @example\n * ```typescript\n * router: {\n * defaultRouteLoadingComponent: () => import('./components/CustomLoading'),\n * routes: [\n * {\n * name: 'home',\n * path: '/',\n * page: './pages/Home',\n * // loading 为空时,将使用 defaultRouteLoadingComponent\n * },\n * ],\n * },\n * ```\n */\n defaultRouteLoadingComponent?: ComponentImport;\n\n /**\n * 是否为路由注入 hydrateFallbackElement\n *\n * 默认关闭。仅在 SSR hydration 场景需要时开启。\n * 若未显式配置,会根据 `options.hydrationData` 自动推断。\n *\n * @default false\n */\n enableHydrateFallback?: boolean;\n}\n"],"names":[],"mappings":"AA+XA;;CAEC,GACD,WAoJC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/RouteErrorBoundary.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\ninterface RouteErrorLike extends Error {\n status?: number;\n statusText?: string;\n data?: unknown;\n cause?: unknown;\n}\n\nexport const RouteErrorBoundary = ({ error, resetErrorBoundary }: FallbackProps) => {\n const [showDetails, setShowDetails] = useState(false);\n const errorObject: RouteErrorLike | null =\n error !== null && typeof error === 'object' ? (error as RouteErrorLike) : null;\n const errorMessage =\n typeof errorObject?.message === 'string' && errorObject.message !== ''\n ? errorObject.message\n : '未知错误';\n const hasCause = errorObject?.cause !== undefined;\n\n const isNotFoundError =\n errorObject?.status === 404 ||\n (typeof errorObject?.statusText === 'string' && /not\\s*found/i.test(errorObject.statusText)) ||\n /no routes matched location|not found|404/i.test(errorMessage);\n\n const title = isNotFoundError ? '页面不存在(404)' : '出错了,请稍后再试';\n const friendlyMessage = isNotFoundError\n ? '访问的路由未注册或不存在,请检查访问地址。'\n : '请稍后再试或联系技术支持';\n const displayMessage = isDevelopment ? errorMessage : friendlyMessage;\n\n return (\n <div\n role=\"alert\"\n style={{\n minHeight: '100vh',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: 24,\n }}\n >\n <div style={{ maxWidth: 760, width: '100%', border: '1px solid #dde5ec', borderRadius: 10, padding: 20 }}>\n <h2 style={{ marginTop: 0 }}>{title}</h2>\n <p>{displayMessage}</p>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <button\n onClick={resetErrorBoundary}\n style={{ border: 'none', background: '#2f80ed', color: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n 刷新重试\n </button>\n {isDevelopment && (\n <button\n onClick={() => setShowDetails(!showDetails)}\n style={{ border: '1px solid #cfd7df', background: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n {showDetails ? '收起详情' : '展开详情'}\n </button>\n )}\n </div>\n\n {isDevelopment && showDetails && (\n <div style={{ background: '#f7fafc', borderRadius: 8, padding: 12, fontSize: 12, fontFamily: 'monospace' }}>\n <div style={{ marginBottom: 10 }}><strong>错误信息:</strong>{errorMessage}</div>\n {errorObject?.stack && (\n <div style={{ marginBottom: 10, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n <strong>堆栈:</strong>\n <br />\n {errorObject.stack}\n </div>\n )}\n {hasCause && (\n <div>\n <strong>原因:</strong>\n {errorObject?.cause instanceof Error ? errorObject.cause.message : String(errorObject?.cause)}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["RouteErrorBoundary","isDevelopment","process","env","NODE_ENV","error","resetErrorBoundary","showDetails","setShowDetails","useState","errorObject","errorMessage","message","hasCause","cause","undefined","isNotFoundError","status","statusText","test","title","friendlyMessage","displayMessage","div","role","style","minHeight","display","justifyContent","alignItems","padding","maxWidth","width","border","borderRadius","h2","marginTop","p","gap","marginBottom","button","onClick","background","color","cursor","fontSize","fontFamily","strong","stack","whiteSpace","wordBreak","br","Error","String"],"mappings":";;;;+BAYaA;;;eAAAA;;;;uBAZY;AAGzB,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AASxC,MAAMJ,qBAAqB,CAAC,EAAEK,KAAK,EAAEC,kBAAkB,EAAiB;IAC7E,MAAM,CAACC,aAAaC,eAAe,GAAGC,IAAAA,eAAQ,EAAC;IAC/C,MAAMC,cACJL,UAAU,QAAQ,OAAOA,UAAU,WAAYA,QAA2B;IAC5E,MAAMM,eACJ,OAAOD,aAAaE,YAAY,YAAYF,YAAYE,OAAO,KAAK,KAChEF,YAAYE,OAAO,GACnB;IACN,MAAMC,WAAWH,aAAaI,UAAUC;IAExC,MAAMC,kBACJN,aAAaO,WAAW,OACvB,OAAOP,aAAaQ,eAAe,YAAY,eAAeC,IAAI,CAACT,YAAYQ,UAAU,KAC1F,4CAA4CC,IAAI,CAACR;IAEnD,MAAMS,QAAQJ,kBAAkB,eAAe;IAC/C,MAAMK,kBAAkBL,kBACpB,0BACA;IACJ,MAAMM,iBAAiBrB,gBAAgBU,eAAeU;IAEtD,qBACE,qBAACE;QACCC,MAAK;QACLC,OAAO;YACLC,WAAW;YACXC,SAAS;YACTC,gBAAgB;YAChBC,YAAY;YACZC,SAAS;QACX;kBAEA,cAAA,sBAACP;YAAIE,OAAO;gBAAEM,UAAU;gBAAKC,OAAO;gBAAQC,QAAQ;gBAAqBC,cAAc;gBAAIJ,SAAS;YAAG;;8BACrG,qBAACK;oBAAGV,OAAO;wBAAEW,WAAW;oBAAE;8BAAIhB;;8BAC9B,qBAACiB;8BAAGf;;8BACJ,sBAACC;oBAAIE,OAAO;wBAAEE,SAAS;wBAAQW,KAAK;wBAAGC,cAAc;oBAAG;;sCACtD,qBAACC;4BACCC,SAASnC;4BACTmB,OAAO;gCAAEQ,QAAQ;gCAAQS,YAAY;gCAAWC,OAAO;gCAAQT,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCACxH;;wBAGA3C,+BACC,qBAACuC;4BACCC,SAAS,IAAMjC,eAAe,CAACD;4BAC/BkB,OAAO;gCAAEQ,QAAQ;gCAAqBS,YAAY;gCAAQR,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCAEjHrC,cAAc,SAAS;;;;gBAK7BN,iBAAiBM,6BAChB,sBAACgB;oBAAIE,OAAO;wBAAEiB,YAAY;wBAAWR,cAAc;wBAAGJ,SAAS;wBAAIe,UAAU;wBAAIC,YAAY;oBAAY;;sCACvG,sBAACvB;4BAAIE,OAAO;gCAAEc,cAAc;4BAAG;;8CAAG,qBAACQ;8CAAO;;gCAAepC;;;wBACxDD,aAAasC,uBACZ,sBAACzB;4BAAIE,OAAO;gCAAEc,cAAc;gCAAIU,YAAY;gCAAYC,WAAW;4BAAa;;8CAC9E,qBAACH;8CAAO;;8CACR,qBAACI;gCACAzC,YAAYsC,KAAK;;;wBAGrBnC,0BACC,sBAACU;;8CACC,qBAACwB;8CAAO;;gCACPrC,aAAaI,iBAAiBsC,QAAQ1C,YAAYI,KAAK,CAACF,OAAO,GAAGyC,OAAO3C,aAAaI;;;;;;;;AAQvG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/RouteErrorBoundary.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\ninterface RouteErrorLike extends Error {\n status?: number;\n statusText?: string;\n data?: unknown;\n cause?: unknown;\n}\n\nexport const RouteErrorBoundary = ({ error, resetErrorBoundary }: FallbackProps) => {\n const [showDetails, setShowDetails] = useState(false);\n const errorObject: RouteErrorLike | null =\n error !== null && typeof error === 'object' ? (error as RouteErrorLike) : null;\n const errorMessage =\n typeof errorObject?.message === 'string' && errorObject.message !== ''\n ? errorObject.message\n : '未知错误';\n const hasCause = errorObject?.cause !== undefined;\n\n const isNotFoundError =\n errorObject?.status === 404 ||\n (typeof errorObject?.statusText === 'string' && /not\\s*found/i.test(errorObject.statusText)) ||\n /no routes matched location|not found|404/i.test(errorMessage);\n\n const title = isNotFoundError ? '页面不存在(404)' : '出错了,请稍后再试';\n const friendlyMessage = isNotFoundError\n ? '访问的路由未注册或不存在,请检查访问地址。'\n : '请稍后再试或联系技术支持';\n const displayMessage = isDevelopment ? errorMessage : friendlyMessage;\n\n return (\n <div\n role=\"alert\"\n style={{\n minHeight: '100vh',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: 24,\n }}\n >\n <div style={{ maxWidth: 760, width: '100%', border: '1px solid #dde5ec', borderRadius: 10, padding: 20 }}>\n <h2 style={{ marginTop: 0 }}>{title}</h2>\n <p>{displayMessage}</p>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <button\n onClick={resetErrorBoundary}\n style={{ border: 'none', background: '#2f80ed', color: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n 刷新重试\n </button>\n {isDevelopment && (\n <button\n onClick={() => setShowDetails(!showDetails)}\n style={{ border: '1px solid #cfd7df', background: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n {showDetails ? '收起详情' : '展开详情'}\n </button>\n )}\n </div>\n\n {isDevelopment && showDetails && (\n <div style={{ background: '#f7fafc', borderRadius: 8, padding: 12, fontSize: 12, fontFamily: 'monospace' }}>\n <div style={{ marginBottom: 10 }}><strong>错误信息:</strong>{errorMessage}</div>\n {errorObject?.stack && (\n <div style={{ marginBottom: 10, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n <strong>堆栈:</strong>\n <br />\n {errorObject.stack}\n </div>\n )}\n {hasCause && (\n <div>\n <strong>原因:</strong>\n {errorObject?.cause instanceof Error ? errorObject.cause.message : String(errorObject?.cause)}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["useState","isDevelopment","process","env","NODE_ENV","RouteErrorBoundary","error","resetErrorBoundary","showDetails","setShowDetails","errorObject","errorMessage","message","hasCause","cause","undefined","isNotFoundError","status","statusText","test","title","friendlyMessage","displayMessage","div","role","style","minHeight","display","justifyContent","alignItems","padding","maxWidth","width","border","borderRadius","h2","marginTop","p","gap","marginBottom","button","onClick","background","color","cursor","fontSize","fontFamily","strong","stack","whiteSpace","wordBreak","br","Error","String"],"mappings":";AAAA,SAASA,QAAQ,QAAQ,QAAQ;AAGjC,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAS/C,OAAO,MAAMC,qBAAqB,CAAC,EAAEC,KAAK,EAAEC,kBAAkB,EAAiB;IAC7E,MAAM,CAACC,aAAaC,eAAe,GAAGT,SAAS;IAC/C,MAAMU,cACJJ,UAAU,QAAQ,OAAOA,UAAU,WAAYA,QAA2B;IAC5E,MAAMK,eACJ,OAAOD,aAAaE,YAAY,YAAYF,YAAYE,OAAO,KAAK,KAChEF,YAAYE,OAAO,GACnB;IACN,MAAMC,WAAWH,aAAaI,UAAUC;IAExC,MAAMC,kBACJN,aAAaO,WAAW,OACvB,OAAOP,aAAaQ,eAAe,YAAY,eAAeC,IAAI,CAACT,YAAYQ,UAAU,KAC1F,4CAA4CC,IAAI,CAACR;IAEnD,MAAMS,QAAQJ,kBAAkB,eAAe;IAC/C,MAAMK,kBAAkBL,kBACpB,0BACA;IACJ,MAAMM,iBAAiBrB,gBAAgBU,eAAeU;IAEtD,qBACE,KAACE;QACCC,MAAK;QACLC,OAAO;YACLC,WAAW;YACXC,SAAS;YACTC,gBAAgB;YAChBC,YAAY;YACZC,SAAS;QACX;kBAEA,cAAA,MAACP;YAAIE,OAAO;gBAAEM,UAAU;gBAAKC,OAAO;gBAAQC,QAAQ;gBAAqBC,cAAc;gBAAIJ,SAAS;YAAG;;8BACrG,KAACK;oBAAGV,OAAO;wBAAEW,WAAW;oBAAE;8BAAIhB;;8BAC9B,KAACiB;8BAAGf;;8BACJ,MAACC;oBAAIE,OAAO;wBAAEE,SAAS;wBAAQW,KAAK;wBAAGC,cAAc;oBAAG;;sCACtD,KAACC;4BACCC,SAASlC;4BACTkB,OAAO;gCAAEQ,QAAQ;gCAAQS,YAAY;gCAAWC,OAAO;gCAAQT,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCACxH;;wBAGA3C,+BACC,KAACuC;4BACCC,SAAS,IAAMhC,eAAe,CAACD;4BAC/BiB,OAAO;gCAAEQ,QAAQ;gCAAqBS,YAAY;gCAAQR,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCAEjHpC,cAAc,SAAS;;;;gBAK7BP,iBAAiBO,6BAChB,MAACe;oBAAIE,OAAO;wBAAEiB,YAAY;wBAAWR,cAAc;wBAAGJ,SAAS;wBAAIe,UAAU;wBAAIC,YAAY;oBAAY;;sCACvG,MAACvB;4BAAIE,OAAO;gCAAEc,cAAc;4BAAG;;8CAAG,KAACQ;8CAAO;;gCAAepC;;;wBACxDD,aAAasC,uBACZ,MAACzB;4BAAIE,OAAO;gCAAEc,cAAc;gCAAIU,YAAY;gCAAYC,WAAW;4BAAa;;8CAC9E,KAACH;8CAAO;;8CACR,KAACI;gCACAzC,YAAYsC,KAAK;;;wBAGrBnC,0BACC,MAACU;;8CACC,KAACwB;8CAAO;;gCACPrC,aAAaI,iBAAiBsC,QAAQ1C,YAAYI,KAAK,CAACF,OAAO,GAAGyC,OAAO3C,aAAaI;;;;;;;;AAQvG,EAAE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '@vlian/logger';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[],\n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n enableHydrateFallback: boolean = false,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...config\n };\n },\n path\n };\n\n if (enableHydrateFallback) {\n reactRoute.hydrateFallbackElement = <DefaultRouteHydrateFallback />;\n }\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n const Component = page;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n Component,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n const Component = page;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n Component,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["transformRoutesToReactRoutes","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","enableHydrateFallback","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","RouteErrorBoundary","convertConfig","m","action","loader","shouldRevalidate","Component","logger","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","hydrateFallbackElement","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","Navigate","to","replace"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '@vlian/logger';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[],\n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n enableHydrateFallback: boolean = false,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...config\n };\n },\n path\n };\n\n if (enableHydrateFallback) {\n reactRoute.hydrateFallbackElement = <DefaultRouteHydrateFallback />;\n }\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n const Component = page;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n Component,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n const Component = page;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n Component,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["Navigate","RouteErrorBoundary","logger","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","transformRoutesToReactRoutes","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","enableHydrateFallback","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","convertConfig","m","action","loader","shouldRevalidate","Component","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","hydrateFallbackElement","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","to","replace"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/router/utils/transform.tsx"],"sourcesContent":["import type { RouterConfig, RouteConfig } from '../types';\nimport { logger } from '@vlian/logger';\nimport { SecurityUtils, SecurityError, ValidationError } from '@vlian/utils';\n\n/**\n * 路径验证配置\n */\nexport interface PathValidationConfig {\n /**\n * 是否启用路径验证(默认 true)\n */\n enablePathValidation?: boolean;\n\n /**\n * 允许的路径前缀列表\n * 例如:['@/pages', '@/components', './pages']\n */\n allowedPathPrefixes?: string[];\n\n /**\n * 最大路径长度(默认 500)\n */\n maxPathLength?: number;\n\n /**\n * 是否允许绝对路径(默认 false)\n */\n allowAbsolutePaths?: boolean;\n}\n\n/**\n * 转换性能配置\n */\nexport interface TransformPerformanceConfig {\n /**\n * 是否启用缓存(默认 true)\n */\n enableCache?: boolean;\n\n /**\n * 缓存过期时间(毫秒,默认 5 分钟)\n */\n cacheTTL?: number;\n\n /**\n * 最大缓存数量(默认 50,LRU 缓存)\n */\n maxCacheSize?: number;\n\n /**\n * 最大递归深度(默认 100)\n */\n maxRecursionDepth?: number;\n\n /**\n * 是否启用并行处理(默认 true)\n */\n enableParallelProcessing?: boolean;\n\n /**\n * 并行处理批次大小(默认 10)\n */\n parallelBatchSize?: number;\n}\n\n/**\n * 转换配置选项\n */\nexport interface TransformOptions {\n /**\n * 路径验证配置\n */\n pathValidation?: PathValidationConfig;\n\n /**\n * 性能配置\n */\n performance?: TransformPerformanceConfig;\n\n /**\n * 是否启用调试日志(默认 false)\n */\n enableDebugLog?: boolean;\n}\n\n/**\n * 转换后的路由项\n * \n * 与 RouteConfig 的区别:\n * - `page`、`layout`、`errors`、`loading` 字段的值是对应 Map 中的动态导入函数,而不是路径字符串\n * - 这些字段可以直接用于动态加载组件,无需再次查找 Map\n * - 所有组件路径字符串都已转换为对应的动态导入函数\n * \n * @example\n * ```typescript\n * const transformedRoute: TransformedRoute = {\n * name: 'home',\n * path: '/',\n * page: () => import('@/pages/home.tsx'), // 动态导入函数\n * handle: { title: '首页', order: 1 },\n * };\n * \n * // 使用动态导入函数加载组件\n * if (transformedRoute.page) {\n * const pageModule = await transformedRoute.page();\n * const PageComponent = pageModule?.default;\n * }\n * ```\n */\nexport interface TransformedRoute {\n /**\n * 页面组件的动态导入函数\n * \n * 如果路由配置中指定了 `page` 路径,则此字段为对应的动态导入函数\n * 如果未指定或为 null,则此字段为 null\n * \n * 调用此函数会返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\n page?: (() => Promise<any>) | null;\n\n /**\n * 布局组件的动态导入函数\n * \n * 如果路由配置中指定了 `layout` 路径,则此字段为对应的动态导入函数\n * 如果未指定或为 null,则此字段为 null\n * \n * 调用此函数会返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\n layout?: (() => Promise<any>) | null;\n\n /**\n * 错误组件的动态导入函数\n * \n * 如果路由配置中指定了 `errors` 路径,则此字段为对应的动态导入函数\n * 如果未指定或为 null,则此字段为 null\n * \n * 调用此函数会返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\n errors?: (() => Promise<any>) | null;\n\n /**\n * 加载组件的动态导入函数\n * \n * 如果路由配置中指定了 `loading` 路径,则此字段为对应的动态导入函数\n * 如果未指定或为 null,则此字段为 null\n * \n * 调用此函数会返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\n loading?: (() => Promise<any>) | null;\n\n /**\n * 路由名称(唯一标识)\n * \n * 用于标识路由的唯一名称,通常用于路由导航和权限控制\n */\n name: string;\n\n /**\n * 路由路径\n * \n * URL 路径,例如:'/'、'/about'、'/user/:id'\n * 如果路由是路由组(isGroup: true),则可能为 undefined\n */\n path: string | undefined;\n\n /**\n * 是否为路由组\n * \n * 路由组用于组织子路由,本身不匹配任何路径\n * 路由组的 path 通常为 undefined\n */\n isGroup?: boolean;\n\n /**\n * 是否启用重定向\n * \n * 如果为 true,表示此路由用于重定向到其他路由\n */\n enableRedirection?: boolean;\n\n /**\n * 路由元数据\n * \n * 包含路由的标题、图标、排序、权限等信息\n * 用于菜单生成、权限控制、SEO 等场景\n */\n handle: {\n /**\n * 路由标题\n */\n title: string;\n \n /**\n * 国际化键名\n * 如果提供,会使用 i18n 系统进行翻译\n */\n i18nKey?: string;\n \n /**\n * 排序值\n * 用于菜单排序,数值越小越靠前\n */\n order: number;\n \n /**\n * 图标名称或路径\n */\n icon?: string;\n \n /**\n * 是否在菜单中隐藏\n */\n hideInMenu?: boolean;\n \n /**\n * 是否隐藏页脚\n */\n hideFooter?: boolean;\n \n /**\n * 是否启用 KeepAlive 缓存\n */\n keepAlive?: boolean;\n \n /**\n * 是否需要登录\n */\n needLogin?: boolean;\n \n /**\n * 允许访问的角色列表\n */\n roles?: Array<string>;\n \n /**\n * 路由名称(与 name 字段相同,用于兼容)\n */\n name?: string;\n \n /**\n * 其他自定义元数据\n */\n [key: string]: unknown;\n };\n\n /**\n * 子路由配置\n * \n * 如果路由有子路由,则此字段包含转换后的子路由列表\n * 子路由会继承父路由的某些配置(如 layout)\n */\n children?: TransformedRoute[];\n}\n\n/**\n * 路由转换结果\n * \n * 包含所有提取的组件路径 Map 和原始路由配置列表\n * \n * @example\n * ```typescript\n * const result: TransformRoutesResult = {\n * pages: new Map([\n * ['@/pages/home.tsx', () => import('@/pages/home.tsx')],\n * ['@/pages/about.tsx', () => import('@/pages/about.tsx')],\n * ]),\n * layouts: new Map([\n * ['@/layouts/MainLayout.tsx', () => import('@/layouts/MainLayout.tsx')],\n * ]),\n * errors: new Map(),\n * loadings: new Map(),\n * routes: [], // 原始路由配置列表\n * };\n * ```\n */\nexport interface TransformRoutesResult {\n /**\n * 页面组件路径 Map\n * \n * key: 组件路径字符串(如 '@/pages/home.tsx')\n * value: 动态导入函数,调用后返回 Promise,resolve 后的值为组件模块对象\n * \n * 用于存储所有路由配置中出现的页面组件路径\n * 相同的路径只会存储一次,避免重复创建动态导入函数\n */\n pages: Map<string, () => Promise<any>>;\n\n /**\n * 布局组件路径 Map\n * \n * key: 组件路径字符串(如 '@/layouts/MainLayout.tsx')\n * value: 动态导入函数,调用后返回 Promise,resolve 后的值为组件模块对象\n * \n * 用于存储所有路由配置中出现的布局组件路径\n * 相同的路径只会存储一次,避免重复创建动态导入函数\n */\n layouts: Map<string, () => Promise<any>>;\n\n /**\n * 错误组件路径 Map\n * \n * key: 组件路径字符串(如 '@/components/ErrorBoundary.tsx')\n * value: 动态导入函数,调用后返回 Promise,resolve 后的值为组件模块对象\n * \n * 用于存储所有路由配置中出现的错误组件路径\n * 相同的路径只会存储一次,避免重复创建动态导入函数\n */\n errors: Map<string, () => Promise<any>>;\n\n /**\n * 加载组件路径 Map\n * \n * key: 组件路径字符串(如 '@/components/Loading.tsx')\n * value: 动态导入函数,调用后返回 Promise,resolve 后的值为组件模块对象\n * \n * 用于存储所有路由配置中出现的加载组件路径\n * 相同的路径只会存储一次,避免重复创建动态导入函数\n */\n loadings: Map<string, () => Promise<any>>;\n\n routes: RouteConfig[];\n}\n\n/**\n * 缓存项\n */\ninterface CacheItem {\n result: TransformRoutesResult;\n timestamp: number;\n hash: string;\n accessTime: number; // LRU 使用\n}\n\n/**\n * LRU 缓存实现\n */\nclass LRUCache {\n private cache = new Map<string, CacheItem>();\n private maxSize: number;\n\n constructor(maxSize: number = 50) {\n this.maxSize = maxSize;\n }\n\n get(key: string): CacheItem | undefined {\n const item = this.cache.get(key);\n if (item) {\n // 更新访问时间\n item.accessTime = Date.now();\n // 移动到末尾(最近使用)\n this.cache.delete(key);\n this.cache.set(key, item);\n }\n return item;\n }\n\n set(key: string, value: CacheItem): void {\n // 如果已存在,先删除\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n // 如果达到最大大小,删除最久未使用的项(第一个)\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n }\n }\n value.accessTime = Date.now();\n this.cache.set(key, value);\n }\n\n delete(key: string): boolean {\n return this.cache.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n size(): number {\n return this.cache.size;\n }\n\n cleanupExpired(cacheTTL: number): void {\n const now = Date.now();\n for (const [key, item] of this.cache.entries()) {\n if (now - item.timestamp > cacheTTL) {\n this.cache.delete(key);\n }\n }\n }\n}\n\n/**\n * 转换缓存(使用 LRU 缓存)\n */\nlet transformCache: LRUCache | null = null;\n\n/**\n * 默认配置\n */\nconst DEFAULT_OPTIONS: Required<TransformOptions> = {\n pathValidation: {\n enablePathValidation: true,\n // 默认仅允许常见本地模块路径,生产环境建议进一步收紧。\n allowedPathPrefixes: ['@/', './', '../'],\n maxPathLength: 500,\n allowAbsolutePaths: false,\n },\n performance: {\n enableCache: true,\n cacheTTL: 5 * 60 * 1000, // 5 分钟\n maxCacheSize: 50, // LRU 缓存最大数量\n maxRecursionDepth: 100,\n enableParallelProcessing: true,\n parallelBatchSize: 10, // 并行处理批次大小\n },\n enableDebugLog: false,\n};\n\n/**\n * 优化的字符串哈希函数(用于缓存键)\n * 使用更高效的哈希算法,支持大字符串\n */\nfunction optimizedHash(str: string): string {\n // 对于小字符串,使用快速哈希\n if (str.length < 100) {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // 转换为 32 位整数\n }\n return Math.abs(hash).toString(36);\n }\n\n // 对于大字符串,使用分段哈希\n let hash = 0;\n const step = Math.max(1, Math.floor(str.length / 100));\n for (let i = 0; i < str.length; i += step) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * 使用 crypto API 的哈希函数(如果可用)\n * 保留此函数供未来使用(异步哈希场景)\n */\n// async function cryptoHash(str: string): Promise<string> {\n// // 检查是否支持 crypto API\n// if (typeof crypto !== 'undefined' && crypto.subtle && crypto.subtle.digest) {\n// try {\n// const encoder = new TextEncoder();\n// const data = encoder.encode(str);\n// const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n// const hashArray = Array.from(new Uint8Array(hashBuffer));\n// return hashArray.map(b => b.toString(16).padStart(2, '0')).join('').substring(0, 16);\n// } catch {\n// // 如果 crypto API 失败,回退到优化哈希\n// return optimizedHash(str);\n// }\n// }\n// return optimizedHash(str);\n// }\n\n/**\n * 同步哈希函数(用于同步场景)\n */\nfunction simpleHash(str: string): string {\n return optimizedHash(str);\n}\n\ntype SerializableRouteConfig = {\n name: string;\n path?: string;\n page?: string;\n pageFn?: string;\n layout?: string;\n layoutFn?: string;\n error?: string;\n errorFn?: string;\n loading?: string;\n loadingFn?: string;\n isGroup?: boolean;\n enableRedirection?: boolean;\n handle?: {\n title?: string;\n order?: number;\n needLogin?: boolean;\n roles?: string[];\n };\n children?: SerializableRouteConfig[];\n};\n\nfunction serializeComponentRef(\n value: unknown,\n): { str?: string; fn?: string } {\n if (typeof value === 'string') {\n return { str: value };\n }\n\n if (typeof value === 'function') {\n // 函数引用无法稳定序列化源码,使用名称和长度参与哈希,避免同名不同体完全碰撞。\n const fnText = String(value);\n return { fn: `${value.name || 'anonymous'}:${fnText.length}` };\n }\n\n return {};\n}\n\nfunction serializeRouteConfig(route: RouteConfig): SerializableRouteConfig {\n const page = serializeComponentRef(route.page);\n const layout = serializeComponentRef(route.layout);\n const routeError = serializeComponentRef(route.error ?? route.errors);\n const loading = serializeComponentRef(route.loading);\n\n return {\n name: route.name,\n path: route.path,\n page: page.str,\n pageFn: page.fn,\n layout: layout.str,\n layoutFn: layout.fn,\n error: routeError.str,\n errorFn: routeError.fn,\n loading: loading.str,\n loadingFn: loading.fn,\n isGroup: route.isGroup,\n enableRedirection: route.enableRedirection,\n handle: route.handle\n ? {\n title: route.handle.title,\n order: route.handle.order,\n needLogin: route.handle.needLogin,\n roles: Array.isArray(route.handle.roles) ? [...route.handle.roles] : undefined,\n }\n : undefined,\n children: route.children?.map((child) => serializeRouteConfig(child)),\n };\n}\n\n/**\n * 生成配置哈希(用于缓存键)\n * 优化:缓存序列化结果,避免重复序列化\n */\nfunction generateConfigHash(routes: RouteConfig[]): string {\n try {\n if (routes.length === 0) {\n return 'empty';\n }\n\n const serializedRoutes = routes.map((route) => serializeRouteConfig(route));\n const configStr = JSON.stringify(serializedRoutes);\n return simpleHash(configStr);\n } catch {\n return '';\n }\n}\n\n/**\n * 路径验证缓存(已验证的路径)\n */\nconst validatedPathCache = new Set<string>();\n\n/**\n * 预编译的正则表达式(用于路径验证)\n */\nconst PATH_TRAVERSAL_REGEX = /\\.\\.(\\/|\\\\)|\\.\\.%2[Ff]|\\.\\.%5[Cc]|%2[Ee]%2[Ee]%2[Ff]|%2[Ee]%2[Ee]%5[Cc]/i;\nconst ABSOLUTE_PATH_REGEX = /^\\/|^[A-Za-z]:\\\\/;\nconst CONTROL_CHAR_REGEX = /[\\x00-\\x1f\\x7f]/;\nconst NULL_BYTE_REGEX = /%00|\\\\0|\\x00/;\nconst URL_SCHEME_REGEX = /^[A-Za-z][A-Za-z0-9+.-]*:/;\n// 保留供未来使用(命令注入检测)\n// const COMMAND_INJECTION_REGEX = /[;|&$`]/;\n// const ALLOWED_CHARS_REGEX = /^[a-zA-Z0-9\\/\\-_.@]+$/;\n\n/**\n * 验证路径是否安全\n * 优化:添加验证缓存、预编译正则、早期返回\n */\nfunction validatePath(\n path: string,\n config: Required<PathValidationConfig>\n): { valid: boolean; error?: string } {\n // 早期返回:检查缓存\n if (validatedPathCache.has(path)) {\n return { valid: true };\n }\n\n // 早期返回:检查路径长度(最快检查)\n if (path.length > config.maxPathLength) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development' \n ? `路径长度超过最大限制 ${config.maxPathLength} 字符`\n : '路径验证失败',\n };\n }\n\n // 早期返回:检查空字符串\n if (path.length === 0) {\n return {\n valid: false,\n error: '路径不能为空',\n };\n }\n\n // 检查路径遍历攻击(使用预编译正则)\n if (PATH_TRAVERSAL_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '路径包含路径遍历字符(../),可能存在安全风险'\n : '路径验证失败',\n };\n }\n\n // 检查空字节注入\n if (NULL_BYTE_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '路径包含空字节,可能存在安全风险'\n : '路径验证失败',\n };\n }\n\n // 检查控制字符\n if (CONTROL_CHAR_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '路径包含控制字符,可能存在安全风险'\n : '路径验证失败',\n };\n }\n\n // 检查命令注入字符(可选,根据需求决定是否启用)\n // if (COMMAND_INJECTION_REGEX.test(path)) {\n // return {\n // valid: false,\n // error: process.env.NODE_ENV === 'development'\n // ? '路径包含潜在的命令注入字符'\n // : '路径验证失败',\n // };\n // }\n\n // 禁止 URL scheme 导入(如 http:, https:, data:, javascript:)\n if (URL_SCHEME_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '不允许使用带协议的路径'\n : '路径验证失败',\n };\n }\n\n // 检查绝对路径(使用预编译正则)\n if (!config.allowAbsolutePaths && ABSOLUTE_PATH_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '不允许使用绝对路径'\n : '路径验证失败',\n };\n }\n\n // 默认仅允许相对路径和别名路径,避免把第三方包名作为动态入口。\n if (!path.startsWith('@/') && !path.startsWith('./') && !path.startsWith('../')) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '仅允许使用 @/、./、../ 开头的模块路径'\n : '路径验证失败',\n };\n }\n\n // 检查路径前缀白名单(优化:使用 Set 提高查找速度)\n if (config.allowedPathPrefixes.length > 0) {\n const prefixSet = new Set(config.allowedPathPrefixes);\n const isAllowed = Array.from(prefixSet).some((prefix) => path.startsWith(prefix));\n if (!isAllowed) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? `路径不在允许的前缀列表中: ${config.allowedPathPrefixes.join(', ')}`\n : '路径验证失败',\n };\n }\n }\n\n // 使用 SecurityUtils 验证输入(最后检查,因为可能较慢)\n const validation = SecurityUtils.validateInput(path);\n if (!validation.safe) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? (validation.reason || '路径包含潜在的危险内容')\n : '路径验证失败',\n };\n }\n\n // 验证通过,添加到缓存(限制缓存大小)\n if (validatedPathCache.size < 1000) {\n validatedPathCache.add(path);\n }\n\n return { valid: true };\n}\n\n/**\n * 预编译的正则表达式(用于路径规范化)\n */\nconst NORMALIZE_REGEX = {\n multipleSlashes: /\\/+/g,\n dotSlash: /\\/\\.\\//g,\n trailingDot: /\\/\\.$/,\n};\n\n/**\n * 规范化路径\n * 优化:合并正则表达式,减少替换次数\n */\nfunction normalizePath(path: string): string {\n // 合并多个替换操作,减少字符串遍历次数\n return path\n .replace(NORMALIZE_REGEX.multipleSlashes, '/')\n .replace(NORMALIZE_REGEX.dotSlash, '/')\n .replace(NORMALIZE_REGEX.trailingDot, '')\n .trim();\n}\n\n/**\n * 类型守卫:检查是否为有效路径字符串\n */\nfunction isValidPathString(path: unknown): path is string {\n return typeof path === 'string' && path.length > 0;\n}\n\n/**\n * 类型守卫:检查是否为动态导入函数\n */\nfunction isComponentImport(path: unknown): path is () => Promise<any> {\n return typeof path === 'function';\n}\n\n/**\n * 创建动态导入函数\n * \n * 将组件路径字符串转换为动态导入函数,用于代码分割和懒加载\n * \n * @param path - 组件路径字符串,支持相对路径和别名路径(如 '@/pages/home.tsx')\n * @returns 返回动态导入函数,调用后会返回 Promise,resolve 后的值为组件模块对象\n * \n * @remarks\n * - 使用 `@vite-ignore` 注释告诉 Vite 忽略此动态导入的静态分析\n * - 使用类型断言 `as any` 是因为 TypeScript 的 `import()` 需要静态字符串字面量\n * - 在运行时,我们可以使用动态路径进行导入\n * - 组件必须使用默认导出(export default)\n * \n * @example\n * ```typescript\n * const importFn = createDynamicImport('@/pages/home.tsx');\n * const module = await importFn();\n * const HomePage = module.default;\n * ```\n */\nfunction createDynamicImport(path: string): () => Promise<any> {\n // 使用类型断言,因为 TypeScript 的 import() 需要静态字符串\n // 但在运行时,我们可以使用动态路径\n return () => import(/* @vite-ignore */ (path as any));\n}\n\n/**\n * 提取并验证组件路径到 Map 中\n * \n * 如果路径有效且 Map 中不存在,则创建动态导入函数并存储到 Map 中\n * 这样可以避免重复创建相同路径的动态导入函数,提高性能\n * \n * @param path - 组件路径,可能是字符串、动态导入函数、null 或 undefined\n * @param map - 目标 Map,用于存储路径到动态导入函数的映射\n * @param config - 路径验证配置\n * @param options - 转换选项\n * @returns 如果成功提取,返回动态导入函数;否则返回 null\n * \n * @remarks\n * - 如果 path 是函数,直接返回,不添加到 Map(函数本身就可以直接使用)\n * - 只有当路径是有效的非空字符串时才会处理并添加到 Map\n * - 如果 Map 中已存在该路径,则直接返回已有的导入函数\n * - 优化:使用 `get()` 一次获取,判断是否为 undefined,减少函数调用\n * - 会进行路径验证和清理\n * \n * @example\n * ```typescript\n * const pages = new Map<string, () => Promise<any>>();\n * const importFn1 = extractAndValidatePath('@/pages/home.tsx', pages, config, options);\n * const importFn2 = extractAndValidatePath(() => import('@/pages/home.tsx'), pages, config, options);\n * ```\n */\nfunction extractAndValidatePath(\n path: string | (() => Promise<any>) | null | undefined,\n map: Map<string, () => Promise<any>>,\n config: Required<PathValidationConfig>,\n options: TransformOptions,\n): (() => Promise<any>) | null {\n // 早期返回:如果是函数,直接返回,不添加到 Map\n if (isComponentImport(path)) {\n return path;\n }\n\n // 早期返回:检查是否为有效路径字符串\n if (!isValidPathString(path)) {\n return null;\n }\n\n // 规范化路径\n const normalizedPath = normalizePath(path);\n\n // 优化:先检查 Map 中是否已存在(避免不必要的验证)\n const existingImport = map.get(normalizedPath);\n if (existingImport !== undefined) {\n return existingImport;\n }\n\n // 路径验证(仅在 Map 中不存在时进行)\n if (config.enablePathValidation) {\n const validation = validatePath(normalizedPath, config);\n if (!validation.valid) {\n // 生产环境错误信息脱敏\n const errorMessage = process.env.NODE_ENV === 'development'\n ? `路径验证失败: ${validation.error}`\n : '路径验证失败';\n \n const error = new SecurityError(\n errorMessage,\n undefined,\n process.env.NODE_ENV === 'development' ? { path: normalizedPath } : {}\n );\n \n if (options.enableDebugLog) {\n logger.error('路径验证失败:', error);\n }\n \n // 开发环境抛出错误,生产环境记录警告并跳过\n if (process.env.NODE_ENV === 'development') {\n throw error;\n } else {\n // 生产环境日志脱敏\n logger.warn('路径验证失败,已跳过');\n return null;\n }\n }\n }\n\n // 创建动态导入函数并存储\n const importFn = createDynamicImport(normalizedPath);\n map.set(normalizedPath, importFn);\n \n if (options.enableDebugLog) {\n logger.debug('提取路径:', normalizedPath);\n }\n\n return importFn;\n}\n\n/**\n * 对象池:复用栈节点对象,减少 GC 压力\n */\nclass StackNodePool {\n private pool: Array<{ route: RouteConfig; depth: number }> = [];\n private maxPoolSize = 100;\n\n acquire(route: RouteConfig, depth: number): { route: RouteConfig; depth: number } {\n if (this.pool.length > 0) {\n const node = this.pool.pop()!;\n node.route = route;\n node.depth = depth;\n return node;\n }\n return { route, depth };\n }\n\n release(node: { route: RouteConfig; depth: number }): void {\n if (this.pool.length < this.maxPoolSize) {\n this.pool.push(node);\n }\n }\n}\n\nconst stackNodePool = new StackNodePool();\n\n/**\n * 只提取组件路径到 Map 中,不转换路由配置\n * \n * 使用迭代方式遍历所有路由(包括子路由),提取组件路径到对应的 Map 中\n * 这种设计可以确保:\n * - 相同的组件路径只会创建一个动态导入函数\n * - 使用迭代而非递归,避免栈溢出\n * - 优化:支持并行处理、使用对象池、预分配数组\n * \n * @param routes - 原始路由配置列表\n * @param result - 结果对象,用于累积收集的组件路径\n * @param config - 路径验证配置\n * @param options - 转换选项\n * @param maxDepth - 最大递归深度\n */\nasync function extractPathsOnly(\n routes: RouteConfig[],\n result: TransformRoutesResult,\n config: Required<PathValidationConfig>,\n options: TransformOptions,\n maxDepth: number,\n): Promise<void> {\n const enableParallel = options.performance?.enableParallelProcessing ?? true;\n const batchSize = options.performance?.parallelBatchSize ?? 10;\n\n // 如果启用并行处理且路由数量较多,使用并行处理\n if (enableParallel && routes.length > batchSize) {\n // 收集所有需要处理的路径(只收集字符串类型,函数类型不需要处理)\n const pathsToProcess: Array<{\n path: string | null | undefined;\n map: Map<string, () => Promise<any>>;\n }> = [];\n\n // 遍历所有路由,收集路径\n const stack: Array<{ route: RouteConfig; depth: number }> = [];\n for (let i = routes.length - 1; i >= 0; i--) {\n stack.push({ route: routes[i], depth: 0 });\n }\n\n while (stack.length > 0) {\n const { route, depth } = stack.pop()!;\n\n if (depth > maxDepth) {\n logger.warn(`路径提取达到最大深度 ${maxDepth},跳过路由:`, route.name);\n continue;\n }\n\n // 收集路径(只收集字符串类型,函数类型不需要处理,会直接使用)\n if (route.page && typeof route.page === 'string') {\n pathsToProcess.push({ path: route.page, map: result.pages });\n }\n if (route.layout && typeof route.layout === 'string') {\n pathsToProcess.push({ path: route.layout, map: result.layouts });\n }\n const routeError = route.error ?? route.errors;\n if (routeError && typeof routeError === 'string') {\n pathsToProcess.push({ path: routeError, map: result.errors });\n }\n if (route.loading && typeof route.loading === 'string') {\n pathsToProcess.push({ path: route.loading, map: result.loadings });\n }\n\n // 处理子路由\n if (route.children && Array.isArray(route.children) && route.children.length > 0) {\n for (let i = route.children.length - 1; i >= 0; i--) {\n stack.push({ route: route.children[i], depth: depth + 1 });\n }\n }\n }\n\n // 并行处理路径(分批处理)\n for (let i = 0; i < pathsToProcess.length; i += batchSize) {\n const batch = pathsToProcess.slice(i, i + batchSize);\n await Promise.all(\n batch.map(({ path, map }) =>\n Promise.resolve(extractAndValidatePath(path, map, config, options))\n )\n );\n }\n } else {\n // 串行处理(原有逻辑,优化:使用对象池)\n const stack: Array<{ route: RouteConfig; depth: number }> = [];\n\n // 初始化栈:将所有路由推入栈中\n for (let i = routes.length - 1; i >= 0; i--) {\n stack.push(stackNodePool.acquire(routes[i], 0));\n }\n\n // 迭代处理栈中的路由\n while (stack.length > 0) {\n const node = stack.pop()!;\n const { route, depth } = node;\n\n // 检查递归深度\n if (depth > maxDepth) {\n logger.warn(`路径提取达到最大深度 ${maxDepth},跳过路由:`, route.name);\n stackNodePool.release(node);\n continue;\n }\n\n // 提取组件路径到 Map 中(同时进行验证)\n extractAndValidatePath(route.page, result.pages, config, options);\n extractAndValidatePath(route.layout, result.layouts, config, options);\n extractAndValidatePath(route.error ?? route.errors, result.errors, config, options);\n extractAndValidatePath(route.loading, result.loadings, config, options);\n\n // 处理子路由\n if (route.children && Array.isArray(route.children) && route.children.length > 0) {\n // 将子路由推入栈中(逆序推入,保证处理顺序正确)\n for (let i = route.children.length - 1; i >= 0; i--) {\n stack.push(stackNodePool.acquire(route.children[i], depth + 1));\n }\n }\n\n // 释放节点到对象池\n stackNodePool.release(node);\n }\n }\n}\n\n/**\n * 清理过期缓存\n * 优化:使用 LRU 缓存的清理方法\n */\nfunction cleanupExpiredCache(cacheTTL: number): void {\n if (transformCache) {\n transformCache.cleanupExpired(cacheTTL);\n }\n}\n\n/**\n * 转换路由配置:提取组件路径到 Map 中,返回原始路由配置\n * \n * 此函数是路由转换的核心函数,主要完成以下任务:\n * 1. 递归提取路由配置中的所有组件路径(page、layout、errors、loading)\n * 2. 将组件路径字符串转换为动态导入函数\n * 3. 将动态导入函数存储在对应的 Map 中,key 为路径字符串,确保不重复\n * 4. 返回原始路由配置列表,不进行转换\n * \n * @param routes - 路由配置列表,可以是:\n * - 路由配置数组(RouteConfig[])\n * - 返回路由配置数组的函数(支持同步或异步:() => RouteConfig[] | Promise<RouteConfig[]>)\n * 支持异步函数是为了支持动态加载路由配置(如从服务器获取)\n * @param options - 转换配置选项\n * @returns 包含以下内容的结果对象:\n * - `pages`: 页面组件路径到动态导入函数的 Map\n * - `layouts`: 布局组件路径到动态导入函数的 Map\n * - `errors`: 错误组件路径到动态导入函数的 Map\n * - `loadings`: 加载组件路径到动态导入函数的 Map\n * - `routes`: 原始路由配置列表,不进行转换\n * \n * @remarks\n * - 如果 `routes` 为 null、undefined 或空数组,返回空结果对象\n * - 如果 `routes` 是函数但返回的不是数组,返回空结果对象\n * - 相同的组件路径只会创建一个动态导入函数,存储在 Map 中复用\n * - 路由配置保持原始格式,组件路径仍为字符串\n * - 支持嵌套路由,会递归处理所有层级的子路由\n * - 支持缓存,相同配置会直接返回缓存结果\n * \n * @example\n * ```typescript\n * // 示例 1: 使用数组配置\n * const result = await transformRoutes([\n * {\n * name: 'home',\n * path: '/',\n * page: '@/pages/home.tsx',\n * errors: '@/pages/error.tsx',\n * handle: { title: '首页', order: 1 },\n * },\n * ]);\n * \n * // 示例 2: 使用异步函数配置\n * const result = await transformRoutes(async () => {\n * const response = await fetch('/api/routes');\n * return response.json();\n * });\n * \n * // 示例 3: 使用配置选项\n * const result = await transformRoutes(routes, {\n * pathValidation: {\n * enablePathValidation: true,\n * allowedPathPrefixes: ['@/pages', '@/components'],\n * },\n * performance: {\n * enableCache: true,\n * cacheTTL: 10 * 60 * 1000, // 10 分钟\n * },\n * });\n * ```\n */\nexport async function transformRoutes(\n routes: RouterConfig['routes'],\n options: TransformOptions = {},\n): Promise<TransformRoutesResult> {\n const startTime = performance.now();\n const mergedOptions: Required<TransformOptions> = {\n pathValidation: { ...DEFAULT_OPTIONS.pathValidation, ...options.pathValidation },\n performance: { ...DEFAULT_OPTIONS.performance, ...options.performance },\n enableDebugLog: options.enableDebugLog ?? DEFAULT_OPTIONS.enableDebugLog,\n };\n\n // 早期返回:如果 routes 为空或未定义,直接返回空结果\n if (!routes) {\n if (mergedOptions.enableDebugLog) {\n logger.debug('路由配置为空,返回空结果');\n }\n return {\n pages: new Map<string, () => Promise<any>>(),\n layouts: new Map<string, () => Promise<any>>(),\n errors: new Map<string, () => Promise<any>>(),\n loadings: new Map<string, () => Promise<any>>(),\n routes: [],\n };\n }\n\n // 处理 routes 可能是函数的情况\n let routesArray: RouteConfig[];\n try {\n routesArray = typeof routes === 'function' ? await routes() : routes;\n } catch (error) {\n const err = error instanceof Error ? error : new Error('路由配置加载失败');\n logger.error('路由配置加载失败:', err);\n throw new ValidationError('路由配置加载失败', { originalError: err });\n }\n\n // 早期返回:如果 routesArray 不是数组,直接返回空结果\n if (!Array.isArray(routesArray) || routesArray.length === 0) {\n if (mergedOptions.enableDebugLog) {\n logger.debug('路由配置不是数组或为空,返回空结果');\n }\n return {\n pages: new Map<string, () => Promise<any>>(),\n layouts: new Map<string, () => Promise<any>>(),\n errors: new Map<string, () => Promise<any>>(),\n loadings: new Map<string, () => Promise<any>>(),\n routes: [],\n };\n }\n\n // 检查缓存\n const cacheTTL: number = (mergedOptions.performance.cacheTTL ?? DEFAULT_OPTIONS.performance.cacheTTL) as number;\n const maxCacheSize: number = (mergedOptions.performance.maxCacheSize ?? DEFAULT_OPTIONS.performance.maxCacheSize) as number;\n \n if (mergedOptions.performance.enableCache) {\n // 初始化 LRU 缓存(如果尚未初始化或大小发生变化)\n if (!transformCache || transformCache.size() !== maxCacheSize) {\n transformCache = new LRUCache(maxCacheSize);\n }\n\n const configHash = generateConfigHash(routesArray);\n if (configHash) {\n const cached = transformCache.get(configHash);\n if (cached && Date.now() - cached.timestamp < cacheTTL) {\n if (mergedOptions.enableDebugLog) {\n logger.debug('使用缓存结果');\n }\n // 直接返回缓存结果(LRU 缓存已处理访问时间更新)\n return cached.result;\n }\n }\n\n // 清理过期缓存\n cleanupExpiredCache(cacheTTL);\n }\n\n // 初始化结果对象\n const result: TransformRoutesResult = {\n pages: new Map<string, () => Promise<any>>(),\n layouts: new Map<string, () => Promise<any>>(),\n errors: new Map<string, () => Promise<any>>(),\n loadings: new Map<string, () => Promise<any>>(),\n routes: [],\n };\n\n try {\n // 性能监控:记录各阶段耗时\n const extractStartTime = performance.now();\n \n // 提取组件路径到 Map 中(不转换路由配置)\n const pathValidation: Required<PathValidationConfig> = {\n enablePathValidation: (mergedOptions.pathValidation.enablePathValidation ?? DEFAULT_OPTIONS.pathValidation.enablePathValidation) as boolean,\n allowedPathPrefixes: (mergedOptions.pathValidation.allowedPathPrefixes ?? DEFAULT_OPTIONS.pathValidation.allowedPathPrefixes) as string[],\n maxPathLength: (mergedOptions.pathValidation.maxPathLength ?? DEFAULT_OPTIONS.pathValidation.maxPathLength) as number,\n allowAbsolutePaths: (mergedOptions.pathValidation.allowAbsolutePaths ?? DEFAULT_OPTIONS.pathValidation.allowAbsolutePaths) as boolean,\n };\n const maxRecursionDepth: number = (mergedOptions.performance.maxRecursionDepth ?? DEFAULT_OPTIONS.performance.maxRecursionDepth) as number;\n \n // 异步提取路径(支持并行处理)\n await extractPathsOnly(\n routesArray,\n result,\n pathValidation,\n mergedOptions as TransformOptions,\n maxRecursionDepth,\n );\n \n const extractEndTime = performance.now();\n const extractDuration = extractEndTime - extractStartTime;\n \n // 直接使用原始路由配置,不进行转换\n result.routes = routesArray;\n\n // 缓存结果\n const cacheStartTime = performance.now();\n if (mergedOptions.performance.enableCache && transformCache) {\n const configHash = generateConfigHash(routesArray);\n if (configHash) {\n // 注意:Map 中包含函数值,structuredClone 会失败;统一使用手动克隆。\n const cachedResult: TransformRoutesResult = {\n pages: new Map(result.pages),\n layouts: new Map(result.layouts),\n errors: new Map(result.errors),\n loadings: new Map(result.loadings),\n routes: JSON.parse(JSON.stringify(result.routes)),\n };\n\n transformCache.set(configHash, {\n result: cachedResult,\n timestamp: Date.now(),\n hash: configHash,\n accessTime: Date.now(),\n });\n }\n }\n const cacheEndTime = performance.now();\n const cacheDuration = cacheEndTime - cacheStartTime;\n\n const endTime = performance.now();\n const totalDuration = endTime - startTime;\n \n if (mergedOptions.enableDebugLog) {\n // 详细的性能报告\n logger.debug(`路由转换完成,总耗时: ${totalDuration.toFixed(2)}ms`, {\n routeCount: result.routes.length,\n pageCount: result.pages.size,\n layoutCount: result.layouts.size,\n errorCount: result.errors.size,\n loadingCount: result.loadings.size,\n performance: {\n extractDuration: `${extractDuration.toFixed(2)}ms`,\n cacheDuration: `${cacheDuration.toFixed(2)}ms`,\n totalDuration: `${totalDuration.toFixed(2)}ms`,\n },\n cache: {\n hit: transformCache ? 'miss' : 'disabled',\n size: transformCache?.size() ?? 0,\n },\n });\n }\n\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error('路由转换失败');\n logger.error('路由转换失败:', err);\n throw new ValidationError('路由转换失败', { originalError: err });\n }\n}\n"],"names":["transformRoutes","LRUCache","get","key","item","cache","accessTime","Date","now","delete","set","value","has","size","maxSize","firstKey","keys","next","clear","cleanupExpired","cacheTTL","entries","timestamp","Map","transformCache","DEFAULT_OPTIONS","pathValidation","enablePathValidation","allowedPathPrefixes","maxPathLength","allowAbsolutePaths","performance","enableCache","maxCacheSize","maxRecursionDepth","enableParallelProcessing","parallelBatchSize","enableDebugLog","optimizedHash","str","length","hash","i","char","charCodeAt","Math","abs","toString","step","max","floor","simpleHash","serializeComponentRef","fnText","String","fn","name","serializeRouteConfig","route","page","layout","routeError","error","errors","loading","path","pageFn","layoutFn","errorFn","loadingFn","isGroup","enableRedirection","handle","title","order","needLogin","roles","Array","isArray","undefined","children","map","child","generateConfigHash","routes","serializedRoutes","configStr","JSON","stringify","validatedPathCache","Set","PATH_TRAVERSAL_REGEX","ABSOLUTE_PATH_REGEX","CONTROL_CHAR_REGEX","NULL_BYTE_REGEX","URL_SCHEME_REGEX","validatePath","config","valid","process","env","NODE_ENV","test","startsWith","prefixSet","isAllowed","from","some","prefix","join","validation","SecurityUtils","validateInput","safe","reason","add","NORMALIZE_REGEX","multipleSlashes","dotSlash","trailingDot","normalizePath","replace","trim","isValidPathString","isComponentImport","createDynamicImport","extractAndValidatePath","options","normalizedPath","existingImport","errorMessage","SecurityError","logger","warn","importFn","debug","StackNodePool","acquire","depth","pool","node","pop","release","maxPoolSize","push","stackNodePool","extractPathsOnly","result","maxDepth","enableParallel","batchSize","pathsToProcess","stack","pages","layouts","loadings","batch","slice","Promise","all","resolve","cleanupExpiredCache","startTime","mergedOptions","routesArray","err","Error","ValidationError","originalError","configHash","cached","extractStartTime","extractEndTime","extractDuration","cacheStartTime","cachedResult","parse","cacheEndTime","cacheDuration","endTime","totalDuration","toFixed","routeCount","pageCount","layoutCount","errorCount","loadingCount","hit"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/router/utils/transform.tsx"],"sourcesContent":["import type { RouterConfig, RouteConfig } from '../types';\nimport { logger } from '@vlian/logger';\nimport { SecurityUtils, SecurityError, ValidationError } from '@vlian/utils';\n\n/**\n * 路径验证配置\n */\nexport interface PathValidationConfig {\n /**\n * 是否启用路径验证(默认 true)\n */\n enablePathValidation?: boolean;\n\n /**\n * 允许的路径前缀列表\n * 例如:['@/pages', '@/components', './pages']\n */\n allowedPathPrefixes?: string[];\n\n /**\n * 最大路径长度(默认 500)\n */\n maxPathLength?: number;\n\n /**\n * 是否允许绝对路径(默认 false)\n */\n allowAbsolutePaths?: boolean;\n}\n\n/**\n * 转换性能配置\n */\nexport interface TransformPerformanceConfig {\n /**\n * 是否启用缓存(默认 true)\n */\n enableCache?: boolean;\n\n /**\n * 缓存过期时间(毫秒,默认 5 分钟)\n */\n cacheTTL?: number;\n\n /**\n * 最大缓存数量(默认 50,LRU 缓存)\n */\n maxCacheSize?: number;\n\n /**\n * 最大递归深度(默认 100)\n */\n maxRecursionDepth?: number;\n\n /**\n * 是否启用并行处理(默认 true)\n */\n enableParallelProcessing?: boolean;\n\n /**\n * 并行处理批次大小(默认 10)\n */\n parallelBatchSize?: number;\n}\n\n/**\n * 转换配置选项\n */\nexport interface TransformOptions {\n /**\n * 路径验证配置\n */\n pathValidation?: PathValidationConfig;\n\n /**\n * 性能配置\n */\n performance?: TransformPerformanceConfig;\n\n /**\n * 是否启用调试日志(默认 false)\n */\n enableDebugLog?: boolean;\n}\n\n/**\n * 转换后的路由项\n * \n * 与 RouteConfig 的区别:\n * - `page`、`layout`、`errors`、`loading` 字段的值是对应 Map 中的动态导入函数,而不是路径字符串\n * - 这些字段可以直接用于动态加载组件,无需再次查找 Map\n * - 所有组件路径字符串都已转换为对应的动态导入函数\n * \n * @example\n * ```typescript\n * const transformedRoute: TransformedRoute = {\n * name: 'home',\n * path: '/',\n * page: () => import('@/pages/home.tsx'), // 动态导入函数\n * handle: { title: '首页', order: 1 },\n * };\n * \n * // 使用动态导入函数加载组件\n * if (transformedRoute.page) {\n * const pageModule = await transformedRoute.page();\n * const PageComponent = pageModule?.default;\n * }\n * ```\n */\nexport interface TransformedRoute {\n /**\n * 页面组件的动态导入函数\n * \n * 如果路由配置中指定了 `page` 路径,则此字段为对应的动态导入函数\n * 如果未指定或为 null,则此字段为 null\n * \n * 调用此函数会返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\n page?: (() => Promise<any>) | null;\n\n /**\n * 布局组件的动态导入函数\n * \n * 如果路由配置中指定了 `layout` 路径,则此字段为对应的动态导入函数\n * 如果未指定或为 null,则此字段为 null\n * \n * 调用此函数会返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\n layout?: (() => Promise<any>) | null;\n\n /**\n * 错误组件的动态导入函数\n * \n * 如果路由配置中指定了 `errors` 路径,则此字段为对应的动态导入函数\n * 如果未指定或为 null,则此字段为 null\n * \n * 调用此函数会返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\n errors?: (() => Promise<any>) | null;\n\n /**\n * 加载组件的动态导入函数\n * \n * 如果路由配置中指定了 `loading` 路径,则此字段为对应的动态导入函数\n * 如果未指定或为 null,则此字段为 null\n * \n * 调用此函数会返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\n loading?: (() => Promise<any>) | null;\n\n /**\n * 路由名称(唯一标识)\n * \n * 用于标识路由的唯一名称,通常用于路由导航和权限控制\n */\n name: string;\n\n /**\n * 路由路径\n * \n * URL 路径,例如:'/'、'/about'、'/user/:id'\n * 如果路由是路由组(isGroup: true),则可能为 undefined\n */\n path: string | undefined;\n\n /**\n * 是否为路由组\n * \n * 路由组用于组织子路由,本身不匹配任何路径\n * 路由组的 path 通常为 undefined\n */\n isGroup?: boolean;\n\n /**\n * 是否启用重定向\n * \n * 如果为 true,表示此路由用于重定向到其他路由\n */\n enableRedirection?: boolean;\n\n /**\n * 路由元数据\n * \n * 包含路由的标题、图标、排序、权限等信息\n * 用于菜单生成、权限控制、SEO 等场景\n */\n handle: {\n /**\n * 路由标题\n */\n title: string;\n \n /**\n * 国际化键名\n * 如果提供,会使用 i18n 系统进行翻译\n */\n i18nKey?: string;\n \n /**\n * 排序值\n * 用于菜单排序,数值越小越靠前\n */\n order: number;\n \n /**\n * 图标名称或路径\n */\n icon?: string;\n \n /**\n * 是否在菜单中隐藏\n */\n hideInMenu?: boolean;\n \n /**\n * 是否隐藏页脚\n */\n hideFooter?: boolean;\n \n /**\n * 是否启用 KeepAlive 缓存\n */\n keepAlive?: boolean;\n \n /**\n * 是否需要登录\n */\n needLogin?: boolean;\n \n /**\n * 允许访问的角色列表\n */\n roles?: Array<string>;\n \n /**\n * 路由名称(与 name 字段相同,用于兼容)\n */\n name?: string;\n \n /**\n * 其他自定义元数据\n */\n [key: string]: unknown;\n };\n\n /**\n * 子路由配置\n * \n * 如果路由有子路由,则此字段包含转换后的子路由列表\n * 子路由会继承父路由的某些配置(如 layout)\n */\n children?: TransformedRoute[];\n}\n\n/**\n * 路由转换结果\n * \n * 包含所有提取的组件路径 Map 和原始路由配置列表\n * \n * @example\n * ```typescript\n * const result: TransformRoutesResult = {\n * pages: new Map([\n * ['@/pages/home.tsx', () => import('@/pages/home.tsx')],\n * ['@/pages/about.tsx', () => import('@/pages/about.tsx')],\n * ]),\n * layouts: new Map([\n * ['@/layouts/MainLayout.tsx', () => import('@/layouts/MainLayout.tsx')],\n * ]),\n * errors: new Map(),\n * loadings: new Map(),\n * routes: [], // 原始路由配置列表\n * };\n * ```\n */\nexport interface TransformRoutesResult {\n /**\n * 页面组件路径 Map\n * \n * key: 组件路径字符串(如 '@/pages/home.tsx')\n * value: 动态导入函数,调用后返回 Promise,resolve 后的值为组件模块对象\n * \n * 用于存储所有路由配置中出现的页面组件路径\n * 相同的路径只会存储一次,避免重复创建动态导入函数\n */\n pages: Map<string, () => Promise<any>>;\n\n /**\n * 布局组件路径 Map\n * \n * key: 组件路径字符串(如 '@/layouts/MainLayout.tsx')\n * value: 动态导入函数,调用后返回 Promise,resolve 后的值为组件模块对象\n * \n * 用于存储所有路由配置中出现的布局组件路径\n * 相同的路径只会存储一次,避免重复创建动态导入函数\n */\n layouts: Map<string, () => Promise<any>>;\n\n /**\n * 错误组件路径 Map\n * \n * key: 组件路径字符串(如 '@/components/ErrorBoundary.tsx')\n * value: 动态导入函数,调用后返回 Promise,resolve 后的值为组件模块对象\n * \n * 用于存储所有路由配置中出现的错误组件路径\n * 相同的路径只会存储一次,避免重复创建动态导入函数\n */\n errors: Map<string, () => Promise<any>>;\n\n /**\n * 加载组件路径 Map\n * \n * key: 组件路径字符串(如 '@/components/Loading.tsx')\n * value: 动态导入函数,调用后返回 Promise,resolve 后的值为组件模块对象\n * \n * 用于存储所有路由配置中出现的加载组件路径\n * 相同的路径只会存储一次,避免重复创建动态导入函数\n */\n loadings: Map<string, () => Promise<any>>;\n\n routes: RouteConfig[];\n}\n\n/**\n * 缓存项\n */\ninterface CacheItem {\n result: TransformRoutesResult;\n timestamp: number;\n hash: string;\n accessTime: number; // LRU 使用\n}\n\n/**\n * LRU 缓存实现\n */\nclass LRUCache {\n private cache = new Map<string, CacheItem>();\n private maxSize: number;\n\n constructor(maxSize: number = 50) {\n this.maxSize = maxSize;\n }\n\n get(key: string): CacheItem | undefined {\n const item = this.cache.get(key);\n if (item) {\n // 更新访问时间\n item.accessTime = Date.now();\n // 移动到末尾(最近使用)\n this.cache.delete(key);\n this.cache.set(key, item);\n }\n return item;\n }\n\n set(key: string, value: CacheItem): void {\n // 如果已存在,先删除\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n // 如果达到最大大小,删除最久未使用的项(第一个)\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n }\n }\n value.accessTime = Date.now();\n this.cache.set(key, value);\n }\n\n delete(key: string): boolean {\n return this.cache.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n size(): number {\n return this.cache.size;\n }\n\n cleanupExpired(cacheTTL: number): void {\n const now = Date.now();\n for (const [key, item] of this.cache.entries()) {\n if (now - item.timestamp > cacheTTL) {\n this.cache.delete(key);\n }\n }\n }\n}\n\n/**\n * 转换缓存(使用 LRU 缓存)\n */\nlet transformCache: LRUCache | null = null;\n\n/**\n * 默认配置\n */\nconst DEFAULT_OPTIONS: Required<TransformOptions> = {\n pathValidation: {\n enablePathValidation: true,\n // 默认仅允许常见本地模块路径,生产环境建议进一步收紧。\n allowedPathPrefixes: ['@/', './', '../'],\n maxPathLength: 500,\n allowAbsolutePaths: false,\n },\n performance: {\n enableCache: true,\n cacheTTL: 5 * 60 * 1000, // 5 分钟\n maxCacheSize: 50, // LRU 缓存最大数量\n maxRecursionDepth: 100,\n enableParallelProcessing: true,\n parallelBatchSize: 10, // 并行处理批次大小\n },\n enableDebugLog: false,\n};\n\n/**\n * 优化的字符串哈希函数(用于缓存键)\n * 使用更高效的哈希算法,支持大字符串\n */\nfunction optimizedHash(str: string): string {\n // 对于小字符串,使用快速哈希\n if (str.length < 100) {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // 转换为 32 位整数\n }\n return Math.abs(hash).toString(36);\n }\n\n // 对于大字符串,使用分段哈希\n let hash = 0;\n const step = Math.max(1, Math.floor(str.length / 100));\n for (let i = 0; i < str.length; i += step) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * 使用 crypto API 的哈希函数(如果可用)\n * 保留此函数供未来使用(异步哈希场景)\n */\n// async function cryptoHash(str: string): Promise<string> {\n// // 检查是否支持 crypto API\n// if (typeof crypto !== 'undefined' && crypto.subtle && crypto.subtle.digest) {\n// try {\n// const encoder = new TextEncoder();\n// const data = encoder.encode(str);\n// const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n// const hashArray = Array.from(new Uint8Array(hashBuffer));\n// return hashArray.map(b => b.toString(16).padStart(2, '0')).join('').substring(0, 16);\n// } catch {\n// // 如果 crypto API 失败,回退到优化哈希\n// return optimizedHash(str);\n// }\n// }\n// return optimizedHash(str);\n// }\n\n/**\n * 同步哈希函数(用于同步场景)\n */\nfunction simpleHash(str: string): string {\n return optimizedHash(str);\n}\n\ntype SerializableRouteConfig = {\n name: string;\n path?: string;\n page?: string;\n pageFn?: string;\n layout?: string;\n layoutFn?: string;\n error?: string;\n errorFn?: string;\n loading?: string;\n loadingFn?: string;\n isGroup?: boolean;\n enableRedirection?: boolean;\n handle?: {\n title?: string;\n order?: number;\n needLogin?: boolean;\n roles?: string[];\n };\n children?: SerializableRouteConfig[];\n};\n\nfunction serializeComponentRef(\n value: unknown,\n): { str?: string; fn?: string } {\n if (typeof value === 'string') {\n return { str: value };\n }\n\n if (typeof value === 'function') {\n // 函数引用无法稳定序列化源码,使用名称和长度参与哈希,避免同名不同体完全碰撞。\n const fnText = String(value);\n return { fn: `${value.name || 'anonymous'}:${fnText.length}` };\n }\n\n return {};\n}\n\nfunction serializeRouteConfig(route: RouteConfig): SerializableRouteConfig {\n const page = serializeComponentRef(route.page);\n const layout = serializeComponentRef(route.layout);\n const routeError = serializeComponentRef(route.error ?? route.errors);\n const loading = serializeComponentRef(route.loading);\n\n return {\n name: route.name,\n path: route.path,\n page: page.str,\n pageFn: page.fn,\n layout: layout.str,\n layoutFn: layout.fn,\n error: routeError.str,\n errorFn: routeError.fn,\n loading: loading.str,\n loadingFn: loading.fn,\n isGroup: route.isGroup,\n enableRedirection: route.enableRedirection,\n handle: route.handle\n ? {\n title: route.handle.title,\n order: route.handle.order,\n needLogin: route.handle.needLogin,\n roles: Array.isArray(route.handle.roles) ? [...route.handle.roles] : undefined,\n }\n : undefined,\n children: route.children?.map((child) => serializeRouteConfig(child)),\n };\n}\n\n/**\n * 生成配置哈希(用于缓存键)\n * 优化:缓存序列化结果,避免重复序列化\n */\nfunction generateConfigHash(routes: RouteConfig[]): string {\n try {\n if (routes.length === 0) {\n return 'empty';\n }\n\n const serializedRoutes = routes.map((route) => serializeRouteConfig(route));\n const configStr = JSON.stringify(serializedRoutes);\n return simpleHash(configStr);\n } catch {\n return '';\n }\n}\n\n/**\n * 路径验证缓存(已验证的路径)\n */\nconst validatedPathCache = new Set<string>();\n\n/**\n * 预编译的正则表达式(用于路径验证)\n */\nconst PATH_TRAVERSAL_REGEX = /\\.\\.(\\/|\\\\)|\\.\\.%2[Ff]|\\.\\.%5[Cc]|%2[Ee]%2[Ee]%2[Ff]|%2[Ee]%2[Ee]%5[Cc]/i;\nconst ABSOLUTE_PATH_REGEX = /^\\/|^[A-Za-z]:\\\\/;\nconst CONTROL_CHAR_REGEX = /[\\x00-\\x1f\\x7f]/;\nconst NULL_BYTE_REGEX = /%00|\\\\0|\\x00/;\nconst URL_SCHEME_REGEX = /^[A-Za-z][A-Za-z0-9+.-]*:/;\n// 保留供未来使用(命令注入检测)\n// const COMMAND_INJECTION_REGEX = /[;|&$`]/;\n// const ALLOWED_CHARS_REGEX = /^[a-zA-Z0-9\\/\\-_.@]+$/;\n\n/**\n * 验证路径是否安全\n * 优化:添加验证缓存、预编译正则、早期返回\n */\nfunction validatePath(\n path: string,\n config: Required<PathValidationConfig>\n): { valid: boolean; error?: string } {\n // 早期返回:检查缓存\n if (validatedPathCache.has(path)) {\n return { valid: true };\n }\n\n // 早期返回:检查路径长度(最快检查)\n if (path.length > config.maxPathLength) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development' \n ? `路径长度超过最大限制 ${config.maxPathLength} 字符`\n : '路径验证失败',\n };\n }\n\n // 早期返回:检查空字符串\n if (path.length === 0) {\n return {\n valid: false,\n error: '路径不能为空',\n };\n }\n\n // 检查路径遍历攻击(使用预编译正则)\n if (PATH_TRAVERSAL_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '路径包含路径遍历字符(../),可能存在安全风险'\n : '路径验证失败',\n };\n }\n\n // 检查空字节注入\n if (NULL_BYTE_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '路径包含空字节,可能存在安全风险'\n : '路径验证失败',\n };\n }\n\n // 检查控制字符\n if (CONTROL_CHAR_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '路径包含控制字符,可能存在安全风险'\n : '路径验证失败',\n };\n }\n\n // 检查命令注入字符(可选,根据需求决定是否启用)\n // if (COMMAND_INJECTION_REGEX.test(path)) {\n // return {\n // valid: false,\n // error: process.env.NODE_ENV === 'development'\n // ? '路径包含潜在的命令注入字符'\n // : '路径验证失败',\n // };\n // }\n\n // 禁止 URL scheme 导入(如 http:, https:, data:, javascript:)\n if (URL_SCHEME_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '不允许使用带协议的路径'\n : '路径验证失败',\n };\n }\n\n // 检查绝对路径(使用预编译正则)\n if (!config.allowAbsolutePaths && ABSOLUTE_PATH_REGEX.test(path)) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '不允许使用绝对路径'\n : '路径验证失败',\n };\n }\n\n // 默认仅允许相对路径和别名路径,避免把第三方包名作为动态入口。\n if (!path.startsWith('@/') && !path.startsWith('./') && !path.startsWith('../')) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? '仅允许使用 @/、./、../ 开头的模块路径'\n : '路径验证失败',\n };\n }\n\n // 检查路径前缀白名单(优化:使用 Set 提高查找速度)\n if (config.allowedPathPrefixes.length > 0) {\n const prefixSet = new Set(config.allowedPathPrefixes);\n const isAllowed = Array.from(prefixSet).some((prefix) => path.startsWith(prefix));\n if (!isAllowed) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? `路径不在允许的前缀列表中: ${config.allowedPathPrefixes.join(', ')}`\n : '路径验证失败',\n };\n }\n }\n\n // 使用 SecurityUtils 验证输入(最后检查,因为可能较慢)\n const validation = SecurityUtils.validateInput(path);\n if (!validation.safe) {\n return {\n valid: false,\n error: process.env.NODE_ENV === 'development'\n ? (validation.reason || '路径包含潜在的危险内容')\n : '路径验证失败',\n };\n }\n\n // 验证通过,添加到缓存(限制缓存大小)\n if (validatedPathCache.size < 1000) {\n validatedPathCache.add(path);\n }\n\n return { valid: true };\n}\n\n/**\n * 预编译的正则表达式(用于路径规范化)\n */\nconst NORMALIZE_REGEX = {\n multipleSlashes: /\\/+/g,\n dotSlash: /\\/\\.\\//g,\n trailingDot: /\\/\\.$/,\n};\n\n/**\n * 规范化路径\n * 优化:合并正则表达式,减少替换次数\n */\nfunction normalizePath(path: string): string {\n // 合并多个替换操作,减少字符串遍历次数\n return path\n .replace(NORMALIZE_REGEX.multipleSlashes, '/')\n .replace(NORMALIZE_REGEX.dotSlash, '/')\n .replace(NORMALIZE_REGEX.trailingDot, '')\n .trim();\n}\n\n/**\n * 类型守卫:检查是否为有效路径字符串\n */\nfunction isValidPathString(path: unknown): path is string {\n return typeof path === 'string' && path.length > 0;\n}\n\n/**\n * 类型守卫:检查是否为动态导入函数\n */\nfunction isComponentImport(path: unknown): path is () => Promise<any> {\n return typeof path === 'function';\n}\n\n/**\n * 创建动态导入函数\n * \n * 将组件路径字符串转换为动态导入函数,用于代码分割和懒加载\n * \n * @param path - 组件路径字符串,支持相对路径和别名路径(如 '@/pages/home.tsx')\n * @returns 返回动态导入函数,调用后会返回 Promise,resolve 后的值为组件模块对象\n * \n * @remarks\n * - 使用 `@vite-ignore` 注释告诉 Vite 忽略此动态导入的静态分析\n * - 使用类型断言 `as any` 是因为 TypeScript 的 `import()` 需要静态字符串字面量\n * - 在运行时,我们可以使用动态路径进行导入\n * - 组件必须使用默认导出(export default)\n * \n * @example\n * ```typescript\n * const importFn = createDynamicImport('@/pages/home.tsx');\n * const module = await importFn();\n * const HomePage = module.default;\n * ```\n */\nfunction createDynamicImport(path: string): () => Promise<any> {\n // 使用类型断言,因为 TypeScript 的 import() 需要静态字符串\n // 但在运行时,我们可以使用动态路径\n return () => import(/* @vite-ignore */ (path as any));\n}\n\n/**\n * 提取并验证组件路径到 Map 中\n * \n * 如果路径有效且 Map 中不存在,则创建动态导入函数并存储到 Map 中\n * 这样可以避免重复创建相同路径的动态导入函数,提高性能\n * \n * @param path - 组件路径,可能是字符串、动态导入函数、null 或 undefined\n * @param map - 目标 Map,用于存储路径到动态导入函数的映射\n * @param config - 路径验证配置\n * @param options - 转换选项\n * @returns 如果成功提取,返回动态导入函数;否则返回 null\n * \n * @remarks\n * - 如果 path 是函数,直接返回,不添加到 Map(函数本身就可以直接使用)\n * - 只有当路径是有效的非空字符串时才会处理并添加到 Map\n * - 如果 Map 中已存在该路径,则直接返回已有的导入函数\n * - 优化:使用 `get()` 一次获取,判断是否为 undefined,减少函数调用\n * - 会进行路径验证和清理\n * \n * @example\n * ```typescript\n * const pages = new Map<string, () => Promise<any>>();\n * const importFn1 = extractAndValidatePath('@/pages/home.tsx', pages, config, options);\n * const importFn2 = extractAndValidatePath(() => import('@/pages/home.tsx'), pages, config, options);\n * ```\n */\nfunction extractAndValidatePath(\n path: string | (() => Promise<any>) | null | undefined,\n map: Map<string, () => Promise<any>>,\n config: Required<PathValidationConfig>,\n options: TransformOptions,\n): (() => Promise<any>) | null {\n // 早期返回:如果是函数,直接返回,不添加到 Map\n if (isComponentImport(path)) {\n return path;\n }\n\n // 早期返回:检查是否为有效路径字符串\n if (!isValidPathString(path)) {\n return null;\n }\n\n // 规范化路径\n const normalizedPath = normalizePath(path);\n\n // 优化:先检查 Map 中是否已存在(避免不必要的验证)\n const existingImport = map.get(normalizedPath);\n if (existingImport !== undefined) {\n return existingImport;\n }\n\n // 路径验证(仅在 Map 中不存在时进行)\n if (config.enablePathValidation) {\n const validation = validatePath(normalizedPath, config);\n if (!validation.valid) {\n // 生产环境错误信息脱敏\n const errorMessage = process.env.NODE_ENV === 'development'\n ? `路径验证失败: ${validation.error}`\n : '路径验证失败';\n \n const error = new SecurityError(\n errorMessage,\n undefined,\n process.env.NODE_ENV === 'development' ? { path: normalizedPath } : {}\n );\n \n if (options.enableDebugLog) {\n logger.error('路径验证失败:', error);\n }\n \n // 开发环境抛出错误,生产环境记录警告并跳过\n if (process.env.NODE_ENV === 'development') {\n throw error;\n } else {\n // 生产环境日志脱敏\n logger.warn('路径验证失败,已跳过');\n return null;\n }\n }\n }\n\n // 创建动态导入函数并存储\n const importFn = createDynamicImport(normalizedPath);\n map.set(normalizedPath, importFn);\n \n if (options.enableDebugLog) {\n logger.debug('提取路径:', normalizedPath);\n }\n\n return importFn;\n}\n\n/**\n * 对象池:复用栈节点对象,减少 GC 压力\n */\nclass StackNodePool {\n private pool: Array<{ route: RouteConfig; depth: number }> = [];\n private maxPoolSize = 100;\n\n acquire(route: RouteConfig, depth: number): { route: RouteConfig; depth: number } {\n if (this.pool.length > 0) {\n const node = this.pool.pop()!;\n node.route = route;\n node.depth = depth;\n return node;\n }\n return { route, depth };\n }\n\n release(node: { route: RouteConfig; depth: number }): void {\n if (this.pool.length < this.maxPoolSize) {\n this.pool.push(node);\n }\n }\n}\n\nconst stackNodePool = new StackNodePool();\n\n/**\n * 只提取组件路径到 Map 中,不转换路由配置\n * \n * 使用迭代方式遍历所有路由(包括子路由),提取组件路径到对应的 Map 中\n * 这种设计可以确保:\n * - 相同的组件路径只会创建一个动态导入函数\n * - 使用迭代而非递归,避免栈溢出\n * - 优化:支持并行处理、使用对象池、预分配数组\n * \n * @param routes - 原始路由配置列表\n * @param result - 结果对象,用于累积收集的组件路径\n * @param config - 路径验证配置\n * @param options - 转换选项\n * @param maxDepth - 最大递归深度\n */\nasync function extractPathsOnly(\n routes: RouteConfig[],\n result: TransformRoutesResult,\n config: Required<PathValidationConfig>,\n options: TransformOptions,\n maxDepth: number,\n): Promise<void> {\n const enableParallel = options.performance?.enableParallelProcessing ?? true;\n const batchSize = options.performance?.parallelBatchSize ?? 10;\n\n // 如果启用并行处理且路由数量较多,使用并行处理\n if (enableParallel && routes.length > batchSize) {\n // 收集所有需要处理的路径(只收集字符串类型,函数类型不需要处理)\n const pathsToProcess: Array<{\n path: string | null | undefined;\n map: Map<string, () => Promise<any>>;\n }> = [];\n\n // 遍历所有路由,收集路径\n const stack: Array<{ route: RouteConfig; depth: number }> = [];\n for (let i = routes.length - 1; i >= 0; i--) {\n stack.push({ route: routes[i], depth: 0 });\n }\n\n while (stack.length > 0) {\n const { route, depth } = stack.pop()!;\n\n if (depth > maxDepth) {\n logger.warn(`路径提取达到最大深度 ${maxDepth},跳过路由:`, route.name);\n continue;\n }\n\n // 收集路径(只收集字符串类型,函数类型不需要处理,会直接使用)\n if (route.page && typeof route.page === 'string') {\n pathsToProcess.push({ path: route.page, map: result.pages });\n }\n if (route.layout && typeof route.layout === 'string') {\n pathsToProcess.push({ path: route.layout, map: result.layouts });\n }\n const routeError = route.error ?? route.errors;\n if (routeError && typeof routeError === 'string') {\n pathsToProcess.push({ path: routeError, map: result.errors });\n }\n if (route.loading && typeof route.loading === 'string') {\n pathsToProcess.push({ path: route.loading, map: result.loadings });\n }\n\n // 处理子路由\n if (route.children && Array.isArray(route.children) && route.children.length > 0) {\n for (let i = route.children.length - 1; i >= 0; i--) {\n stack.push({ route: route.children[i], depth: depth + 1 });\n }\n }\n }\n\n // 并行处理路径(分批处理)\n for (let i = 0; i < pathsToProcess.length; i += batchSize) {\n const batch = pathsToProcess.slice(i, i + batchSize);\n await Promise.all(\n batch.map(({ path, map }) =>\n Promise.resolve(extractAndValidatePath(path, map, config, options))\n )\n );\n }\n } else {\n // 串行处理(原有逻辑,优化:使用对象池)\n const stack: Array<{ route: RouteConfig; depth: number }> = [];\n\n // 初始化栈:将所有路由推入栈中\n for (let i = routes.length - 1; i >= 0; i--) {\n stack.push(stackNodePool.acquire(routes[i], 0));\n }\n\n // 迭代处理栈中的路由\n while (stack.length > 0) {\n const node = stack.pop()!;\n const { route, depth } = node;\n\n // 检查递归深度\n if (depth > maxDepth) {\n logger.warn(`路径提取达到最大深度 ${maxDepth},跳过路由:`, route.name);\n stackNodePool.release(node);\n continue;\n }\n\n // 提取组件路径到 Map 中(同时进行验证)\n extractAndValidatePath(route.page, result.pages, config, options);\n extractAndValidatePath(route.layout, result.layouts, config, options);\n extractAndValidatePath(route.error ?? route.errors, result.errors, config, options);\n extractAndValidatePath(route.loading, result.loadings, config, options);\n\n // 处理子路由\n if (route.children && Array.isArray(route.children) && route.children.length > 0) {\n // 将子路由推入栈中(逆序推入,保证处理顺序正确)\n for (let i = route.children.length - 1; i >= 0; i--) {\n stack.push(stackNodePool.acquire(route.children[i], depth + 1));\n }\n }\n\n // 释放节点到对象池\n stackNodePool.release(node);\n }\n }\n}\n\n/**\n * 清理过期缓存\n * 优化:使用 LRU 缓存的清理方法\n */\nfunction cleanupExpiredCache(cacheTTL: number): void {\n if (transformCache) {\n transformCache.cleanupExpired(cacheTTL);\n }\n}\n\n/**\n * 转换路由配置:提取组件路径到 Map 中,返回原始路由配置\n * \n * 此函数是路由转换的核心函数,主要完成以下任务:\n * 1. 递归提取路由配置中的所有组件路径(page、layout、errors、loading)\n * 2. 将组件路径字符串转换为动态导入函数\n * 3. 将动态导入函数存储在对应的 Map 中,key 为路径字符串,确保不重复\n * 4. 返回原始路由配置列表,不进行转换\n * \n * @param routes - 路由配置列表,可以是:\n * - 路由配置数组(RouteConfig[])\n * - 返回路由配置数组的函数(支持同步或异步:() => RouteConfig[] | Promise<RouteConfig[]>)\n * 支持异步函数是为了支持动态加载路由配置(如从服务器获取)\n * @param options - 转换配置选项\n * @returns 包含以下内容的结果对象:\n * - `pages`: 页面组件路径到动态导入函数的 Map\n * - `layouts`: 布局组件路径到动态导入函数的 Map\n * - `errors`: 错误组件路径到动态导入函数的 Map\n * - `loadings`: 加载组件路径到动态导入函数的 Map\n * - `routes`: 原始路由配置列表,不进行转换\n * \n * @remarks\n * - 如果 `routes` 为 null、undefined 或空数组,返回空结果对象\n * - 如果 `routes` 是函数但返回的不是数组,返回空结果对象\n * - 相同的组件路径只会创建一个动态导入函数,存储在 Map 中复用\n * - 路由配置保持原始格式,组件路径仍为字符串\n * - 支持嵌套路由,会递归处理所有层级的子路由\n * - 支持缓存,相同配置会直接返回缓存结果\n * \n * @example\n * ```typescript\n * // 示例 1: 使用数组配置\n * const result = await transformRoutes([\n * {\n * name: 'home',\n * path: '/',\n * page: '@/pages/home.tsx',\n * errors: '@/pages/error.tsx',\n * handle: { title: '首页', order: 1 },\n * },\n * ]);\n * \n * // 示例 2: 使用异步函数配置\n * const result = await transformRoutes(async () => {\n * const response = await fetch('/api/routes');\n * return response.json();\n * });\n * \n * // 示例 3: 使用配置选项\n * const result = await transformRoutes(routes, {\n * pathValidation: {\n * enablePathValidation: true,\n * allowedPathPrefixes: ['@/pages', '@/components'],\n * },\n * performance: {\n * enableCache: true,\n * cacheTTL: 10 * 60 * 1000, // 10 分钟\n * },\n * });\n * ```\n */\nexport async function transformRoutes(\n routes: RouterConfig['routes'],\n options: TransformOptions = {},\n): Promise<TransformRoutesResult> {\n const startTime = performance.now();\n const mergedOptions: Required<TransformOptions> = {\n pathValidation: { ...DEFAULT_OPTIONS.pathValidation, ...options.pathValidation },\n performance: { ...DEFAULT_OPTIONS.performance, ...options.performance },\n enableDebugLog: options.enableDebugLog ?? DEFAULT_OPTIONS.enableDebugLog,\n };\n\n // 早期返回:如果 routes 为空或未定义,直接返回空结果\n if (!routes) {\n if (mergedOptions.enableDebugLog) {\n logger.debug('路由配置为空,返回空结果');\n }\n return {\n pages: new Map<string, () => Promise<any>>(),\n layouts: new Map<string, () => Promise<any>>(),\n errors: new Map<string, () => Promise<any>>(),\n loadings: new Map<string, () => Promise<any>>(),\n routes: [],\n };\n }\n\n // 处理 routes 可能是函数的情况\n let routesArray: RouteConfig[];\n try {\n routesArray = typeof routes === 'function' ? await routes() : routes;\n } catch (error) {\n const err = error instanceof Error ? error : new Error('路由配置加载失败');\n logger.error('路由配置加载失败:', err);\n throw new ValidationError('路由配置加载失败', { originalError: err });\n }\n\n // 早期返回:如果 routesArray 不是数组,直接返回空结果\n if (!Array.isArray(routesArray) || routesArray.length === 0) {\n if (mergedOptions.enableDebugLog) {\n logger.debug('路由配置不是数组或为空,返回空结果');\n }\n return {\n pages: new Map<string, () => Promise<any>>(),\n layouts: new Map<string, () => Promise<any>>(),\n errors: new Map<string, () => Promise<any>>(),\n loadings: new Map<string, () => Promise<any>>(),\n routes: [],\n };\n }\n\n // 检查缓存\n const cacheTTL: number = (mergedOptions.performance.cacheTTL ?? DEFAULT_OPTIONS.performance.cacheTTL) as number;\n const maxCacheSize: number = (mergedOptions.performance.maxCacheSize ?? DEFAULT_OPTIONS.performance.maxCacheSize) as number;\n \n if (mergedOptions.performance.enableCache) {\n // 初始化 LRU 缓存(如果尚未初始化或大小发生变化)\n if (!transformCache || transformCache.size() !== maxCacheSize) {\n transformCache = new LRUCache(maxCacheSize);\n }\n\n const configHash = generateConfigHash(routesArray);\n if (configHash) {\n const cached = transformCache.get(configHash);\n if (cached && Date.now() - cached.timestamp < cacheTTL) {\n if (mergedOptions.enableDebugLog) {\n logger.debug('使用缓存结果');\n }\n // 直接返回缓存结果(LRU 缓存已处理访问时间更新)\n return cached.result;\n }\n }\n\n // 清理过期缓存\n cleanupExpiredCache(cacheTTL);\n }\n\n // 初始化结果对象\n const result: TransformRoutesResult = {\n pages: new Map<string, () => Promise<any>>(),\n layouts: new Map<string, () => Promise<any>>(),\n errors: new Map<string, () => Promise<any>>(),\n loadings: new Map<string, () => Promise<any>>(),\n routes: [],\n };\n\n try {\n // 性能监控:记录各阶段耗时\n const extractStartTime = performance.now();\n \n // 提取组件路径到 Map 中(不转换路由配置)\n const pathValidation: Required<PathValidationConfig> = {\n enablePathValidation: (mergedOptions.pathValidation.enablePathValidation ?? DEFAULT_OPTIONS.pathValidation.enablePathValidation) as boolean,\n allowedPathPrefixes: (mergedOptions.pathValidation.allowedPathPrefixes ?? DEFAULT_OPTIONS.pathValidation.allowedPathPrefixes) as string[],\n maxPathLength: (mergedOptions.pathValidation.maxPathLength ?? DEFAULT_OPTIONS.pathValidation.maxPathLength) as number,\n allowAbsolutePaths: (mergedOptions.pathValidation.allowAbsolutePaths ?? DEFAULT_OPTIONS.pathValidation.allowAbsolutePaths) as boolean,\n };\n const maxRecursionDepth: number = (mergedOptions.performance.maxRecursionDepth ?? DEFAULT_OPTIONS.performance.maxRecursionDepth) as number;\n \n // 异步提取路径(支持并行处理)\n await extractPathsOnly(\n routesArray,\n result,\n pathValidation,\n mergedOptions as TransformOptions,\n maxRecursionDepth,\n );\n \n const extractEndTime = performance.now();\n const extractDuration = extractEndTime - extractStartTime;\n \n // 直接使用原始路由配置,不进行转换\n result.routes = routesArray;\n\n // 缓存结果\n const cacheStartTime = performance.now();\n if (mergedOptions.performance.enableCache && transformCache) {\n const configHash = generateConfigHash(routesArray);\n if (configHash) {\n // 注意:Map 中包含函数值,structuredClone 会失败;统一使用手动克隆。\n const cachedResult: TransformRoutesResult = {\n pages: new Map(result.pages),\n layouts: new Map(result.layouts),\n errors: new Map(result.errors),\n loadings: new Map(result.loadings),\n routes: JSON.parse(JSON.stringify(result.routes)),\n };\n\n transformCache.set(configHash, {\n result: cachedResult,\n timestamp: Date.now(),\n hash: configHash,\n accessTime: Date.now(),\n });\n }\n }\n const cacheEndTime = performance.now();\n const cacheDuration = cacheEndTime - cacheStartTime;\n\n const endTime = performance.now();\n const totalDuration = endTime - startTime;\n \n if (mergedOptions.enableDebugLog) {\n // 详细的性能报告\n logger.debug(`路由转换完成,总耗时: ${totalDuration.toFixed(2)}ms`, {\n routeCount: result.routes.length,\n pageCount: result.pages.size,\n layoutCount: result.layouts.size,\n errorCount: result.errors.size,\n loadingCount: result.loadings.size,\n performance: {\n extractDuration: `${extractDuration.toFixed(2)}ms`,\n cacheDuration: `${cacheDuration.toFixed(2)}ms`,\n totalDuration: `${totalDuration.toFixed(2)}ms`,\n },\n cache: {\n hit: transformCache ? 'miss' : 'disabled',\n size: transformCache?.size() ?? 0,\n },\n });\n }\n\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error('路由转换失败');\n logger.error('路由转换失败:', err);\n throw new ValidationError('路由转换失败', { originalError: err });\n }\n}\n"],"names":["logger","SecurityUtils","SecurityError","ValidationError","LRUCache","get","key","item","cache","accessTime","Date","now","delete","set","value","has","size","maxSize","firstKey","keys","next","clear","cleanupExpired","cacheTTL","entries","timestamp","Map","transformCache","DEFAULT_OPTIONS","pathValidation","enablePathValidation","allowedPathPrefixes","maxPathLength","allowAbsolutePaths","performance","enableCache","maxCacheSize","maxRecursionDepth","enableParallelProcessing","parallelBatchSize","enableDebugLog","optimizedHash","str","length","hash","i","char","charCodeAt","Math","abs","toString","step","max","floor","simpleHash","serializeComponentRef","fnText","String","fn","name","serializeRouteConfig","route","page","layout","routeError","error","errors","loading","path","pageFn","layoutFn","errorFn","loadingFn","isGroup","enableRedirection","handle","title","order","needLogin","roles","Array","isArray","undefined","children","map","child","generateConfigHash","routes","serializedRoutes","configStr","JSON","stringify","validatedPathCache","Set","PATH_TRAVERSAL_REGEX","ABSOLUTE_PATH_REGEX","CONTROL_CHAR_REGEX","NULL_BYTE_REGEX","URL_SCHEME_REGEX","validatePath","config","valid","process","env","NODE_ENV","test","startsWith","prefixSet","isAllowed","from","some","prefix","join","validation","validateInput","safe","reason","add","NORMALIZE_REGEX","multipleSlashes","dotSlash","trailingDot","normalizePath","replace","trim","isValidPathString","isComponentImport","createDynamicImport","extractAndValidatePath","options","normalizedPath","existingImport","errorMessage","warn","importFn","debug","StackNodePool","acquire","depth","pool","node","pop","release","maxPoolSize","push","stackNodePool","extractPathsOnly","result","maxDepth","enableParallel","batchSize","pathsToProcess","stack","pages","layouts","loadings","batch","slice","Promise","all","resolve","cleanupExpiredCache","transformRoutes","startTime","mergedOptions","routesArray","err","Error","originalError","configHash","cached","extractStartTime","extractEndTime","extractDuration","cacheStartTime","cachedResult","parse","cacheEndTime","cacheDuration","endTime","totalDuration","toFixed","routeCount","pageCount","layoutCount","errorCount","loadingCount","hit"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/router/validation/RouterConfigValidator.ts"],"sourcesContent":["/**\n * 路由配置验证器\n * 使用 Zod 进行配置验证,并提供友好的错误信息\n */\n\nimport { z } from 'zod';\nimport { ConfigValidationError } from '../../config/ConfigValidator';\nimport { logger } from '@vlian/logger';\nimport { safeValidateRouterConfig } from './schema';\n\n/**\n * 路由配置验证器\n */\nexport class RouterConfigValidator {\n /**\n * 验证路由配置\n * \n * @param config - 要验证的路由配置\n * @returns 验证后的路由配置\n * @throws ConfigValidationError 如果配置验证失败\n */\n static validate(config: unknown) {\n const result = safeValidateRouterConfig(config);\n\n if (!result.success) {\n // 构建友好的错误信息\n const errorMessages = result.error.issues.map((issue: z.ZodIssue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : 'root';\n return `路由配置项 \"${path}\": ${issue.message}`;\n });\n\n const friendlyMessage = `路由配置验证失败:\\n${errorMessages.join('\\n')}`;\n\n logger.error('路由配置验证失败', {\n errors: result.error.issues,\n config,\n });\n\n throw new ConfigValidationError(friendlyMessage, result.error);\n }\n\n return result.data;\n }\n\n /**\n * 安全验证路由配置(不抛出异常)\n * \n * @param config - 要验证的路由配置\n * @returns 验证结果\n */\n static safeValidate(config: unknown) {\n return safeValidateRouterConfig(config);\n }\n\n /**\n * 验证路由配置并提供修复建议\n * \n * @param config - 要验证的路由配置\n * @returns 验证结果和修复建议\n */\n static validateWithSuggestions(config: unknown): {\n success: boolean;\n data?: unknown;\n errors?: z.ZodIssue[];\n suggestions?: string[];\n } {\n const result = safeValidateRouterConfig(config);\n\n if (!result.success) {\n const suggestions: string[] = [];\n\n result.error.issues.forEach((issue: z.ZodIssue) => {\n const path = issue.path.join('.');\n\n // 根据错误类型提供修复建议\n if (issue.code === 'invalid_type') {\n const invalidTypeIssue = issue as z.ZodIssue & { expected: string; received: string };\n suggestions.push(\n `配置项 \"${path}\" 类型错误: 期望 ${invalidTypeIssue.expected},实际 ${invalidTypeIssue.received}`\n );\n } else if (issue.code === 'too_small') {\n suggestions.push(\n `配置项 \"${path}\" 值太小: ${issue.message}`\n );\n } else if (issue.code === 'too_big') {\n suggestions.push(\n `配置项 \"${path}\" 值太大: ${issue.message}`\n );\n } else {\n suggestions.push(`配置项 \"${path}\": ${issue.message}`);\n }\n });\n\n return {\n success: false,\n errors: result.error.issues,\n suggestions,\n };\n }\n\n return {\n success: true,\n data: result.data,\n };\n }\n}\n"],"names":["RouterConfigValidator","validate","config","result","safeValidateRouterConfig","success","errorMessages","error","issues","map","issue","path","length","join","message","friendlyMessage","logger","errors","ConfigValidationError","data","safeValidate","validateWithSuggestions","suggestions","forEach","code","invalidTypeIssue","push","expected","received"],"mappings":"AAAA;;;CAGC;;;;+BAUYA;;;eAAAA;;;iCAPyB;wBACf;wBACkB;AAKlC,IAAA,AAAMA,wBAAN,MAAMA;IACX;;;;;;GAMC,GACD,OAAOC,SAASC,MAAe,EAAE;QAC/B,MAAMC,SAASC,IAAAA,gCAAwB,EAACF;QAExC,IAAI,CAACC,OAAOE,OAAO,EAAE;YACnB,YAAY;YACZ,MAAMC,gBAAgBH,OAAOI,KAAK,CAACC,MAAM,CAACC,GAAG,CAAC,CAACC;gBAC7C,MAAMC,OAAOD,MAAMC,IAAI,CAACC,MAAM,GAAG,IAAIF,MAAMC,IAAI,CAACE,IAAI,CAAC,OAAO;gBAC5D,OAAO,CAAC,OAAO,EAAEF,KAAK,GAAG,EAAED,MAAMI,OAAO,EAAE;YAC5C;YAEA,MAAMC,kBAAkB,CAAC,WAAW,EAAET,cAAcO,IAAI,CAAC,OAAO;YAEhEG,cAAM,CAACT,KAAK,CAAC,YAAY;gBACvBU,QAAQd,OAAOI,KAAK,CAACC,MAAM;gBAC3BN;YACF;YAEA,MAAM,IAAIgB,sCAAqB,CAACH,iBAAiBZ,OAAOI,KAAK;QAC/D;QAEA,OAAOJ,OAAOgB,IAAI;IACpB;IAEA;;;;;GAKC,GACD,OAAOC,aAAalB,MAAe,EAAE;QACnC,OAAOE,IAAAA,gCAAwB,EAACF;IAClC;IAEA;;;;;GAKC,GACD,OAAOmB,wBAAwBnB,MAAe,EAK5C;QACA,MAAMC,SAASC,IAAAA,gCAAwB,EAACF;QAExC,IAAI,CAACC,OAAOE,OAAO,EAAE;YACnB,MAAMiB,cAAwB,EAAE;YAEhCnB,OAAOI,KAAK,CAACC,MAAM,CAACe,OAAO,CAAC,CAACb;gBAC3B,MAAMC,OAAOD,MAAMC,IAAI,CAACE,IAAI,CAAC;gBAE7B,eAAe;gBACf,IAAIH,MAAMc,IAAI,KAAK,gBAAgB;oBACjC,MAAMC,mBAAmBf;oBACzBY,YAAYI,IAAI,CACd,CAAC,KAAK,EAAEf,KAAK,WAAW,EAAEc,iBAAiBE,QAAQ,CAAC,IAAI,EAAEF,iBAAiBG,QAAQ,EAAE;gBAEzF,OAAO,IAAIlB,MAAMc,IAAI,KAAK,aAAa;oBACrCF,YAAYI,IAAI,CACd,CAAC,KAAK,EAAEf,KAAK,OAAO,EAAED,MAAMI,OAAO,EAAE;gBAEzC,OAAO,IAAIJ,MAAMc,IAAI,KAAK,WAAW;oBACnCF,YAAYI,IAAI,CACd,CAAC,KAAK,EAAEf,KAAK,OAAO,EAAED,MAAMI,OAAO,EAAE;gBAEzC,OAAO;oBACLQ,YAAYI,IAAI,CAAC,CAAC,KAAK,EAAEf,KAAK,GAAG,EAAED,MAAMI,OAAO,EAAE;gBACpD;YACF;YAEA,OAAO;gBACLT,SAAS;gBACTY,QAAQd,OAAOI,KAAK,CAACC,MAAM;gBAC3Bc;YACF;QACF;QAEA,OAAO;YACLjB,SAAS;YACTc,MAAMhB,OAAOgB,IAAI;QACnB;IACF;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/router/validation/RouterConfigValidator.ts"],"sourcesContent":["/**\n * 路由配置验证器\n * 使用 Zod 进行配置验证,并提供友好的错误信息\n */\n\nimport { z } from 'zod';\nimport { ConfigValidationError } from '../../config/ConfigValidator';\nimport { logger } from '@vlian/logger';\nimport { safeValidateRouterConfig } from './schema';\n\n/**\n * 路由配置验证器\n */\nexport class RouterConfigValidator {\n /**\n * 验证路由配置\n * \n * @param config - 要验证的路由配置\n * @returns 验证后的路由配置\n * @throws ConfigValidationError 如果配置验证失败\n */\n static validate(config: unknown) {\n const result = safeValidateRouterConfig(config);\n\n if (!result.success) {\n // 构建友好的错误信息\n const errorMessages = result.error.issues.map((issue: z.ZodIssue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : 'root';\n return `路由配置项 \"${path}\": ${issue.message}`;\n });\n\n const friendlyMessage = `路由配置验证失败:\\n${errorMessages.join('\\n')}`;\n\n logger.error('路由配置验证失败', {\n errors: result.error.issues,\n config,\n });\n\n throw new ConfigValidationError(friendlyMessage, result.error);\n }\n\n return result.data;\n }\n\n /**\n * 安全验证路由配置(不抛出异常)\n * \n * @param config - 要验证的路由配置\n * @returns 验证结果\n */\n static safeValidate(config: unknown) {\n return safeValidateRouterConfig(config);\n }\n\n /**\n * 验证路由配置并提供修复建议\n * \n * @param config - 要验证的路由配置\n * @returns 验证结果和修复建议\n */\n static validateWithSuggestions(config: unknown): {\n success: boolean;\n data?: unknown;\n errors?: z.ZodIssue[];\n suggestions?: string[];\n } {\n const result = safeValidateRouterConfig(config);\n\n if (!result.success) {\n const suggestions: string[] = [];\n\n result.error.issues.forEach((issue: z.ZodIssue) => {\n const path = issue.path.join('.');\n\n // 根据错误类型提供修复建议\n if (issue.code === 'invalid_type') {\n const invalidTypeIssue = issue as z.ZodIssue & { expected: string; received: string };\n suggestions.push(\n `配置项 \"${path}\" 类型错误: 期望 ${invalidTypeIssue.expected},实际 ${invalidTypeIssue.received}`\n );\n } else if (issue.code === 'too_small') {\n suggestions.push(\n `配置项 \"${path}\" 值太小: ${issue.message}`\n );\n } else if (issue.code === 'too_big') {\n suggestions.push(\n `配置项 \"${path}\" 值太大: ${issue.message}`\n );\n } else {\n suggestions.push(`配置项 \"${path}\": ${issue.message}`);\n }\n });\n\n return {\n success: false,\n errors: result.error.issues,\n suggestions,\n };\n }\n\n return {\n success: true,\n data: result.data,\n };\n }\n}\n"],"names":["ConfigValidationError","logger","safeValidateRouterConfig","RouterConfigValidator","validate","config","result","success","errorMessages","error","issues","map","issue","path","length","join","message","friendlyMessage","errors","data","safeValidate","validateWithSuggestions","suggestions","forEach","code","invalidTypeIssue","push","expected","received"],"mappings":"AAAA;;;CAGC,GAGD,SAASA,qBAAqB,QAAQ,+BAA+B;AACrE,SAASC,MAAM,QAAQ,gBAAgB;AACvC,SAASC,wBAAwB,QAAQ,WAAW;AAEpD;;CAEC,GACD,OAAO,MAAMC;IACX;;;;;;GAMC,GACD,OAAOC,SAASC,MAAe,EAAE;QAC/B,MAAMC,SAASJ,yBAAyBG;QAExC,IAAI,CAACC,OAAOC,OAAO,EAAE;YACnB,YAAY;YACZ,MAAMC,gBAAgBF,OAAOG,KAAK,CAACC,MAAM,CAACC,GAAG,CAAC,CAACC;gBAC7C,MAAMC,OAAOD,MAAMC,IAAI,CAACC,MAAM,GAAG,IAAIF,MAAMC,IAAI,CAACE,IAAI,CAAC,OAAO;gBAC5D,OAAO,CAAC,OAAO,EAAEF,KAAK,GAAG,EAAED,MAAMI,OAAO,EAAE;YAC5C;YAEA,MAAMC,kBAAkB,CAAC,WAAW,EAAET,cAAcO,IAAI,CAAC,OAAO;YAEhEd,OAAOQ,KAAK,CAAC,YAAY;gBACvBS,QAAQZ,OAAOG,KAAK,CAACC,MAAM;gBAC3BL;YACF;YAEA,MAAM,IAAIL,sBAAsBiB,iBAAiBX,OAAOG,KAAK;QAC/D;QAEA,OAAOH,OAAOa,IAAI;IACpB;IAEA;;;;;GAKC,GACD,OAAOC,aAAaf,MAAe,EAAE;QACnC,OAAOH,yBAAyBG;IAClC;IAEA;;;;;GAKC,GACD,OAAOgB,wBAAwBhB,MAAe,EAK5C;QACA,MAAMC,SAASJ,yBAAyBG;QAExC,IAAI,CAACC,OAAOC,OAAO,EAAE;YACnB,MAAMe,cAAwB,EAAE;YAEhChB,OAAOG,KAAK,CAACC,MAAM,CAACa,OAAO,CAAC,CAACX;gBAC3B,MAAMC,OAAOD,MAAMC,IAAI,CAACE,IAAI,CAAC;gBAE7B,eAAe;gBACf,IAAIH,MAAMY,IAAI,KAAK,gBAAgB;oBACjC,MAAMC,mBAAmBb;oBACzBU,YAAYI,IAAI,CACd,CAAC,KAAK,EAAEb,KAAK,WAAW,EAAEY,iBAAiBE,QAAQ,CAAC,IAAI,EAAEF,iBAAiBG,QAAQ,EAAE;gBAEzF,OAAO,IAAIhB,MAAMY,IAAI,KAAK,aAAa;oBACrCF,YAAYI,IAAI,CACd,CAAC,KAAK,EAAEb,KAAK,OAAO,EAAED,MAAMI,OAAO,EAAE;gBAEzC,OAAO,IAAIJ,MAAMY,IAAI,KAAK,WAAW;oBACnCF,YAAYI,IAAI,CACd,CAAC,KAAK,EAAEb,KAAK,OAAO,EAAED,MAAMI,OAAO,EAAE;gBAEzC,OAAO;oBACLM,YAAYI,IAAI,CAAC,CAAC,KAAK,EAAEb,KAAK,GAAG,EAAED,MAAMI,OAAO,EAAE;gBACpD;YACF;YAEA,OAAO;gBACLT,SAAS;gBACTW,QAAQZ,OAAOG,KAAK,CAACC,MAAM;gBAC3BY;YACF;QACF;QAEA,OAAO;YACLf,SAAS;YACTY,MAAMb,OAAOa,IAAI;QACnB;IACF;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/router/validation/index.ts"],"sourcesContent":["/**\n * 路由配置验证模块入口\n */\n\nexport * from './schema';\nexport * from './RouterConfigValidator';\n"],"names":[],"mappings":"AAAA;;CAEC;;;;qBAEa;qBACA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/router/validation/index.ts"],"sourcesContent":["/**\n * 路由配置验证模块入口\n */\n\nexport * from './schema';\nexport * from './RouterConfigValidator';\n"],"names":[],"mappings":"AAAA;;CAEC,GAED,cAAc,WAAW;AACzB,cAAc,0BAA0B"}
|
|
@@ -1 +0,0 @@
|
|
|
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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"}
|
|
@@ -1 +0,0 @@
|
|
|
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":"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,MAAMC,sBAAsBzB,EACzBE,MAAM,CAAC;IACNwB,UAAU1B,EAAEI,MAAM,GAAGG,QAAQ;IAC7BoB,QAAQ3B,EAAE4B,MAAM,CAAC5B,EAAEI,MAAM,IAAIJ,EAAEsB,KAAK,CAAC;QAACtB,EAAEa,OAAO;QAAIb,EAAEI,MAAM;QAAIJ,EAAES,MAAM;KAAG,GAAGF,QAAQ;IACrFsB,eAAe7B,EAAE8B,OAAO,GAAGvB,QAAQ;IACnCwB,QAAQ/B,EAAE8B,OAAO,GAAGvB,QAAQ;IAC5ByB,gBAAgBhC,EAAEkB,KAAK,CAAClB,EAAEI,MAAM,IAAIG,QAAQ;IAC5C0B,cAAcjC,EAAES,MAAM,GAAGC,GAAG,GAAGwB,WAAW,GAAG3B,QAAQ;AACvD,GACCa,WAAW;AAEd,MAAMe,yBAAyBnC,EAC5BE,MAAM,CAAC;IACNkC,gBAAgBpC,EACbE,MAAM,CAAC;QACNmC,sBAAsBrC,EAAEa,OAAO,GAAGN,QAAQ;QAC1C+B,qBAAqBtC,EAAEkB,KAAK,CAAClB,EAAEI,MAAM,GAAGC,GAAG,CAAC,IAAIE,QAAQ;QACxDgC,eAAevC,EAAES,MAAM,GAAGC,GAAG,GAAG8B,QAAQ,GAAGjC,QAAQ;QACnDkC,oBAAoBzC,EAAEa,OAAO,GAAGN,QAAQ;IAC1C,GACCA,QAAQ;IACXmC,aAAa1C,EACVE,MAAM,CAAC;QACNyC,aAAa3C,EAAEa,OAAO,GAAGN,QAAQ;QACjCqC,UAAU5C,EAAES,MAAM,GAAGC,GAAG,GAAG8B,QAAQ,GAAGjC,QAAQ;QAC9CsC,cAAc7C,EAAES,MAAM,GAAGC,GAAG,GAAG8B,QAAQ,GAAGjC,QAAQ;QAClDuC,mBAAmB9C,EAAES,MAAM,GAAGC,GAAG,GAAG8B,QAAQ,GAAGjC,QAAQ;QACvDwC,0BAA0B/C,EAAEa,OAAO,GAAGN,QAAQ;QAC9CyC,mBAAmBhD,EAAES,MAAM,GAAGC,GAAG,GAAG8B,QAAQ,GAAGjC,QAAQ;IACzD,GACCA,QAAQ;IACX0C,gBAAgBjD,EAAEa,OAAO,GAAGN,QAAQ;AACtC,GACCa,WAAW;AAEd;;CAEC,GACD,OAAO,MAAM8B,oBAAoClD,EAAEmD,IAAI,CAAC,IACtDnD,EAAEE,MAAM,CAAC;QACPkD,QAAQ/B,sBAAsBd,QAAQ,GAAG8C,QAAQ;QACjDC,MAAMjC,sBAAsBd,QAAQ,GAAG8C,QAAQ;QAC/CE,SAASlC,sBAAsBd,QAAQ,GAAG8C,QAAQ;QAClDG,OAAOnC,sBAAsBd,QAAQ,GAAG8C,QAAQ;QAChDI,QAAQpC,sBAAsBd,QAAQ,GAAG8C,QAAQ;QACjDlC,MAAMnB,EAAEI,MAAM,GAAGC,GAAG,CAAC,GAAG;QACxBqD,MAAM1D,EAAEI,MAAM,GAAGG,QAAQ;QACzBoD,SAAS3D,EAAEa,OAAO,GAAGN,QAAQ;QAC7BqD,mBAAmB5D,EAAEa,OAAO,GAAGN,QAAQ;QACvCsD,QAAQ5D;QACR6D,UAAU9D,EAAEkB,KAAK,CAACgC,mBAAmB3C,QAAQ;IAC/C,IACA;AAEF;;CAEC,GACD,OAAO,MAAMwD,qBAAqB/D,EAAEE,MAAM,CAAC;IACzC8D,SAAShE,EAAEsB,KAAK,CAAC;QAACtB,EAAEa,OAAO;QAAIb,EAAEiE,OAAO,CAAC;KAAY,EAAE1D,QAAQ;IAC/D2D,QAAQlE,EACLsB,KAAK,CAAC;QACLtB,EAAEkB,KAAK,CAACgC;QACRlD,EAAEuB,QAAQ;KACX,EACAhB,QAAQ;IACX4D,MAAMnE,EAAEoE,IAAI,CAAC;QAAC;QAAW;QAAQ;KAAS,EAAE7D,QAAQ;IACpD8D,SAAS5C,oBAAoBlB,QAAQ;IACrC+D,aAAatE,EACVE,MAAM,CAAC;QACNqE,UAAUvE,EAAEI,MAAM,GAAGG,QAAQ;QAC7BiE,aAAaxE,EAAE4B,MAAM,CAAC5B,EAAEI,MAAM,IAAIJ,EAAEI,MAAM,IAAIG,QAAQ;IACxD,GACCA,QAAQ;IACXkE,kBAAkBtC,uBAAuB5B,QAAQ;IACjDmE,SAAS1E,EACNE,MAAM,CAAC;QACNyE,UAAU3E,EAAEoE,IAAI,CAAC;YAAC;YAAQ;YAAc;YAAO;SAAU,EAAE7D,QAAQ;QACnEqE,OAAO5E,EAAES,MAAM,GAAGC,GAAG,GAAG8B,QAAQ,GAAGjC,QAAQ;QAC3CsE,mBAAmB7E,EAAES,MAAM,GAAGC,GAAG,GAAGwB,WAAW,GAAG3B,QAAQ;QAC1DuE,SAAS9E,EAAES,MAAM,GAAGC,GAAG,GAAG8B,QAAQ,GAAGjC,QAAQ;IAC/C,GACCA,QAAQ;IACXwE,uBAAuB/E,EAAEa,OAAO,GAAGN,QAAQ;AAC7C,GAAGyE,WAAW,CAAC,CAACC,QAAQC;IACtB,IAAI,CAACC,MAAMC,OAAO,CAACH,OAAOf,MAAM,GAAG;QACjC;IACF;IAEA,MAAMmB,eAAe,IAAIC;IAEzB,MAAMC,OAAO,CAACrB,QAAkDsB;QAC9DtB,OAAOuB,OAAO,CAAC,CAACC,OAAOC;YACrB,MAAMC,cAAc,GAAGJ,WAAW,CAAC,EAAEG,MAAM,CAAC,CAAC;YAC7C,MAAME,eAAeR,aAAaS,GAAG,CAACJ,MAAMvE,IAAI;YAChD,IAAI0E,cAAc;gBAChBX,IAAIa,QAAQ,CAAC;oBACXC,MAAMhG,EAAEiG,YAAY,CAACC,MAAM;oBAC3BxC,MAAM;wBAAC;wBAAUiC;wBAAO;qBAAO;oBAC/BQ,SAAS,CAAC,SAAS,EAAET,MAAMvE,IAAI,CAAC,SAAS,EAAE0E,cAAc;gBAC3D;YACF,OAAO;gBACLR,aAAae,GAAG,CAACV,MAAMvE,IAAI,EAAEyE;YAC/B;YAEA,IAAIT,MAAMC,OAAO,CAACM,MAAM5B,QAAQ,KAAK4B,MAAM5B,QAAQ,CAACuC,MAAM,GAAG,GAAG;gBAC9Dd,KAAKG,MAAM5B,QAAQ,EAA8C,GAAG8B,YAAY,SAAS,CAAC;YAC5F;QACF;IACF;IAEAL,KAAKN,OAAOf,MAAM,EAAE;AACtB,GAAG;AAEH;;;;;;CAMC,GACD,OAAO,SAASoC,qBAAqBrB,MAAe;IAClD,OAAOlB,mBAAmBwC,KAAK,CAACtB;AAClC;AAEA;;;;;CAKC,GACD,OAAO,SAASuB,yBAAyBvB,MAAe;IACtD,OAAOlB,mBAAmB0C,SAAS,CAACxB;AACtC"}
|