@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.
Files changed (422) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -4
  3. package/ai-codex.ts +1 -0
  4. package/ai.ts +1 -0
  5. package/app-documents.ts +1 -0
  6. package/camera.ts +13 -0
  7. package/config-plugin.d.cts +2 -0
  8. package/contracts.ts +2 -0
  9. package/diagnostics.ts +1 -0
  10. package/expo-config.d.cts +1 -0
  11. package/metro.cjs +4 -1
  12. package/metro.d.cts +12 -0
  13. package/native.cjs +3 -1
  14. package/native.d.cts +6 -0
  15. package/package.json +93 -15
  16. package/patches/camera/react-native-nitro-image.patch +320 -0
  17. package/patches/camera/react-native-nitro-modules.patch +50 -0
  18. package/patches/camera/react-native-vision-camera.patch +2662 -0
  19. package/patches/camera/upstream.json +22 -0
  20. package/patches/dependencies.json +8 -0
  21. package/patches/react-native-enriched-markdown@1.0.2.patch +8684 -0
  22. package/postinstall.cjs +1 -0
  23. package/schema.json +276 -58
  24. package/settings-observable.ts +1 -0
  25. package/settings-window.ts +1 -0
  26. package/shortcuts-commands.ts +1 -0
  27. package/shortcuts-keyboard.ts +3 -0
  28. package/ui-classnames.ts +1 -0
  29. package/ui-glass.ts +1 -0
  30. package/ui-search.ts +1 -0
  31. package/ui-sidebar.ts +1 -0
  32. package/ui-split-view.ts +1 -0
  33. package/ui-swipe.ts +1 -0
  34. package/ui-symbol.ts +1 -0
  35. package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
  36. package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
  37. package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
  38. package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
  39. package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
  40. package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
  41. package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
  42. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
  43. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
  44. package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
  45. package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
  46. package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
  47. package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
  48. package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
  49. package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
  50. package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
  51. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
  52. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
  53. package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
  54. package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
  55. package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
  56. package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
  57. package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
  58. package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
  59. package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
  60. package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
  61. package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
  62. package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
  63. package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
  64. package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
  65. package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
  66. package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +145 -59
  67. package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +61 -0
  68. package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +10 -4
  69. package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +37 -8
  70. package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +86 -25
  71. package/vendor/node_modules/@legendapp/spark-cli/dist/dependency-pins.js +132 -0
  72. package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +13 -4
  73. package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +13 -10
  74. package/vendor/node_modules/@legendapp/spark-cli/dist/errors.js +100 -0
  75. package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +2 -2
  76. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
  77. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
  78. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-native.cjs +5 -1
  79. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
  80. package/vendor/node_modules/@legendapp/spark-cli/dist/helpers.js +1 -1
  81. package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +52 -44
  82. package/vendor/node_modules/@legendapp/spark-cli/dist/json.js +16 -0
  83. package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
  84. package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
  85. package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
  86. package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +86 -0
  87. package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
  88. package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
  89. package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
  90. package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
  91. package/vendor/node_modules/@legendapp/spark-cli/dist/process.js +7 -0
  92. package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +90 -32
  93. package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +86 -5
  94. package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
  95. package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
  96. package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
  97. package/vendor/node_modules/@legendapp/spark-cli/dist/universal.cjs +2 -1
  98. package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
  99. package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +5 -9
  100. package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
  101. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
  102. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
  103. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +12 -10
  104. package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
  105. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
  106. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
  107. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
  108. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
  109. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
  110. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
  111. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
  112. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
  113. package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
  114. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
  115. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
  116. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
  117. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
  118. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
  119. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
  120. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +14 -12
  121. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
  122. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +14 -12
  123. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
  124. package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
  125. package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
  126. package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
  127. package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
  128. package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
  129. package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
  130. package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
  131. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
  132. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
  133. package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
  134. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
  135. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
  136. package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
  137. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
  138. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
  139. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
  140. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
  141. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
  142. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
  143. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
  144. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
  145. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
  146. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
  147. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
  148. package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
  149. package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
  150. package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
  151. package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
  152. package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
  153. package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
  154. package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
  155. package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
  156. package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
  157. package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
  158. package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
  159. package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
  160. package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
  161. package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
  162. package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
  163. package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
  164. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
  165. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
  166. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
  167. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
  168. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
  169. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
  170. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
  171. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
  172. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
  173. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
  174. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
  175. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
  176. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
  177. package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
  178. package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
  179. package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
  180. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
  181. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
  182. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +116 -0
  183. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
  184. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
  185. package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
  186. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
  187. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
  188. package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
  189. package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
  190. package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
  191. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
  192. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
  193. package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
  194. package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +18 -3
  195. package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
  196. package/vendor/node_modules/@legendapp/spark-desktop-config/expo.cjs +1 -0
  197. package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
  198. package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
  199. package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
  200. package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.cjs +106 -0
  201. package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.d.cts +1 -0
  202. package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +7 -5
  203. package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
  204. package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
  205. package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
  206. package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
  207. package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
  208. package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
  209. package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
  210. package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
  211. package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
  212. package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
  213. package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
  214. package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
  215. package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
  216. package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
  217. package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
  218. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
  219. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
  220. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
  221. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
  222. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
  223. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
  224. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
  225. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
  226. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
  227. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
  228. package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
  229. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
  230. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
  231. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
  232. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
  233. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
  234. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3169 -0
  235. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
  236. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
  237. package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
  238. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
  239. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +146 -70
  240. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
  241. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
  242. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
  243. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
  244. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
  245. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
  246. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
  247. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
  248. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
  249. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
  250. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
  251. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
  252. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
  253. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
  254. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
  255. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
  256. package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
  257. package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
  258. package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
  259. package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
  260. package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
  261. package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
  262. package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
  263. package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
  264. package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
  265. package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
  266. package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
  267. package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
  268. package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
  269. package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
  270. package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
  271. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
  272. package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
  273. package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
  274. package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
  275. package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
  276. package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
  277. package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
  278. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
  279. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
  280. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
  281. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
  282. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
  283. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
  284. package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
  285. package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
  286. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
  287. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
  288. package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
  289. package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
  290. package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
  291. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
  292. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
  293. package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
  294. package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
  295. package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
  296. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
  297. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
  298. package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
  299. package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
  300. package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
  301. package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
  302. package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
  303. package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
  304. package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
  305. package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
  306. package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
  307. package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
  308. package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
  309. package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
  310. package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
  311. package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
  312. package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
  313. package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +51 -8
  314. package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
  315. package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
  316. package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
  317. package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
  318. package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
  319. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
  320. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
  321. package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
  322. package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
  323. package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
  324. package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
  325. package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
  326. package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
  327. package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
  328. package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
  329. package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
  330. package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
  331. package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
  332. package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
  333. package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
  334. package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
  335. package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
  336. package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
  337. package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
  338. package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
  339. package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
  340. package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
  341. package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
  342. package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
  343. package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
  344. package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
  345. package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
  346. package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
  347. package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
  348. package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
  349. package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
  350. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
  351. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
  352. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
  353. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1419 -0
  354. package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
  355. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
  356. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
  357. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
  358. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
  359. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
  360. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
  361. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
  362. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
  363. package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.h +10 -0
  364. package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.mm +422 -0
  365. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
  366. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
  367. package/vendor/node_modules/@legendapp/spark-ui/package.json +17 -4
  368. package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
  369. package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
  370. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +37 -0
  371. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +86 -0
  372. package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
  373. package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
  374. package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
  375. package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
  376. package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
  377. package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
  378. package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
  379. package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
  380. package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
  381. package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
  382. package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
  383. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
  384. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
  385. package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
  386. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
  387. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
  388. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
  389. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
  390. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
  391. package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
  392. package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/SwipeActionsNativeComponent.ts +11 -0
  393. package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/index.tsx +41 -0
  394. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
  395. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
  396. package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
  397. package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
  398. package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
  399. package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
  400. package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
  401. package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
  402. package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
  403. package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
  404. package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
  405. package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
  406. package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
  407. package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
  408. package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
  409. package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
  410. package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
  411. package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
  412. package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
  413. package/windows-macos.ts +1 -0
  414. package/expo-metro.cjs +0 -1
  415. package/message-dialog.ts +0 -1
  416. package/universal.cjs +0 -1
  417. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
  418. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
  419. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
  420. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
  421. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
  422. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.mm +0 -53
