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
|
@@ -6,6 +6,7 @@ import Foundation
|
|
|
6
6
|
import UIKit
|
|
7
7
|
import AVFoundation
|
|
8
8
|
import os
|
|
9
|
+
import CatalystCoreLogic
|
|
9
10
|
|
|
10
11
|
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: "ImageHandler")
|
|
11
12
|
|
|
@@ -20,7 +21,7 @@ class ImageHandler: NSObject {
|
|
|
20
21
|
weak var delegate: ImageHandlerDelegate?
|
|
21
22
|
private var currentPhotoURL: URL?
|
|
22
23
|
private var currentCameraOptions: [String: Any] = [:]
|
|
23
|
-
|
|
24
|
+
|
|
24
25
|
// Helper to check camera permissions
|
|
25
26
|
func checkCameraPermission(completion: @escaping (Bool) -> Void) {
|
|
26
27
|
switch AVCaptureDevice.authorizationStatus(for: .video) {
|
|
@@ -38,36 +39,36 @@ class ImageHandler: NSObject {
|
|
|
38
39
|
completion(false)
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
// Create a file for saving an image
|
|
43
44
|
func createImageFile() -> URL {
|
|
44
45
|
let dateFormatter = DateFormatter()
|
|
45
46
|
dateFormatter.dateFormat = "yyyyMMdd_HHmmss"
|
|
46
47
|
let timeStamp = dateFormatter.string(from: Date())
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
49
50
|
let imageDirectory = documentsDirectory.appendingPathComponent("Pictures", isDirectory: true)
|
|
50
|
-
|
|
51
|
+
|
|
51
52
|
// Create directory if it doesn't exist
|
|
52
53
|
if !FileManager.default.fileExists(atPath: imageDirectory.path) {
|
|
53
54
|
try? FileManager.default.createDirectory(at: imageDirectory, withIntermediateDirectories: true)
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
+
|
|
56
57
|
return imageDirectory.appendingPathComponent("JPEG_\(timeStamp)_.jpg")
|
|
57
58
|
}
|
|
58
|
-
|
|
59
|
+
|
|
59
60
|
// Create a simple mock image
|
|
60
61
|
func createMockImage() -> UIImage? {
|
|
61
62
|
let size = CGSize(width: 1024, height: 768)
|
|
62
63
|
UIGraphicsBeginImageContextWithOptions(size, false, 1.0)
|
|
63
64
|
defer { UIGraphicsEndImageContext() }
|
|
64
|
-
|
|
65
|
+
|
|
65
66
|
// Fill with a gradient background
|
|
66
67
|
let context = UIGraphicsGetCurrentContext()!
|
|
67
68
|
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
|
68
69
|
let colors = [UIColor.systemBlue.cgColor, UIColor.systemTeal.cgColor]
|
|
69
70
|
let locations: [CGFloat] = [0.0, 1.0]
|
|
70
|
-
|
|
71
|
+
|
|
71
72
|
if let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: locations) {
|
|
72
73
|
context.drawLinearGradient(
|
|
73
74
|
gradient,
|
|
@@ -76,14 +77,14 @@ class ImageHandler: NSObject {
|
|
|
76
77
|
options: []
|
|
77
78
|
)
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
+
|
|
80
81
|
// Add text "Mock Camera Image"
|
|
81
82
|
let text = "Mock Camera Image"
|
|
82
83
|
let attributes: [NSAttributedString.Key: Any] = [
|
|
83
84
|
.font: UIFont.boldSystemFont(ofSize: 48),
|
|
84
85
|
.foregroundColor: UIColor.white
|
|
85
86
|
]
|
|
86
|
-
|
|
87
|
+
|
|
87
88
|
let textSize = text.size(withAttributes: attributes)
|
|
88
89
|
let textRect = CGRect(
|
|
89
90
|
x: (size.width - textSize.width) / 2,
|
|
@@ -91,19 +92,19 @@ class ImageHandler: NSObject {
|
|
|
91
92
|
width: textSize.width,
|
|
92
93
|
height: textSize.height
|
|
93
94
|
)
|
|
94
|
-
|
|
95
|
+
|
|
95
96
|
text.draw(in: textRect, withAttributes: attributes)
|
|
96
|
-
|
|
97
|
+
|
|
97
98
|
// Add current date/time
|
|
98
99
|
let dateFormatter = DateFormatter()
|
|
99
100
|
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
|
|
100
101
|
let dateText = dateFormatter.string(from: Date())
|
|
101
|
-
|
|
102
|
+
|
|
102
103
|
let dateAttributes: [NSAttributedString.Key: Any] = [
|
|
103
104
|
.font: UIFont.systemFont(ofSize: 24),
|
|
104
105
|
.foregroundColor: UIColor.white
|
|
105
106
|
]
|
|
106
|
-
|
|
107
|
+
|
|
107
108
|
let dateTextSize = dateText.size(withAttributes: dateAttributes)
|
|
108
109
|
let dateTextRect = CGRect(
|
|
109
110
|
x: (size.width - dateTextSize.width) / 2,
|
|
@@ -111,12 +112,12 @@ class ImageHandler: NSObject {
|
|
|
111
112
|
width: dateTextSize.width,
|
|
112
113
|
height: dateTextSize.height
|
|
113
114
|
)
|
|
114
|
-
|
|
115
|
+
|
|
115
116
|
dateText.draw(in: dateTextRect, withAttributes: dateAttributes)
|
|
116
|
-
|
|
117
|
+
|
|
117
118
|
return UIGraphicsGetImageFromCurrentImageContext()
|
|
118
119
|
}
|
|
119
|
-
|
|
120
|
+
|
|
120
121
|
// Save actual camera captured image and notify delegate
|
|
121
122
|
func saveActualCameraImage(_ image: UIImage) {
|
|
122
123
|
let fileURL = createImageFile()
|
|
@@ -159,7 +160,7 @@ class ImageHandler: NSObject {
|
|
|
159
160
|
delegate?.imageHandler(self, didFailWithError: error)
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
|
-
|
|
163
|
+
|
|
163
164
|
// Present camera
|
|
164
165
|
func presentCamera(from viewController: UIViewController, options: [String: Any] = [:]) {
|
|
165
166
|
logger.debug("presentCamera called with options: \(options)")
|
|
@@ -186,7 +187,7 @@ class ImageHandler: NSObject {
|
|
|
186
187
|
presentCameraUnavailableAlert(from: viewController)
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
|
-
|
|
190
|
+
|
|
190
191
|
// Set up notification observer for AVCaptureSession errors
|
|
191
192
|
private func setupAVCaptureErrorObserver() {
|
|
192
193
|
NotificationCenter.default.addObserver(
|
|
@@ -196,14 +197,14 @@ class ImageHandler: NSObject {
|
|
|
196
197
|
object: nil
|
|
197
198
|
)
|
|
198
199
|
}
|
|
199
|
-
|
|
200
|
+
|
|
200
201
|
// Handle AVCaptureSession runtime errors
|
|
201
202
|
@objc private func handleAVCaptureSessionRuntimeError(_ notification: Notification) {
|
|
202
203
|
if let error = notification.userInfo?[AVCaptureSessionErrorKey] as? NSError {
|
|
203
204
|
// Check for specific error code
|
|
204
205
|
if error.domain == AVFoundationErrorDomain && error.code == -11800 {
|
|
205
206
|
logger.debug("Detected AVFoundation error -11800, generating mock image")
|
|
206
|
-
|
|
207
|
+
|
|
207
208
|
// Dismiss any presented view controllers if needed
|
|
208
209
|
if let rootViewController = topMostRootViewController(),
|
|
209
210
|
let presented = rootViewController.presentedViewController as? UIImagePickerController {
|
|
@@ -217,20 +218,20 @@ class ImageHandler: NSObject {
|
|
|
217
218
|
}
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
|
-
|
|
221
|
+
|
|
221
222
|
private func topMostRootViewController() -> UIViewController? {
|
|
222
223
|
let windowScenes = UIApplication.shared.connectedScenes
|
|
223
224
|
.compactMap { $0 as? UIWindowScene }
|
|
224
|
-
|
|
225
|
+
|
|
225
226
|
if let keyWindow = windowScenes
|
|
226
227
|
.flatMap({ $0.windows })
|
|
227
228
|
.first(where: { $0.isKeyWindow }) {
|
|
228
229
|
return keyWindow.rootViewController
|
|
229
230
|
}
|
|
230
|
-
|
|
231
|
+
|
|
231
232
|
return windowScenes.first?.windows.first?.rootViewController
|
|
232
233
|
}
|
|
233
|
-
|
|
234
|
+
|
|
234
235
|
// Present photo library
|
|
235
236
|
func presentPhotoLibrary(from viewController: UIViewController) {
|
|
236
237
|
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
|
|
@@ -238,7 +239,7 @@ class ImageHandler: NSObject {
|
|
|
238
239
|
imagePicker.delegate = self
|
|
239
240
|
imagePicker.sourceType = .photoLibrary
|
|
240
241
|
imagePicker.allowsEditing = false
|
|
241
|
-
|
|
242
|
+
|
|
242
243
|
DispatchQueue.main.async {
|
|
243
244
|
viewController.present(imagePicker, animated: true)
|
|
244
245
|
}
|
|
@@ -247,7 +248,7 @@ class ImageHandler: NSObject {
|
|
|
247
248
|
delegate?.imageHandler(self, didFailWithError: error)
|
|
248
249
|
}
|
|
249
250
|
}
|
|
250
|
-
|
|
251
|
+
|
|
251
252
|
// Show camera unavailable alert
|
|
252
253
|
private func presentCameraUnavailableAlert(from viewController: UIViewController) {
|
|
253
254
|
let isSimulator = isRunningOnSimulator()
|
|
@@ -261,7 +262,7 @@ class ImageHandler: NSObject {
|
|
|
261
262
|
message: message,
|
|
262
263
|
preferredStyle: .alert
|
|
263
264
|
)
|
|
264
|
-
|
|
265
|
+
|
|
265
266
|
alert.addAction(UIAlertAction(title: "Yes", style: .default) { [weak self] _ in
|
|
266
267
|
guard let self = self else { return }
|
|
267
268
|
if isSimulator {
|
|
@@ -272,17 +273,17 @@ class ImageHandler: NSObject {
|
|
|
272
273
|
self.presentPhotoLibrary(from: viewController)
|
|
273
274
|
}
|
|
274
275
|
})
|
|
275
|
-
|
|
276
|
+
|
|
276
277
|
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { [weak self] _ in
|
|
277
278
|
guard let self = self else { return }
|
|
278
279
|
self.delegate?.imageHandlerDidCancel(self)
|
|
279
280
|
})
|
|
280
|
-
|
|
281
|
+
|
|
281
282
|
DispatchQueue.main.async {
|
|
282
283
|
viewController.present(alert, animated: true)
|
|
283
284
|
}
|
|
284
285
|
}
|
|
285
|
-
|
|
286
|
+
|
|
286
287
|
// Present permission alert
|
|
287
288
|
func presentPermissionAlert(from viewController: UIViewController) {
|
|
288
289
|
let alert = UIAlertController(
|
|
@@ -290,23 +291,23 @@ class ImageHandler: NSObject {
|
|
|
290
291
|
message: "Please allow camera access in Settings to use this feature",
|
|
291
292
|
preferredStyle: .alert
|
|
292
293
|
)
|
|
293
|
-
|
|
294
|
+
|
|
294
295
|
alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
|
|
295
296
|
if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
|
|
296
297
|
UIApplication.shared.open(settingsURL)
|
|
297
298
|
}
|
|
298
299
|
})
|
|
299
|
-
|
|
300
|
+
|
|
300
301
|
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { [weak self] _ in
|
|
301
302
|
guard let self = self else { return }
|
|
302
303
|
self.delegate?.imageHandlerDidCancel(self)
|
|
303
304
|
})
|
|
304
|
-
|
|
305
|
+
|
|
305
306
|
DispatchQueue.main.async {
|
|
306
307
|
viewController.present(alert, animated: true)
|
|
307
308
|
}
|
|
308
309
|
}
|
|
309
|
-
|
|
310
|
+
|
|
310
311
|
// Apply camera options to UIImagePickerController
|
|
311
312
|
private func applyCameraOptions(to imagePicker: UIImagePickerController, options: [String: Any]) {
|
|
312
313
|
logger.debug("Applying camera options: \(options)")
|
|
@@ -440,7 +441,7 @@ class ImageHandler: NSObject {
|
|
|
440
441
|
|
|
441
442
|
// MARK: - UIImagePickerControllerDelegate
|
|
442
443
|
extension ImageHandler: UIImagePickerControllerDelegate & UINavigationControllerDelegate {
|
|
443
|
-
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey
|
|
444
|
+
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
|
|
444
445
|
picker.dismiss(animated: true)
|
|
445
446
|
|
|
446
447
|
// Process actual camera capture or use mock for simulator
|
|
@@ -452,16 +453,16 @@ extension ImageHandler: UIImagePickerControllerDelegate & UINavigationController
|
|
|
452
453
|
saveMockImage()
|
|
453
454
|
}
|
|
454
455
|
}
|
|
455
|
-
|
|
456
|
+
|
|
456
457
|
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
|
457
458
|
picker.dismiss(animated: true)
|
|
458
459
|
logger.debug("Camera capture cancelled")
|
|
459
460
|
delegate?.imageHandlerDidCancel(self)
|
|
460
461
|
}
|
|
461
|
-
|
|
462
|
+
|
|
462
463
|
func imagePickerController(_ picker: UIImagePickerController, didFailWithError error: Error) {
|
|
463
464
|
picker.dismiss(animated: true)
|
|
464
|
-
|
|
465
|
+
|
|
465
466
|
let nsError = error as NSError
|
|
466
467
|
// Check for specific AVFoundation error
|
|
467
468
|
if nsError.domain == AVFoundationErrorDomain && nsError.code == -11800 {
|
|
@@ -8,7 +8,7 @@ final class ResourceURLProtocol: URLProtocol {
|
|
|
8
8
|
private var dataTask: URLSessionDataTask?
|
|
9
9
|
private static let handledKey = "ResourceURLProtocolHandled"
|
|
10
10
|
private static var isRegistered = false
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
// MARK: - Protocol Registration
|
|
13
13
|
static func register() {
|
|
14
14
|
guard !isRegistered else { return }
|
|
@@ -16,13 +16,13 @@ final class ResourceURLProtocol: URLProtocol {
|
|
|
16
16
|
isRegistered = true
|
|
17
17
|
logger.info("✅ ResourceURLProtocol registered for GET cache interception")
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
static func unregister() {
|
|
21
21
|
guard isRegistered else { return }
|
|
22
22
|
URLProtocol.unregisterClass(self)
|
|
23
23
|
isRegistered = false
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
// MARK: - URLProtocol
|
|
27
27
|
override class func canInit(with request: URLRequest) -> Bool {
|
|
28
28
|
guard let url = request.url else {
|
|
@@ -65,7 +65,7 @@ final class ResourceURLProtocol: URLProtocol {
|
|
|
65
65
|
override class func canonicalRequest(for request: URLRequest) -> URLRequest {
|
|
66
66
|
return request
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
override func startLoading() {
|
|
70
70
|
guard let url = request.url else {
|
|
71
71
|
logger.error("❌ No URL in request")
|
|
@@ -83,23 +83,23 @@ final class ResourceURLProtocol: URLProtocol {
|
|
|
83
83
|
return
|
|
84
84
|
}
|
|
85
85
|
URLProtocol.setProperty(true, forKey: ResourceURLProtocol.handledKey, in: mutableRequest)
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
Task { [weak self] in
|
|
88
88
|
guard let self else { return }
|
|
89
89
|
do {
|
|
90
90
|
// Try to load from cache first
|
|
91
91
|
let cacheableRequest = CacheManager.shared.createCacheableRequest(from: url)
|
|
92
92
|
let (cachedData, cacheState, mimeType) = await CacheManager.shared.getCachedResource(for: cacheableRequest)
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
if let cachedData = cachedData, cacheState != .expired {
|
|
95
95
|
logger.info("✅ Serving cached content for: \(url.absoluteString)")
|
|
96
|
-
|
|
96
|
+
|
|
97
97
|
// Create response
|
|
98
98
|
var headers: [String: String] = [:]
|
|
99
99
|
if let mimeType = mimeType {
|
|
100
100
|
headers["Content-Type"] = mimeType
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
|
|
103
103
|
guard let response = HTTPURLResponse(
|
|
104
104
|
url: url,
|
|
105
105
|
statusCode: 200,
|
|
@@ -113,7 +113,7 @@ final class ResourceURLProtocol: URLProtocol {
|
|
|
113
113
|
}
|
|
114
114
|
return
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
// Send cached response
|
|
118
118
|
await MainActor.run { [weak self] in
|
|
119
119
|
guard let self else { return }
|
|
@@ -123,23 +123,23 @@ final class ResourceURLProtocol: URLProtocol {
|
|
|
123
123
|
}
|
|
124
124
|
return
|
|
125
125
|
}
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
// If not in cache or expired, load from network using URLSession
|
|
128
128
|
logger.info("🌐 Fetching from network: \(url.absoluteString)")
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
let config = URLSessionConfiguration.ephemeral
|
|
131
131
|
config.requestCachePolicy = .reloadIgnoringLocalCacheData
|
|
132
132
|
config.protocolClasses = []
|
|
133
133
|
let session = URLSession(configuration: config)
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
let (data, response) = try await session.data(for: mutableRequest as URLRequest)
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
if let httpResponse = response as? HTTPURLResponse {
|
|
138
138
|
// Cache the response if it's valid
|
|
139
139
|
if CacheManager.shared.isCacheableResponse(httpResponse, for: request) {
|
|
140
140
|
CacheManager.shared.storeCachedResponse(httpResponse, data: data, for: request)
|
|
141
141
|
}
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
// Send response to client
|
|
144
144
|
await MainActor.run { [weak self] in
|
|
145
145
|
guard let self else { return }
|
|
@@ -157,7 +157,7 @@ final class ResourceURLProtocol: URLProtocol {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
|
-
|
|
160
|
+
|
|
161
161
|
override func stopLoading() {
|
|
162
162
|
dataTask?.cancel()
|
|
163
163
|
}
|
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
//
|
|
8
8
|
|
|
9
9
|
import WebKit
|
|
10
|
+
import CatalystCoreLogic
|
|
10
11
|
|
|
11
12
|
public enum WebKitConfig {
|
|
12
13
|
@available(iOS, introduced: 11.0, deprecated: 15.0, message: "Custom WKProcessPool instances have no effect on iOS 15+.")
|
|
13
14
|
public static let sharedProcessPool = WKProcessPool()
|
|
14
|
-
|
|
15
|
+
|
|
15
16
|
private static var legacyPrewarmedWebView: WKWebView?
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
/// Recreate the legacy shared process pool behavior for iOS versions where it still matters.
|
|
18
19
|
@discardableResult
|
|
19
20
|
public static func prewarmProcessPoolIfNeeded() -> WKWebView? {
|
|
@@ -31,7 +32,7 @@ public enum WebKitConfig {
|
|
|
31
32
|
return legacyPrewarmedWebView
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
/// Apply the shared process pool only on OS versions where Apple still honors it.
|
|
36
37
|
public static func applySharedProcessPoolIfNeeded(to configuration: WKWebViewConfiguration) {
|
|
37
38
|
if #available(iOS 15, *) {
|
|
@@ -14,6 +14,7 @@ import os
|
|
|
14
14
|
import UserNotifications
|
|
15
15
|
#if canImport(GoogleSignIn)
|
|
16
16
|
import GoogleSignIn
|
|
17
|
+
import CatalystCoreLogic
|
|
17
18
|
#endif
|
|
18
19
|
|
|
19
20
|
private let commandLogger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: CatalystConstants.Logging.Categories.commandHandler)
|
|
@@ -28,6 +29,10 @@ protocol BridgeCommandHandlerDelegate: AnyObject {
|
|
|
28
29
|
|
|
29
30
|
// MARK: - Bridge Command Handler
|
|
30
31
|
|
|
32
|
+
// One class handling every JS-callable native command; splitting it would
|
|
33
|
+
// only move the surface into extensions in the same file. Tracked for a
|
|
34
|
+
// real decomposition separately.
|
|
35
|
+
// swiftlint:disable:next type_body_length
|
|
31
36
|
class BridgeCommandHandler {
|
|
32
37
|
|
|
33
38
|
private weak var viewController: UIViewController?
|
|
@@ -717,7 +722,7 @@ class BridgeCommandHandler {
|
|
|
717
722
|
let autoCancel = json["autoCancel"] as? Bool ?? true
|
|
718
723
|
let dataDict = json["data"] as? [String: Any]
|
|
719
724
|
|
|
720
|
-
var actionsConfig: [NotificationAction]?
|
|
725
|
+
var actionsConfig: [NotificationAction]?
|
|
721
726
|
if let actionsArray = json["actions"] as? [[String: Any]] {
|
|
722
727
|
actionsConfig = actionsArray.compactMap { item in
|
|
723
728
|
let title = item["title"] as? String ?? ""
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import Foundation
|
|
10
10
|
import UIKit
|
|
11
11
|
import os
|
|
12
|
+
import CatalystCoreLogic
|
|
12
13
|
|
|
13
14
|
private let fileLogger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: CatalystConstants.Logging.Categories.fileHandler)
|
|
14
15
|
|
|
@@ -303,7 +304,7 @@ class BridgeFileHandler: NSObject {
|
|
|
303
304
|
popoverController.permittedArrowDirections = []
|
|
304
305
|
}
|
|
305
306
|
|
|
306
|
-
shareController.completionWithItemsHandler = { [weak self]
|
|
307
|
+
shareController.completionWithItemsHandler = { [weak self] _, completed, _, error in
|
|
307
308
|
if let error = error {
|
|
308
309
|
fileLogger.error("Sharing failed: \(error.localizedDescription)")
|
|
309
310
|
self?.delegate?.sendErrorCallback(eventName: "ON_INTENT_ERROR", error: "Sharing failed: \(error.localizedDescription)", code: "SHARING_ERROR")
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import Foundation
|
|
10
10
|
import WebKit
|
|
11
11
|
import os
|
|
12
|
+
import CatalystCoreLogic
|
|
12
13
|
|
|
13
14
|
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: CatalystConstants.Logging.Categories.javascriptInterface)
|
|
14
15
|
|
|
@@ -146,4 +147,4 @@ class BridgeJavaScriptInterface {
|
|
|
146
147
|
"component": "BridgeJavaScriptInterface"
|
|
147
148
|
])
|
|
148
149
|
}
|
|
149
|
-
}
|
|
150
|
+
}
|
|
@@ -10,6 +10,7 @@ import Foundation
|
|
|
10
10
|
import WebKit
|
|
11
11
|
import JSONSchema
|
|
12
12
|
import os
|
|
13
|
+
import CatalystCoreLogic
|
|
13
14
|
|
|
14
15
|
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: CatalystConstants.Logging.Categories.messageValidator)
|
|
15
16
|
|
|
@@ -220,7 +221,6 @@ class BridgeMessageValidator {
|
|
|
220
221
|
]
|
|
221
222
|
]
|
|
222
223
|
|
|
223
|
-
|
|
224
224
|
// MARK: - Public Validation Interface
|
|
225
225
|
|
|
226
226
|
static func validate(message: WKScriptMessage) -> BridgeValidationResult {
|
|
@@ -583,8 +583,7 @@ class BridgeMessageValidator {
|
|
|
583
583
|
if
|
|
584
584
|
let minFilesValue = object["minFiles"] as? NSNumber,
|
|
585
585
|
let maxFilesValue = object["maxFiles"] as? NSNumber,
|
|
586
|
-
minFilesValue.intValue > maxFilesValue.intValue
|
|
587
|
-
{
|
|
586
|
+
minFilesValue.intValue > maxFilesValue.intValue {
|
|
588
587
|
logger.error("minFiles cannot be greater than maxFiles for pickFile command")
|
|
589
588
|
return BridgeValidationError(
|
|
590
589
|
message: "minFiles cannot be greater than maxFiles",
|
|
@@ -596,8 +595,7 @@ class BridgeMessageValidator {
|
|
|
596
595
|
if
|
|
597
596
|
let minSizeValue = object["minFileSize"] as? NSNumber,
|
|
598
597
|
let maxSizeValue = object["maxFileSize"] as? NSNumber,
|
|
599
|
-
minSizeValue.int64Value > maxSizeValue.int64Value
|
|
600
|
-
{
|
|
598
|
+
minSizeValue.int64Value > maxSizeValue.int64Value {
|
|
601
599
|
logger.error("minFileSize cannot be greater than maxFileSize for pickFile command")
|
|
602
600
|
return BridgeValidationError(
|
|
603
601
|
message: "minFileSize cannot be greater than maxFileSize",
|
|
@@ -10,6 +10,7 @@ import UIKit
|
|
|
10
10
|
import AVFoundation
|
|
11
11
|
import os
|
|
12
12
|
import UserNotifications
|
|
13
|
+
import CatalystCoreLogic
|
|
13
14
|
|
|
14
15
|
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: "NativeBridge")
|
|
15
16
|
|
|
@@ -105,7 +106,6 @@ class NativeBridge: NSObject, BridgeCommandHandlerDelegate, BridgeFileHandlerDel
|
|
|
105
106
|
}
|
|
106
107
|
self.transitionManager = tm
|
|
107
108
|
|
|
108
|
-
|
|
109
109
|
setupNotificationNavigationHandler()
|
|
110
110
|
|
|
111
111
|
let initTime = (CFAbsoluteTimeGetCurrent() - initStart) * 1000
|
|
@@ -174,7 +174,7 @@ class NativeBridge: NSObject, BridgeCommandHandlerDelegate, BridgeFileHandlerDel
|
|
|
174
174
|
let registerTime = (CFAbsoluteTimeGetCurrent() - registerStart) * 1000
|
|
175
175
|
logWithTimestamp("✅ NativeBridge registered (took \(String(format: "%.2f", registerTime))ms)")
|
|
176
176
|
}
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
// Unregister to prevent memory leaks
|
|
179
179
|
func unregister() {
|
|
180
180
|
guard isRegistered else { return }
|
|
@@ -182,7 +182,6 @@ class NativeBridge: NSObject, BridgeCommandHandlerDelegate, BridgeFileHandlerDel
|
|
|
182
182
|
messageHandlerProxy = nil
|
|
183
183
|
isRegistered = false
|
|
184
184
|
|
|
185
|
-
|
|
186
185
|
if let listenerId = networkStatusListenerId {
|
|
187
186
|
NetworkMonitor.shared.removeListener(listenerId)
|
|
188
187
|
networkStatusListenerId = nil
|
|
@@ -214,8 +213,7 @@ class NativeBridge: NSObject, BridgeCommandHandlerDelegate, BridgeFileHandlerDel
|
|
|
214
213
|
let status = NetworkMonitor.shared.currentStatus
|
|
215
214
|
sendNetworkStatusUpdate(status)
|
|
216
215
|
}
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
|
|
219
217
|
// MARK: - JavaScript Interface Delegation
|
|
220
218
|
|
|
221
219
|
// Delegate JavaScript methods to the dedicated interface
|
|
@@ -236,7 +234,6 @@ class NativeBridge: NSObject, BridgeCommandHandlerDelegate, BridgeFileHandlerDel
|
|
|
236
234
|
internal func sendErrorCallback(eventName: String, error: String, code: String) {
|
|
237
235
|
jsInterface.sendErrorCallback(eventName: eventName, error: error, code: code)
|
|
238
236
|
}
|
|
239
|
-
|
|
240
237
|
|
|
241
238
|
// MARK: - BridgeFileHandlerDelegate
|
|
242
239
|
|
|
@@ -275,8 +272,11 @@ extension NativeBridge: WKScriptMessageHandler {
|
|
|
275
272
|
|
|
276
273
|
// MARK: - Command Execution
|
|
277
274
|
|
|
278
|
-
// Secure command execution with comprehensive error handling
|
|
279
|
-
//
|
|
275
|
+
// Secure command execution with comprehensive error handling. All
|
|
276
|
+
// native functionality is accessed through this controlled entry
|
|
277
|
+
// point: a flat dispatch `switch` over every JS-callable command —
|
|
278
|
+
// the branch count is the command count, not incidental complexity.
|
|
279
|
+
// swiftlint:disable:next cyclomatic_complexity
|
|
280
280
|
private func executeCommand(_ command: String, params: Any?) {
|
|
281
281
|
switch command {
|
|
282
282
|
case "openCamera":
|
|
@@ -400,8 +400,8 @@ extension NativeBridge: WKScriptMessageHandler {
|
|
|
400
400
|
var autoZoom = false
|
|
401
401
|
var initialZoom: Float = 1.0
|
|
402
402
|
var scanFormat = "all"
|
|
403
|
-
var fpsMin: Int?
|
|
404
|
-
var fpsMax: Int?
|
|
403
|
+
var fpsMin: Int?
|
|
404
|
+
var fpsMax: Int?
|
|
405
405
|
|
|
406
406
|
if let dict = jsonStringToDict(params) {
|
|
407
407
|
logger.info("📹 startVideoStream — dict keys: \(dict.keys.sorted().joined(separator: ", "))")
|
|
@@ -418,10 +418,18 @@ extension NativeBridge: WKScriptMessageHandler {
|
|
|
418
418
|
fpsMax = fps["max"] as? Int
|
|
419
419
|
}
|
|
420
420
|
} else {
|
|
421
|
-
|
|
421
|
+
let paramsType = type(of: params)
|
|
422
|
+
logger.warning("📹 startVideoStream — could not parse params (type=\(paramsType)), using defaults")
|
|
422
423
|
}
|
|
423
424
|
|
|
424
|
-
|
|
425
|
+
let fpsMinStr = String(describing: fpsMin)
|
|
426
|
+
let fpsMaxStr = String(describing: fpsMax)
|
|
427
|
+
logger.info(
|
|
428
|
+
"""
|
|
429
|
+
📹 startVideoStream — starting with facing=\(facing) autoZoom=\(autoZoom) \
|
|
430
|
+
initialZoom=\(initialZoom) format=\(scanFormat) fpsMin=\(fpsMinStr) fpsMax=\(fpsMaxStr)
|
|
431
|
+
"""
|
|
432
|
+
)
|
|
425
433
|
cam.start(facing: facing, autoZoom: autoZoom, initialZoom: initialZoom,
|
|
426
434
|
scanFormat: scanFormat, fpsMin: fpsMin, fpsMax: fpsMax)
|
|
427
435
|
}
|
|
@@ -527,7 +535,6 @@ extension NativeBridge: WKScriptMessageHandler {
|
|
|
527
535
|
}
|
|
528
536
|
}
|
|
529
537
|
|
|
530
|
-
|
|
531
538
|
// MARK: - Safe Area Methods
|
|
532
539
|
|
|
533
540
|
/// Get current safe area insets and send via callback
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import SwiftUI
|
|
2
|
+
import CatalystCoreLogic
|
|
2
3
|
|
|
3
4
|
public struct SplashView: View {
|
|
4
5
|
@ObservedObject var webViewModel: WebViewModel
|
|
@@ -40,7 +41,7 @@ public struct SplashView: View {
|
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
+
|
|
44
45
|
// Load custom splash screen image from Assets.xcassets (copied from public folder during build)
|
|
45
46
|
private func loadSplashImage() -> UIImage? {
|
|
46
47
|
// Try to load the launch screen image from Assets.xcassets
|
|
@@ -49,10 +50,10 @@ public struct SplashView: View {
|
|
|
49
50
|
print("✅ Loaded launch screen image from Assets.xcassets")
|
|
50
51
|
return image
|
|
51
52
|
}
|
|
52
|
-
|
|
53
|
+
|
|
53
54
|
// Fallback: Try to load using Bundle.main.path (for backward compatibility)
|
|
54
55
|
let imageExtensions = ["png", "jpg", "jpeg"]
|
|
55
|
-
|
|
56
|
+
|
|
56
57
|
for ext in imageExtensions {
|
|
57
58
|
if let path = Bundle.main.path(forResource: "launchscreen", ofType: ext),
|
|
58
59
|
let image = UIImage(contentsOfFile: path) {
|
|
@@ -60,7 +61,7 @@ public struct SplashView: View {
|
|
|
60
61
|
return image
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
|
-
|
|
64
|
+
|
|
64
65
|
print("❌ No launch screen image found")
|
|
65
66
|
return nil
|
|
66
67
|
}
|
|
@@ -88,7 +89,7 @@ extension Color {
|
|
|
88
89
|
.sRGB,
|
|
89
90
|
red: Double(r) / 255,
|
|
90
91
|
green: Double(g) / 255,
|
|
91
|
-
blue:
|
|
92
|
+
blue: Double(b) / 255,
|
|
92
93
|
opacity: Double(a) / 255
|
|
93
94
|
)
|
|
94
95
|
}
|