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
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import CryptoKit
|
|
3
3
|
import os
|
|
4
|
+
import CatalystCoreLogic
|
|
4
5
|
|
|
5
6
|
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: "CacheManager")
|
|
6
7
|
|
|
7
8
|
public final class CacheManager {
|
|
8
9
|
public static let shared = CacheManager()
|
|
9
10
|
private let queue = DispatchQueue(label: "com.app.cachemanager", attributes: .concurrent)
|
|
10
|
-
|
|
11
|
+
|
|
11
12
|
enum CacheState {
|
|
12
13
|
case fresh // Content is within fresh window
|
|
13
14
|
case stale // Content is in stale-while-revalidate window
|
|
14
15
|
case expired // Content is expired
|
|
15
16
|
}
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
private struct CachePolicy {
|
|
18
19
|
static let freshWindow: TimeInterval = CatalystConstants.Cache.freshWindow
|
|
19
20
|
static let staleWindow: TimeInterval = CatalystConstants.Cache.staleWindow
|
|
@@ -25,13 +26,13 @@ public final class CacheManager {
|
|
|
25
26
|
private var resourceCache: [String: CachedResource] = [:]
|
|
26
27
|
private let cacheDirectory: URL
|
|
27
28
|
private let compiledCachePatterns: [NSRegularExpression]
|
|
28
|
-
|
|
29
|
+
|
|
29
30
|
private struct CachedResource: Codable {
|
|
30
31
|
let data: Data
|
|
31
32
|
let timestamp: Date
|
|
32
33
|
let mimeType: String
|
|
33
34
|
let urlString: String
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
var response: HTTPURLResponse? {
|
|
36
37
|
guard let url = URL(string: urlString) else { return nil }
|
|
37
38
|
return HTTPURLResponse(
|
|
@@ -42,7 +43,7 @@ public final class CacheManager {
|
|
|
42
43
|
)
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
+
|
|
46
47
|
private init() {
|
|
47
48
|
let initStart = CFAbsoluteTimeGetCurrent()
|
|
48
49
|
|
|
@@ -87,7 +88,7 @@ public final class CacheManager {
|
|
|
87
88
|
|
|
88
89
|
loadCacheFromDisk()
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
+
|
|
91
92
|
private func loadCacheFromDisk() {
|
|
92
93
|
let loadStart = CFAbsoluteTimeGetCurrent()
|
|
93
94
|
|
|
@@ -117,17 +118,17 @@ public final class CacheManager {
|
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
|
-
|
|
121
|
+
|
|
121
122
|
private func getCacheKey(for url: URL) -> String {
|
|
122
123
|
let digest = SHA256.hash(data: Data(url.absoluteString.utf8))
|
|
123
124
|
return digest.map { String(format: "%02x", $0) }.joined()
|
|
124
125
|
}
|
|
125
|
-
|
|
126
|
+
|
|
126
127
|
private func getCacheFilePath(for url: URL) -> URL {
|
|
127
128
|
return cacheDirectory.appendingPathComponent(getCacheKey(for: url))
|
|
128
129
|
.appendingPathExtension("cache")
|
|
129
130
|
}
|
|
130
|
-
|
|
131
|
+
|
|
131
132
|
func shouldCacheURL(_ url: URL) -> Bool {
|
|
132
133
|
let urlString = url.absoluteString
|
|
133
134
|
|
|
@@ -146,10 +147,10 @@ public final class CacheManager {
|
|
|
146
147
|
guard let url = request.url else { return false }
|
|
147
148
|
return shouldCacheURL(url) || OfflineCacheService.shared.shouldCacheOfflineRouteSubresource(request)
|
|
148
149
|
}
|
|
149
|
-
|
|
150
|
+
|
|
150
151
|
private func getCacheState(for timestamp: Date) -> CacheState {
|
|
151
152
|
let age = Date().timeIntervalSince(timestamp)
|
|
152
|
-
|
|
153
|
+
|
|
153
154
|
if age <= CachePolicy.freshWindow {
|
|
154
155
|
return .fresh
|
|
155
156
|
} else if age <= (CachePolicy.freshWindow + CachePolicy.staleWindow) {
|
|
@@ -158,7 +159,7 @@ public final class CacheManager {
|
|
|
158
159
|
return .expired
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
|
-
|
|
162
|
+
|
|
162
163
|
func getCachedResource(for request: URLRequest) async -> (Data?, CacheState, String?) {
|
|
163
164
|
let manager = self
|
|
164
165
|
return await withCheckedContinuation { continuation in
|
|
@@ -167,22 +168,22 @@ public final class CacheManager {
|
|
|
167
168
|
continuation.resume(returning: (nil, .expired, nil))
|
|
168
169
|
return
|
|
169
170
|
}
|
|
170
|
-
|
|
171
|
+
|
|
171
172
|
if let cachedResource = manager.resourceCache[urlString] {
|
|
172
173
|
let state = manager.getCacheState(for: cachedResource.timestamp)
|
|
173
|
-
|
|
174
|
+
|
|
174
175
|
switch state {
|
|
175
176
|
case .fresh:
|
|
176
177
|
logger.info("🟢 Fresh cache hit for: \(urlString)")
|
|
177
178
|
continuation.resume(returning: (cachedResource.data, .fresh, cachedResource.mimeType))
|
|
178
|
-
|
|
179
|
+
|
|
179
180
|
case .stale:
|
|
180
181
|
logger.info("🟡 Stale cache hit for: \(urlString)")
|
|
181
182
|
Task {
|
|
182
183
|
await manager.revalidateResource(request: request)
|
|
183
184
|
}
|
|
184
185
|
continuation.resume(returning: (cachedResource.data, .stale, cachedResource.mimeType))
|
|
185
|
-
|
|
186
|
+
|
|
186
187
|
case .expired:
|
|
187
188
|
logger.info("🔴 Cache expired for: \(urlString)")
|
|
188
189
|
continuation.resume(returning: (nil, .expired, nil))
|
|
@@ -198,17 +199,17 @@ public final class CacheManager {
|
|
|
198
199
|
}
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
|
-
|
|
202
|
+
|
|
202
203
|
private func revalidateResource(request: URLRequest) async {
|
|
203
204
|
logger.info("🔄 Starting revalidation for: \(request.url?.absoluteString ?? "")")
|
|
204
205
|
let fetchStartMs = CatalystPerf.nativeTimeMs()
|
|
205
|
-
|
|
206
|
+
|
|
206
207
|
do {
|
|
207
208
|
let configuration = URLSessionConfiguration.ephemeral
|
|
208
209
|
configuration.protocolClasses = []
|
|
209
210
|
let networkSession = URLSession(configuration: configuration)
|
|
210
211
|
let (data, response) = try await networkSession.data(for: request)
|
|
211
|
-
|
|
212
|
+
|
|
212
213
|
if let httpResponse = response as? HTTPURLResponse,
|
|
213
214
|
isCacheableResponse(httpResponse, for: request) {
|
|
214
215
|
CatalystPerf.add([
|
|
@@ -227,20 +228,20 @@ public final class CacheManager {
|
|
|
227
228
|
logger.error("Revalidation failed: \(error.localizedDescription)")
|
|
228
229
|
}
|
|
229
230
|
}
|
|
230
|
-
|
|
231
|
+
|
|
231
232
|
func storeCachedResponse(_ response: HTTPURLResponse, data: Data, for request: URLRequest) {
|
|
232
233
|
queue.async(flags: .barrier) {
|
|
233
234
|
guard let url = request.url else { return }
|
|
234
|
-
|
|
235
|
+
|
|
235
236
|
let resource = CachedResource(
|
|
236
237
|
data: data,
|
|
237
238
|
timestamp: Date(),
|
|
238
239
|
mimeType: response.mimeType ?? "application/octet-stream",
|
|
239
240
|
urlString: url.absoluteString
|
|
240
241
|
)
|
|
241
|
-
|
|
242
|
+
|
|
242
243
|
self.resourceCache[url.absoluteString] = resource
|
|
243
|
-
|
|
244
|
+
|
|
244
245
|
let cachedResponse = CachedURLResponse(
|
|
245
246
|
response: response,
|
|
246
247
|
data: data,
|
|
@@ -248,7 +249,7 @@ public final class CacheManager {
|
|
|
248
249
|
storagePolicy: .allowed
|
|
249
250
|
)
|
|
250
251
|
self.session.configuration.urlCache?.storeCachedResponse(cachedResponse, for: request)
|
|
251
|
-
|
|
252
|
+
|
|
252
253
|
let cacheFile = self.getCacheFilePath(for: url)
|
|
253
254
|
do {
|
|
254
255
|
let encodedData = try JSONEncoder().encode(resource)
|
|
@@ -259,29 +260,29 @@ public final class CacheManager {
|
|
|
259
260
|
}
|
|
260
261
|
}
|
|
261
262
|
}
|
|
262
|
-
|
|
263
|
+
|
|
263
264
|
func clearCache() {
|
|
264
265
|
queue.async(flags: .barrier) {
|
|
265
266
|
self.resourceCache.removeAll()
|
|
266
267
|
self.session.configuration.urlCache?.removeAllCachedResponses()
|
|
267
|
-
|
|
268
|
+
|
|
268
269
|
try? FileManager.default.removeItem(at: self.cacheDirectory)
|
|
269
270
|
try? FileManager.default.createDirectory(
|
|
270
271
|
at: self.cacheDirectory,
|
|
271
272
|
withIntermediateDirectories: true,
|
|
272
273
|
attributes: nil
|
|
273
274
|
)
|
|
274
|
-
|
|
275
|
+
|
|
275
276
|
logger.info("All caches cleared")
|
|
276
277
|
}
|
|
277
278
|
}
|
|
278
|
-
|
|
279
|
+
|
|
279
280
|
func createCacheableRequest(from url: URL) -> URLRequest {
|
|
280
281
|
var request = URLRequest(url: url)
|
|
281
282
|
request.cachePolicy = .returnCacheDataElseLoad
|
|
282
283
|
return request
|
|
283
284
|
}
|
|
284
|
-
|
|
285
|
+
|
|
285
286
|
func isCacheableResponse(_ response: HTTPURLResponse) -> Bool {
|
|
286
287
|
guard let url = response.url else { return false }
|
|
287
288
|
return (200...299 ~= response.statusCode) && shouldCacheURL(url)
|
|
@@ -308,7 +309,7 @@ public final class CacheManager {
|
|
|
308
309
|
mimeType.hasSuffix("+json") ||
|
|
309
310
|
mimeType == "text/event-stream"
|
|
310
311
|
}
|
|
311
|
-
|
|
312
|
+
|
|
312
313
|
func getCacheStatistics() -> (memoryUsed: Int, diskUsed: Int) {
|
|
313
314
|
let memoryUsed = session.configuration.urlCache?.currentMemoryUsage ?? 0
|
|
314
315
|
|
|
@@ -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 logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: "CameraTransportUtils")
|
|
14
15
|
|
|
@@ -360,4 +361,4 @@ class CameraTransportUtils {
|
|
|
360
361
|
formatter.countStyle = .file
|
|
361
362
|
return formatter.string(fromByteCount: bytes)
|
|
362
363
|
}
|
|
363
|
-
}
|
|
364
|
+
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import Foundation
|
|
9
9
|
import UIKit
|
|
10
10
|
import os
|
|
11
|
+
import CatalystCoreLogic
|
|
11
12
|
|
|
12
13
|
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: "DeviceInfoUtils")
|
|
13
14
|
|
|
@@ -36,7 +37,6 @@ class DeviceInfoUtils {
|
|
|
36
37
|
]
|
|
37
38
|
|
|
38
39
|
deviceInfo["appInfo"] = ConfigConstants.appInfo
|
|
39
|
-
|
|
40
40
|
|
|
41
41
|
logger.debug("Device info retrieved successfully: \(deviceInfo.description)")
|
|
42
42
|
return deviceInfo
|
|
@@ -10,6 +10,7 @@ import UIKit
|
|
|
10
10
|
import UniformTypeIdentifiers
|
|
11
11
|
import PhotosUI
|
|
12
12
|
import os
|
|
13
|
+
import CatalystCoreLogic
|
|
13
14
|
|
|
14
15
|
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.app", category: "FilePickerHandler")
|
|
15
16
|
|
|
@@ -182,7 +183,7 @@ class FilePickerHandler: NSObject {
|
|
|
182
183
|
// Use photo picker if all MIME types are images/videos, else use document picker
|
|
183
184
|
let mimeTypes = options.mimeType.lowercased().split(separator: ",").map { $0.trimmingCharacters(in: .whitespaces) }
|
|
184
185
|
let allMedia = mimeTypes.allSatisfy { $0.hasPrefix("image/") || $0.hasPrefix("video/") }
|
|
185
|
-
|
|
186
|
+
|
|
186
187
|
if allMedia, #available(iOS 14.0, *) {
|
|
187
188
|
presentPhotoPicker(from: viewController, options: options)
|
|
188
189
|
} else {
|
|
@@ -197,7 +198,7 @@ class FilePickerHandler: NSObject {
|
|
|
197
198
|
let mimeTypes = options.mimeType.lowercased().split(separator: ",").map { $0.trimmingCharacters(in: .whitespaces) }
|
|
198
199
|
let hasImages = mimeTypes.contains { $0.hasPrefix("image/") }
|
|
199
200
|
let hasVideos = mimeTypes.contains { $0.hasPrefix("video/") }
|
|
200
|
-
|
|
201
|
+
|
|
201
202
|
var config = PHPickerConfiguration()
|
|
202
203
|
config.selectionLimit = options.selectionLimit
|
|
203
204
|
config.filter = (hasImages && hasVideos) ? .any(of: [.images, .videos]) : hasVideos ? .videos : .images
|
|
@@ -377,6 +378,9 @@ class FilePickerHandler: NSObject {
|
|
|
377
378
|
)
|
|
378
379
|
}
|
|
379
380
|
|
|
381
|
+
// A per-extension MIME lookup table expressed as a `switch` — the
|
|
382
|
+
// branch count is the number of extensions mapped.
|
|
383
|
+
// swiftlint:disable:next cyclomatic_complexity
|
|
380
384
|
private func getMimeType(for url: URL) -> String {
|
|
381
385
|
// First try UTType - only return if it has a preferredMIMEType
|
|
382
386
|
if let utType = UTType(filenameExtension: url.pathExtension),
|
|
@@ -386,7 +390,7 @@ class FilePickerHandler: NSObject {
|
|
|
386
390
|
|
|
387
391
|
// Fallback based on file extension with comprehensive mapping
|
|
388
392
|
let ext = url.pathExtension.lowercased()
|
|
389
|
-
|
|
393
|
+
|
|
390
394
|
switch ext {
|
|
391
395
|
// Images
|
|
392
396
|
case "jpg", "jpeg": return "image/jpeg"
|
|
@@ -399,7 +403,7 @@ class FilePickerHandler: NSObject {
|
|
|
399
403
|
case "heif": return "image/heif"
|
|
400
404
|
case "ico": return "image/x-icon"
|
|
401
405
|
case "tiff", "tif": return "image/tiff"
|
|
402
|
-
|
|
406
|
+
|
|
403
407
|
// Documents
|
|
404
408
|
case "pdf": return "application/pdf"
|
|
405
409
|
case "doc": return "application/msword"
|
|
@@ -408,25 +412,25 @@ class FilePickerHandler: NSObject {
|
|
|
408
412
|
case "xlsx": return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
409
413
|
case "ppt": return "application/vnd.ms-powerpoint"
|
|
410
414
|
case "pptx": return "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
411
|
-
|
|
415
|
+
|
|
412
416
|
// Text
|
|
413
417
|
case "txt": return "text/plain"
|
|
414
418
|
case "html", "htm": return "text/html"
|
|
415
419
|
case "css": return "text/css"
|
|
416
420
|
case "csv": return "text/csv"
|
|
417
|
-
|
|
421
|
+
|
|
418
422
|
// Data
|
|
419
423
|
case "json": return "application/json"
|
|
420
424
|
case "xml": return "application/xml"
|
|
421
425
|
case "js": return "application/javascript"
|
|
422
|
-
|
|
426
|
+
|
|
423
427
|
// Archives
|
|
424
428
|
case "zip": return "application/zip"
|
|
425
429
|
case "rar": return "application/x-rar-compressed"
|
|
426
430
|
case "7z": return "application/x-7z-compressed"
|
|
427
431
|
case "tar": return "application/x-tar"
|
|
428
432
|
case "gz": return "application/gzip"
|
|
429
|
-
|
|
433
|
+
|
|
430
434
|
// Video
|
|
431
435
|
case "mp4": return "video/mp4"
|
|
432
436
|
case "mov": return "video/quicktime"
|
|
@@ -435,7 +439,7 @@ class FilePickerHandler: NSObject {
|
|
|
435
439
|
case "mkv": return "video/x-matroska"
|
|
436
440
|
case "m4v": return "video/x-m4v"
|
|
437
441
|
case "flv": return "video/x-flv"
|
|
438
|
-
|
|
442
|
+
|
|
439
443
|
// Audio
|
|
440
444
|
case "mp3": return "audio/mpeg"
|
|
441
445
|
case "wav": return "audio/wav"
|
|
@@ -444,7 +448,7 @@ class FilePickerHandler: NSObject {
|
|
|
444
448
|
case "aac": return "audio/aac"
|
|
445
449
|
case "flac": return "audio/flac"
|
|
446
450
|
case "wma": return "audio/x-ms-wma"
|
|
447
|
-
|
|
451
|
+
|
|
448
452
|
default:
|
|
449
453
|
logger.warning("Unknown file extension '\(ext)', using application/octet-stream")
|
|
450
454
|
return "application/octet-stream"
|
|
@@ -517,7 +521,6 @@ class FilePickerHandler: NSObject {
|
|
|
517
521
|
}
|
|
518
522
|
}
|
|
519
523
|
|
|
520
|
-
|
|
521
524
|
private func processFileWithFrameworkServer(url: URL, metadata: FileMetadata) -> FileProcessingResult {
|
|
522
525
|
logger.info("Processing file with framework server transport")
|
|
523
526
|
|
|
@@ -821,14 +824,14 @@ extension FilePickerHandler: PHPickerViewControllerDelegate {
|
|
|
821
824
|
"public.png",
|
|
822
825
|
"public.gif"
|
|
823
826
|
]
|
|
824
|
-
|
|
827
|
+
|
|
825
828
|
// Check if any specific image type is available
|
|
826
829
|
for specificType in specificImageTypes {
|
|
827
830
|
if itemProvider.hasItemConformingToTypeIdentifier(specificType) {
|
|
828
831
|
return specificType
|
|
829
832
|
}
|
|
830
833
|
}
|
|
831
|
-
|
|
834
|
+
|
|
832
835
|
// Check for specific video types
|
|
833
836
|
let specificVideoTypes = [
|
|
834
837
|
UTType.mpeg4Movie.identifier,
|
|
@@ -836,13 +839,13 @@ extension FilePickerHandler: PHPickerViewControllerDelegate {
|
|
|
836
839
|
"public.mpeg-4",
|
|
837
840
|
"com.apple.quicktime-movie"
|
|
838
841
|
]
|
|
839
|
-
|
|
842
|
+
|
|
840
843
|
for specificType in specificVideoTypes {
|
|
841
844
|
if itemProvider.hasItemConformingToTypeIdentifier(specificType) {
|
|
842
845
|
return specificType
|
|
843
846
|
}
|
|
844
847
|
}
|
|
845
|
-
|
|
848
|
+
|
|
846
849
|
// Fall back to generic types
|
|
847
850
|
if itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
|
|
848
851
|
return UTType.image.identifier
|
|
@@ -971,7 +974,7 @@ extension FilePickerHandler: PHPickerViewControllerDelegate {
|
|
|
971
974
|
fileExtension = "dat"
|
|
972
975
|
logger.warning("Unknown type identifier '\(typeIdentifier)', defaulting to 'dat' extension")
|
|
973
976
|
}
|
|
974
|
-
|
|
977
|
+
|
|
975
978
|
logger.debug("Using file extension '\(fileExtension)' from type identifier fallback")
|
|
976
979
|
return fileExtension
|
|
977
980
|
}
|
|
@@ -980,12 +983,12 @@ extension FilePickerHandler: PHPickerViewControllerDelegate {
|
|
|
980
983
|
guard let utType = UTType(typeIdentifier) else {
|
|
981
984
|
return nil
|
|
982
985
|
}
|
|
983
|
-
|
|
986
|
+
|
|
984
987
|
// If UTType has a preferred MIME type, return it
|
|
985
988
|
if let mimeType = utType.preferredMIMEType {
|
|
986
989
|
return mimeType
|
|
987
990
|
}
|
|
988
|
-
|
|
991
|
+
|
|
989
992
|
// Handle generic types by checking if they conform to specific types
|
|
990
993
|
if utType.conforms(to: .jpeg) {
|
|
991
994
|
return "image/jpeg"
|
|
@@ -1000,7 +1003,7 @@ extension FilePickerHandler: PHPickerViewControllerDelegate {
|
|
|
1000
1003
|
} else if utType.conforms(to: .movie) {
|
|
1001
1004
|
return "video/mp4" // Default for generic videos
|
|
1002
1005
|
}
|
|
1003
|
-
|
|
1006
|
+
|
|
1004
1007
|
return nil
|
|
1005
1008
|
}
|
|
1006
1009
|
}
|