@@ -1,11 +1,11 @@
1
- import { packageSources } from "./release.js";
1
+ import { installedRelease, materializeReleasePackages, packageSources, verifyMaterializedReleasePackages } from "./release.js";
2
2
  import { packageManager, managerCommand, localArchive } from "./package-manager.js";
3
3
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { createRequire } from "node:module";
6
6
  import ts from "typescript";
7
7
  import { run } from "./commands.js";
8
- import { readJson } from "./project.js";
8
+ import { readJson, writeJson } from "./project.js";
9
9
  export const integrationMarker = "// spark: existing Expo project";
10
10
  /** Wrap an existing export without reprinting or moving the application's code. */
11
11
  export function composeExport(source, file, module, fn, root = true) {
@@ -43,8 +43,8 @@ export function composeMetro(source, file) {
43
43
  if (!replacements.length)
44
44
  throw new Error(`Cannot safely compose ${file}: use Expo's getDefaultConfig before adding desktop support. No files were changed.`);
45
45
  for (const { start, end } of replacements.sort((a, b) => b.start - a.start))
46
- source = source.slice(0, start) + '"@legendapp/spark/expo-metro"' + source.slice(end);
47
- return composeExport(source, file, "@legendapp/spark/expo-metro", "withSparkMetro", false);
46
+ source = source.slice(0, start) + '"@legendapp/spark/metro"' + source.slice(end);
47
+ return composeExport(source, file, "@legendapp/spark/metro", "withSparkMetro", false);
48
48
  }
49
49
  export async function addDesktop(root, manifestFile) {
50
50
  const pkgFile = path.join(root, "package.json");
@@ -54,6 +54,7 @@ export async function addDesktop(root, manifestFile) {
54
54
  if (pkg.type === "module")
55
55
  throw new Error("ES module package configurations need explicit composition; automatic add desktop currently supports Expo's CommonJS project layout. No files were changed.");
56
56
  const manager = packageManager(root);
57
+ const release = manifestFile ? undefined : installedRelease();
57
58
  const req = createRequire(pkgFile);
58
59
  const installed = (name) => readJson(req.resolve(`${name}/package.json`)).version;
59
60
  // Never upgrade the mobile baseline as a side effect of adding desktop.
@@ -72,6 +73,43 @@ export async function addDesktop(root, manifestFile) {
72
73
  if (existsSync(desktopFile)) {
73
74
  if (readJson(desktopFile).extends !== "expo")
74
75
  throw new Error("This app already uses spark-owned configuration; add desktop is for existing Expo projects.");
76
+ if (release) {
77
+ const sources = packageSources(undefined, release);
78
+ const replacement = new Map(Object.entries(release.packages).map(([name, asset]) => [asset.url, sources[name]]));
79
+ const portableSources = new Set(replacement.values());
80
+ let changed = false, needsVerify = false;
81
+ function secureDependencies(value) {
82
+ if (typeof value === "string") {
83
+ const portable = replacement.get(value);
84
+ if (portable) {
85
+ changed = true;
86
+ needsVerify = true;
87
+ return portable;
88
+ }
89
+ if (portableSources.has(value))
90
+ needsVerify = true;
91
+ return value;
92
+ }
93
+ if (Array.isArray(value))
94
+ return value.map(secureDependencies);
95
+ if (value && typeof value === "object")
96
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, secureDependencies(item)]));
97
+ return value;
98
+ }
99
+ for (const field of ["dependencies", "devDependencies", "optionalDependencies", "overrides", "resolutions", "pnpm"])
100
+ if (pkg[field])
101
+ pkg[field] = secureDependencies(pkg[field]);
102
+ if (needsVerify) {
103
+ await materializeReleasePackages(release, root);
104
+ verifyMaterializedReleasePackages(release, root);
105
+ if (changed)
106
+ writeJson(pkgFile, pkg);
107
+ const ignoreFile = path.join(root, ".gitignore");
108
+ const ignore = existsSync(ignoreFile) ? readFileSync(ignoreFile, "utf8") : "";
109
+ if (!ignore.includes("!/spark-packages/**"))
110
+ writeFileSync(ignoreFile, `${ignore}${ignore.endsWith("\n") || !ignore ? "" : "\n"}\n# Spark verified release package inputs\n!/spark-packages/\n!/spark-packages/**\n`);
111
+ }
112
+ }
75
113
  await run(root, managerCommand(manager, ["install"]));
76
114
  console.log("Desktop integration already exists; dependencies installed. Existing configuration preserved.");
77
115
  return;
@@ -101,7 +139,7 @@ export async function addDesktop(root, manifestFile) {
101
139
  files.set(native, composeExport(existsSync(path.join(root, native)) ? readFileSync(path.join(root, native), "utf8") : "module.exports = {};\n", native, "@legendapp/spark/native", "withSparkNative"));
102
140
  const template = path.resolve(import.meta.dirname, "../templates/universal");
103
141
  const defaults = readJson(path.join(template, "package.json"));
104
- const archives = packageSources(manifestFile);
142
+ const archives = packageSources(manifestFile, release);
105
143
  const local = ["@legendapp/spark"];
106
144
  const dependencies = {};
107
145
  for (const name of local) {
@@ -123,7 +161,8 @@ export async function addDesktop(root, manifestFile) {
123
161
  }
124
162
  // Resolve local transitive SDK packages without replacing any mobile pins.
125
163
  const vendor = ["@react-native-runtimes/core", "react-native-nitro-modules", "@op-engineering/op-sqlite", "react-native-webview"];
126
- const overrides = { ...Object.fromEntries(local.map(name => [name, dependencies[name]])), "@expo/cli": "54.0.27" };
164
+ const overrides = { ...Object.fromEntries(local.map(name => [name, dependencies[name]])), "@expo/cli": "54.0.27",
165
+ "react-native-macos": defaults.overrides["react-native-macos"], "react-native-windows": defaults.overrides["react-native-windows"] };
127
166
  for (const name of vendor) {
128
167
  if (archives[name]) {
129
168
  overrides[name] = archives[name];
@@ -154,11 +193,15 @@ export async function addDesktop(root, manifestFile) {
154
193
  files.set("desktop.config.json", JSON.stringify(desktop, null, 2) + "\n");
155
194
  const ignoreFile = path.join(root, ".gitignore");
156
195
  const ignore = existsSync(ignoreFile) ? readFileSync(ignoreFile, "utf8") : "";
157
- files.set(".gitignore", `${ignore}${ignore.endsWith("\n") || !ignore ? "" : "\n"}\n# spark generated desktop state\n/.spark/\n/macos/\n/windows/\n`);
196
+ files.set(".gitignore", `${ignore}${ignore.endsWith("\n") || !ignore ? "" : "\n"}\n# spark generated desktop state\n/.spark/\n/macos/\n/windows/\n${release ? "\n# Spark verified release package inputs\n!/spark-packages/\n!/spark-packages/**\n" : ""}`);
158
197
  // All conflicts are checked before the first write. The integration is kept
159
198
  // reviewable/retryable if the package manager fails; never regenerate mobile.
199
+ if (release)
200
+ await materializeReleasePackages(release, root);
160
201
  for (const [file, content] of files)
161
202
  writeFileSync(path.join(root, file), content);
203
+ if (release)
204
+ verifyMaterializedReleasePackages(release, root);
162
205
  await run(root, managerCommand(manager, ["install"]));
163
206
  console.log(`Added desktop support to ${root}. Existing entry point and mobile/web scripts are unchanged.\nRun spark build --dev --platform macos, then spark dev --platform macos. Windows native builds run on Windows.`);
164
207
  }
@@ -1,5 +1,5 @@
1
1
  export function buildMode(values) {
2
- const prebuilt = values.runner || values.prebuilt || values.go;
2
+ const prebuilt = values.runner;
3
3
  if ([prebuilt, values.dev, values.preview, values.release].filter(Boolean).length > 1) {
4
4
  throw new Error("Choose only one build mode: --dev, --preview, --release, or --runner.");
5
5
  }
@@ -1,5 +1,8 @@
1
+ import { restoreNativeMetadata } from "./native-metadata.js";
2
+ import { assertNativePatchPreflight } from "./native-patch-preflight.js";
3
+ import { missingNativeFrameworks, preparationChanges, preserveMacOSPods } from "./native-preparation.js";
1
4
  import { macOSReleaseSettings } from "./macos-release.js";
2
- import { projectPlatform } from "./platform.js";
5
+ import { macOSXcodeArchitecture, projectPlatform } from "./platform.js";
3
6
  import { isUniversal, isExpoProject } from "@legendapp/spark-desktop-config/config.cjs";
4
7
  import { buildWindows } from "./windows.js";
5
8
  import { copyHelpers } from "./helpers.js";
@@ -8,10 +11,12 @@ import { cpSync, existsSync, mkdirSync, readFileSync, realpathSync, readdirSync,
8
11
  import path from "node:path";
9
12
  import { registerRuntime } from "./local.js";
10
13
  import { binary, doctor, run } from "./commands.js";
11
- import { prepareConfig, entryFile, digest, hashFiles, hostSourceSignature, nativePackages, readJson, runtimeFor, selection, stateFile, writeJson, validateBuildModules, goConfigurationIssues, } from "./project.js";
12
- export async function analyze(root, packages = nativePackages(root)) {
14
+ import { prepareConfig, entryFile, digest, hashFiles, nativePreparationInputs, nativeProjectFingerprint, localSigningIdentity, nativePackages, readJson, runtimeFor, selection, stateFile, writeJson, validateBuildModules, goConfigurationIssues, } from "./project.js";
15
+ export async function analyze(root) {
16
+ assertNativePatchPreflight(root);
13
17
  if (projectPlatform(root) === "windows")
14
18
  throw new Error("Windows production analysis is not implemented; use spark build --dev.");
19
+ const packages = nativePackages(root, { applyExcludes: false });
15
20
  prepareConfig(root);
16
21
  const dir = stateFile(root, "analysis");
17
22
  mkdirSync(dir, { recursive: true });
@@ -21,7 +26,9 @@ export async function analyze(root, packages = nativePackages(root)) {
21
26
  "--platform",
22
27
  "macos",
23
28
  "--entry-file",
24
- entryFile(root),
29
+ // Metro resolves export entries from its server root, which can be the
30
+ // containing workspace rather than this app's project root.
31
+ path.resolve(root, entryFile(root)),
25
32
  "--bundle-output",
26
33
  path.join(dir, "app.js"),
27
34
  "--sourcemap-output",
@@ -32,7 +39,7 @@ export async function analyze(root, packages = nativePackages(root)) {
32
39
  "false",
33
40
  "--max-workers",
34
41
  "2",
35
- ], { env: { CI: "1", ...env }, capture: true });
42
+ ], { env: { CI: "1", ...env }, label: "Analyzing production JavaScript" });
36
43
  await exportBundle({ SPARK_RUNTIME_DISCOVERY: "1" });
37
44
  const discovery = readJson(path.join(dir, "app.map"));
38
45
  const runtimeCore = packages.find(pkg => pkg.name === "@react-native-runtimes/core");
@@ -51,27 +58,74 @@ export async function analyze(root, packages = nativePackages(root)) {
51
58
  (!source.includes("/node_modules/") || /["']@react-native-runtimes\/core["']/.test(readFileSync(source, "utf8")))) });
52
59
  await exportBundle({ SPARK_RUNTIME_SOURCES: runtimeSources });
53
60
  const map = readJson(path.join(dir, "app.map"));
61
+ const sourceFile = (source) => source.includes("\0") ? undefined
62
+ : [path.resolve(root, source), path.resolve(root, source.replace(/^\//, ""))].find(file => existsSync(file));
54
63
  const used = new Set();
55
64
  for (const source of map.sources) {
65
+ const file = sourceFile(source);
66
+ const resolved = file ? realpathSync(file) : source;
56
67
  for (const pkg of packages) {
57
68
  // Metro's source map can contain absolute paths or project-relative node_modules paths.
58
69
  if (source.startsWith(pkg.root + "/") ||
70
+ resolved.startsWith(pkg.root + "/") ||
59
71
  source.includes(`/node_modules/${pkg.name}/`) ||
60
72
  source.startsWith(`node_modules/${pkg.name}/`))
61
73
  used.add(pkg.name);
62
74
  }
63
75
  }
64
76
  const config = readAppConfig(root);
65
- const result = selection(packages, used, config.expo?.extra?.spark?.include ?? []);
77
+ const explicitExcluded = config.expo?.autolinking?.exclude ?? [];
78
+ const include = config.expo?.extra?.spark?.include ?? [];
79
+ const result = selection(packages, used, include, explicitExcluded);
80
+ const violations = packages.filter(pkg => explicitExcluded.includes(pkg.name)).flatMap(pkg => {
81
+ const reasons = [];
82
+ if (used.has(pkg.name))
83
+ reasons.push("used by the production bundle");
84
+ if (include.includes(pkg.name))
85
+ reasons.push("explicit native include");
86
+ for (const included of result.included) {
87
+ if (included.requires.includes(pkg.name))
88
+ reasons.push(`required by included ${included.name} (spark.requires)`);
89
+ if (Object.hasOwn(included.json.dependencies ?? {}, pkg.name) && !Object.hasOwn(included.json.optionalDependencies ?? {}, pkg.name))
90
+ reasons.push(`required by included ${included.name} (dependencies)`);
91
+ if (Object.hasOwn(included.json.peerDependencies ?? {}, pkg.name) && !included.json.peerDependenciesMeta?.[pkg.name]?.optional)
92
+ reasons.push(`required by included ${included.name} (peerDependencies)`);
93
+ }
94
+ if (!reasons.length)
95
+ return [];
96
+ const names = [pkg.name];
97
+ if (pkg.name.startsWith("@legendapp/spark-"))
98
+ names.push(`@legendapp/spark/${pkg.name.slice("@legendapp/spark-".length).replace(/^desktop-/, "")}`);
99
+ const importedFrom = map.sources.find(source => {
100
+ if (source.includes("/node_modules/") || source.startsWith("node_modules/"))
101
+ return false;
102
+ const file = sourceFile(source);
103
+ return file !== undefined && names.some(name => readFileSync(file, "utf8").includes(name));
104
+ });
105
+ return [{ name: pkg.name, reasons, ...(importedFrom ? { importedFrom } : {}) }];
106
+ });
66
107
  writeJson(stateFile(root, "selection-report.json"), {
67
108
  included: result.included.map((p) => p.name),
68
109
  excluded: result.excluded.map((p) => p.name),
69
110
  reasons: result.reasons,
70
111
  sources: map.sources,
112
+ nativeCheck: { violations },
71
113
  });
114
+ if (violations.length)
115
+ throw new Error([
116
+ `Release native-module check failed: ${violations.length} excluded native package${violations.length === 1 ? " is" : "s are"} required.`,
117
+ ...violations.flatMap(violation => [
118
+ ` ${violation.name}`,
119
+ ...violation.reasons.map(reason => ` ${reason}${reason === "used by the production bundle" && violation.importedFrom ? ` (e.g. ${violation.importedFrom})` : ""}`),
120
+ " excluded by desktop.config.json expo.autolinking.exclude",
121
+ ]),
122
+ "Fix: stop excluding it, or remove the import. In legend-apps, add the package (or its @legendapp/spark/<subpath>) to apps/<app>/app.manifest.ts nativeModules.macos.",
123
+ "Details: .spark/selection-report.json (nativeCheck)",
124
+ ].join("\n"));
72
125
  return result;
73
126
  }
74
127
  export async function build(root, mode, force = false) {
128
+ assertNativePatchPreflight(root);
75
129
  const lock = stateFile(root, "build.lock");
76
130
  mkdirSync(path.dirname(lock), { recursive: true });
77
131
  try {
@@ -118,11 +172,10 @@ async function buildUnlocked(root, mode, force) {
118
172
  throw new Error(`Build the Spark Runner from a generic SDK starter: ${issues.join("; ")}`);
119
173
  }
120
174
  await doctor(root);
121
- const all = nativePackages(root);
122
175
  const productionGraph = mode === "release" || mode === "preview";
123
176
  const chosen = productionGraph
124
- ? await analyze(root, all)
125
- : { included: all, excluded: [] };
177
+ ? await analyze(root)
178
+ : { included: nativePackages(root), excluded: [] };
126
179
  validateBuildModules(mode, chosen.included);
127
180
  const runtime = runtimeFor(root, chosen.included, mode);
128
181
  const productionHash = productionGraph
@@ -131,23 +184,19 @@ async function buildUnlocked(root, mode, force) {
131
184
  if (productionHash)
132
185
  runtime.fingerprint = digest(runtime.fingerprint + productionHash);
133
186
  const resultFile = stateFile(root, `${mode}-build.json`);
134
- if (!force && existsSync(resultFile)) {
135
- const existing = readJson(resultFile);
136
- if (existing.runtime.fingerprint === runtime.fingerprint &&
137
- existsSync(existing.app)) {
138
- console.log(`Reusing ${existing.app}`);
139
- return existing;
140
- }
141
- }
187
+ const excludedNames = [...new Set([
188
+ ...(readAppConfig(root).expo.autolinking?.exclude ?? []),
189
+ ...chosen.excluded.map((p) => p.name),
190
+ ])];
142
191
  writeJson(stateFile(root, "native-selection.json"), {
143
- excluded: chosen.excluded.map((p) => p.name),
192
+ excluded: excludedNames,
144
193
  included: chosen.included.map((p) => ({ name: p.name, root: p.root })),
145
194
  });
146
195
  const rnConfig = path.join(root, "react-native.config.js");
147
196
  const marker = "// Generated by spark; extend with configuration plugins.";
148
- if (existsSync(rnConfig) &&
197
+ if (!isUniversal(root) && (existsSync(rnConfig) &&
149
198
  !readFileSync(rnConfig, "utf8").startsWith(marker) &&
150
- !(isExpoProject(root) && readFileSync(rnConfig, "utf8").includes("// spark: existing Expo project")))
199
+ !(isExpoProject(root) && readFileSync(rnConfig, "utf8").includes("// spark: existing Expo project"))))
151
200
  throw new Error("Existing react-native.config.js is not spark-managed. Compose the native selection explicitly before building.");
152
201
  if (!isUniversal(root))
153
202
  writeFileSync(rnConfig, `${marker}\nconst selection = require('./.spark/native-selection.json');\nmodule.exports = { dependencies: Object.fromEntries([\n...selection.included.map(p => [p.name, { root: p.root }]),\n...selection.excluded.map(name => [name, { platforms: { ios: null, macos: null, android: null } }])\n]) };\n`);
@@ -155,66 +204,99 @@ async function buildUnlocked(root, mode, force) {
155
204
  if (!isUniversal(root)) {
156
205
  pkg.expo ??= {};
157
206
  pkg.expo.autolinking ??= {};
158
- pkg.expo.autolinking.exclude = chosen.excluded.map((p) => p.name);
207
+ pkg.expo.autolinking.exclude = excludedNames;
159
208
  writeJson(path.join(root, "package.json"), pkg);
160
209
  }
161
- const preparation = digest(JSON.stringify({
162
- config: readAppConfig(root),
163
- packages: chosen.included.map((p) => [
164
- p.name,
165
- hashFiles(p.root, [
166
- "package.json",
167
- p.json.codegenConfig?.jsSrcsDir ?? "src",
168
- ...readdirSync(p.root).filter((name) => name.endsWith(".podspec")),
169
- ]),
170
- ]),
171
- plugin: hostSourceSignature(root),
172
- }));
210
+ const inputs = nativePreparationInputs(root, chosen.included);
211
+ const preparation = { fingerprint: digest(JSON.stringify(inputs)), inputs, projectFingerprint: nativeProjectFingerprint(inputs, chosen.included) };
173
212
  const preparedFile = stateFile(root, "native-preparation.json");
174
- const needsPreparation = force ||
175
- !existsSync(preparedFile) ||
176
- readJson(preparedFile).fingerprint !== preparation ||
213
+ const prepared = existsSync(preparedFile) ? readJson(preparedFile) : undefined;
214
+ const nativeRoot = path.join(root, "macos");
215
+ const hasNativeProject = existsSync(nativeRoot) && readdirSync(nativeRoot).some(name => name.endsWith(".xcodeproj") && existsSync(path.join(nativeRoot, name, "project.pbxproj")));
216
+ const needsProject = force || !hasNativeProject || prepared?.projectFingerprint !== preparation.projectFingerprint;
217
+ const needsPreparation = needsProject ||
218
+ prepared?.fingerprint !== preparation.fingerprint ||
177
219
  !existsSync(path.join(root, "macos/Pods/Manifest.lock"));
178
- if (needsPreparation) {
220
+ const existing = existsSync(resultFile) ? readJson(resultFile) : undefined;
221
+ if (!force && existing) {
222
+ if (existing.runtime.fingerprint === runtime.fingerprint &&
223
+ existing.preparation?.fingerprint === preparation.fingerprint &&
224
+ existing.product === path.basename(existing.app) &&
225
+ existsSync(existing.app)) {
226
+ console.log(`Reusing ${existing.app}`);
227
+ return existing;
228
+ }
229
+ }
230
+ const reasons = force ? ["forced build"] : !existing ? ["no cached app"] : [
231
+ ...preparationChanges(existing.preparation, preparation),
232
+ ...(existing.runtime.fingerprint !== runtime.fingerprint ? ["runtime inputs changed"] : []),
233
+ ...(!existsSync(existing.app) ? ["cached app missing"] : []),
234
+ ...(existing.product !== path.basename(existing.app) ? ["cached app product is unverified"] : []),
235
+ ];
236
+ console.log(`Building ${mode} runtime: ${reasons.join("; ")}.`);
237
+ const nativeConfig = readAppConfig(root).expo;
238
+ if (needsPreparation)
239
+ rmSync(preparedFile, { force: true });
240
+ if (needsProject) {
241
+ console.log(`Preparing native project (preserving CocoaPods cache): ${force ? "forced build" : !hasNativeProject ? "native project missing" : preparationChanges(prepared, preparation).join("; ") || "native project provenance missing"}.`);
179
242
  const manifest = readFileSync(path.join(root, "package.json"), "utf8");
243
+ const appJson = path.join(root, "app.json");
244
+ const originalAppJson = existsSync(appJson) ? readFileSync(appJson, "utf8") : undefined;
180
245
  try {
181
- await run(root, [
246
+ await preserveMacOSPods(root, () => run(root, [
182
247
  binary(root, "expo-desktop"),
183
248
  "prebuild",
184
249
  "--platform",
185
250
  "macos",
186
251
  "--template",
187
- "expo-desktop-template-bare-minimum@54.81.1-beta.6",
252
+ "expo-desktop-template-bare-minimum@54.81.1",
188
253
  "--no-install",
189
- ...(force ? ["--clean"] : []),
190
- ], { env: { CI: "1" }, capture: true });
191
- // beta.5 copies all-platform template dependencies even for macOS. Preserve this
254
+ // Template renaming is not idempotent (HelloWorld becomes
255
+ // LegendHelloWorld, then LegendLegendHelloWorld). Native projects
256
+ // are generated output; recreate them only when project inputs change.
257
+ "--clean",
258
+ ], { env: { CI: "1" }, label: "Generating native project" }));
259
+ // Expo Desktop copies all-platform template dependencies even for macOS. Preserve this
192
260
  // platform's installed manifest instead of silently adding uninstalled Windows packages.
193
261
  }
194
262
  finally {
195
263
  writeFileSync(path.join(root, "package.json"), manifest);
264
+ // Upstream template replacement also rewrites app.json substrings.
265
+ if (originalAppJson !== undefined)
266
+ writeFileSync(appJson, originalAppJson);
196
267
  }
268
+ }
269
+ if (needsPreparation) {
197
270
  // ReactCodegen's source glob must not pick up bindings from a previously larger graph.
198
271
  rmSync(path.join(root, "macos/build/generated"), {
199
272
  recursive: true,
200
273
  force: true,
201
274
  });
275
+ }
276
+ const missing = missingNativeFrameworks(root);
277
+ if (needsPreparation || missing.length) {
278
+ if (needsPreparation && !needsProject)
279
+ console.log(`Updating CocoaPods dependencies: ${prepared?.fingerprint !== preparation.fingerprint ? preparationChanges(prepared, preparation).join("; ") : "CocoaPods state missing"}.`);
280
+ if (missing.length && !needsPreparation)
281
+ console.log(`Restoring missing native frameworks:\n${missing.join("\n")}`);
202
282
  await run(root, ["pod", "install"], {
203
283
  cwd: path.join(root, "macos"),
204
284
  env: { RCT_NEW_ARCH_ENABLED: "1" },
205
- capture: true,
285
+ label: "Installing CocoaPods dependencies",
206
286
  });
207
- writeJson(preparedFile, { fingerprint: preparation });
287
+ const remaining = missingNativeFrameworks(root);
288
+ if (remaining.length)
289
+ throw new Error(`Native frameworks are missing after pod install. Restore the package's native artifacts and retry:\n${remaining.join("\n")}`);
290
+ writeJson(preparedFile, preparation);
208
291
  }
209
- const nativeRoot = path.join(root, "macos");
292
+ await restoreNativeMetadata(root, nativeConfig);
210
293
  const workspace = readdirSync(nativeRoot).find((name) => name.endsWith(".xcworkspace"));
211
294
  if (!workspace)
212
295
  throw new Error("Prebuild did not produce a macOS workspace.");
213
296
  const name = workspace.slice(0, -".xcworkspace".length);
214
297
  const configuration = mode === "release" ? "Release" : "Debug";
215
- const derived = stateFile(root, "DerivedData");
216
- console.log(`Building ${mode === "go" ? "Spark Runner" : mode} runtime (${configuration}, arm64)…`);
217
- // Export once for analysis; native build performs the normal production bundle step.
298
+ const xcodeArch = macOSXcodeArchitecture(runtime.arch);
299
+ const derived = stateFile(root, `DerivedData/macos-${runtime.arch}`);
218
300
  await run(root, [
219
301
  "xcodebuild",
220
302
  "-workspace",
@@ -224,10 +306,10 @@ async function buildUnlocked(root, mode, force) {
224
306
  "-configuration",
225
307
  configuration,
226
308
  "-destination",
227
- "platform=macOS,arch=arm64",
309
+ `platform=macOS,arch=${xcodeArch}`,
228
310
  "-derivedDataPath",
229
311
  derived,
230
- "ARCHS=arm64",
312
+ `ARCHS=${xcodeArch}`,
231
313
  "ONLY_ACTIVE_ARCH=YES",
232
314
  "CODE_SIGNING_ALLOWED=NO",
233
315
  ...(mode === "release" ? macOSReleaseSettings : []),
@@ -236,14 +318,15 @@ async function buildUnlocked(root, mode, force) {
236
318
  "build",
237
319
  ], {
238
320
  env: { RCT_NEW_ARCH_ENABLED: "1", ENTRY_FILE: entryFile(root), ...(productionGraph ? { SPARK_RUNTIME_SOURCES: stateFile(root, "analysis/runtime-sources.json") } : {}) },
239
- capture: true,
321
+ label: `Building ${mode === "go" ? "Spark Runner" : mode} runtime (${configuration}, ${runtime.arch})`,
240
322
  });
241
323
  const products = path.join(derived, "Build", "Products", configuration);
242
- const product = readdirSync(products).find((name) => name.endsWith(".app"));
243
- if (!product)
244
- throw new Error("Build completed without an app product.");
245
- const destination = stateFile(root, `products/${mode}/${product}`);
246
- rmSync(destination, { recursive: true, force: true });
324
+ // The scheme's product, not the first .app: a renamed app leaves its old bundle in DerivedData.
325
+ const product = `${name}.app`;
326
+ if (!existsSync(path.join(products, product)))
327
+ throw new Error(`Build completed without ${product}.`);
328
+ const destination = stateFile(root, `products/macos-${runtime.arch}/${mode}/${product}`);
329
+ rmSync(path.dirname(destination), { recursive: true, force: true });
247
330
  mkdirSync(path.dirname(destination), { recursive: true });
248
331
  cpSync(path.join(products, product), destination, { recursive: true, verbatimSymlinks: true });
249
332
  if (mode === "release" &&
@@ -251,7 +334,10 @@ async function buildUnlocked(root, mode, force) {
251
334
  throw new Error("Standalone build is missing its JavaScript bundle.");
252
335
  const result = {
253
336
  app: destination,
337
+ // Older receipts may record a stale bundle selected from DerivedData.
338
+ product,
254
339
  runtime: runtimeFor(root, chosen.included, mode),
340
+ preparation,
255
341
  };
256
342
  if (mode === "go" && process.env.SPARK_RELEASE_REVISION) {
257
343
  if (!/^[a-f0-9]{40}$/.test(process.env.SPARK_RELEASE_REVISION))
@@ -269,9 +355,9 @@ async function buildUnlocked(root, mode, force) {
269
355
  if (existsSync(hermes))
270
356
  await run(root, ["strip", "-S", "-x", hermes], { capture: true });
271
357
  }
272
- // Local standalone outputs remain ad-hoc. `spark package` signs a separate
273
- // staging copy with Developer ID for distribution.
274
- await run(root, ["codesign", "--force", "--deep", "--sign", "-", destination], { capture: true });
358
+ // Development apps can opt into a local identity for same-team native plugins.
359
+ // Standalone outputs remain ad-hoc until `spark package` signs its staging copy.
360
+ await run(root, ["codesign", "--force", "--deep", "--sign", localSigningIdentity(root, mode), destination], { capture: true });
275
361
  writeJson(resultFile, result);
276
362
  console.log(`Built ${destination}`);
277
363
  return result;
@@ -0,0 +1,61 @@
1
+ import { parseArgs } from "node:util";
2
+ import { buildMode } from "./build-mode.js";
3
+ const options = {
4
+ example: { type: "string" }, "package-manager": { type: "string" },
5
+ runtime: { type: "string", multiple: true }, universal: { type: "boolean" },
6
+ device: { type: "string" }, project: { type: "string" }, platform: { type: "string" },
7
+ packages: { type: "string" }, port: { type: "string" }, runner: { type: "boolean" },
8
+ dev: { type: "boolean" }, release: { type: "boolean" }, preview: { type: "boolean" },
9
+ force: { type: "boolean" }, "dry-run": { type: "boolean" }, "submission-id": { type: "string" }, help: { type: "boolean", short: "h" },
10
+ };
11
+ const commands = {
12
+ create: { flags: ["example", "package-manager", "universal", "platform", "packages"], arguments: [1, 1] },
13
+ "add desktop": { flags: ["project", "packages"], arguments: [0, 0] },
14
+ "sdk export": { flags: ["packages", "runtime"], arguments: [1, 1] },
15
+ "sdk import": { flags: [], arguments: [1, 1] },
16
+ "sdk register": { flags: [], arguments: [1, 1] },
17
+ "sdk pack": { flags: ["project", "platform"], arguments: [0, 0] },
18
+ "sdk package-runner": { flags: ["project", "platform", "force", "submission-id"], arguments: [0, 0] },
19
+ "sdk build-runner": { flags: ["project", "platform", "packages", "package-manager", "force"], arguments: [0, 0] },
20
+ build: { flags: ["project", "platform", "device", "port", "runner", "dev", "release", "preview", "force"], arguments: [0, 0] },
21
+ prebuild: { flags: ["project", "platform"], arguments: [0, 0] },
22
+ doctor: { flags: ["project"], arguments: [0, 0] },
23
+ upgrade: { flags: ["project", "dry-run"], arguments: [0, 0] },
24
+ "updates init": { flags: ["project", "platform"], arguments: [1, 1] },
25
+ credentials: { flags: ["project", "platform"], arguments: [0, 0] },
26
+ package: { flags: ["project", "platform", "force", "submission-id"], arguments: [0, 0] },
27
+ analyze: { flags: ["project", "platform"], arguments: [0, 0] },
28
+ open: { flags: ["project", "platform", "port"], arguments: [0, 1] },
29
+ };
30
+ /** Validate the command grammar before resolving a project or performing side effects. */
31
+ export function cliArguments(args) {
32
+ const parsed = parseArgs({ args, allowPositionals: true, options });
33
+ const { values, positionals } = parsed;
34
+ const grouped = ["sdk", "add", "updates"].includes(positionals[0]);
35
+ const command = positionals.slice(0, grouped ? 2 : 1).join(" ");
36
+ if (!command || (grouped && positionals.length === 1 && values.help)) {
37
+ if (Object.keys(values).some(key => key !== "help"))
38
+ throw new Error("Choose a command before specifying options. Run spark --help.");
39
+ return parsed;
40
+ }
41
+ const contract = commands[command];
42
+ if (!contract)
43
+ throw new Error(`Unknown command: ${command}. Run spark --help.`);
44
+ for (const key of Object.keys(values))
45
+ if (key !== "help" && !contract.flags.includes(key))
46
+ throw new Error(`--${key} is not an option for spark ${command}`);
47
+ const count = positionals.length - (grouped ? 2 : 1);
48
+ if ((!values.help && count < contract.arguments[0]) || count > contract.arguments[1])
49
+ throw new Error(`Invalid arguments for spark ${command}. Expected ${contract.arguments[0] === contract.arguments[1] ? contract.arguments[0] : "zero or one"} positional argument(s).`);
50
+ if (values.platform && !["macos", "windows", "ios", "android", "web"].includes(values.platform))
51
+ throw new Error("Platform must be macos, windows, ios, android, or web.");
52
+ if (values.port !== undefined && (!Number.isInteger(Number(values.port)) || Number(values.port) < 1 || Number(values.port) > 65535))
53
+ throw new Error("Port must be an integer between 1 and 65535.");
54
+ if (values["package-manager"] && !["npm", "pnpm", "yarn", "bun"].includes(values["package-manager"]))
55
+ throw new Error("Package manager must be npm, pnpm, yarn, or bun.");
56
+ if (command === "build")
57
+ buildMode(values);
58
+ if (command === "sdk build-runner" && values.project && (values.packages || values["package-manager"]))
59
+ throw new Error("--packages and --package-manager configure a generated Runner project; omit --project to use them.");
60
+ return parsed;
61
+ }
@@ -3,7 +3,8 @@ import { checkExpoDesktopNode } from "./expo-node.js";
3
3
  import { appendFileSync, mkdirSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { createRequire } from "node:module";
6
- import { stateFile } from "./project.js";
6
+ import { statePath as stateFile } from "@legendapp/spark-desktop-config/config.cjs";
7
+ import { CommandError } from "./errors.js";
7
8
  const running = new Map();
8
9
  const secretFlags = new Set(["--password", "--apple-id-password", "--token", "--secret", "--api-key", "-P"]);
9
10
  export function commandRedactor(argv, secrets = []) {
@@ -39,6 +40,9 @@ export async function run(root, argv, options = {}) {
39
40
  running.get(root).add(child);
40
41
  let output = "";
41
42
  const log = stateFile(root, `logs/${Date.now()}-${crypto.randomUUID()}-${path.basename(argv[0])}.log`);
43
+ const started = Date.now();
44
+ if (options.label)
45
+ console.log(`${options.label}…\nLog: ${log}`);
42
46
  async function consume(stream, target) {
43
47
  const decoder = new TextDecoder();
44
48
  for await (const chunk of stream) {
@@ -71,7 +75,9 @@ export async function run(root, argv, options = {}) {
71
75
  process.stdout.write(redact(output));
72
76
  }
73
77
  if (code)
74
- throw new Error(`${argv.map(redact).join(" ")} exited ${code}. See ${log}\n${redact(output).slice(-1800)}`);
78
+ throw new CommandError(argv.map(redact), code, redact(output), log);
79
+ if (options.label)
80
+ console.log(`${options.label} finished (${((Date.now() - started) / 1000).toFixed(1)}s).`);
75
81
  return output;
76
82
  }
77
83
  export function binary(root, name) {
@@ -94,8 +100,8 @@ export async function doctor(root) {
94
100
  await run(root, ["pwsh.exe", "-File", path.join(windows, "Scripts/rnw-dependencies.ps1")]);
95
101
  return;
96
102
  }
97
- if (process.platform !== "darwin" || process.arch !== "arm64")
98
- throw new Error("The prototype supports Apple Silicon macOS only.");
103
+ if (process.platform !== "darwin")
104
+ throw new Error("Native macOS builds require macOS.");
99
105
  for (const tool of ["node", "pod", "xcodebuild"])
100
106
  if (!which(tool))
101
107
  throw new Error(`Missing ${tool}. Install the macOS native prerequisites described in docs/development.md, then retry the build.`);