catalyst-core 0.3.0-beta.5 → 0.3.0-canary.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +185 -71
- package/dist/errors/generateDocs.js +100 -0
- package/dist/errors/index.js +243 -0
- package/dist/errors/registry.js +483 -0
- package/dist/errors-index.json +506 -0
- package/dist/globals.d.ts +62 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.jsx +5 -8
- package/dist/logger.js +1 -1
- package/dist/native/androidProject/app/build.gradle.kts +142 -7
- package/dist/native/androidProject/app/src/main/AndroidManifest.xml +4 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +2 -2
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/camera/BarcodeDetector.kt +3 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/camera/CameraSessionManager.kt +3 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FrameworkServerUtils.kt +43 -8
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/BridgeUtilsTest.kt +181 -1
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/CameraUtilsTest.kt +156 -236
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FileSizeRouterUtilsTest.kt +471 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FileUtilsTest.kt +222 -226
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FrameworkServerUtilsTest.kt +300 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/IntentUtilsTest.kt +244 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/MetricsMonitorTest.kt +359 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/NativeBridgeTest.kt +108 -63
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/NotificationUtilsTest.kt +329 -385
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/OfflineCacheServiceTest.kt +302 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/PerfEventBufferTest.kt +133 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/UtilsKtTest.kt +152 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/WebCacheManagerTest.kt +145 -324
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/BarcodeDetectorTest.kt +132 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/HoldControllerTest.kt +155 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/TorchControllerTest.kt +150 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/VideoStreamStateMachineTest.kt +120 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/VideoStreamStateTest.kt +62 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/ViewfinderMapperTest.kt +143 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/ZoomControllerTest.kt +421 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/design/DesignTokensTest.kt +207 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/plugins/PluginBridgeTest.kt +368 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/FridaDetectorTest.kt +193 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/SecurityCheckManagerTest.kt +260 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/SecurityCheckSchedulerTest.kt +166 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/DeviceInfoUtilsTest.kt +167 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/DownloadUtilsTest.kt +197 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/NetworkMonitorTest.kt +271 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/PushNotificationUtilsTest.kt +119 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/SafeAreaUtilsTest.kt +108 -0
- package/dist/native/androidProject/build.gradle.kts +1 -0
- package/dist/native/androidProject/gradle/libs.versions.toml +26 -0
- package/dist/native/androidProject/settings.gradle.kts +11 -8
- package/dist/native/androidSetup.js +2 -2
- package/dist/native/bridge/WebBridge.d.ts +98 -0
- package/dist/native/bridge/WebBridge.js +40 -6
- package/dist/native/bridge/constants/NativeInterfaces.d.ts +391 -0
- package/dist/native/bridge/errors.d.ts +67 -0
- package/dist/native/bridge/errors.js +66 -151
- package/dist/native/bridge/hooks/index.d.ts +13 -0
- package/dist/native/bridge/hooks/index.js +0 -6
- package/dist/native/bridge/hooks/useAI.d.ts +1 -0
- package/dist/native/bridge/hooks/useAI.js +3 -1
- package/dist/native/bridge/hooks/useCamera.d.ts +86 -0
- package/dist/native/bridge/hooks/useCamera.js +35 -6
- package/dist/native/bridge/hooks/useDataProtection.d.ts +17 -0
- package/dist/native/bridge/hooks/useDeviceInfo.d.ts +34 -0
- package/dist/native/bridge/hooks/useDeviceInfo.js +5 -0
- package/dist/native/bridge/hooks/useFilePicker.d.ts +53 -0
- package/dist/native/bridge/hooks/useFilePicker.js +13 -0
- package/dist/native/bridge/hooks/useGoogleSignIn.d.ts +12 -0
- package/dist/native/bridge/hooks/useHapticFeedback.d.ts +76 -0
- package/dist/native/bridge/hooks/useHapticFeedback.js +6 -1
- package/dist/native/bridge/hooks/useIntent.d.ts +33 -0
- package/dist/native/bridge/hooks/useIntent.js +2 -0
- package/dist/native/bridge/hooks/useNativeTransition.d.ts +53 -0
- package/dist/native/bridge/hooks/useNativeTransition.js +12 -5
- package/dist/native/bridge/hooks/useNetworkStatus.d.ts +22 -0
- package/dist/native/bridge/hooks/useNetworkStatus.js +7 -0
- package/dist/native/bridge/hooks/useNotification.d.ts +83 -0
- package/dist/native/bridge/hooks/useNotification.js +81 -34
- package/dist/native/bridge/hooks/useSafeArea.d.ts +12 -0
- package/dist/native/bridge/hooks/useSafeArea.js +8 -0
- package/dist/native/bridge/hooks/useVideoStream.d.ts +67 -0
- package/dist/native/bridge/hooks/useVideoStream.js +38 -52
- package/dist/native/bridge/hooks/utils.d.ts +4 -0
- package/dist/native/bridge/hooks.d.ts +1 -0
- package/dist/native/bridge/perf/collectors/ApiCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/ApiCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/CacheCollector.d.ts +43 -0
- package/dist/native/bridge/perf/collectors/CacheCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/HookCollector.d.ts +37 -0
- package/dist/native/bridge/perf/collectors/HookCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/InsightsCollector.d.ts +103 -0
- package/dist/native/bridge/perf/collectors/InsightsCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/InteractionCollector.d.ts +53 -0
- package/dist/native/bridge/perf/collectors/InteractionCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/KeyboardCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/KeyboardCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/NavigationCollector.d.ts +37 -0
- package/dist/native/bridge/perf/collectors/NavigationCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/NetworkTimingCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/NetworkTimingCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/RenderCollector.d.ts +47 -0
- package/dist/native/bridge/perf/collectors/RenderCollector.js +8 -0
- package/dist/native/bridge/perf/collectors/ScrollCollector.d.ts +29 -0
- package/dist/native/bridge/perf/collectors/ScrollCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/ThreadCollector.d.ts +31 -0
- package/dist/native/bridge/perf/collectors/ThreadCollector.js +4 -0
- package/dist/native/bridge/perf/core/constants.d.ts +76 -0
- package/dist/native/bridge/perf/core/measure.d.ts +39 -0
- package/dist/native/bridge/perf/core/measure.js +4 -0
- package/dist/native/bridge/perf/core/session.d.ts +49 -0
- package/dist/native/bridge/perf/core/session.js +4 -0
- package/dist/native/bridge/perf/core/store.d.ts +37 -0
- package/dist/native/bridge/perf/core/store.js +4 -0
- package/dist/native/bridge/perf/core/summary.d.ts +60 -0
- package/dist/native/bridge/perf/core/traceExport.d.ts +10 -0
- package/dist/native/bridge/perf/core/waterfalls.d.ts +2 -0
- package/dist/native/bridge/perf/index.d.ts +63 -0
- package/dist/native/bridge/perf/index.js +4 -0
- package/dist/native/bridge/safeArea.d.ts +11 -0
- package/dist/native/bridge/safeArea.js +2 -0
- package/dist/native/bridge/useBaseHook.d.ts +137 -0
- package/dist/native/bridge/useBaseHook.js +34 -4
- package/dist/native/bridge/utils/CameraUtils.d.ts +94 -0
- package/dist/native/bridge/utils/CameraUtils.js +4 -0
- package/dist/native/bridge/utils/FileObjectConverter.d.ts +36 -0
- package/dist/native/bridge/utils/NativeBridge.d.ts +270 -0
- package/dist/native/bridge/utils/NativeBridge.js +10 -0
- package/dist/native/buildAndroid/index.js +1 -1
- package/dist/native/buildAppAndroid.js +9 -0
- package/dist/native/buildAppIos.js +16 -1
- package/dist/native/buildErrorFormat.js +57 -0
- package/dist/native/buildIos/config.js +15 -1
- package/dist/native/buildIos/index.js +1 -1
- package/dist/native/buildIos/plugins.js +10 -1
- package/dist/native/iosnativeWebView/CoreLogic/Package.swift +36 -0
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Camera/VideoStreamState.swift +1 -1
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Camera/VideoStreamStateMachine.swift +6 -4
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/BootTimingUtility.swift +3 -3
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/FrameworkServerUtils.swift +14 -9
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NetworkMonitor.swift +11 -9
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NotificationHandlerProvider.swift +1 -1
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/URLWhitelistManager.swift +7 -7
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/AnyCodableTests.swift +154 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/BootTimingUtilityTests.swift +23 -5
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/CatalystConstantsTests.swift +192 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/ConfigMappingTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/FrameworkServerUtilsErrorPathTests.swift +106 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/FrameworkServerUtilsLoopbackTests.swift +243 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/FrameworkServerUtilsTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/NetworkMonitorTests.swift +119 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/NotificationHandlerProviderTests.swift +59 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/NotificationHandlerTests.swift +1 -1
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/URLWhitelistManagerTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/VideoStreamStateMachineTests.swift +171 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/VideoStreamStateTests.swift +91 -0
- package/dist/native/iosnativeWebView/Package.swift +10 -9
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/LocalNotificationHandler.swift +7 -2
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/NotificationManager.swift +1 -2
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/PushNotificationHandler.swift +5 -4
- package/dist/native/iosnativeWebView/Sources/Core/Camera/CameraSessionManager.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Camera/HoldController.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Camera/NativeCameraManager.swift +6 -5
- package/dist/native/iosnativeWebView/Sources/Core/Camera/ZoomController.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Plugins/PluginBridge.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/CacheManager.swift +31 -30
- package/dist/native/iosnativeWebView/Sources/Core/Utils/CameraTransportUtils.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/Utils/DeviceInfoUtils.swift +1 -1
- package/dist/native/iosnativeWebView/Sources/Core/Utils/FilePickerHandler.swift +22 -19
- package/dist/native/iosnativeWebView/Sources/Core/Utils/ImageHandler.swift +40 -39
- package/dist/native/iosnativeWebView/Sources/Core/Utils/PerfEventBuffer.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/ResourceURLProtocol.swift +15 -15
- package/dist/native/iosnativeWebView/Sources/Core/Utils/WebKitConfig.swift +4 -3
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeCommandHandler.swift +6 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeDelegateHandler.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeFileHandler.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeJavaScriptInterface.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeMessageValidator.swift +3 -5
- package/dist/native/iosnativeWebView/Sources/Core/WebView/NativeBridge.swift +20 -13
- package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashView.swift +6 -5
- package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashViewModel.swift +14 -13
- package/dist/native/iosnativeWebView/Sources/Core/WebView/TransitionManager.swift +3 -3
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebView.swift +9 -8
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewModel.swift +7 -6
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewNavigationDelegate.swift +24 -25
- package/dist/native/iosnativeWebView/iosnativeWebView/AppDelegate.swift +6 -1
- package/dist/native/iosnativeWebView/iosnativeWebView/ContentView.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/iosnativeWebViewApp.swift +4 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.pbxproj +2 -22
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/BridgeMessageValidatorTests.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/CacheManagerTests.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/FilePickerHandlerTests.swift +2 -1
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/NativeBridgeTests.swift +15 -9
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/WebViewTests.swift +1 -0
- package/dist/native/setupEmulatorIos.js +2 -2
- package/dist/native/terminalProgress.js +17 -17
- package/dist/router/ClientRouter.d.ts +8 -0
- package/dist/router/ClientRouter.js +13 -11
- package/dist/router/ServerRouter.d.ts +13 -0
- package/dist/router/ServerRouter.js +19 -7
- package/dist/scripts/build.js +14 -2
- package/dist/scripts/loadEnvironmentVariables.js +3 -2
- package/dist/scripts/plugins.js +1 -1
- package/dist/scripts/preServerInit.js +49 -3
- package/dist/scripts/preflight.js +111 -0
- package/dist/scripts/scriptUtils.js +46 -1
- package/dist/scripts/serve.js +7 -3
- package/dist/scripts/start.js +8 -3
- package/dist/server/expressServer.d.ts +1 -0
- package/dist/server/expressServer.js +247 -271
- package/dist/server/manifestCache.d.ts +2 -0
- package/dist/server/manifestCache.js +25 -33
- package/dist/server/renderer/ChunkExtractor.d.ts +44 -0
- package/dist/server/renderer/ChunkExtractor.js +113 -125
- package/dist/server/renderer/document/Body.d.ts +21 -0
- package/dist/server/renderer/document/Body.jsx +45 -45
- package/dist/server/renderer/document/FastRefresh.d.ts +3 -0
- package/dist/server/renderer/document/FastRefresh.jsx +7 -13
- package/dist/server/renderer/document/Head.d.ts +20 -0
- package/dist/server/renderer/document/Head.jsx +32 -32
- package/dist/server/renderer/document/index.d.ts +2 -0
- package/dist/server/renderer/document/index.jsx +2 -2
- package/dist/server/renderer/extract.d.ts +67 -0
- package/dist/server/renderer/extract.js +92 -89
- package/dist/server/renderer/handler.d.ts +2 -0
- package/dist/server/renderer/handler.jsx +401 -404
- package/dist/server/renderer/index.d.ts +2 -0
- package/dist/server/renderer/index.js +5 -8
- package/dist/server/renderer/render.d.ts +35 -0
- package/dist/server/renderer/render.js +25 -32
- package/dist/server/utils/botDetectionMiddleware.d.ts +1 -0
- package/dist/server/utils/botDetectionMiddleware.js +33 -23
- package/dist/server/utils/cjsRequire.d.ts +8 -0
- package/dist/server/utils/cjsRequire.js +2 -2
- package/dist/server/utils/userAgentUtil.d.ts +7 -0
- package/dist/server/utils/userAgentUtil.js +68 -71
- package/dist/server/utils/validator.d.ts +31 -0
- package/dist/server/utils/validator.js +133 -158
- package/dist/vite/inject-cache-key-plugin.js +3 -27
- package/dist/vite/moduleAliases.js +36 -0
- package/dist/vite/node-loader.mjs +2 -29
- package/dist/vite/resolveDevServerConfig.js +4 -1
- package/dist/vite/vite.config.js +2 -29
- package/dist/web-router/components/MetaTag.d.ts +4 -0
- package/dist/web-router/components/MetaTag.jsx +26 -28
- package/dist/web-router/components/MetaTag.test.jsx +100 -0
- package/dist/web-router/components/RouterDataProvider.d.ts +96 -0
- package/dist/web-router/components/RouterDataProvider.jsx +260 -259
- package/dist/web-router/components/RouterDataProvider.server.test.jsx +98 -0
- package/dist/web-router/components/RouterDataProvider.test.jsx +310 -0
- package/dist/web-router/components/Split.d.ts +74 -0
- package/dist/web-router/components/Split.jsx +147 -156
- package/dist/web-router/components/Split.server.test.jsx +52 -0
- package/dist/web-router/components/Split.test.jsx +167 -0
- package/dist/web-router/components/SplitInview.d.ts +22 -0
- package/dist/web-router/components/SplitInview.jsx +78 -89
- package/dist/web-router/components/SplitInview.test.jsx +112 -0
- package/dist/web-router/components/SsrRequestContext.d.ts +20 -0
- package/dist/web-router/components/SsrRequestContext.jsx +17 -7
- package/dist/web-router/components/SsrRequestContext.test.jsx +53 -0
- package/dist/web-router/context.d.ts +15 -0
- package/dist/web-router/context.jsx +5 -5
- package/dist/web-router/context.test.jsx +10 -0
- package/dist/web-router/utils/metaDataUtils.d.ts +24 -0
- package/dist/web-router/utils/metaDataUtils.jsx +86 -86
- package/dist/web-router/utils/metaDataUtils.test.jsx +188 -0
- package/dist/web-router/vitest.setup.js +12 -0
- package/mcp_v2/knowledge-base.json +115 -17
- package/mcp_v2/mcp.js +141 -3
- package/mcp_v2/package-lock.json +2031 -0
- package/mcp_v2/package.json +13 -2
- package/mcp_v2/scripts/copyErrorsIndex.cjs +34 -0
- package/mcp_v2/test/errors.test.ts +123 -0
- package/mcp_v2/test/github.test.ts +177 -0
- package/mcp_v2/tools/errors.d.ts +20 -0
- package/mcp_v2/tools/errors.js +63 -0
- package/mcp_v2/tools/github.d.ts +41 -0
- package/mcp_v2/tools/github.js +231 -0
- package/mcp_v2/vitest.config.mjs +22 -0
- package/package.json +60 -11
- package/test/errors/docsDrift.test.ts +113 -0
- package/test/errors/index.test.ts +200 -0
- package/test/errors/registry.test.ts +108 -0
- package/test/scripts/preflight.test.ts +118 -0
- package/test/server/ChunkExtractor.test.ts +97 -0
- package/test/server/extract.test.ts +128 -0
- package/test/server/fixtures/template/server/document.jsx +19 -0
- package/test/server/fixtures/template/server/index.js +10 -0
- package/test/server/fixtures/template/src/js/containers/App/index.jsx +33 -0
- package/test/server/fixtures/template/src/js/routes/index.jsx +72 -0
- package/test/server/fixtures/template/src/js/routes/utils.jsx +39 -0
- package/test/server/fixtures/template/src/js/store/index.js +19 -0
- package/test/server/handler.assets.test.ts +330 -0
- package/test/server/handler.test.ts +208 -0
- package/test/server/manifestCache.test.ts +71 -0
- package/test/server/render.test.ts +71 -0
- package/test/server/scriptUtils.test.ts +103 -0
- package/test/server/userAgentUtil.test.ts +48 -0
- package/test/server/validator.test.ts +225 -0
- package/test/vite/resolveDevServerConfig.test.js +4 -1
- package/tsconfig.test.json +23 -0
- package/vitest.config.ts +93 -0
- package/dist/caching.js +0 -1
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/DeviceInfoUtilsTest.kt +0 -187
- package/dist/native/bridge/standardizedHooks.js +0 -611
- package/dist/router.js +0 -1
- package/dist/scripts/validator.js +0 -149
- package/dist/web-router/hooks.jsx +0 -72
- package/dist/web-router/types/components/MetaTag.d.ts +0 -2
- package/dist/web-router/types/components/RouterDataProvider.d.ts +0 -95
- package/dist/web-router/types/context.d.ts +0 -14
- package/dist/web-router/types/hooks.d.ts +0 -1
- package/dist/web-router/types/index.d.ts +0 -3
- package/dist/web-router/types/utils/metaDataUtils.d.ts +0 -40
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Constants/CatalystConstants.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Constants/ConfigConstants.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Notifications/NotificationModels.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Protocols/NotificationHandlerProtocol.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NullNotificationHandler.swift +0 -0
package/mcp_v2/tools/github.js
CHANGED
|
@@ -120,6 +120,41 @@ const ISSUE_TEMPLATES = {
|
|
|
120
120
|
},
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
// Pull-request templates, one per change type. Section lists mirror the
|
|
124
|
+
// `##` headings in .github/PULL_REQUEST_TEMPLATE/<change_type>.md exactly —
|
|
125
|
+
// the drift test in test/github.test.ts asserts that, the same way it
|
|
126
|
+
// checks ISSUE_TEMPLATES against .github/ISSUE_TEMPLATE/*.yml.
|
|
127
|
+
const PR_TEMPLATES = {
|
|
128
|
+
fix: {
|
|
129
|
+
change_type: "fix",
|
|
130
|
+
name: "Bug fix",
|
|
131
|
+
use_when: "The PR corrects broken, ignored, regressed, or misdocumented behavior.",
|
|
132
|
+
sections: ["Root cause", "Repro", "Fix", "Regression test", "Affected error codes"],
|
|
133
|
+
},
|
|
134
|
+
feature: {
|
|
135
|
+
change_type: "feature",
|
|
136
|
+
name: "Feature",
|
|
137
|
+
use_when: "The PR adds a new capability, hook, CLI behavior, or framework ergonomics change.",
|
|
138
|
+
sections: ["What", "Why", "New error codes", "Test coverage"],
|
|
139
|
+
},
|
|
140
|
+
chore: {
|
|
141
|
+
change_type: "chore",
|
|
142
|
+
name: "Chore (no behaviour change)",
|
|
143
|
+
use_when:
|
|
144
|
+
"The PR changes deps, CI, tooling, docs, or internal structure with no runtime behavior change.",
|
|
145
|
+
sections: ["What triggered this", "Change", "No behaviour change"],
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Appended verbatim to every rendered PR body. Kept in sync with the shared
|
|
150
|
+
// footer in .github/PULL_REQUEST_TEMPLATE*.md (also asserted by the drift test).
|
|
151
|
+
const PR_FOOTER_CHECKLIST = [
|
|
152
|
+
"- [ ] `npm run test:unit` passes locally",
|
|
153
|
+
"- [ ] `npm run lint` passes locally",
|
|
154
|
+
"- [ ] No new raw `throw new Error(...)` in changed files",
|
|
155
|
+
"- [ ] Coverage gate (`coverage-summary`, #415/#437) not regressed",
|
|
156
|
+
].join("\n")
|
|
157
|
+
|
|
123
158
|
function init(projectInfo) {
|
|
124
159
|
_projectInfo = projectInfo
|
|
125
160
|
}
|
|
@@ -1122,7 +1157,203 @@ async function handle_create_github_issue(args = {}) {
|
|
|
1122
1157
|
}
|
|
1123
1158
|
}
|
|
1124
1159
|
|
|
1160
|
+
// ── Pull request workflow ────────────────────────────────────────────────────
|
|
1161
|
+
|
|
1162
|
+
function resolvePrChangeType(args) {
|
|
1163
|
+
const requested = typeof args.change_type === "string" ? args.change_type.trim().toLowerCase() : ""
|
|
1164
|
+
if (PR_TEMPLATES[requested]) return requested
|
|
1165
|
+
|
|
1166
|
+
const text = `${args.title || ""}\n${args.summary || args.body || ""}`.toLowerCase()
|
|
1167
|
+
if (/\b(fix|bug|regress|broken|crash|incorrect)\b/.test(text)) return "fix"
|
|
1168
|
+
if (/\b(feat|feature|add\s+support|new\s+(hook|api|capability))\b/.test(text)) return "feature"
|
|
1169
|
+
return "chore"
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
// Compose a PR body in the shape of the matching .github/PULL_REQUEST_TEMPLATE
|
|
1173
|
+
// file. Pre-structured markdown (already has `##` headings) is passed through
|
|
1174
|
+
// untouched; otherwise the structured per-type fields are laid out in the
|
|
1175
|
+
// template's section order. The shared footer checklist is always appended.
|
|
1176
|
+
function buildPrBody(args) {
|
|
1177
|
+
const changeType = resolvePrChangeType(args)
|
|
1178
|
+
const rawBody = stripExistingFooter(args.body)
|
|
1179
|
+
const closesLine =
|
|
1180
|
+
args.closes_issue != null && `${args.closes_issue}`.trim()
|
|
1181
|
+
? `Closes #${`${args.closes_issue}`.replace(/^#/, "").trim()}`
|
|
1182
|
+
: ""
|
|
1183
|
+
|
|
1184
|
+
let content
|
|
1185
|
+
if (rawBody && hasMarkdownHeadings(rawBody)) {
|
|
1186
|
+
content = rawBody
|
|
1187
|
+
} else {
|
|
1188
|
+
const sections = []
|
|
1189
|
+
if (changeType === "fix") {
|
|
1190
|
+
appendSection(sections, "Root cause", firstNonEmpty(args.root_cause, args.summary, rawBody))
|
|
1191
|
+
appendSection(sections, "Repro", args.repro || args.steps_to_reproduce)
|
|
1192
|
+
appendSection(sections, "Fix", firstNonEmpty(args.fix, args.proposed_fix))
|
|
1193
|
+
appendSection(sections, "Regression test", args.regression_test)
|
|
1194
|
+
appendSection(sections, "Affected error codes", firstNonEmpty(args.affected_error_codes, "none"))
|
|
1195
|
+
} else if (changeType === "feature") {
|
|
1196
|
+
appendSection(sections, "What", firstNonEmpty(args.what, args.summary, rawBody))
|
|
1197
|
+
appendSection(sections, "Why", firstNonEmpty(args.why, args.motivation))
|
|
1198
|
+
appendSection(
|
|
1199
|
+
sections,
|
|
1200
|
+
"New error codes",
|
|
1201
|
+
firstNonEmpty(args.new_error_codes, "No new error codes")
|
|
1202
|
+
)
|
|
1203
|
+
appendSection(sections, "Test coverage", args.coverage_delta || args.test_coverage)
|
|
1204
|
+
} else {
|
|
1205
|
+
appendSection(
|
|
1206
|
+
sections,
|
|
1207
|
+
"What triggered this",
|
|
1208
|
+
firstNonEmpty(args.change_trigger, args.summary, rawBody)
|
|
1209
|
+
)
|
|
1210
|
+
appendSection(sections, "Change", firstNonEmpty(args.change, args.summary, rawBody))
|
|
1211
|
+
appendSection(
|
|
1212
|
+
sections,
|
|
1213
|
+
"No behaviour change",
|
|
1214
|
+
args.no_behaviour_change === true || args.no_behaviour_change === "true"
|
|
1215
|
+
? "- [x] Confirmed: no runtime behaviour change — output, public API, and error codes are unchanged"
|
|
1216
|
+
: "- [ ] Confirmed: no runtime behaviour change — output, public API, and error codes are unchanged"
|
|
1217
|
+
)
|
|
1218
|
+
}
|
|
1219
|
+
content = sections.join("\n\n").trim()
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
const body = [closesLine, content, "---", PR_FOOTER_CHECKLIST].filter(Boolean).join("\n\n").trim()
|
|
1223
|
+
|
|
1224
|
+
return { change_type: changeType, body }
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
async function handle_create_github_pr(args = {}) {
|
|
1228
|
+
const { title } = args
|
|
1229
|
+
if (!title || typeof title !== "string" || title.trim() === "") {
|
|
1230
|
+
return { ok: false, error: "title is required and must be a non-empty string." }
|
|
1231
|
+
}
|
|
1232
|
+
if (
|
|
1233
|
+
!firstNonEmpty(args.body, args.summary, args.root_cause, args.what, args.change, args.change_trigger)
|
|
1234
|
+
) {
|
|
1235
|
+
return {
|
|
1236
|
+
ok: false,
|
|
1237
|
+
error: "body or a structured field (summary / root_cause / what / change / change_trigger) is required.",
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
const root = getProjectRoot(args)
|
|
1242
|
+
const head = firstNonEmpty(args.head, runGit(root, "git rev-parse --abbrev-ref HEAD")) || ""
|
|
1243
|
+
if (!head || head === "HEAD") {
|
|
1244
|
+
return {
|
|
1245
|
+
ok: false,
|
|
1246
|
+
error: "Could not resolve the head branch. Pass head explicitly (you may be in a detached HEAD).",
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
const base = firstNonEmpty(args.base) || "main"
|
|
1250
|
+
if (head === base) {
|
|
1251
|
+
return { ok: false, error: `head and base are the same branch (${head}).` }
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
const { change_type: changeType, body } = buildPrBody(args)
|
|
1255
|
+
const draft = args.draft !== false
|
|
1256
|
+
const dryRun = args.dry_run !== false
|
|
1257
|
+
|
|
1258
|
+
const remoteHead = runGit(root, `git rev-parse --verify --quiet origin/${head}`)
|
|
1259
|
+
const commits = runGit(root, `git log --oneline origin/${base}..${head} 2>/dev/null`) || ""
|
|
1260
|
+
const tokenResult = getToken()
|
|
1261
|
+
|
|
1262
|
+
const preview = {
|
|
1263
|
+
type: "pull_request",
|
|
1264
|
+
repo: `${GITHUB_OWNER}/${GITHUB_REPO}`,
|
|
1265
|
+
title: title.trim(),
|
|
1266
|
+
head,
|
|
1267
|
+
base,
|
|
1268
|
+
draft,
|
|
1269
|
+
change_type: changeType,
|
|
1270
|
+
suggested_template: PR_TEMPLATES[changeType],
|
|
1271
|
+
body,
|
|
1272
|
+
head_pushed: Boolean(remoteHead),
|
|
1273
|
+
commits_ahead_of_base: commits ? commits.split("\n") : [],
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
if (dryRun) {
|
|
1277
|
+
return {
|
|
1278
|
+
ok: true,
|
|
1279
|
+
dry_run: true,
|
|
1280
|
+
preview,
|
|
1281
|
+
token_source: tokenResult.ok ? tokenResult.source : "none",
|
|
1282
|
+
auth_warning: tokenResult.ok ? null : tokenResult.error,
|
|
1283
|
+
push_warning: remoteHead
|
|
1284
|
+
? null
|
|
1285
|
+
: `origin/${head} not found — push the branch before publishing: git push -u origin ${head}`,
|
|
1286
|
+
instructions:
|
|
1287
|
+
"Show the rendered PR preview (title, head → base, change type, body) to the developer. Ask whether to edit, cancel, or publish. Publish only after explicit approval with dry_run:false.",
|
|
1288
|
+
next_action:
|
|
1289
|
+
"Wait for explicit developer approval before calling create_github_pr with dry_run:false.",
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
if (!remoteHead) {
|
|
1294
|
+
return {
|
|
1295
|
+
ok: false,
|
|
1296
|
+
blocked: true,
|
|
1297
|
+
error: `origin/${head} does not exist. Push the branch first: git push -u origin ${head}`,
|
|
1298
|
+
preview,
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
if (!tokenResult.ok) {
|
|
1303
|
+
return { ok: false, error: tokenResult.error, preview }
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
try {
|
|
1307
|
+
const res = await githubRequest(
|
|
1308
|
+
"POST",
|
|
1309
|
+
`/repos/${GITHUB_OWNER}/${GITHUB_REPO}/pulls`,
|
|
1310
|
+
tokenResult.token,
|
|
1311
|
+
{ title: title.trim(), head, base, body, draft }
|
|
1312
|
+
)
|
|
1313
|
+
|
|
1314
|
+
if (res.status === 201) {
|
|
1315
|
+
return {
|
|
1316
|
+
ok: true,
|
|
1317
|
+
message: `PR #${res.body.number} created successfully.`,
|
|
1318
|
+
number: res.body.number,
|
|
1319
|
+
url: res.body.html_url,
|
|
1320
|
+
head,
|
|
1321
|
+
base,
|
|
1322
|
+
draft: res.body.draft,
|
|
1323
|
+
change_type: changeType,
|
|
1324
|
+
token_source: tokenResult.source,
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
const apiMessage = res.body && res.body.message ? res.body.message : JSON.stringify(res.body)
|
|
1329
|
+
const fallbackDir = ensureFallbackDir(root)
|
|
1330
|
+
const fallbackPath = path.join(
|
|
1331
|
+
fallbackDir,
|
|
1332
|
+
`${new Date().toISOString().replace(/[:.]/g, "-")}-pr-${slugify(title)}.md`
|
|
1333
|
+
)
|
|
1334
|
+
fs.writeFileSync(
|
|
1335
|
+
fallbackPath,
|
|
1336
|
+
[`# ${title.trim()}`, "", `Base: ${base} · Head: ${head}`, "", "## Body", "", body, ""].join(
|
|
1337
|
+
"\n"
|
|
1338
|
+
),
|
|
1339
|
+
"utf8"
|
|
1340
|
+
)
|
|
1341
|
+
return {
|
|
1342
|
+
ok: false,
|
|
1343
|
+
error: `GitHub API returned HTTP ${res.status}: ${apiMessage}`,
|
|
1344
|
+
fallback: { markdown_path: fallbackPath },
|
|
1345
|
+
}
|
|
1346
|
+
} catch (err) {
|
|
1347
|
+
return { ok: false, error: `Network error while calling GitHub API: ${err.message}` }
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1125
1351
|
module.exports = {
|
|
1126
1352
|
init,
|
|
1127
1353
|
handle_create_github_issue,
|
|
1354
|
+
handle_create_github_pr,
|
|
1355
|
+
ISSUE_TEMPLATES,
|
|
1356
|
+
PR_TEMPLATES,
|
|
1357
|
+
PR_FOOTER_CHECKLIST,
|
|
1358
|
+
DEFAULT_LABELS,
|
|
1128
1359
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config"
|
|
2
|
+
|
|
3
|
+
// Framework-level (Tier 1) unit tests for catalyst-mcp's own internals.
|
|
4
|
+
// mcp_v2 lives inside packages/catalyst-core/mcp_v2/ (it ships bundled
|
|
5
|
+
// inside the catalyst-core package, see ../mcp_v2/scripts/copyErrorsIndex.cjs
|
|
6
|
+
// and errors.js's own packaged-path handling) and is NOT matched by the
|
|
7
|
+
// packages/* workspace glob, so it's invisible to `npm run test:unit` unless
|
|
8
|
+
// explicitly wired in — see the root package.json's test:unit script.
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
test: {
|
|
11
|
+
environment: "node",
|
|
12
|
+
include: ["test/**/*.test.ts"],
|
|
13
|
+
// tools/errors.js itself is CommonJS, loaded via require() from the
|
|
14
|
+
// .ts test file below. .ts, not .cts: this Vite/Rollup version's SSR
|
|
15
|
+
// transform doesn't strip TS syntax from .cts files at all (fails to
|
|
16
|
+
// parse even a single type annotation — a real tooling gap,
|
|
17
|
+
// confirmed empirically, not a config mistake). vitest's own
|
|
18
|
+
// describe/it/expect exports can't be require()'d, only import'd —
|
|
19
|
+
// globals injects them instead.
|
|
20
|
+
globals: true,
|
|
21
|
+
},
|
|
22
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "catalyst-core",
|
|
3
|
-
"version": "0.3.0-
|
|
3
|
+
"version": "0.3.0-canary.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.jsx",
|
|
6
6
|
"description": "Web framework that provides great performance out of the box",
|
|
@@ -16,41 +16,71 @@
|
|
|
16
16
|
"@catalyst/template": "."
|
|
17
17
|
},
|
|
18
18
|
"exports": {
|
|
19
|
-
".":
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.jsx"
|
|
22
|
+
},
|
|
20
23
|
"./package.json": "./package.json",
|
|
21
24
|
"./logger": "./dist/logger.js",
|
|
22
|
-
"./
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"./
|
|
25
|
+
"./router/ClientRouter": {
|
|
26
|
+
"types": "./dist/router/ClientRouter.d.ts",
|
|
27
|
+
"default": "./dist/router/ClientRouter.js"
|
|
28
|
+
},
|
|
29
|
+
"./WebBridge": {
|
|
30
|
+
"types": "./dist/native/bridge/WebBridge.d.ts",
|
|
31
|
+
"default": "./dist/native/bridge/WebBridge.js"
|
|
32
|
+
},
|
|
33
|
+
"./hooks": {
|
|
34
|
+
"types": "./dist/native/bridge/hooks.d.ts",
|
|
35
|
+
"default": "./dist/native/bridge/hooks.js"
|
|
36
|
+
},
|
|
37
|
+
"./errors": "./dist/errors/index.js",
|
|
27
38
|
"./sentry": "./dist/sentry.cjs",
|
|
28
39
|
"./otel": "./dist/otel.js"
|
|
29
40
|
},
|
|
41
|
+
"typesVersions": {
|
|
42
|
+
"*": {
|
|
43
|
+
"hooks": [
|
|
44
|
+
"./dist/native/bridge/hooks.d.ts"
|
|
45
|
+
],
|
|
46
|
+
"WebBridge": [
|
|
47
|
+
"./dist/native/bridge/WebBridge.d.ts"
|
|
48
|
+
],
|
|
49
|
+
"router/ClientRouter": [
|
|
50
|
+
"./dist/router/ClientRouter.d.ts"
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
},
|
|
30
54
|
"scripts": {
|
|
31
55
|
"lint": "eslint .",
|
|
32
56
|
"lint-staged": "lint-staged",
|
|
33
57
|
"test:unit": "node --test \"test/**/*.test.js\"",
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
34
59
|
"prettify": "prettier . --write",
|
|
35
|
-
"prepare": "node ../../scripts/safe-rimraf.js ./dist && cp -r ./src ./dist && babel src/native --out-dir dist/native --config-file ./babel.native.config.cjs --ignore '**/.build/**' && babel src/sentry.js --out-file dist/sentry.cjs --config-file ./babel.native.config.cjs",
|
|
60
|
+
"prepare": "node ../../scripts/safe-rimraf.js ./dist && node scripts/build-dist.mjs && cp -r ./src/native ./dist/native && babel src/native --out-dir dist/native --config-file ./babel.native.config.cjs --extensions '.js,.jsx,.ts,.tsx' --ignore '**/.build/**' && node scripts/strip-ts-sources.mjs ./dist/native && babel src/sentry.js --out-file dist/sentry.cjs --config-file ./babel.native.config.cjs && tsc -p tsconfig.declarations.json && node ./mcp_v2/scripts/copyErrorsIndex.cjs",
|
|
36
61
|
"prepublishOnly": "npm run prepare",
|
|
62
|
+
"test": "npm run test:types && vitest run",
|
|
63
|
+
"test:watch": "vitest",
|
|
64
|
+
"test:types": "tsc -p tsconfig.test.json --noEmit",
|
|
37
65
|
"test:fixture": "sh ../../scripts/test-catalyst-core.sh"
|
|
38
66
|
},
|
|
39
67
|
"license": "MIT",
|
|
68
|
+
"engines": {
|
|
69
|
+
"node": ">=22.12"
|
|
70
|
+
},
|
|
40
71
|
"dependencies": {
|
|
41
72
|
"@vitejs/plugin-react": "^4.4.1",
|
|
73
|
+
"ansis": "^4.3.1",
|
|
42
74
|
"body-parser": "^1.20.2",
|
|
43
75
|
"compression": "^1.7.4",
|
|
44
76
|
"cookie-parser": "^1.4.6",
|
|
45
77
|
"express": "^4.18.2",
|
|
46
78
|
"express-static-gzip": "^2.1.7",
|
|
47
|
-
"picocolors": "^1.0.0",
|
|
48
79
|
"react": "19.0.0",
|
|
49
80
|
"react-dom": "19.0.0",
|
|
50
81
|
"react-helmet-async": "^1.3.0",
|
|
51
82
|
"react-redux": "^9.2.0",
|
|
52
83
|
"react-refresh": "^0.14.0",
|
|
53
|
-
"react-router": "^7.18.2",
|
|
54
84
|
"redux": "^4.2.1",
|
|
55
85
|
"sanitize-html": "^2.17.6",
|
|
56
86
|
"sass": "^1.89.2",
|
|
@@ -60,6 +90,15 @@
|
|
|
60
90
|
"winston": "^3.11.0",
|
|
61
91
|
"winston-daily-rotate-file": "^5.0.0"
|
|
62
92
|
},
|
|
93
|
+
"peerDependencies": {
|
|
94
|
+
"@types/react": "^19.0.0",
|
|
95
|
+
"react-router": "^7.18.2"
|
|
96
|
+
},
|
|
97
|
+
"peerDependenciesMeta": {
|
|
98
|
+
"@types/react": {
|
|
99
|
+
"optional": true
|
|
100
|
+
}
|
|
101
|
+
},
|
|
63
102
|
"devDependencies": {
|
|
64
103
|
"@babel/cli": "^7.23.0",
|
|
65
104
|
"@babel/core": "^7.23.2",
|
|
@@ -69,6 +108,13 @@
|
|
|
69
108
|
"@babel/preset-typescript": "^7.24.7",
|
|
70
109
|
"@commitlint/cli": "^19.3.0",
|
|
71
110
|
"@commitlint/config-conventional": "^19.2.2",
|
|
111
|
+
"@testing-library/dom": "10.4.1",
|
|
112
|
+
"@testing-library/jest-dom": "7.0.1",
|
|
113
|
+
"@testing-library/react": "16.3.2",
|
|
114
|
+
"@types/node": "^22.20.1",
|
|
115
|
+
"@types/react": "^19.2.18",
|
|
116
|
+
"@types/react-dom": "^19.2.5",
|
|
117
|
+
"@vitest/coverage-v8": "4.1.9",
|
|
72
118
|
"eslint": "^8.26.0",
|
|
73
119
|
"eslint-plugin-babel": "^5.3.1",
|
|
74
120
|
"eslint-plugin-react": "^7.34.1",
|
|
@@ -77,8 +123,11 @@
|
|
|
77
123
|
"eslint-plugin-risxss": "^2.1.0",
|
|
78
124
|
"eslint-plugin-security": "^3.0.0",
|
|
79
125
|
"husky": "^9.0.11",
|
|
126
|
+
"jsdom": "30.0.1",
|
|
80
127
|
"lint-staged": "^15.2.2",
|
|
81
|
-
"prettier": "^3.2.5"
|
|
128
|
+
"prettier": "^3.2.5",
|
|
129
|
+
"typescript": "^7.0.2",
|
|
130
|
+
"vitest": "4.1.9"
|
|
82
131
|
},
|
|
83
132
|
"lint-staged": {
|
|
84
133
|
"*.{js,jsx}": [
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from "vitest"
|
|
2
|
+
import { mkdtempSync, rmSync, readFileSync, readdirSync, existsSync } from "fs"
|
|
3
|
+
import { tmpdir } from "os"
|
|
4
|
+
import path from "path"
|
|
5
|
+
import { fileURLToPath } from "url"
|
|
6
|
+
import { generateDocs } from "../../src/errors/generateDocs.js"
|
|
7
|
+
import { ERROR_DEFINITIONS } from "../../src/errors/registry.js"
|
|
8
|
+
|
|
9
|
+
// Framework-level (Tier 1) contract test: catches the "edited registry.js
|
|
10
|
+
// without regenerating docs" or "hand-edited a generated .md directly"
|
|
11
|
+
// mistake. Regenerates into a scratch dir (never touches the committed
|
|
12
|
+
// errors/ tree) and diffs the core-owned slice against what's checked in.
|
|
13
|
+
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
15
|
+
const __dirname = path.dirname(__filename)
|
|
16
|
+
|
|
17
|
+
// test/errors -> repo root /errors (the committed output)
|
|
18
|
+
const COMMITTED_ERRORS_DIR = path.resolve(__dirname, "../../../../errors")
|
|
19
|
+
|
|
20
|
+
// Shape of one errors/index.json entry, as written by generateDocs.js.
|
|
21
|
+
// registry.js/generateDocs.js stay plain JS until #420's source conversion —
|
|
22
|
+
// this type exists only to give the test file real safety in the meantime.
|
|
23
|
+
interface IndexEntry {
|
|
24
|
+
category: string
|
|
25
|
+
message: string
|
|
26
|
+
details: string
|
|
27
|
+
suggestedAction: string
|
|
28
|
+
docUrl: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let scratchDir: string | undefined
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
if (scratchDir) rmSync(scratchDir, { recursive: true, force: true })
|
|
35
|
+
scratchDir = undefined
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe("generated error docs match committed output (docs-drift check)", () => {
|
|
39
|
+
it("regenerating into a scratch dir produces byte-identical .md files for every core-owned code", () => {
|
|
40
|
+
scratchDir = mkdtempSync(path.join(tmpdir(), "catalyst-core-docs-drift-"))
|
|
41
|
+
generateDocs(scratchDir)
|
|
42
|
+
|
|
43
|
+
const mismatches: string[] = []
|
|
44
|
+
for (const [code, def] of Object.entries(ERROR_DEFINITIONS)) {
|
|
45
|
+
const relPath = path.join(def.category, `${code}.md`)
|
|
46
|
+
const committedPath = path.join(COMMITTED_ERRORS_DIR, relPath)
|
|
47
|
+
const scratchPath = path.join(scratchDir, relPath)
|
|
48
|
+
|
|
49
|
+
if (!existsSync(committedPath)) {
|
|
50
|
+
mismatches.push(`${relPath}: missing from committed errors/ — run generateDocs.js and commit the output`)
|
|
51
|
+
continue
|
|
52
|
+
}
|
|
53
|
+
const committed = readFileSync(committedPath, "utf8")
|
|
54
|
+
const fresh = readFileSync(scratchPath, "utf8")
|
|
55
|
+
if (committed !== fresh) {
|
|
56
|
+
mismatches.push(`${relPath}: committed content differs from what generateDocs() produces today`)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
expect(mismatches).toEqual([])
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it("committed index.json has an up-to-date entry for every core-owned code", () => {
|
|
63
|
+
const indexPath = path.join(COMMITTED_ERRORS_DIR, "index.json")
|
|
64
|
+
const committedIndex: Record<string, IndexEntry> = JSON.parse(readFileSync(indexPath, "utf8"))
|
|
65
|
+
|
|
66
|
+
const mismatches: string[] = []
|
|
67
|
+
for (const [code, def] of Object.entries(ERROR_DEFINITIONS)) {
|
|
68
|
+
const entry = committedIndex[code]
|
|
69
|
+
if (!entry) {
|
|
70
|
+
mismatches.push(`${code}: missing from committed errors/index.json`)
|
|
71
|
+
continue
|
|
72
|
+
}
|
|
73
|
+
if (entry.category !== def.category) mismatches.push(`${code}: index.json category "${entry.category}" !== registry "${def.category}"`)
|
|
74
|
+
if (entry.message !== def.defaultMessage) mismatches.push(`${code}: index.json message drifted from registry defaultMessage`)
|
|
75
|
+
if (entry.details !== def.defaultDetails) mismatches.push(`${code}: index.json details drifted from registry defaultDetails`)
|
|
76
|
+
if (entry.suggestedAction !== def.suggestedAction) mismatches.push(`${code}: index.json suggestedAction drifted from registry`)
|
|
77
|
+
}
|
|
78
|
+
expect(mismatches).toEqual([])
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it("committed index.json has no stale core-category entry for a code removed from the registry", () => {
|
|
82
|
+
const indexPath = path.join(COMMITTED_ERRORS_DIR, "index.json")
|
|
83
|
+
const committedIndex: Record<string, IndexEntry> = JSON.parse(readFileSync(indexPath, "utf8"))
|
|
84
|
+
const ownedCategories = new Set(Object.values(ERROR_DEFINITIONS).map((d) => d.category))
|
|
85
|
+
|
|
86
|
+
const stale: string[] = []
|
|
87
|
+
for (const [code, entry] of Object.entries(committedIndex)) {
|
|
88
|
+
if (ownedCategories.has(entry.category) && !(code in ERROR_DEFINITIONS)) {
|
|
89
|
+
stale.push(`${code}: stale entry in errors/index.json — its category ("${entry.category}") is core-owned but this code no longer exists in the registry`)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
expect(stale).toEqual([])
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it("committed errors/ tree has no stray core-category .md files not backed by a current registry entry", () => {
|
|
96
|
+
const ownedCategories = new Set(Object.values(ERROR_DEFINITIONS).map((d) => d.category))
|
|
97
|
+
const knownFiles = new Set(
|
|
98
|
+
Object.entries(ERROR_DEFINITIONS).map(([code, def]) => path.join(def.category, `${code}.md`))
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
const stray: string[] = []
|
|
102
|
+
for (const category of ownedCategories) {
|
|
103
|
+
const dir = path.join(COMMITTED_ERRORS_DIR, category)
|
|
104
|
+
if (!existsSync(dir)) continue
|
|
105
|
+
for (const file of readdirSync(dir)) {
|
|
106
|
+
if (!file.endsWith(".md")) continue
|
|
107
|
+
const rel = path.join(category, file)
|
|
108
|
+
if (!knownFiles.has(rel)) stray.push(rel)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
expect(stray).toEqual([])
|
|
112
|
+
})
|
|
113
|
+
})
|