@legendapp/spark 0.0.1-next.2 → 0.0.1-next.4
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/LICENSE +21 -0
- package/README.md +10 -4
- package/ai-codex.ts +1 -0
- package/ai.ts +1 -0
- package/app-documents.ts +1 -0
- package/camera.ts +13 -0
- package/config-plugin.d.cts +2 -0
- package/contracts.ts +2 -0
- package/diagnostics.ts +1 -0
- package/expo-config.d.cts +1 -0
- package/metro.cjs +4 -1
- package/metro.d.cts +12 -0
- package/native.cjs +3 -1
- package/native.d.cts +6 -0
- package/package.json +93 -15
- package/patches/camera/react-native-nitro-image.patch +320 -0
- package/patches/camera/react-native-nitro-modules.patch +50 -0
- package/patches/camera/react-native-vision-camera.patch +2662 -0
- package/patches/camera/upstream.json +22 -0
- package/patches/dependencies.json +8 -0
- package/patches/react-native-enriched-markdown@1.0.2.patch +8684 -0
- package/postinstall.cjs +1 -0
- package/schema.json +276 -58
- package/settings-observable.ts +1 -0
- package/settings-window.ts +1 -0
- package/shortcuts-commands.ts +1 -0
- package/shortcuts-keyboard.ts +3 -0
- package/ui-classnames.ts +1 -0
- package/ui-glass.ts +1 -0
- package/ui-search.ts +1 -0
- package/ui-sidebar.ts +1 -0
- package/ui-split-view.ts +1 -0
- package/ui-swipe.ts +1 -0
- package/ui-symbol.ts +1 -0
- package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
- package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
- package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
- package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
- package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
- package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
- package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
- package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
- package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
- package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
- package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
- package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
- package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
- package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +145 -59
- package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +61 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +10 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +37 -8
- package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +86 -25
- package/vendor/node_modules/@legendapp/spark-cli/dist/dependency-pins.js +132 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +13 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +13 -10
- package/vendor/node_modules/@legendapp/spark-cli/dist/errors.js +100 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-native.cjs +5 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/helpers.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +52 -44
- package/vendor/node_modules/@legendapp/spark-cli/dist/json.js +16 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +86 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/process.js +7 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +90 -32
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +86 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
- package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
- package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/universal.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +5 -9
- package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +12 -10
- package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +14 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +14 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
- package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
- package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
- package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
- package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
- package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
- package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
- package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +116 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +18 -3
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.cjs +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.cjs +106 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.d.cts +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +7 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
- package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
- package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
- package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
- package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
- package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3169 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +146 -70
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
- package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
- package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
- package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
- package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
- package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
- package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
- package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
- package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
- package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
- package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
- package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
- package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
- package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
- package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
- package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
- package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
- package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +51 -8
- package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
- package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
- package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
- package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
- package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
- package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
- package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
- package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
- package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
- package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
- package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
- package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
- package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
- package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1419 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.h +10 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.mm +422 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
- package/vendor/node_modules/@legendapp/spark-ui/package.json +17 -4
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +37 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +86 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
- package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
- package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
- package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
- package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
- package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/SwipeActionsNativeComponent.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/index.tsx +41 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
- package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
- package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
- package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
- package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
- package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
- package/windows-macos.ts +1 -0
- package/expo-metro.cjs +0 -1
- package/message-dialog.ts +0 -1
- package/universal.cjs +0 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.mm +0 -53
|
@@ -15,8 +15,10 @@ const patches = [
|
|
|
15
15
|
' const onPressAsync = async (key)=>{',
|
|
16
16
|
` const onPressAsync = async (key)=>{\n try {\n if (await require(${extension}).handleKey(key)) return;\n } catch (error) {\n _log.exception(error);\n return;\n }`],
|
|
17
17
|
['startAsync.js', '0e062078e63ad6264b1393d403ad56d65a38c6430d30fdac50cd656486cd418b',
|
|
18
|
-
'
|
|
19
|
-
|
|
18
|
+
' await (0, _profile.profile)(devServerManager.startAsync.bind(devServerManager))(startOptions);',
|
|
19
|
+
// Dependency validation can wait on the network after Metro is listening.
|
|
20
|
+
// Report actual server readiness before those optional startup checks.
|
|
21
|
+
` await (0, _profile.profile)(devServerManager.startAsync.bind(devServerManager))(startOptions);\n require(${extension}).ready(devServerManager.getNativeDevServerPort(), { dev: options.dev, minify: options.minify, https: options.https });`],
|
|
20
22
|
];
|
|
21
23
|
|
|
22
24
|
function preparePatch(root) {
|
|
@@ -19,7 +19,7 @@ exports.withSparkMetro = config => {
|
|
|
19
19
|
if (config && typeof config.then === 'function') return config.then(exports.withSparkMetro);
|
|
20
20
|
if (!config || typeof config !== 'object') throw new Error('Spark needs an object or promise from metro.config');
|
|
21
21
|
const upstream = defaults.get(path.resolve(config.projectRoot || process.cwd()));
|
|
22
|
-
if (!upstream) throw new Error('Compose Metro with getDefaultConfig from @legendapp/spark
|
|
22
|
+
if (!upstream) throw new Error('Compose Metro with getDefaultConfig from @legendapp/spark/metro');
|
|
23
23
|
const customResolve = config.resolver?.resolveRequest;
|
|
24
24
|
if (customResolve && customResolve !== upstream.resolveRequest) {
|
|
25
25
|
const desktopResolve = upstream.resolveRequest;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
exports.withSparkNative = (original, root) => {
|
|
2
|
-
if (!['macos', 'windows'].includes(process.env.SPARK_PLATFORM))
|
|
2
|
+
if (!['macos', 'windows'].includes(process.env.SPARK_PLATFORM)) {
|
|
3
|
+
const patched = require('@legendapp/spark-desktop-config/native-patches.cjs').prepareNativePatches(root);
|
|
4
|
+
if (!Object.keys(patched).length) return original;
|
|
5
|
+
return { ...original, dependencies: { ...patched, ...original.dependencies } };
|
|
6
|
+
}
|
|
3
7
|
const generated = require('./universal.cjs').nativeConfig(root);
|
|
4
8
|
const dependencies = { ...original.dependencies };
|
|
5
9
|
for (const [name, config] of Object.entries(generated.dependencies ?? {})) {
|
|
@@ -2,7 +2,7 @@ import { spawnProcess, which } from "./process.js";
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
|
-
/** Check the actual Node/Expo pair before handing work to Expo Desktop
|
|
5
|
+
/** Check the actual Node/Expo pair before handing work to Expo Desktop. */
|
|
6
6
|
export async function checkExpoDesktopNode(root) {
|
|
7
7
|
const requireApp = createRequire(path.join(root, "package.json"));
|
|
8
8
|
const requireDesktop = createRequire(requireApp.resolve("expo-desktop/package.json"));
|
|
@@ -10,12 +10,12 @@ export async function checkExpoDesktopNode(root) {
|
|
|
10
10
|
const node = which("node");
|
|
11
11
|
if (!node)
|
|
12
12
|
throw new Error("Missing node. Install Node 24.19.0 (the version in .nvmrc), then retry.");
|
|
13
|
-
// Use the
|
|
13
|
+
// Use the static named imports used by Expo Desktop. Older Node releases cannot
|
|
14
14
|
// discover these exports in Expo's Babel-generated CommonJS modules.
|
|
15
15
|
const child = spawnProcess([node, "--input-type=module", "-e",
|
|
16
16
|
`import { AndroidConfig, IOSConfig } from ${JSON.stringify(configPlugins)}; if (!AndroidConfig || !IOSConfig) throw new Error('Missing Expo config exports');`,
|
|
17
17
|
], { cwd: root, stdout: "ignore", stderr: "pipe" });
|
|
18
18
|
const [stderr, code] = await Promise.all([new Response(child.stderr).text(), child.exited]);
|
|
19
19
|
if (code !== 0)
|
|
20
|
-
throw new Error(`Expo Desktop
|
|
20
|
+
throw new Error(`Expo Desktop could not load its config plugins using ${node}. Use Node 24.19.0 (nvm install && nvm use from the framework checkout), then retry. Node 24.12.0 cannot import these CommonJS named exports.\n${stderr.trim()}`);
|
|
21
21
|
}
|
|
@@ -2,8 +2,8 @@ import { copyFileSync, lstatSync, mkdirSync, realpathSync, chmodSync, readdirSyn
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { architecture } from "./platform.js";
|
|
5
|
-
const { validateHelpers } = createRequire(import.meta.url)("@legendapp/spark-desktop-config/helpers.cjs");
|
|
6
5
|
export function resolveHelpers(root, helpers = {}, platform = "macos", arch = architecture(platform)) {
|
|
6
|
+
const { validateHelpers } = createRequire(import.meta.url)("@legendapp/spark-desktop-config/helpers.cjs");
|
|
7
7
|
validateHelpers(helpers);
|
|
8
8
|
const base = realpathSync(root);
|
|
9
9
|
function inspect(file) {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { spawnProcess } from "./process.js";
|
|
1
|
+
import { nodeCommand, spawnProcess } from "./process.js";
|
|
2
2
|
import { examples } from "./examples.js";
|
|
3
3
|
import { prepareGoProfile } from "./go-profile.js";
|
|
4
4
|
import { exportSDK, importSDK } from "./sdk-transfer.js";
|
|
5
5
|
import { hostPlatform } from "./platform.js";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import {
|
|
7
|
+
import { cliArguments } from "./cli-arguments.js";
|
|
8
8
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { prepareConfig, readConfig, isExpoProject } from "@legendapp/spark-desktop-config/config.cjs";
|
|
10
|
-
import {
|
|
10
|
+
import { prepareWindows } from "./windows.js";
|
|
11
11
|
import { create, refreshLocalPackages } from "./create.js";
|
|
12
12
|
import { addDesktop } from "./add-desktop.js";
|
|
13
13
|
import { buildMode } from "./build-mode.js";
|
|
@@ -20,37 +20,13 @@ import { doctor, run } from "./commands.js";
|
|
|
20
20
|
import { findFramework, findProject, sparkHome, creationManifest, packageManifest, registerRuntime } from "./local.js";
|
|
21
21
|
import { readJson, stateFile, VERSION, writeJson } from "./project.js";
|
|
22
22
|
import { devCommand } from "./dev-command.js";
|
|
23
|
+
import { printDependencyPins, upgradeDependencyPins } from "./dependency-pins.js";
|
|
24
|
+
import { reportError } from "./errors.js";
|
|
23
25
|
async function main() {
|
|
24
26
|
const argv = process.argv.slice(2);
|
|
25
27
|
if (argv[0] === "dev")
|
|
26
28
|
return devCommand(argv.slice(1));
|
|
27
|
-
const { positionals, values } =
|
|
28
|
-
args: argv,
|
|
29
|
-
allowPositionals: true,
|
|
30
|
-
options: {
|
|
31
|
-
example: { type: "string" },
|
|
32
|
-
"package-manager": { type: "string" },
|
|
33
|
-
runtime: { type: "string", multiple: true },
|
|
34
|
-
universal: { type: "boolean" },
|
|
35
|
-
device: { type: "string" },
|
|
36
|
-
project: { type: "string" },
|
|
37
|
-
platform: { type: "string" },
|
|
38
|
-
packages: { type: "string" },
|
|
39
|
-
port: { type: "string" },
|
|
40
|
-
runner: { type: "boolean" },
|
|
41
|
-
prebuilt: { type: "boolean" },
|
|
42
|
-
go: { type: "boolean" }, // Legacy desktop build alias; dev --go belongs to Expo.
|
|
43
|
-
dev: { type: "boolean" },
|
|
44
|
-
release: { type: "boolean" },
|
|
45
|
-
preview: { type: "boolean" },
|
|
46
|
-
force: { type: "boolean" },
|
|
47
|
-
"no-open": { type: "boolean" },
|
|
48
|
-
"submission-id": { type: "string" },
|
|
49
|
-
help: { type: "boolean", short: "h" },
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
if (values.platform && !["macos", "windows", "ios", "android", "web"].includes(values.platform))
|
|
53
|
-
throw new Error("Platform must be macos, windows, ios, android, or web.");
|
|
29
|
+
const { positionals, values } = cliArguments(argv);
|
|
54
30
|
if (values.platform)
|
|
55
31
|
process.env.SPARK_PLATFORM = values.platform;
|
|
56
32
|
const platform = (values.platform ?? hostPlatform());
|
|
@@ -58,25 +34,25 @@ async function main() {
|
|
|
58
34
|
const start = path.resolve(projectOption ?? process.cwd());
|
|
59
35
|
const project = () => findProject(start);
|
|
60
36
|
const port = values.port === undefined ? undefined : Number(values.port);
|
|
61
|
-
if (port !== undefined && (!Number.isInteger(port) || port < 1 || port > 65535))
|
|
62
|
-
throw new Error("Port must be an integer between 1 and 65535.");
|
|
63
37
|
const command = positionals[0];
|
|
64
38
|
if (!values.help && !values.platform && !(command === "open" && positionals[1]) && ["build", "prebuild", "analyze", "package", "open", "updates", "credentials"].includes(command ?? "") && isExpoProject(project())) {
|
|
65
39
|
process.env.SPARK_PLATFORM = readConfig(project()).expo.platforms[0];
|
|
66
40
|
}
|
|
67
41
|
if (values.example && (command !== "create" || !examples.includes(values.example)))
|
|
68
42
|
throw new Error(`Use create --example ${examples.join(" | ")}`);
|
|
69
|
-
if (values.universal && command !== "create")
|
|
70
|
-
throw new Error("--universal is a create option.");
|
|
71
43
|
if (!values.help && ["build", "prebuild"].includes(command ?? "")) {
|
|
72
44
|
const root = project();
|
|
73
45
|
const selected = readConfig(root).expo.platforms[0];
|
|
46
|
+
if (!["ios", "android", "web"].includes(selected) && (values.device || values.port))
|
|
47
|
+
throw new Error("--device and --port are mobile build options; use spark dev for desktop launch options.");
|
|
74
48
|
if (["ios", "android", "web"].includes(selected)) {
|
|
49
|
+
if (values.force)
|
|
50
|
+
throw new Error("--force is a desktop build option.");
|
|
75
51
|
if (command === "build" && selected === "web")
|
|
76
52
|
throw new Error("Use expo export --platform web for web production output.");
|
|
77
53
|
if (command === "prebuild" && selected === "web")
|
|
78
54
|
throw new Error("Web has no native project to prebuild.");
|
|
79
|
-
if (values.runner || values.
|
|
55
|
+
if (values.runner || values.release || values.preview || (command === "build" && !values.dev))
|
|
80
56
|
throw new Error("Mobile builds use --dev in this slice; Expo owns mobile distribution workflows.");
|
|
81
57
|
prepareConfig(root);
|
|
82
58
|
const args = command === "prebuild" ? ["prebuild", "--platform", selected, "--no-install"] : [`run:${selected}`, ...(values.device ? ["--device", values.device] : []), ...(port ? ["--port", String(port)] : [])];
|
|
@@ -104,6 +80,8 @@ async function main() {
|
|
|
104
80
|
spark build Build a standalone desktop app
|
|
105
81
|
spark prebuild Generate a Windows/mobile native project
|
|
106
82
|
spark package Sign and notarize a distribution archive
|
|
83
|
+
spark doctor Check app dependency pins and native tooling (exits 1 on issues)
|
|
84
|
+
spark upgrade Align app dependency pins with Spark (--dry-run previews changes)
|
|
107
85
|
|
|
108
86
|
Inside an app: npm run dev, npm run build, npm run package (or pnpm, yarn, bun)
|
|
109
87
|
|
|
@@ -125,8 +103,6 @@ Overrides: --project <directory>, --port <number>, dev --runner-binary <runtime
|
|
|
125
103
|
case "create": {
|
|
126
104
|
if (!positionals[1])
|
|
127
105
|
throw new Error("Usage: spark create MyApp");
|
|
128
|
-
if (!values.universal && !["macos", "windows"].includes(platform))
|
|
129
|
-
throw new Error("Use create --universal for mobile/web targets");
|
|
130
106
|
await create(path.resolve(positionals[1]), creationManifest(values.packages), platform, !!values.universal || !!values.example, values.example, values["package-manager"]);
|
|
131
107
|
break;
|
|
132
108
|
}
|
|
@@ -169,8 +145,6 @@ Overrides: --project <directory>, --port <number>, dev --runner-binary <runtime
|
|
|
169
145
|
process.exitCode = 2;
|
|
170
146
|
break;
|
|
171
147
|
}
|
|
172
|
-
case "build-go": // Legacy alias; persisted runtime metadata still uses "go".
|
|
173
|
-
case "build-prebuilt": // Legacy command alias.
|
|
174
148
|
case "build-runner": {
|
|
175
149
|
let root;
|
|
176
150
|
if (projectOption)
|
|
@@ -201,10 +175,44 @@ Overrides: --project <directory>, --port <number>, dev --runner-binary <runtime
|
|
|
201
175
|
throw new Error("For macOS, spark build --dev generates and builds the native project.");
|
|
202
176
|
await prepareWindows(project(), "dev");
|
|
203
177
|
break;
|
|
204
|
-
case "doctor":
|
|
205
|
-
|
|
178
|
+
case "doctor": {
|
|
179
|
+
let root;
|
|
180
|
+
let pinIssues = false;
|
|
181
|
+
try {
|
|
182
|
+
root = project();
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
console.log("No Spark app found; skipping dependency pin check.");
|
|
186
|
+
}
|
|
187
|
+
if (root) {
|
|
188
|
+
try {
|
|
189
|
+
const issues = upgradeDependencyPins(root, true);
|
|
190
|
+
printDependencyPins(issues);
|
|
191
|
+
if (issues.length) {
|
|
192
|
+
process.exitCode = 1;
|
|
193
|
+
pinIssues = true;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
console.error(`Dependency pin check failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
198
|
+
process.exitCode = 1;
|
|
199
|
+
pinIssues = true;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
await doctor(root ?? start);
|
|
206
203
|
console.log("Native toolchain available.");
|
|
204
|
+
if (pinIssues)
|
|
205
|
+
console.log("Dependency pin issues found; run spark upgrade.");
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
case "upgrade": {
|
|
209
|
+
const issues = upgradeDependencyPins(project(), !!values["dry-run"]);
|
|
210
|
+
console.log(values["dry-run"] ? "Dependency pin changes (dry run):" : "Dependency pin changes:");
|
|
211
|
+
printDependencyPins(issues);
|
|
212
|
+
if (issues.length)
|
|
213
|
+
console.log(values["dry-run"] ? "No files changed. Run spark upgrade, then run your package manager's install command (npm/pnpm/yarn/bun install)." : "Updated package.json. Run your package manager's install command (npm/pnpm/yarn/bun install).");
|
|
207
214
|
break;
|
|
215
|
+
}
|
|
208
216
|
case "updates": {
|
|
209
217
|
if (positionals[1] !== "init" || !positionals[2])
|
|
210
218
|
throw new Error("Usage: spark updates init https://example.com/updates/appcast.xml");
|
|
@@ -216,8 +224,8 @@ Overrides: --project <directory>, --port <number>, dev --runner-binary <runtime
|
|
|
216
224
|
console.log("Signing credentials configured. Run spark package to prepare a distribution archive.");
|
|
217
225
|
break;
|
|
218
226
|
case "package": {
|
|
219
|
-
if (process.platform !== "darwin"
|
|
220
|
-
throw new Error("
|
|
227
|
+
if (process.platform !== "darwin")
|
|
228
|
+
throw new Error("macOS packaging requires macOS.");
|
|
221
229
|
const result = await packageApp(project(), { force: !!values.force, submissionId: values["submission-id"] });
|
|
222
230
|
if (result.pending)
|
|
223
231
|
process.exitCode = 2;
|
|
@@ -258,6 +266,6 @@ try {
|
|
|
258
266
|
await main();
|
|
259
267
|
}
|
|
260
268
|
catch (error) {
|
|
261
|
-
|
|
269
|
+
reportError(process.cwd(), error, "Spark");
|
|
262
270
|
process.exitCode = 1;
|
|
263
271
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export function readJson(file) {
|
|
4
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
5
|
+
}
|
|
6
|
+
export function writeJson(file, value) {
|
|
7
|
+
const content = JSON.stringify(value, null, 2) + "\n";
|
|
8
|
+
// Metro watches JSON too: rewriting unchanged session state on every runtime
|
|
9
|
+
// check causes empty Fast Refresh updates even when app code has not changed.
|
|
10
|
+
if (existsSync(file) && readFileSync(file, "utf8") === content)
|
|
11
|
+
return;
|
|
12
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
13
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
14
|
+
writeFileSync(temporary, content);
|
|
15
|
+
renameSync(temporary, file);
|
|
16
|
+
}
|
|
@@ -35,7 +35,7 @@ export function readRuntime(app) {
|
|
|
35
35
|
try {
|
|
36
36
|
const windows = existsSync(path.join(app, "spark-runtime.json"));
|
|
37
37
|
const runtime = readJson(path.join(app, windows ? "spark-runtime.json" : "Contents/Resources/spark-runtime.json"));
|
|
38
|
-
if (runtime.schema !== 1 || runtime.framework !== VERSION || !["macos", "windows"].includes(runtime.platform) || !
|
|
38
|
+
if (runtime.schema !== 1 || runtime.framework !== VERSION || !["macos", "windows"].includes(runtime.platform) || !["arm64", "x64"].includes(runtime.arch) || !runtime.modules || typeof runtime.modules !== "object" || typeof runtime.fingerprint !== "string")
|
|
39
39
|
return undefined;
|
|
40
40
|
if (!existsSync(path.join(app, windows ? "MyApp.exe" : "Contents/MacOS")) || windows !== (runtime.platform === "windows"))
|
|
41
41
|
return undefined;
|
|
@@ -16,6 +16,11 @@ function runtimePlan(root, env = process.env) {
|
|
|
16
16
|
.map(e => e.name).concat(["src"]) };
|
|
17
17
|
}
|
|
18
18
|
function withDesktop(config, options = {}) {
|
|
19
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) throw new Error("Expected desktop Metro options");
|
|
20
|
+
for (const [key, value] of Object.entries(options)) {
|
|
21
|
+
if (!["runtimes", "watch"].includes(key)) throw new Error(`Unknown desktop Metro option: ${key}`);
|
|
22
|
+
if (value !== undefined && typeof value !== "boolean") throw new Error(`${key} must be boolean`);
|
|
23
|
+
}
|
|
19
24
|
// Expo 54 sets the react-native export condition only for iOS/Android.
|
|
20
25
|
// Desktop must also select native package exports (e.g. Uniwind's runtime).
|
|
21
26
|
const conditions = { ...config.resolver?.unstable_conditionsByPlatform };
|
|
@@ -24,10 +29,26 @@ function withDesktop(config, options = {}) {
|
|
|
24
29
|
}
|
|
25
30
|
config = { ...config, resolver: { ...config.resolver, unstable_conditionsByPlatform: conditions } };
|
|
26
31
|
const root = path.resolve(config.projectRoot || process.cwd());
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
// Keep the configured workspace root so lazy imports outside the app have
|
|
33
|
+
// valid URLs. Only the prebuilt host's fixed entry URLs are app-relative.
|
|
34
|
+
const serverRoot = path.resolve(config.server?.unstable_serverRoot || root);
|
|
35
|
+
const entryPrefix = path.relative(serverRoot, root).split(path.sep).map(encodeURIComponent).join("/");
|
|
36
|
+
if (entryPrefix && (entryPrefix === ".." || entryPrefix.startsWith("../"))) {
|
|
37
|
+
throw new Error("Metro's server root must contain the Spark project");
|
|
38
|
+
}
|
|
39
|
+
const rewrite = config.server?.rewriteRequestUrl;
|
|
40
|
+
config = { ...config, server: { ...config.server, unstable_serverRoot: serverRoot,
|
|
41
|
+
rewriteRequestUrl(value) {
|
|
42
|
+
const url = new URL(value, "http://localhost");
|
|
43
|
+
const platform = url.searchParams.get("platform");
|
|
44
|
+
if (entryPrefix && (!platform || ["macos", "windows"].includes(platform)) &&
|
|
45
|
+
/^\/(index|\.threaded-runtime\/entry)\.(bundle|map|delta)$/.test(url.pathname)) {
|
|
46
|
+
url.pathname = `/${entryPrefix}${url.pathname}`;
|
|
47
|
+
value = value.startsWith("/") ? `${url.pathname}${url.search}${url.hash}` : url.href;
|
|
48
|
+
}
|
|
49
|
+
return rewrite ? rewrite(value) : value;
|
|
50
|
+
},
|
|
51
|
+
} };
|
|
31
52
|
let core;
|
|
32
53
|
try { core = require.resolve("@react-native-runtimes/core/metro", { paths: [root] }); } catch {}
|
|
33
54
|
if (!core || options.runtimes === false) {
|
|
@@ -40,7 +61,7 @@ function withDesktop(config, options = {}) {
|
|
|
40
61
|
const plan = runtimePlan(root);
|
|
41
62
|
const generatedEntry = path.join(root, ".threaded-runtime/entry.js");
|
|
42
63
|
if (plan.enabled) {
|
|
43
|
-
config = withThreadedRuntime(config, {
|
|
64
|
+
config = withThreadedRuntime(config, { roots: plan.roots, watch: plan.production ? false : options.watch });
|
|
44
65
|
// Production roots come from Metro's resolved graph, including worker files
|
|
45
66
|
// shipped by dependencies. Do not register unrelated index.<name>.ts files.
|
|
46
67
|
if (plan.production) generateThreadedRuntimeEntry({ projectRoot: root, generatedEntry, roots: plan.roots, runtimeEntries: [] });
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { existsSync, readdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { run } from "./commands.js";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
const { identity } = createRequire(import.meta.url)("@legendapp/spark-desktop-config/identity.cjs");
|
|
6
|
+
/** Restore app-owned values after Expo Desktop's template string replacement. */
|
|
7
|
+
export async function restoreNativeMetadata(root, config, execute = run) {
|
|
8
|
+
const overrides = { ...config.macos?.infoPlist, ...identity(config) };
|
|
9
|
+
const nativeRoot = path.join(root, "macos");
|
|
10
|
+
const matches = [];
|
|
11
|
+
for (const entry of readdirSync(nativeRoot, { withFileTypes: true })) {
|
|
12
|
+
if (!entry.isDirectory())
|
|
13
|
+
continue;
|
|
14
|
+
const file = path.join(nativeRoot, entry.name, "Info.plist");
|
|
15
|
+
if (!existsSync(file))
|
|
16
|
+
continue;
|
|
17
|
+
const info = JSON.parse(await execute(root, ["plutil", "-convert", "json", "-o", "-", file], { capture: true }));
|
|
18
|
+
if ("SparkProjectIdentifier" in info)
|
|
19
|
+
matches.push({ file, info });
|
|
20
|
+
}
|
|
21
|
+
if (matches.length !== 1)
|
|
22
|
+
throw new Error(`Expected one generated Spark Info.plist, found ${matches.length}`);
|
|
23
|
+
const { file, info } = matches[0];
|
|
24
|
+
writeFileSync(file, JSON.stringify({ ...info, ...overrides }));
|
|
25
|
+
await execute(root, ["plutil", "-convert", "xml1", file], { capture: true });
|
|
26
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { prepareNativePatches } from "@legendapp/spark-desktop-config/native-patches.cjs";
|
|
5
|
+
import { findFramework } from "./local.js";
|
|
6
|
+
import { installedPackages, readJson, VERSION } from "./project.js";
|
|
7
|
+
const required = ["@react-native-runtimes/core", "react-native-nitro-modules", "@op-engineering/op-sqlite", "react-native-webview"];
|
|
8
|
+
const optional = ["expo-audio"];
|
|
9
|
+
export function validatePackedNativePatches(packages, requirements, frameworkVersion = VERSION) {
|
|
10
|
+
if (!requirements || requirements.schema !== 1 || requirements.frameworkVersion !== frameworkVersion || !requirements.packages || typeof requirements.packages !== "object")
|
|
11
|
+
return [`The installed @legendapp/spark SDK does not include native patch provenance for ${frameworkVersion}. Run spark add desktop to install the matching SDK packages, then retry.`];
|
|
12
|
+
const installed = new Map(packages.map(pkg => [pkg.name, pkg.json]));
|
|
13
|
+
const errors = [];
|
|
14
|
+
for (const name of required)
|
|
15
|
+
if (!installed.has(name))
|
|
16
|
+
errors.push(`${name} is missing; reinstall the dependencies from this Spark SDK.`);
|
|
17
|
+
for (const name of [...required, ...optional]) {
|
|
18
|
+
const actual = installed.get(name);
|
|
19
|
+
if (!actual)
|
|
20
|
+
continue;
|
|
21
|
+
const expected = requirements.packages[name];
|
|
22
|
+
const spark = actual.spark;
|
|
23
|
+
if (!expected || typeof expected.version !== "string" || !/^[a-f0-9]{64}$/.test(expected.patchHash) ||
|
|
24
|
+
(!expected.upstreamIntegrity && !expected.upstreamRevision) || actual.version !== expected.version || spark?.sdk !== true || spark.patchHash !== expected.patchHash ||
|
|
25
|
+
spark.upstreamIntegrity !== expected.upstreamIntegrity || spark.upstreamRevision !== expected.upstreamRevision) {
|
|
26
|
+
errors.push(`${name}@${actual.version} is not the matching patched Spark SDK package.`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return errors;
|
|
30
|
+
}
|
|
31
|
+
export function validateWorkspaceNativePatches(root, packages) {
|
|
32
|
+
const framework = findFramework(root);
|
|
33
|
+
if (!framework)
|
|
34
|
+
return ["The Spark SDK is missing native patch provenance. Run spark add desktop to install matching SDK packages, then retry."];
|
|
35
|
+
const frameworkPackage = readJson(path.join(framework, "package.json"));
|
|
36
|
+
const map = frameworkPackage.sparkWorkspacePatches;
|
|
37
|
+
if (!map)
|
|
38
|
+
return ["The Spark workspace has no install-time patch inventory. Run npm run postinstall in the framework checkout, then retry."];
|
|
39
|
+
const pins = readJson(path.join(framework, "patches/workspace/upstream.json"));
|
|
40
|
+
const installed = new Map(packages.map(pkg => [pkg.name, pkg]));
|
|
41
|
+
const errors = [];
|
|
42
|
+
for (const name of [...required, ...optional]) {
|
|
43
|
+
const pkg = installed.get(name);
|
|
44
|
+
if (!pkg) {
|
|
45
|
+
if (required.includes(name))
|
|
46
|
+
errors.push(`${name} is missing; reinstall the dependencies from this Spark workspace.`);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const entry = Object.entries(map).find(([key]) => key.slice(0, key.lastIndexOf("@")) === name);
|
|
50
|
+
const pin = pins[name];
|
|
51
|
+
if (!entry || !pin || !entry[0].endsWith(`@${pin.version}`) || pkg.json.version !== pin.version) {
|
|
52
|
+
errors.push(`${name}@${pkg.json.version} does not match the Spark workspace patch inventory.`);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const patchFile = path.resolve(framework, entry[1]);
|
|
56
|
+
if (!patchFile.startsWith(framework + path.sep) || !existsSync(patchFile)) {
|
|
57
|
+
errors.push(`${name} has no readable Spark workspace patch. Run npm run postinstall in the framework checkout.`);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const patchHash = createHash("sha256").update(readFileSync(patchFile)).digest("hex");
|
|
61
|
+
const receipt = pkg.json.spark?.workspacePatch;
|
|
62
|
+
const expectedRevision = pin.revision;
|
|
63
|
+
if (!receipt || receipt.schema !== 1 || receipt.version !== pin.version || receipt.patchHash !== patchHash ||
|
|
64
|
+
receipt.upstreamIntegrity !== pin.integrity || (expectedRevision && receipt.upstreamRevision !== expectedRevision)) {
|
|
65
|
+
errors.push(`${name}@${pkg.json.version} has no matching applied workspace patch stamp. Run npm run postinstall in the framework checkout, then retry.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return errors;
|
|
69
|
+
}
|
|
70
|
+
export function assertNativePatchPreflight(root) {
|
|
71
|
+
prepareNativePatches(root);
|
|
72
|
+
const packages = installedPackages(root);
|
|
73
|
+
const framework = findFramework(root);
|
|
74
|
+
let errors;
|
|
75
|
+
const spark = packages.find(pkg => pkg.name === "@legendapp/spark");
|
|
76
|
+
const requirements = spark?.json.spark?.nativePatchRequirements;
|
|
77
|
+
if (requirements)
|
|
78
|
+
errors = validatePackedNativePatches(packages, requirements);
|
|
79
|
+
else if (framework)
|
|
80
|
+
errors = validateWorkspaceNativePatches(root, packages);
|
|
81
|
+
else {
|
|
82
|
+
errors = validatePackedNativePatches(packages, requirements);
|
|
83
|
+
}
|
|
84
|
+
if (errors.length)
|
|
85
|
+
throw new Error(`Native patch preparation stopped before changing project files:\n${errors.map(error => `- ${error}`).join("\n")}`);
|
|
86
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { stateFile } from "./project.js";
|
|
4
|
+
export async function preserveMacOSPods(root, prepare) {
|
|
5
|
+
const native = path.join(root, "macos");
|
|
6
|
+
const cache = stateFile(root, "prebuild-cache/macos");
|
|
7
|
+
const entries = ["Pods", "Podfile.lock"];
|
|
8
|
+
function restore() {
|
|
9
|
+
for (const entry of entries) {
|
|
10
|
+
const saved = path.join(cache, entry);
|
|
11
|
+
const destination = path.join(native, entry);
|
|
12
|
+
if (!existsSync(saved))
|
|
13
|
+
continue;
|
|
14
|
+
if (existsSync(destination))
|
|
15
|
+
throw new Error(`Cannot restore CocoaPods cache: both ${saved} and ${destination} exist.`);
|
|
16
|
+
mkdirSync(native, { recursive: true });
|
|
17
|
+
renameSync(saved, destination);
|
|
18
|
+
}
|
|
19
|
+
rmSync(cache, { recursive: true, force: true });
|
|
20
|
+
}
|
|
21
|
+
// A terminated prebuild may leave the only copy of Pods in the cache.
|
|
22
|
+
restore();
|
|
23
|
+
try {
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
const source = path.join(native, entry);
|
|
26
|
+
if (!existsSync(source))
|
|
27
|
+
continue;
|
|
28
|
+
mkdirSync(cache, { recursive: true });
|
|
29
|
+
renameSync(source, path.join(cache, entry));
|
|
30
|
+
}
|
|
31
|
+
await prepare();
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
restore();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function preparationChanges(previous, current) {
|
|
38
|
+
if (!previous?.inputs)
|
|
39
|
+
return ["native preparation provenance missing"];
|
|
40
|
+
const reasons = [];
|
|
41
|
+
if (JSON.stringify(previous.inputs.config) !== JSON.stringify(current.inputs?.config)) {
|
|
42
|
+
const updatesChanged = JSON.stringify(previous.inputs.config.expo?.extra?.spark?.updates) !== JSON.stringify(current.inputs?.config.expo?.extra?.spark?.updates);
|
|
43
|
+
reasons.push(updatesChanged ? "native configuration changed (updater settings)" : "native configuration changed");
|
|
44
|
+
}
|
|
45
|
+
if (previous.inputs.plugin !== current.inputs?.plugin)
|
|
46
|
+
reasons.push("native host/config plugin changed");
|
|
47
|
+
const before = new Map(previous.inputs.packages.map(([name, root, contents]) => [name, { root, contents }]));
|
|
48
|
+
for (const [name, root, contents] of current.inputs?.packages ?? []) {
|
|
49
|
+
const prior = before.get(name);
|
|
50
|
+
if (!prior)
|
|
51
|
+
reasons.push(`${name} added`);
|
|
52
|
+
else {
|
|
53
|
+
if (prior.root !== root)
|
|
54
|
+
reasons.push(`${name} location changed`);
|
|
55
|
+
if (prior.contents !== contents)
|
|
56
|
+
reasons.push(`${name} preparation sources changed`);
|
|
57
|
+
}
|
|
58
|
+
before.delete(name);
|
|
59
|
+
}
|
|
60
|
+
for (const name of before.keys())
|
|
61
|
+
reasons.push(`${name} removed`);
|
|
62
|
+
return reasons.length ? reasons : previous.fingerprint !== current.fingerprint ? ["native preparation inputs changed"] : [];
|
|
63
|
+
}
|
|
64
|
+
export function missingNativeFrameworks(root) {
|
|
65
|
+
const pods = path.join(root, "macos/Pods");
|
|
66
|
+
const support = path.join(pods, "Target Support Files");
|
|
67
|
+
if (!existsSync(support))
|
|
68
|
+
return [support];
|
|
69
|
+
const missing = new Set();
|
|
70
|
+
for (const target of readdirSync(support)) {
|
|
71
|
+
const script = path.join(support, target, `${target}-xcframeworks.sh`);
|
|
72
|
+
if (!existsSync(script))
|
|
73
|
+
continue;
|
|
74
|
+
// CocoaPods lists only the frameworks and slices selected for this target.
|
|
75
|
+
for (const match of readFileSync(script, "utf8").matchAll(/^install_xcframework "([^"]+)" "[^"]+" "[^"]+" (.+)$/gm)) {
|
|
76
|
+
const framework = match[1].replaceAll("${PODS_ROOT}", pods).replaceAll("$(PODS_ROOT)", pods);
|
|
77
|
+
if (framework.includes("$"))
|
|
78
|
+
throw new Error(`Cannot resolve native framework input: ${framework}`);
|
|
79
|
+
if (!existsSync(path.join(framework, "Info.plist")))
|
|
80
|
+
missing.add(path.normalize(framework));
|
|
81
|
+
for (const slice of match[2].matchAll(/"([^"]+)"/g)) {
|
|
82
|
+
if (!existsSync(path.join(framework, slice[1])))
|
|
83
|
+
missing.add(path.join(framework, slice[1]));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return [...missing];
|
|
88
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { run } from "./commands.js";
|
|
4
|
+
import { stateFile } from "./project.js";
|
|
5
|
+
// Security returns attributes only. Never request or print credential data.
|
|
6
|
+
const discovery = String.raw `
|
|
7
|
+
import Foundation
|
|
8
|
+
import Security
|
|
9
|
+
import LocalAuthentication
|
|
10
|
+
|
|
11
|
+
struct KeychainError: Error { let status: OSStatus }
|
|
12
|
+
func check(_ status: OSStatus) throws {
|
|
13
|
+
if status != errSecSuccess { throw KeychainError(status: status) }
|
|
14
|
+
}
|
|
15
|
+
func profiles(_ query: [CFString: Any]) throws -> [String] {
|
|
16
|
+
var result: CFTypeRef?
|
|
17
|
+
let status = SecItemCopyMatching(query as CFDictionary, &result)
|
|
18
|
+
var names: [String] = []
|
|
19
|
+
if status != errSecItemNotFound {
|
|
20
|
+
try check(status)
|
|
21
|
+
let prefix = "com.apple.gke.notary.tool.saved-creds."
|
|
22
|
+
for item in result as? [[String: Any]] ?? [] {
|
|
23
|
+
if let account = item[kSecAttrAccount as String] as? String, account.hasPrefix(prefix) {
|
|
24
|
+
let name = String(account.dropFirst(prefix.count))
|
|
25
|
+
if !name.isEmpty { names.append(name) }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return names
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
do {
|
|
33
|
+
let context = LAContext()
|
|
34
|
+
context.interactionNotAllowed = true
|
|
35
|
+
var query: [CFString: Any] = [
|
|
36
|
+
kSecClass: kSecClassGenericPassword,
|
|
37
|
+
kSecAttrLabel: "com.apple.gke.notary.tool",
|
|
38
|
+
kSecMatchLimit: kSecMatchLimitAll,
|
|
39
|
+
kSecReturnAttributes: true,
|
|
40
|
+
kSecReturnData: false,
|
|
41
|
+
kSecUseAuthenticationContext: context
|
|
42
|
+
]
|
|
43
|
+
if CommandLine.arguments.count > 1 {
|
|
44
|
+
var keychain: SecKeychain?
|
|
45
|
+
try check(SecKeychainOpen(CommandLine.arguments[1], &keychain))
|
|
46
|
+
if let keychain { query[kSecMatchSearchList] = [keychain] }
|
|
47
|
+
}
|
|
48
|
+
var names = try profiles(query)
|
|
49
|
+
if CommandLine.arguments.count == 1 {
|
|
50
|
+
query[kSecUseDataProtectionKeychain] = true
|
|
51
|
+
query[kSecAttrSynchronizable] = kSecAttrSynchronizableAny
|
|
52
|
+
names += try profiles(query)
|
|
53
|
+
}
|
|
54
|
+
let data = try JSONSerialization.data(withJSONObject: Array(Set(names)).sorted())
|
|
55
|
+
print(String(decoding: data, as: UTF8.self))
|
|
56
|
+
} catch {
|
|
57
|
+
let message: String
|
|
58
|
+
if let error = error as? KeychainError {
|
|
59
|
+
message = SecCopyErrorMessageString(error.status, nil) as String? ?? "OSStatus \(error.status)"
|
|
60
|
+
} else { message = String(describing: error) }
|
|
61
|
+
FileHandle.standardError.write(Data("Cannot list notarization Keychain profiles: \(message)\n".utf8))
|
|
62
|
+
exit(1)
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
65
|
+
export async function listNotaryProfiles(root, keychain, execute = run) {
|
|
66
|
+
const file = stateFile(root, "notary-profiles.swift");
|
|
67
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
68
|
+
writeFileSync(file, discovery);
|
|
69
|
+
const output = await execute(root, ["xcrun", "swift", "-suppress-warnings", file, ...(keychain ? [keychain] : [])], { capture: true });
|
|
70
|
+
const profiles = JSON.parse(output);
|
|
71
|
+
if (!Array.isArray(profiles) || !profiles.every(profile => typeof profile === "string" && profile.length > 0)) {
|
|
72
|
+
throw new Error("Invalid notarization profile discovery result.");
|
|
73
|
+
}
|
|
74
|
+
return [...new Set(profiles)].sort();
|
|
75
|
+
}
|
|
@@ -69,16 +69,18 @@ async function packageUnlocked(root, options, deps) {
|
|
|
69
69
|
if (config.extra?.spark?.updates && !result.runtime.modules["@legendapp/spark-updates"])
|
|
70
70
|
throw new Error("Updates are configured but the module was pruned. Import @legendapp/spark/updates from the app entry.");
|
|
71
71
|
const entitlements = distributionEntitlements(appEntitlements(root, result.runtime.modules));
|
|
72
|
+
if (!config.macos?.bundleIdentifier || !config.version)
|
|
73
|
+
throw new Error("Packaging requires macos.bundleIdentifier and version");
|
|
72
74
|
const byPath = config.extra?.spark?.signing?.macos?.entitlementsByPath ?? {};
|
|
73
75
|
const info = JSON.parse(await execute(root, ["plutil", "-convert", "json", "-o", "-", path.join(result.app, "Contents/Info.plist")], { capture: true }));
|
|
74
|
-
const expected = { runner: options.runner, bundleId: config.macos.bundleIdentifier, version: config.version, buildVersion: info.CFBundleVersion, entitlements, byPath };
|
|
76
|
+
const expected = { arch: result.runtime.arch, runner: options.runner, bundleId: config.macos.bundleIdentifier, version: config.version, buildVersion: info.CFBundleVersion, entitlements, byPath };
|
|
75
77
|
if (!expected.bundleId || !expected.version || !expected.buildVersion)
|
|
76
78
|
throw new Error("Bundle identifier and release version metadata must be configured before packaging.");
|
|
77
79
|
const inputHash = artifactHash(result.app);
|
|
78
80
|
const key = digest(JSON.stringify({ recipe: 1, inputHash, identity: identity.hash, entitlements, byPath }));
|
|
79
81
|
const folder = stateFile(root, `packaging/${key}`);
|
|
80
82
|
const app = path.join(folder, path.basename(result.app));
|
|
81
|
-
const safeName = `${config.slug ?? config.name}-${config.version}
|
|
83
|
+
const safeName = `${config.slug ?? config.name}-${config.version}-${result.runtime.arch}`.replace(/[^A-Za-z0-9._-]/g, "-");
|
|
82
84
|
const upload = path.join(folder, `${safeName}-${key.slice(0, 16)}-notary.zip`);
|
|
83
85
|
const statePath = path.join(folder, "state.json");
|
|
84
86
|
mkdirSync(folder, { recursive: true });
|