peachsim 0.1.939 → 0.1.1399

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 (396) hide show
  1. package/README.md +28 -22
  2. package/cli/app-catalog.ts +29 -14
  3. package/cli/app-fonts.ts +5 -3
  4. package/cli/bridge-flow-runner.ts +40 -29
  5. package/cli/cloud-client.ts +57 -21
  6. package/cli/cloud-test-tunnel.ts +12 -18
  7. package/cli/commands/agent.ts +1 -1
  8. package/cli/commands/app-fonts.ts +3 -3
  9. package/cli/commands/assert.ts +8 -8
  10. package/cli/commands/auth.ts +8 -3
  11. package/cli/commands/box/bundle-plane.ts +13 -1
  12. package/cli/commands/box.ts +16 -5
  13. package/cli/commands/compat.ts +1 -1
  14. package/cli/commands/config.ts +2 -2
  15. package/cli/commands/control.ts +125 -71
  16. package/cli/commands/cpu-profile.ts +45 -1
  17. package/cli/commands/daemon.ts +131 -33
  18. package/cli/commands/debug.ts +24 -17
  19. package/cli/commands/desktop.ts +7 -1
  20. package/cli/commands/detect.ts +101 -0
  21. package/cli/commands/detox.ts +6 -6
  22. package/cli/commands/device.ts +12 -12
  23. package/cli/commands/electron.ts +32 -14
  24. package/cli/commands/flow.ts +49 -41
  25. package/cli/commands/guest-host.ts +39 -1
  26. package/cli/commands/inspect/core.ts +14 -8
  27. package/cli/commands/inspect/list.ts +1 -1
  28. package/cli/commands/inspect/settle.ts +5 -3
  29. package/cli/commands/inspect/settling.ts +229 -44
  30. package/cli/commands/inspect/wait-idle.ts +3 -2
  31. package/cli/commands/inspect.ts +105 -93
  32. package/cli/commands/install-cli.ts +36 -15
  33. package/cli/commands/install-desktop.ts +68 -195
  34. package/cli/commands/kotlin.ts +6 -5
  35. package/cli/commands/login.ts +5 -5
  36. package/cli/commands/maestro-compare.ts +554 -0
  37. package/cli/commands/maestro-generate.ts +6 -3
  38. package/cli/commands/maestro.ts +22 -0
  39. package/cli/commands/mode.ts +2 -2
  40. package/cli/commands/no-bridge-hint.ts +6 -2
  41. package/cli/commands/platform.ts +35 -6
  42. package/cli/commands/preview.ts +6 -0
  43. package/cli/commands/project-report.ts +10 -12
  44. package/cli/commands/record.ts +37 -37
  45. package/cli/commands/runtime.ts +9 -9
  46. package/cli/commands/screenshot-layers.ts +4 -4
  47. package/cli/commands/screenshot-mode.ts +2 -2
  48. package/cli/commands/screenshot.ts +8 -8
  49. package/cli/commands/screenshots-capture.ts +2 -2
  50. package/cli/commands/serve.ts +9 -12
  51. package/cli/commands/setup.ts +29 -14
  52. package/cli/commands/shell-boolean-mode.ts +2 -2
  53. package/cli/commands/show-touches-mode.ts +2 -2
  54. package/cli/commands/skills.ts +11 -11
  55. package/cli/commands/swift.ts +29 -11
  56. package/cli/commands/telemetry.ts +2 -2
  57. package/cli/commands/test.ts +5 -0
  58. package/cli/commands/three-mode.ts +3 -3
  59. package/cli/commands/timeline.ts +4 -4
  60. package/cli/commands/upgrade.ts +2 -2
  61. package/cli/commands/upload.ts +15 -15
  62. package/cli/commands/what-happened.ts +2 -2
  63. package/cli/current-sim.ts +6 -3
  64. package/cli/desktop-companion.ts +55 -149
  65. package/cli/dev-build-freshness.ts +2 -2
  66. package/cli/drivers/desktop.ts +17 -9
  67. package/cli/drivers/electron.ts +1 -2
  68. package/cli/drivers/playwright-sim-host.ts +11 -2
  69. package/cli/drivers/playwright.ts +35 -2
  70. package/cli/drivers/types.ts +8 -0
  71. package/cli/maestro-compare.ts +670 -0
  72. package/cli/outbound-endpoints.ts +46 -8
  73. package/cli/recording-access.ts +6 -6
  74. package/cli/run-registry.ts +1 -1
  75. package/cli/runtime-compat.ts +5 -1
  76. package/cli/send-to-box.ts +3 -3
  77. package/cli/shell-init.ts +2 -1
  78. package/cli/ws-bridge.ts +9 -5
  79. package/detox/element-types.ts +1 -0
  80. package/detox/gestures.ts +3 -3
  81. package/detox/index.ts +67 -38
  82. package/detox/navigation-lifecycle.ts +9 -6
  83. package/detox/proof-frame.cjs +6 -4
  84. package/dist-lib/agent-daemon-client.cjs +1 -1
  85. package/dist-lib/agent-events.cjs +1 -1
  86. package/dist-lib/attached-projects.cjs +1 -1
  87. package/dist-lib/auth/shared-session.cjs +1 -1
  88. package/dist-lib/backend-origin.cjs +1 -1
  89. package/dist-lib/beta.cjs +1 -1
  90. package/dist-lib/beta.mjs +1 -1
  91. package/dist-lib/bridge-constants.cjs +1 -1
  92. package/dist-lib/bridge-contract-input.cjs +42 -17
  93. package/dist-lib/bridge-contract-input.mjs +41 -16
  94. package/dist-lib/bridge-contract.cjs +1 -4
  95. package/dist-lib/bridge-contract.mjs +1 -3
  96. package/dist-lib/bundle-channel.cjs +2918 -550
  97. package/dist-lib/capture-contract.cjs +65 -24
  98. package/dist-lib/capture-contract.mjs +63 -24
  99. package/dist-lib/cloud-contract.cjs +2 -2
  100. package/dist-lib/cloud-contract.mjs +2 -2
  101. package/dist-lib/cloud-test-args.cjs +1 -1
  102. package/dist-lib/cloud-test-args.mjs +1 -1
  103. package/dist-lib/cloud.cjs +3 -3
  104. package/dist-lib/cloud.mjs +3 -3
  105. package/dist-lib/config.cjs +15 -5
  106. package/dist-lib/config.mjs +154 -0
  107. package/dist-lib/detox/index.cjs +495 -139
  108. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  109. package/dist-lib/expo-swift-bundle.cjs +1168 -238
  110. package/dist-lib/expo-swift-metadata.cjs +34 -23
  111. package/dist-lib/expo-swift-metadata.mjs +32 -23
  112. package/dist-lib/home-paths.cjs +2 -2
  113. package/dist-lib/host/bridge-host.cjs +2938 -654
  114. package/dist-lib/host/fetch-proxy-handler.cjs +14 -1
  115. package/dist-lib/host/fetch-proxy-overrides.cjs +7 -1
  116. package/dist-lib/host/fetch-proxy-overrides.mjs +5 -1
  117. package/dist-lib/host/replacement-module-handler.cjs +2 -2
  118. package/dist-lib/host/websocket-proxy.cjs +1 -1
  119. package/dist-lib/index.cjs +999 -353
  120. package/dist-lib/jump-to-source-babel.cjs +1 -1
  121. package/dist-lib/jump-to-source-native.cjs +1 -1
  122. package/dist-lib/kotlin-host.cjs +332 -19
  123. package/dist-lib/menu.cjs +1 -1
  124. package/dist-lib/menu.mjs +1 -1
  125. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  126. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  127. package/dist-lib/metro-production-bundle.cjs +7 -7
  128. package/dist-lib/metro-production-bundle.mjs +5 -5
  129. package/dist-lib/metro.cjs +688 -250
  130. package/dist-lib/native-app-identity-project.cjs +2647 -0
  131. package/dist-lib/native-app-identity-project.mjs +1257 -0
  132. package/dist-lib/native-app-identity.cjs +325 -25
  133. package/dist-lib/native-app-identity.mjs +323 -25
  134. package/dist-lib/native-firebase-metadata.cjs +1 -1
  135. package/dist-lib/native-firebase-metadata.mjs +1 -1
  136. package/dist-lib/plist.cjs +1 -1
  137. package/dist-lib/plist.mjs +1 -1
  138. package/dist-lib/profiles.cjs +1 -1
  139. package/dist-lib/public-brand.cjs +1 -1
  140. package/dist-lib/react-native-host-modules.cjs +5 -1
  141. package/dist-lib/react-native-host-modules.mjs +5 -1
  142. package/dist-lib/scripts/dev-server-scanner.cjs +57 -32
  143. package/dist-lib/sdk.cjs +231 -51
  144. package/dist-lib/sdk.mjs +231 -51
  145. package/dist-lib/skills.cjs +4107 -1374
  146. package/dist-lib/swift-compile.cjs +290 -30
  147. package/dist-lib/swift-compile.mjs +290 -30
  148. package/dist-lib/swift-package.cjs +143 -12
  149. package/dist-lib/swift-package.mjs +137 -11
  150. package/dist-lib/swift-submit.cjs +47 -5
  151. package/dist-lib/swift-submit.mjs +42 -5
  152. package/dist-lib/swift-toolchain.cjs +7 -2
  153. package/dist-lib/swift.cjs +1 -1
  154. package/dist-lib/vite-swift.cjs +1392 -458
  155. package/dist-lib/vite.cjs +13 -17
  156. package/dist-lib/worklet-executable.cjs +248 -33
  157. package/dist-lib/worklet-executable.mjs +248 -33
  158. package/install.sh +10 -1
  159. package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Resources.kt +9 -9
  160. package/kotlin/AndroidViewSources/android/graphics/Canvas.kt +20 -0
  161. package/kotlin/AndroidViewSources/android/view/View.kt +211 -0
  162. package/kotlin/AndroidViewSources/android/widget/FrameLayout.kt +61 -0
  163. package/kotlin/AndroidViewSources/android/widget/LinearLayout.kt +49 -0
  164. package/kotlin/AppSources/android/view/Window.kt +36 -0
  165. package/kotlin/AppSources/android/view/WindowInsets.kt +9 -0
  166. package/kotlin/AppSources/android/view/WindowInsetsController.kt +5 -0
  167. package/kotlin/AppSources/android/window/OnBackInvokedDispatcher.kt +48 -0
  168. package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +20 -5
  169. package/kotlin/AppSources/androidx/compose/foundation/layout/WindowInsets.kt +15 -0
  170. package/kotlin/AppSources/androidx/compose/ui/platform/ComposeView.kt +2 -1
  171. package/kotlin/AppSources/dev/peach/app/PeachApp.kt +42 -50
  172. package/kotlin/ComposeSources/PeachComposeHost.kt +200 -84
  173. package/kotlin/ExpoComposeSources/PeachAndroidView.kt +87 -0
  174. package/kotlin/ExpoComposeSources/PeachExpoViewMount.kt +24 -0
  175. package/kotlin/ExpoComposeSources/dev/peach/expo/PeachExpoCompose.kt +28 -0
  176. package/kotlin/ExpoComposeSources/expo/modules/kotlin/views/ExpoComposeView.kt +70 -0
  177. package/kotlin/ExpoSources/dev/peach/expo/PeachExpoRuntime.kt +513 -0
  178. package/kotlin/ExpoSources/dev/peach/expo/PeachExpoTypes.kt +173 -0
  179. package/kotlin/ExpoSources/expo/modules/kotlin/AppContext.kt +20 -0
  180. package/kotlin/ExpoSources/expo/modules/kotlin/Promise.kt +19 -0
  181. package/kotlin/ExpoSources/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +198 -0
  182. package/kotlin/ExpoSources/expo/modules/kotlin/exception/CodedException.kt +126 -0
  183. package/kotlin/ExpoSources/expo/modules/kotlin/functions/Functions.kt +132 -0
  184. package/kotlin/ExpoSources/expo/modules/kotlin/jni/JavaScriptTypedArray.kt +81 -0
  185. package/kotlin/ExpoSources/expo/modules/kotlin/modules/Module.kt +98 -0
  186. package/kotlin/ExpoSources/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +236 -0
  187. package/kotlin/ExpoSources/expo/modules/kotlin/records/Record.kt +12 -0
  188. package/kotlin/ExpoSources/expo/modules/kotlin/runtime/Runtime.kt +9 -0
  189. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObject.kt +50 -0
  190. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +57 -0
  191. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedRef.kt +19 -0
  192. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/ConcreteTypedArrays.kt +158 -0
  193. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/GenericTypedArray.kt +8 -0
  194. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArray.kt +29 -0
  195. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArrayIterator.kt +9 -0
  196. package/kotlin/ExpoSources/expo/modules/kotlin/types/AnyType.kt +155 -0
  197. package/kotlin/ExpoSources/expo/modules/kotlin/types/Either.kt +91 -0
  198. package/kotlin/ExpoSources/expo/modules/kotlin/types/Enumerable.kt +6 -0
  199. package/kotlin/ExpoSources/expo/modules/kotlin/viewevent/ViewEvent.kt +54 -0
  200. package/kotlin/ExpoSources/expo/modules/kotlin/views/ExpoView.kt +23 -0
  201. package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +71 -0
  202. package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewProps.kt +35 -0
  203. package/kotlin/README.md +13 -3
  204. package/kotlin/Sources/android/os/Build.kt +17 -0
  205. package/kotlin/Sources/android/os/Handler.kt +35 -0
  206. package/kotlin/Sources/android/os/Looper.kt +17 -0
  207. package/kotlin/Sources/android/os/MessageQueue.kt +56 -0
  208. package/kotlin/Sources/android/os/SystemClock.kt +14 -0
  209. package/kotlin/Sources/android/util/Log.kt +64 -0
  210. package/kotlin/Sources/java/security/MessageDigest.kt +114 -0
  211. package/kotlin/Sources/kotlin/text/StringFormat.kt +9 -0
  212. package/kotlin/Sources/org/json/JSON.kt +44 -0
  213. package/kotlin/fixtures/counter/Counter.d.kt.ts +1 -0
  214. package/kotlin/fixtures/counter/Counter.kt +10 -3
  215. package/kotlin/fixtures/counter/CounterApp.native.tsx +1 -1
  216. package/kotlin/fixtures/counter/vite.config.ts +2 -2
  217. package/kotlin/fixtures/headless-counter/Headless.kt +7 -6
  218. package/kotlin/fixtures/import-animation/Animation.d.kt.ts +7 -0
  219. package/kotlin/fixtures/import-animation/Animation.kt +80 -0
  220. package/kotlin/fixtures/import-animation/ImportAnimation.native.tsx +13 -0
  221. package/kotlin/fixtures/import-animation/README.md +24 -0
  222. package/kotlin/fixtures/import-animation/app/_layout.tsx +4 -0
  223. package/kotlin/fixtures/import-animation/app/index+spa.tsx +1 -0
  224. package/kotlin/fixtures/import-animation/app/routes.d.ts +18 -0
  225. package/kotlin/fixtures/import-animation/package.json +23 -0
  226. package/kotlin/fixtures/import-animation/tsconfig.json +20 -0
  227. package/kotlin/fixtures/import-animation/vite.config.ts +20 -0
  228. package/kotlin/fixtures/import-editor/Editor.d.kt.ts +7 -0
  229. package/kotlin/fixtures/import-editor/Editor.kt +59 -0
  230. package/kotlin/fixtures/import-editor/ImportEditor.native.tsx +23 -0
  231. package/kotlin/fixtures/import-editor/README.md +27 -0
  232. package/kotlin/fixtures/import-editor/app/_layout.tsx +4 -0
  233. package/kotlin/fixtures/import-editor/app/index+spa.tsx +1 -0
  234. package/kotlin/fixtures/import-editor/package.json +23 -0
  235. package/kotlin/fixtures/import-editor/tsconfig.json +20 -0
  236. package/kotlin/fixtures/import-editor/vite.config.ts +20 -0
  237. package/kotlin/fixtures/import-effects/Effects.d.kt.ts +7 -0
  238. package/kotlin/fixtures/import-effects/Effects.kt +87 -0
  239. package/kotlin/fixtures/import-effects/ImportEffects.native.tsx +13 -0
  240. package/kotlin/fixtures/import-effects/README.md +19 -0
  241. package/kotlin/fixtures/import-effects/app/_layout.tsx +4 -0
  242. package/kotlin/fixtures/import-effects/app/index+spa.tsx +1 -0
  243. package/kotlin/fixtures/import-effects/package.json +23 -0
  244. package/kotlin/fixtures/import-effects/tsconfig.json +20 -0
  245. package/kotlin/fixtures/import-effects/vite.config.ts +20 -0
  246. package/kotlin/fixtures/import-layout/ImportLayout.native.tsx +13 -0
  247. package/kotlin/fixtures/import-layout/Layout.d.kt.ts +7 -0
  248. package/kotlin/fixtures/import-layout/Layout.kt +72 -0
  249. package/kotlin/fixtures/import-layout/README.md +24 -0
  250. package/kotlin/fixtures/import-layout/app/_layout.tsx +4 -0
  251. package/kotlin/fixtures/import-layout/app/index+spa.tsx +1 -0
  252. package/kotlin/fixtures/import-layout/package.json +23 -0
  253. package/kotlin/fixtures/import-layout/tsconfig.json +20 -0
  254. package/kotlin/fixtures/import-layout/vite.config.ts +20 -0
  255. package/kotlin/fixtures/import-navigation/ImportNavigation.native.tsx +18 -0
  256. package/kotlin/fixtures/import-navigation/Navigation.d.kt.ts +7 -0
  257. package/kotlin/fixtures/import-navigation/Navigation.kt +104 -0
  258. package/kotlin/fixtures/import-navigation/README.md +31 -0
  259. package/kotlin/fixtures/import-navigation/app/_layout.tsx +4 -0
  260. package/kotlin/fixtures/import-navigation/app/index+spa.tsx +1 -0
  261. package/kotlin/fixtures/import-navigation/package.json +23 -0
  262. package/kotlin/fixtures/import-navigation/tsconfig.json +20 -0
  263. package/kotlin/fixtures/import-navigation/vite.config.ts +20 -0
  264. package/kotlin/fixtures/import-overlays/ImportOverlays.native.tsx +29 -0
  265. package/kotlin/fixtures/import-overlays/Overlays.d.kt.ts +7 -0
  266. package/kotlin/fixtures/import-overlays/Overlays.kt +93 -0
  267. package/kotlin/fixtures/import-overlays/README.md +34 -0
  268. package/kotlin/fixtures/import-overlays/app/_layout.tsx +4 -0
  269. package/kotlin/fixtures/import-overlays/app/index+spa.tsx +1 -0
  270. package/kotlin/fixtures/import-overlays/package.json +23 -0
  271. package/kotlin/fixtures/import-overlays/tsconfig.json +20 -0
  272. package/kotlin/fixtures/import-overlays/vite.config.ts +20 -0
  273. package/kotlin/fixtures/import-scroll/ImportScroll.native.tsx +13 -0
  274. package/kotlin/fixtures/import-scroll/README.md +23 -0
  275. package/kotlin/fixtures/import-scroll/Scroll.d.kt.ts +7 -0
  276. package/kotlin/fixtures/import-scroll/Scroll.kt +91 -0
  277. package/kotlin/fixtures/import-scroll/app/_layout.tsx +4 -0
  278. package/kotlin/fixtures/import-scroll/app/index+spa.tsx +1 -0
  279. package/kotlin/fixtures/import-scroll/package.json +23 -0
  280. package/kotlin/fixtures/import-scroll/tsconfig.json +20 -0
  281. package/kotlin/fixtures/import-scroll/vite.config.ts +20 -0
  282. package/kotlin/fixtures/import-selection/ImportSelection.native.tsx +44 -0
  283. package/kotlin/fixtures/import-selection/README.md +32 -0
  284. package/kotlin/fixtures/import-selection/Selection.d.kt.ts +8 -0
  285. package/kotlin/fixtures/import-selection/Selection.kt +78 -0
  286. package/kotlin/fixtures/import-selection/app/_layout.tsx +4 -0
  287. package/kotlin/fixtures/import-selection/app/index+spa.tsx +1 -0
  288. package/kotlin/fixtures/import-selection/package.json +23 -0
  289. package/kotlin/fixtures/import-selection/tsconfig.json +20 -0
  290. package/kotlin/fixtures/import-selection/vite.config.ts +20 -0
  291. package/kotlin/fixtures/import-surfaces/ImportSurfaces.native.tsx +13 -0
  292. package/kotlin/fixtures/import-surfaces/README.md +22 -0
  293. package/kotlin/fixtures/import-surfaces/Surfaces.d.kt.ts +7 -0
  294. package/kotlin/fixtures/import-surfaces/Surfaces.kt +64 -0
  295. package/kotlin/fixtures/import-surfaces/app/_layout.tsx +4 -0
  296. package/kotlin/fixtures/import-surfaces/app/index+spa.tsx +1 -0
  297. package/kotlin/fixtures/import-surfaces/package.json +23 -0
  298. package/kotlin/fixtures/import-surfaces/tsconfig.json +20 -0
  299. package/kotlin/fixtures/import-surfaces/vite.config.ts +20 -0
  300. package/kotlin/fixtures/import-values/ImportValues.native.tsx +35 -0
  301. package/kotlin/fixtures/import-values/README.md +23 -0
  302. package/kotlin/fixtures/import-values/Values.d.kt.ts +11 -0
  303. package/kotlin/fixtures/import-values/Values.kt +66 -0
  304. package/kotlin/fixtures/import-values/app/_layout.tsx +4 -0
  305. package/kotlin/fixtures/import-values/app/index+spa.tsx +1 -0
  306. package/kotlin/fixtures/import-values/package.json +23 -0
  307. package/kotlin/fixtures/import-values/tsconfig.json +20 -0
  308. package/kotlin/fixtures/import-values/vite.config.ts +20 -0
  309. package/kotlin/fixtures/kotlin-app-variants/BarBehavior.kt +38 -0
  310. package/kotlin/fixtures/kotlin-app-variants/BarVisibility.kt +36 -0
  311. package/kotlin/fixtures/kotlin-app-variants/Ime.kt +3 -1
  312. package/kotlin/fixtures/kotlin-app-variants/TransientInsets.kt +50 -0
  313. package/kotlin/fork/NOTICE +6 -1
  314. package/kotlin/fork/README.md +15 -7
  315. package/kotlin/fork/build.sh +2 -0
  316. package/kotlin/fork/compose-worker-globals.patch +186 -4
  317. package/kotlin/fork/fork.json +2 -2
  318. package/kotlin/fork/skiko-worker-clock.patch +12 -0
  319. package/kotlin/toolchain.json +12 -12
  320. package/kotlin/tools/expo-types.main.kts +115 -0
  321. package/package.json +17 -23
  322. package/scripts/dev-server-scanner.ts +92 -66
  323. package/skills/contrast/SKILL.md +2 -2
  324. package/skills/peach-debug/SKILL.md +1 -1
  325. package/skills/peach-perf/SKILL.md +1 -1
  326. package/skills/peach-setup/SKILL.md +2 -1
  327. package/skills/peach-test/SKILL.md +8 -0
  328. package/src/assetCatalogContract.ts +43 -1
  329. package/src/bridge-contract-input.ts +46 -19
  330. package/src/bridge-contract.ts +0 -1
  331. package/src/bundle-channel.mjs +197 -84
  332. package/src/bundleGlobalFooter.ts +38 -0
  333. package/src/capture-contract.ts +107 -33
  334. package/src/cloud-contract.ts +5 -1
  335. package/src/cloud.ts +5 -2
  336. package/src/config.ts +22 -3
  337. package/src/configured-bundle-producer.ts +1 -1
  338. package/src/desktop-host-delivery.ts +95 -1
  339. package/src/expo-kotlin-bundle.ts +29 -0
  340. package/src/expo-kotlin-host.ts +201 -0
  341. package/src/expo-swift-host.ts +96 -76
  342. package/src/expoKotlinContract.ts +70 -0
  343. package/src/expoSwiftContract.ts +4 -25
  344. package/src/home-paths.ts +7 -4
  345. package/src/host/bridge-host.ts +23 -3
  346. package/src/host/fetch-proxy-handler.ts +13 -0
  347. package/src/host/fetch-proxy-overrides.ts +11 -0
  348. package/src/host/replacement-module-handler.ts +5 -2
  349. package/src/index.ts +3 -1
  350. package/src/kotlin-host.ts +463 -19
  351. package/src/metro-plugin.ts +56 -28
  352. package/src/metro-production-bundle.ts +2 -2
  353. package/src/native-app-identity-project.ts +190 -0
  354. package/src/native-app-identity.ts +398 -34
  355. package/src/native-firebase-config.ts +69 -15
  356. package/src/native-seam-manifest.ts +6 -0
  357. package/src/one-widget-discovery.ts +2 -1
  358. package/src/openstep-plist.ts +107 -0
  359. package/src/react-native-host-modules.ts +4 -0
  360. package/src/runtime-assets.ts +2 -2
  361. package/src/sim-client.ts +2 -2
  362. package/src/swift-binary-modules.ts +3 -1
  363. package/src/swift-compile.ts +286 -38
  364. package/src/swift-distribution-contract.ts +4 -0
  365. package/src/swift-distribution.lock.json +123 -12
  366. package/src/swift-distribution.ts +7 -3
  367. package/src/swift-host.ts +298 -83
  368. package/src/swift-package-manifest.ts +29 -2
  369. package/src/swift-package.ts +180 -10
  370. package/src/swift-packages.ts +4 -0
  371. package/src/swift-standin-emit.ts +4 -1
  372. package/src/swift-standins.ts +274 -15
  373. package/src/swift-submit.ts +62 -7
  374. package/src/swift-toolchain.ts +6 -1
  375. package/src/swiftContract.ts +126 -3
  376. package/src/vite-plugin-one.ts +13 -16
  377. package/src/vite-plugin-swift.ts +4 -5
  378. package/src/vite-plugin.ts +360 -144
  379. package/src/vite.d.ts +1 -1
  380. package/src/worker-system-chunks.ts +221 -0
  381. package/src/worklet-executable.ts +348 -38
  382. package/src/worklets-babel.ts +1 -1
  383. package/src/xcode-project.ts +243 -127
  384. package/dist-lib/agent-identity.cjs +0 -39
  385. package/dist-lib/agent-sessions.cjs +0 -760
  386. package/dist-lib/cli-constants.cjs +0 -32
  387. package/dist-lib/render-mode.cjs +0 -44
  388. package/kotlin/AppSources/android/view/View.kt +0 -74
  389. package/kotlin/AppSources/android/widget/FrameLayout.kt +0 -6
  390. package/src/render-mode.ts +0 -15
  391. /package/kotlin/{AppSources → AndroidViewSources}/android/content/Context.kt +0 -0
  392. /package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Configuration.kt +0 -0
  393. /package/kotlin/{AppSources → AndroidViewSources}/android/graphics/Color.kt +0 -0
  394. /package/kotlin/{AppSources → AndroidViewSources}/android/util/DisplayMetrics.kt +0 -0
  395. /package/kotlin/{AppSources → AndroidViewSources}/dev/peach/app/JavaFormat.kt +0 -0
  396. /package/kotlin/{AppSources → Sources}/java/lang/Runnable.kt +0 -0
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.939 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -471,6 +471,7 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
471
471
  } catch {
472
472
  return false;
473
473
  }
474
+ if (url.pathname !== REPLACEMENT_MODULE_ROUTE) return false;
474
475
  if (options.requireLoopbackOrigin) {
475
476
  const origin = req.headers.origin;
476
477
  const remoteAddress = req.socket.remoteAddress?.replace(/^::ffff:/, "");
@@ -488,7 +489,6 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
488
489
  return true;
489
490
  }
490
491
  }
491
- if (url.pathname !== REPLACEMENT_MODULE_ROUTE) return false;
492
492
  if (options.requestToken && url.searchParams.get("token") !== options.requestToken) {
493
493
  res.writeHead(403, { "Content-Type": "text/plain; charset=utf-8" });
494
494
  res.end("replacement module request token is invalid");
@@ -582,16 +582,6 @@ var init_replacement_module_handler = __esm({
582
582
  }
583
583
  });
584
584
 
585
- // src/is-record.ts
586
- function isRecord2(value) {
587
- return typeof value === "object" && value !== null && !Array.isArray(value);
588
- }
589
- var init_is_record = __esm({
590
- "src/is-record.ts"() {
591
- "use strict";
592
- }
593
- });
594
-
595
585
  // ../../node_modules/plist/lib/parse.js
596
586
  var require_parse = __commonJS({
597
587
  "../../node_modules/plist/lib/parse.js"(exports2) {
@@ -1943,6 +1933,16 @@ var require_lib = __commonJS({
1943
1933
  }
1944
1934
  });
1945
1935
 
1936
+ // src/is-record.ts
1937
+ function isRecord3(value) {
1938
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1939
+ }
1940
+ var init_is_record = __esm({
1941
+ "src/is-record.ts"() {
1942
+ "use strict";
1943
+ }
1944
+ });
1945
+
1946
1946
  // ../contrast-runtime-delivery/src/version.ts
1947
1947
  function isValidRuntimeVersion(value) {
1948
1948
  return value.length <= 100 && /^[0-9A-Za-z][0-9A-Za-z._+-]*$/.test(value);
@@ -1966,26 +1966,32 @@ __export(config_exports, {
1966
1966
  hasPeachConfig: () => hasPeachConfig,
1967
1967
  isPeachConfig: () => isPeachConfig,
1968
1968
  mergePeachConfig: () => mergePeachConfig,
1969
+ readNativeRenderer: () => readNativeRenderer,
1969
1970
  readPeachBundleConfig: () => readPeachBundleConfig,
1970
1971
  readPeachBundleConfigFooter: () => readPeachBundleConfigFooter,
1971
1972
  readPeachConfigFromSearchParams: () => readPeachConfigFromSearchParams
1972
1973
  });
1974
+ function readNativeRenderer(value) {
1975
+ if (value === void 0) return void 0;
1976
+ if (value === "paper" || value === "fabric") return value;
1977
+ throw new Error("nativeRenderer must be paper or fabric");
1978
+ }
1973
1979
  function collectConfiguredFileModules(config) {
1974
1980
  return [
1975
1981
  ...new Set(
1976
1982
  ["modules", "turboModules", "nativeModules", "nativeViews"].flatMap((key) => {
1977
1983
  const entries = config && Reflect.get(config, key);
1978
- if (!isRecord2(entries)) return [];
1984
+ if (!isRecord3(entries)) return [];
1979
1985
  return Object.values(entries).flatMap(
1980
- (entry) => isRecord2(entry) && typeof entry.file === "string" ? [entry.file] : []
1986
+ (entry) => isRecord3(entry) && typeof entry.file === "string" ? [entry.file] : []
1981
1987
  );
1982
1988
  })
1983
1989
  )
1984
1990
  ];
1985
1991
  }
1986
1992
  function isPeachConfig(value) {
1987
- if (!isRecord2(value)) return false;
1988
- return (value.runtimeVersion === void 0 || typeof value.runtimeVersion === "string" && value.runtimeVersion === value.runtimeVersion.trim() && isValidRuntimeVersion(value.runtimeVersion)) && [
1993
+ if (!isRecord3(value)) return false;
1994
+ return (value.nativeRenderer === void 0 || value.nativeRenderer === "paper" || value.nativeRenderer === "fabric") && (value.runtimeVersion === void 0 || typeof value.runtimeVersion === "string" && value.runtimeVersion === value.runtimeVersion.trim() && isValidRuntimeVersion(value.runtimeVersion)) && [
1989
1995
  "modules",
1990
1996
  "turboModules",
1991
1997
  "nativeModules",
@@ -1994,13 +2000,13 @@ function isPeachConfig(value) {
1994
2000
  "network",
1995
2001
  "settings",
1996
2002
  "initialState"
1997
- ].every((key) => value[key] === void 0 || isRecord2(value[key])) && (value.nativeViews === void 0 || isRecord2(value.nativeViews) && Object.values(value.nativeViews).every(
1998
- (entry) => entry === "noop" || isRecord2(entry) && typeof entry.file === "string" && entry.file.length > 0
2003
+ ].every((key) => value[key] === void 0 || isRecord3(value[key])) && (value.nativeViews === void 0 || isRecord3(value.nativeViews) && Object.values(value.nativeViews).every(
2004
+ (entry) => entry === "noop" || isRecord3(entry) && typeof entry.file === "string" && entry.file.length > 0
1999
2005
  ));
2000
2006
  }
2001
2007
  function readPeachBundleConfig(value) {
2002
2008
  if (value === void 0 || value === null) return null;
2003
- if (!isRecord2(value) || !isPeachConfig(value.config) || !Array.isArray(value.runtimePackages) || !value.runtimePackages.every((name2) => typeof name2 === "string")) {
2009
+ if (!isRecord3(value) || !isPeachConfig(value.config) || !Array.isArray(value.runtimePackages) || !value.runtimePackages.every((name2) => typeof name2 === "string")) {
2004
2010
  throw new Error("configured bundle metadata is malformed");
2005
2011
  }
2006
2012
  return { config: value.config, runtimePackages: [...value.runtimePackages] };
@@ -2039,7 +2045,7 @@ function hasOwnKeys(value) {
2039
2045
  }
2040
2046
  function hasPeachConfig(config) {
2041
2047
  if (!config) return false;
2042
- return typeof config.runtimeVersion === "string" && config.runtimeVersion.length > 0 || hasOwnKeys(config.modules) || hasOwnKeys(config.turboModules) || hasOwnKeys(config.nativeModules) || hasOwnKeys(config.nativeViews) || hasOwnKeys(config.env) || hasOwnKeys(config.network?.remap) || hasOwnKeys(config.settings) || hasOwnKeys(config.initialState);
2048
+ return config.nativeRenderer !== void 0 || typeof config.runtimeVersion === "string" && config.runtimeVersion.length > 0 || hasOwnKeys(config.modules) || hasOwnKeys(config.turboModules) || hasOwnKeys(config.nativeModules) || hasOwnKeys(config.nativeViews) || hasOwnKeys(config.env) || hasOwnKeys(config.network?.remap) || hasOwnKeys(config.settings) || hasOwnKeys(config.initialState);
2043
2049
  }
2044
2050
  function mergePeachConfig(base, override) {
2045
2051
  if (!hasPeachConfig(base) && !hasPeachConfig(override)) return void 0;
@@ -2047,6 +2053,7 @@ function mergePeachConfig(base, override) {
2047
2053
  if (!hasPeachConfig(override)) return base ? { ...base } : void 0;
2048
2054
  return {
2049
2055
  runtimeVersion: override.runtimeVersion ?? base.runtimeVersion,
2056
+ nativeRenderer: override.nativeRenderer ?? base.nativeRenderer,
2050
2057
  modules: { ...base.modules || {}, ...override.modules || {} },
2051
2058
  turboModules: { ...base.turboModules || {}, ...override.turboModules || {} },
2052
2059
  nativeModules: {
@@ -2068,14 +2075,16 @@ function mergePeachConfig(base, override) {
2068
2075
  function readPeachConfigFromSearchParams(searchParams) {
2069
2076
  const raw = searchParams.get(PEACH_CONFIG_QUERY_PARAM);
2070
2077
  if (!raw) return void 0;
2078
+ let parsed;
2071
2079
  try {
2072
- const parsed = JSON.parse(raw);
2073
- return hasPeachConfig(parsed) ? parsed : void 0;
2080
+ parsed = JSON.parse(raw);
2074
2081
  } catch (error) {
2075
2082
  const message = error instanceof Error ? error.message : String(error);
2076
2083
  console.warn(`[peach] invalid ${PEACH_CONFIG_QUERY_PARAM}: ${message}`);
2077
2084
  return void 0;
2078
2085
  }
2086
+ if (isRecord3(parsed)) readNativeRenderer(parsed.nativeRenderer);
2087
+ return isPeachConfig(parsed) && hasPeachConfig(parsed) ? parsed : void 0;
2079
2088
  }
2080
2089
  function applyPeachConfigToUrl(url, config) {
2081
2090
  const parsed = new URL(url);
@@ -2126,12 +2135,12 @@ function resolveFileEntries(entries, configDir) {
2126
2135
  return Object.fromEntries(
2127
2136
  Object.entries(entries).map(([name2, resolution]) => [
2128
2137
  name2,
2129
- resolution && typeof resolution === "object" && "file" in resolution && typeof resolution.file === "string" ? { ...resolution, file: import_node_path7.default.resolve(configDir, resolution.file) } : resolution
2138
+ resolution && typeof resolution === "object" && "file" in resolution && typeof resolution.file === "string" ? { ...resolution, file: import_node_path8.default.resolve(configDir, resolution.file) } : resolution
2130
2139
  ])
2131
2140
  );
2132
2141
  }
2133
2142
  function resolveConfigReplacementFiles(config, configPath) {
2134
- const configDir = import_node_path7.default.dirname(configPath);
2143
+ const configDir = import_node_path8.default.dirname(configPath);
2135
2144
  return {
2136
2145
  ...config,
2137
2146
  modules: resolveFileEntries(config.modules, configDir),
@@ -2166,11 +2175,11 @@ async function resolveRNXAppConfig(startDir = process.cwd()) {
2166
2175
  const project = resolveAppProject(startDir);
2167
2176
  return { project, config: await loadRNXAppConfig(project) };
2168
2177
  }
2169
- var import_node_path7, import_jiti;
2178
+ var import_node_path8, import_jiti;
2170
2179
  var init_app_config = __esm({
2171
2180
  "cli/app-config.ts"() {
2172
2181
  "use strict";
2173
- import_node_path7 = __toESM(require("node:path"), 1);
2182
+ import_node_path8 = __toESM(require("node:path"), 1);
2174
2183
  import_jiti = require("jiti");
2175
2184
  init_config();
2176
2185
  init_config();
@@ -2200,14 +2209,14 @@ async function produceConfiguredBundle(source, config, runtimePackages) {
2200
2209
  const neededPackages = /* @__PURE__ */ new Set();
2201
2210
  const factories = [];
2202
2211
  const visit = (filePath) => {
2203
- const real = import_node_fs7.default.realpathSync(filePath);
2212
+ const real = import_node_fs8.default.realpathSync(filePath);
2204
2213
  const previous = files.get(real);
2205
2214
  if (previous !== void 0) return previous;
2206
2215
  const id = "peach-config-file:" + files.size;
2207
2216
  files.set(real, id);
2208
2217
  const compiled = compileReplacementModule({
2209
2218
  filePath: real,
2210
- source: import_node_fs7.default.readFileSync(real, "utf8"),
2219
+ source: import_node_fs8.default.readFileSync(real, "utf8"),
2211
2220
  runtimePackages,
2212
2221
  localModuleUrl: (specifier) => visit(resolveReplacementModuleFile(real, specifier))
2213
2222
  });
@@ -2223,7 +2232,7 @@ async function produceConfiguredBundle(source, config, runtimePackages) {
2223
2232
  if (!entries || typeof entries !== "object") continue;
2224
2233
  for (const resolution of Object.values(entries)) {
2225
2234
  if (resolution && typeof resolution === "object" && "file" in resolution && typeof resolution.file === "string") {
2226
- resolution.file = visit(import_node_path8.default.resolve(resolution.file));
2235
+ resolution.file = visit(import_node_path9.default.resolve(resolution.file));
2227
2236
  }
2228
2237
  }
2229
2238
  }
@@ -2234,7 +2243,7 @@ async function produceConfiguredBundle(source, config, runtimePackages) {
2234
2243
  const compact = await (0, import_terser.minify)(code, {
2235
2244
  compress: false,
2236
2245
  mangle: false,
2237
- format: { comments: false, beautify: false }
2246
+ format: { comments: false }
2238
2247
  });
2239
2248
  if (!compact.code || /[\n\r]/.test(compact.code))
2240
2249
  throw new Error("configured bundle prefix must preserve the guest source lines");
@@ -2247,12 +2256,12 @@ async function produceConfiguredBundle(source, config, runtimePackages) {
2247
2256
  const identityStart = source.lastIndexOf("\nglobalThis.__sootsimModulePaths=");
2248
2257
  return prefix2 + (identityStart < 0 ? source + footer : source.slice(0, identityStart) + footer + source.slice(identityStart));
2249
2258
  }
2250
- var import_node_fs7, import_node_path8, import_sucrase, import_terser;
2259
+ var import_node_fs8, import_node_path9, import_sucrase, import_terser;
2251
2260
  var init_configured_bundle_producer = __esm({
2252
2261
  "src/configured-bundle-producer.ts"() {
2253
2262
  "use strict";
2254
- import_node_fs7 = __toESM(require("node:fs"), 1);
2255
- import_node_path8 = __toESM(require("node:path"), 1);
2263
+ import_node_fs8 = __toESM(require("node:fs"), 1);
2264
+ import_node_path9 = __toESM(require("node:path"), 1);
2256
2265
  import_sucrase = require("sucrase");
2257
2266
  import_terser = require("terser");
2258
2267
  init_replacementModule();
@@ -2265,9 +2274,9 @@ var init_configured_bundle_producer = __esm({
2265
2274
  var metro_plugin_exports = {};
2266
2275
  __export(metro_plugin_exports, {
2267
2276
  default: () => metro_plugin_default,
2268
- toRNXDevelopmentBundleUrl: () => toRNXDevelopmentBundleUrl,
2269
- toRNXProductionBundleUrl: () => toRNXProductionBundleUrl,
2270
- withRNX: () => withRNX
2277
+ toPeachDevelopmentBundleUrl: () => toPeachDevelopmentBundleUrl,
2278
+ toPeachProductionBundleUrl: () => toPeachProductionBundleUrl,
2279
+ withPeach: () => withPeach
2271
2280
  });
2272
2281
  module.exports = __toCommonJS(metro_plugin_exports);
2273
2282
  var import_fs2 = __toESM(require("fs"), 1);
@@ -2300,7 +2309,7 @@ init_replacement_module_handler();
2300
2309
  // src/metro-production-bundle.ts
2301
2310
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
2302
2311
  var RNX_METRO_MODULE_IDENTITY_VERSION = 2;
2303
- function toRNXProductionBundleUrl(bundleUrl) {
2312
+ function toPeachProductionBundleUrl(bundleUrl) {
2304
2313
  const relative2 = bundleUrl.startsWith("/");
2305
2314
  const url = new URL(bundleUrl, "http://peachsim.local");
2306
2315
  url.searchParams.set("dev", "false");
@@ -2308,7 +2317,7 @@ function toRNXProductionBundleUrl(bundleUrl) {
2308
2317
  url.searchParams.set("minify", "true");
2309
2318
  return relative2 ? `${url.pathname}${url.search}${url.hash}` : url.toString();
2310
2319
  }
2311
- function toRNXDevelopmentBundleUrl(bundleUrl) {
2320
+ function toPeachDevelopmentBundleUrl(bundleUrl) {
2312
2321
  const relative2 = bundleUrl.startsWith("/");
2313
2322
  const url = new URL(bundleUrl, "http://peachsim.local");
2314
2323
  url.searchParams.set("dev", "true");
@@ -2338,6 +2347,101 @@ function appendRNXMetroModuleIdentityFooter(bundleText, identity) {
2338
2347
  ${RNXSIM_METRO_SOURCE_MAP_COMMENT}${detached.sourceMappingUrl}`;
2339
2348
  }
2340
2349
 
2350
+ // src/openstep-plist.ts
2351
+ var isDict = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2352
+ var str = (value) => typeof value === "string" ? value : void 0;
2353
+ var list = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
2354
+ function parseOpenStepPlist(text2) {
2355
+ let i = 0;
2356
+ const fail = (message) => {
2357
+ const line = text2.slice(0, i).split("\n").length;
2358
+ throw new Error(`project.pbxproj line ${line}: ${message}`);
2359
+ };
2360
+ const skip = () => {
2361
+ for (; ; ) {
2362
+ const ch = text2[i];
2363
+ if (ch === " " || ch === " " || ch === "\n" || ch === "\r") i++;
2364
+ else if (ch === "/" && text2[i + 1] === "*") {
2365
+ const end = text2.indexOf("*/", i + 2);
2366
+ if (end < 0) fail("unterminated comment");
2367
+ i = end + 2;
2368
+ } else if (ch === "/" && text2[i + 1] === "/") {
2369
+ const end = text2.indexOf("\n", i);
2370
+ i = end < 0 ? text2.length : end + 1;
2371
+ } else return;
2372
+ }
2373
+ };
2374
+ const quoted = () => {
2375
+ i++;
2376
+ let out = "";
2377
+ for (; ; ) {
2378
+ const ch = text2[i++];
2379
+ if (ch === void 0) fail("unterminated string");
2380
+ if (ch === '"') return out;
2381
+ if (ch !== "\\") {
2382
+ out += ch;
2383
+ continue;
2384
+ }
2385
+ const next = text2[i++];
2386
+ if (next === "n") out += "\n";
2387
+ else if (next === "t") out += " ";
2388
+ else if (next === "r") out += "\r";
2389
+ else if (next === "U") {
2390
+ out += String.fromCharCode(parseInt(text2.slice(i, i + 4), 16));
2391
+ i += 4;
2392
+ } else out += next;
2393
+ }
2394
+ };
2395
+ const value = () => {
2396
+ skip();
2397
+ const ch = text2[i];
2398
+ if (ch === "{") {
2399
+ i++;
2400
+ const dict = {};
2401
+ for (; ; ) {
2402
+ skip();
2403
+ if (text2[i] === "}") {
2404
+ i++;
2405
+ return dict;
2406
+ }
2407
+ const key = value();
2408
+ if (typeof key !== "string") fail("dictionary key is not a string");
2409
+ skip();
2410
+ if (text2[i++] !== "=") fail("expected =");
2411
+ if (Object.hasOwn(dict, key)) fail(`duplicate key ${key}`);
2412
+ dict[key] = value();
2413
+ skip();
2414
+ if (text2[i++] !== ";") fail("expected ;");
2415
+ }
2416
+ }
2417
+ if (ch === "(") {
2418
+ i++;
2419
+ const list2 = [];
2420
+ for (; ; ) {
2421
+ skip();
2422
+ if (text2[i] === ")") {
2423
+ i++;
2424
+ return list2;
2425
+ }
2426
+ list2.push(value());
2427
+ skip();
2428
+ if (text2[i] === ",") i++;
2429
+ else if (text2[i] !== ")") fail("expected , or )");
2430
+ }
2431
+ }
2432
+ if (ch === '"') return quoted();
2433
+ const start = i;
2434
+ while (i < text2.length && /[A-Za-z0-9_$+/:.\-<>]/.test(text2[i])) i++;
2435
+ if (i === start) fail(`unexpected ${JSON.stringify(ch ?? "end of file")}`);
2436
+ return text2.slice(start, i);
2437
+ };
2438
+ if (text2.startsWith("// !$*UTF8*$!")) i = text2.indexOf("\n") + 1;
2439
+ const root = value();
2440
+ skip();
2441
+ if (i !== text2.length) fail("trailing content");
2442
+ return root;
2443
+ }
2444
+
2341
2445
  // src/native-app-identity.ts
2342
2446
  var NATIVE_APP_IDENTITY_PREFIX = "globalThis.__sootsimNativeAppIdentity=";
2343
2447
  var METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
@@ -2348,7 +2452,9 @@ function nonEmptyString(value) {
2348
2452
  return typeof value === "string" && value.length > 0 ? value : null;
2349
2453
  }
2350
2454
  function createNativeAppIdentityFooter(identity) {
2351
- const payload = JSON.stringify(identity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
2455
+ const footerIdentity = { ...identity };
2456
+ delete footerIdentity.oneUpdates;
2457
+ const payload = JSON.stringify(footerIdentity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
2352
2458
  return `
2353
2459
  ${NATIVE_APP_IDENTITY_PREFIX}${payload};`;
2354
2460
  }
@@ -2449,30 +2555,119 @@ function appTargetReleaseSettings(pbxproj, targetName, infoPlistRelativePath) {
2449
2555
  (candidate) => candidate.name === "Release" && named(candidate.settings)
2450
2556
  )?.settings ?? null;
2451
2557
  }
2452
- function nativeAppIdentityFromIos(files, parseInfoPlist) {
2558
+ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget) {
2453
2559
  const pbxprojPath = Object.keys(files).find(
2454
- (path11) => /(?:^|\/)ios\/[^/]+\.xcodeproj\/project\.pbxproj$/.test(path11)
2455
- );
2560
+ (path12) => /(?:^|\/)ios\/[^/]+\.xcodeproj\/project\.pbxproj$/.test(path12)
2561
+ ) ?? Object.keys(files).find(
2562
+ (path12) => /(?:^|\/)[^/]+\.xcodeproj\/project\.pbxproj$/.test(path12)
2563
+ ) ?? Object.keys(files).find((path12) => /(?:^|\/)project\.pbxproj$/.test(path12));
2456
2564
  if (!pbxprojPath) return null;
2457
2565
  const pbxproj = files[pbxprojPath];
2458
- const applicationTargets = new Set(
2459
- [
2460
- ...pbxproj.matchAll(
2461
- /isa = PBXNativeTarget;[^}]*?name = "?([^";]+)"?;[^}]*?productType = "com\.apple\.product-type\.application";/g
2462
- )
2463
- ].map((match) => match[1])
2566
+ let objects = {};
2567
+ try {
2568
+ const parsed = parseOpenStepPlist(pbxproj);
2569
+ if (isRecord(parsed)) {
2570
+ objects = isRecord(parsed.objects) ? parsed.objects : parsed;
2571
+ }
2572
+ } catch {
2573
+ }
2574
+ const targets = [];
2575
+ for (const [id, obj] of Object.entries(objects)) {
2576
+ if (isRecord(obj) && obj.isa === "PBXNativeTarget" && typeof obj.name === "string") {
2577
+ targets.push({
2578
+ id,
2579
+ name: obj.name,
2580
+ productType: typeof obj.productType === "string" ? obj.productType : void 0,
2581
+ buildConfigurationList: typeof obj.buildConfigurationList === "string" ? obj.buildConfigurationList : void 0
2582
+ });
2583
+ }
2584
+ }
2585
+ const applicationTargetNames = new Set(
2586
+ targets.filter((t) => t.productType === "com.apple.product-type.application").map((t) => t.name)
2464
2587
  );
2465
- const appDelegatePattern = /(?:^|\/)ios\/([^/]+)\/AppDelegate\.(?:swift|mm|m)$/;
2466
- const targetName = Object.keys(files).filter((path11) => !path11.includes("/Pods/")).map((path11) => path11.match(appDelegatePattern)?.[1]).find((name2) => name2 !== void 0 && applicationTargets.has(name2)) ?? null;
2467
- if (!targetName) return null;
2468
- const plist3 = files[`ios/${targetName}/Info.plist`];
2588
+ if (applicationTargetNames.size === 0) {
2589
+ for (const match of pbxproj.matchAll(
2590
+ /isa = PBXNativeTarget;[^}]*?name = "?([^";]+)"?;[^}]*?productType = "com\.apple\.product-type\.application";/g
2591
+ )) {
2592
+ applicationTargetNames.add(match[1]);
2593
+ }
2594
+ }
2595
+ let targetName = null;
2596
+ if (iosTarget) {
2597
+ if (applicationTargetNames.has(iosTarget)) {
2598
+ targetName = iosTarget;
2599
+ } else {
2600
+ return null;
2601
+ }
2602
+ } else if (applicationTargetNames.size === 1) {
2603
+ targetName = [...applicationTargetNames][0];
2604
+ } else if (applicationTargetNames.size > 1) {
2605
+ const appDelegatePattern = /(?:^|\/)ios\/([^/]+)\/AppDelegate\.(?:swift|mm|m)$/;
2606
+ const delegateTargets = Object.keys(files).filter((path12) => !path12.includes("/Pods/")).map((path12) => path12.match(appDelegatePattern)?.[1]).filter(
2607
+ (name2) => typeof name2 === "string" && applicationTargetNames.has(name2)
2608
+ );
2609
+ if (delegateTargets.length === 1) {
2610
+ targetName = delegateTargets[0];
2611
+ } else {
2612
+ return null;
2613
+ }
2614
+ } else {
2615
+ return null;
2616
+ }
2617
+ const selectedTarget = targets.find((t) => t.name === targetName);
2618
+ const settings = {
2619
+ TARGET_NAME: targetName,
2620
+ PRODUCT_NAME: targetName
2621
+ };
2622
+ for (const obj of Object.values(objects)) {
2623
+ if (isRecord(obj) && obj.isa === "PBXProject" && typeof obj.buildConfigurationList === "string") {
2624
+ const listObj = objects[obj.buildConfigurationList];
2625
+ if (isRecord(listObj) && Array.isArray(listObj.buildConfigurations)) {
2626
+ for (const configId of listObj.buildConfigurations) {
2627
+ if (typeof configId === "string") {
2628
+ const configObj = objects[configId];
2629
+ if (isRecord(configObj) && configObj.name === "Release" && isRecord(configObj.buildSettings)) {
2630
+ for (const [k, v] of Object.entries(configObj.buildSettings)) {
2631
+ if (typeof v === "string") settings[k] = v;
2632
+ }
2633
+ }
2634
+ }
2635
+ }
2636
+ }
2637
+ }
2638
+ }
2639
+ if (selectedTarget?.buildConfigurationList) {
2640
+ const listObj = objects[selectedTarget.buildConfigurationList];
2641
+ if (isRecord(listObj) && Array.isArray(listObj.buildConfigurations)) {
2642
+ for (const configId of listObj.buildConfigurations) {
2643
+ if (typeof configId === "string") {
2644
+ const configObj = objects[configId];
2645
+ if (isRecord(configObj) && configObj.name === "Release" && isRecord(configObj.buildSettings)) {
2646
+ for (const [k, v] of Object.entries(configObj.buildSettings)) {
2647
+ if (typeof v === "string") settings[k] = v;
2648
+ }
2649
+ }
2650
+ }
2651
+ }
2652
+ }
2653
+ } else {
2654
+ const legacy = appTargetReleaseSettings(
2655
+ pbxproj,
2656
+ targetName,
2657
+ `${targetName}/Info.plist`
2658
+ );
2659
+ if (legacy) Object.assign(settings, legacy);
2660
+ }
2661
+ let plist3;
2662
+ const infoPlistPath = settings.INFOPLIST_FILE;
2663
+ if (infoPlistPath) {
2664
+ const normalized = infoPlistPath.replace(/^"|"$/g, "");
2665
+ plist3 = files[`ios/${normalized}`] ?? files[normalized] ?? Object.entries(files).find(([k]) => k.endsWith(`/${normalized}`))?.[1];
2666
+ }
2667
+ if (!plist3) {
2668
+ plist3 = files[`ios/${targetName}/Info.plist`] ?? files[`${targetName}/Info.plist`] ?? Object.entries(files).find(([k]) => k.endsWith(`/${targetName}/Info.plist`))?.[1];
2669
+ }
2469
2670
  if (!plist3) return null;
2470
- const settings = appTargetReleaseSettings(
2471
- pbxproj,
2472
- targetName,
2473
- `${targetName}/Info.plist`
2474
- );
2475
- if (!settings) return null;
2476
2671
  const bundleIdentifier = identityFieldFrom(
2477
2672
  settings,
2478
2673
  plistString(plist3, "CFBundleIdentifier"),
@@ -2499,8 +2694,57 @@ function nativeAppIdentityFromIos(files, parseInfoPlist) {
2499
2694
  const applicationName = identityFieldFrom(settings, plistString(plist3, "CFBundleDisplayName"), void 0) ?? bundleName;
2500
2695
  const dictionary = parseInfoPlist(plist3);
2501
2696
  if (!isRecord(dictionary)) throw new Error("native app Info.plist is not a dictionary");
2697
+ const declaredDisplayName = dictionary.CFBundleDisplayName;
2698
+ const applicationDisplayName = typeof declaredDisplayName === "string" ? resolveBuildSetting(declaredDisplayName, settings) : void 0;
2699
+ if (applicationDisplayName === null)
2700
+ throw new Error("native app Info.plist CFBundleDisplayName is unresolved");
2701
+ const declaredBackgroundColor = dictionary.RCTRootViewBackgroundColor;
2702
+ const rootViewBackgroundColor = typeof declaredBackgroundColor === "number" && Number.isInteger(declaredBackgroundColor) ? declaredBackgroundColor : void 0;
2703
+ const icons = dictionary.CFBundleIcons;
2704
+ const alternates = isRecord(icons) ? icons.CFBundleAlternateIcons : void 0;
2705
+ const alternateIconNames = /* @__PURE__ */ new Set();
2706
+ for (const name2 of isRecord(alternates) ? Object.keys(alternates) : []) {
2707
+ const resolved = resolveBuildSetting(name2, settings);
2708
+ if (resolved === null) throw new Error("native alternate icon name is unresolved");
2709
+ alternateIconNames.add(resolved);
2710
+ }
2711
+ const alternateSetting = resolveBuildSetting(
2712
+ settings.ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES ?? "",
2713
+ settings
2714
+ );
2715
+ if (alternateSetting === null)
2716
+ throw new Error("native alternate icon setting is unresolved");
2717
+ for (const match of alternateSetting.replace(/\\"/g, '"').matchAll(/"([^"]*)"|([^\s(),]+)/g)) {
2718
+ alternateIconNames.add(match[1] ?? match[2]);
2719
+ }
2502
2720
  const intentIds = dictionary.OneAppIntentIdentifiers;
2503
2721
  const appIntentIdentifiers = Array.isArray(intentIds) && intentIds.every((value) => typeof value === "string") ? intentIds.map((value) => resolveBuildSetting(value, settings)) : [];
2722
+ const backgroundIds = dictionary.BGTaskSchedulerPermittedIdentifiers;
2723
+ const backgroundTaskIdentifiers = Array.isArray(backgroundIds) && backgroundIds.every((value) => typeof value === "string") ? backgroundIds.map((value) => resolveBuildSetting(value, settings)) : [];
2724
+ const declaredModes = dictionary.UIBackgroundModes;
2725
+ const backgroundModes = Array.isArray(declaredModes) && declaredModes.every((value) => typeof value === "string") ? declaredModes.map((value) => resolveBuildSetting(value, settings)) : [];
2726
+ const screenOrientationLists = [
2727
+ "UISupportedInterfaceOrientations",
2728
+ "UISupportedInterfaceOrientations~ipad"
2729
+ ].map((key) => {
2730
+ const list2 = dictionary[key];
2731
+ if (!Array.isArray(list2) || !list2.every((value) => typeof value === "string"))
2732
+ return [];
2733
+ return list2.map((value) => {
2734
+ const resolved = resolveBuildSetting(value, settings);
2735
+ if (resolved === null) throw new Error(`native app Info.plist ${key} is unresolved`);
2736
+ return resolved;
2737
+ });
2738
+ });
2739
+ const [supportedInterfaceOrientations, ipadSupportedInterfaceOrientations] = screenOrientationLists;
2740
+ const declaredDefaultOrientationMask = dictionary.EXDefaultScreenOrientationMask;
2741
+ const defaultScreenOrientationMask = typeof declaredDefaultOrientationMask === "string" ? resolveBuildSetting(declaredDefaultOrientationMask, settings) : void 0;
2742
+ if (defaultScreenOrientationMask === null)
2743
+ throw new Error("native app Info.plist EXDefaultScreenOrientationMask is unresolved");
2744
+ const declaredShareGroup = dictionary.ExpoShareIntoAppGroupId;
2745
+ const shareIntoAppGroupId = typeof declaredShareGroup === "string" ? resolveBuildSetting(declaredShareGroup, settings) : void 0;
2746
+ if (shareIntoAppGroupId === null)
2747
+ throw new Error("native app Info.plist ExpoShareIntoAppGroupId is unresolved");
2504
2748
  const querySchemes = dictionary.LSApplicationQueriesSchemes;
2505
2749
  if (querySchemes !== void 0 && !Array.isArray(querySchemes)) {
2506
2750
  throw new Error("native app Info.plist LSApplicationQueriesSchemes is not an array");
@@ -2514,7 +2758,8 @@ function nativeAppIdentityFromIos(files, parseInfoPlist) {
2514
2758
  });
2515
2759
  const permissionUsageDescriptions = {};
2516
2760
  for (const [key, value] of Object.entries(dictionary)) {
2517
- if (!/^NS.*UsageDescription$/.test(key)) continue;
2761
+ if (!/^NS.*UsageDescription$/.test(key) && key !== "NSLocationTemporaryUsageDescriptionDictionary")
2762
+ continue;
2518
2763
  if (typeof value !== "string") {
2519
2764
  permissionUsageDescriptions[key] = value;
2520
2765
  continue;
@@ -2535,28 +2780,35 @@ function nativeAppIdentityFromIos(files, parseInfoPlist) {
2535
2780
  }
2536
2781
  return {
2537
2782
  applicationName,
2783
+ ...applicationDisplayName === void 0 ? {} : { applicationDisplayName },
2784
+ ...rootViewBackgroundColor === void 0 ? {} : { rootViewBackgroundColor },
2538
2785
  bundleName,
2539
2786
  appVersion,
2540
2787
  buildVersion,
2541
2788
  bundleIdentifier,
2542
2789
  platform: "ios",
2790
+ supportedInterfaceOrientations,
2791
+ ipadSupportedInterfaceOrientations,
2792
+ ...defaultScreenOrientationMask === void 0 ? {} : { defaultScreenOrientationMask },
2793
+ alternateIconNames: [...alternateIconNames],
2543
2794
  permissionUsageDescriptions,
2544
2795
  urlQuerySchemes,
2796
+ ...shareIntoAppGroupId === void 0 ? {} : { shareIntoAppGroupId },
2797
+ backgroundTaskIdentifiers: backgroundTaskIdentifiers.every((value) => value !== null) ? backgroundTaskIdentifiers : [],
2798
+ backgroundModes: backgroundModes.every((value) => value !== null) ? backgroundModes : [],
2545
2799
  appIntentIdentifiers: appIntentIdentifiers.every((value) => value !== null) ? appIntentIdentifiers : []
2546
2800
  };
2547
2801
  }
2548
2802
  function canExtractNativeAppIdentity(platform) {
2549
2803
  return platform === "ios";
2550
2804
  }
2551
- function extractNativeAppIdentityFromFiles(files, platform, parseInfoPlist) {
2552
- return canExtractNativeAppIdentity(platform) ? nativeAppIdentityFromIos(files, parseInfoPlist) : null;
2805
+ function extractNativeAppIdentityFromFiles(files, platform, parseInfoPlist, iosTarget) {
2806
+ return canExtractNativeAppIdentity(platform) ? nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget) : null;
2553
2807
  }
2554
2808
 
2555
- // src/native-firebase-config.ts
2809
+ // src/native-app-identity-project.ts
2556
2810
  var import_node_fs5 = __toESM(require("node:fs"), 1);
2557
- var import_node_module = require("node:module");
2558
2811
  var import_node_path5 = __toESM(require("node:path"), 1);
2559
- init_is_record();
2560
2812
 
2561
2813
  // src/plist.ts
2562
2814
  var import_plist = __toESM(require_plist(), 1);
@@ -2903,98 +3155,6 @@ function isJsonObject(value) {
2903
3155
  }
2904
3156
 
2905
3157
  // src/xcode-project.ts
2906
- function parseOpenStepPlist(text2) {
2907
- let i = 0;
2908
- const fail = (message) => {
2909
- const line = text2.slice(0, i).split("\n").length;
2910
- throw new Error(`project.pbxproj line ${line}: ${message}`);
2911
- };
2912
- const skip = () => {
2913
- for (; ; ) {
2914
- const ch = text2[i];
2915
- if (ch === " " || ch === " " || ch === "\n" || ch === "\r") i++;
2916
- else if (ch === "/" && text2[i + 1] === "*") {
2917
- const end = text2.indexOf("*/", i + 2);
2918
- if (end < 0) fail("unterminated comment");
2919
- i = end + 2;
2920
- } else if (ch === "/" && text2[i + 1] === "/") {
2921
- const end = text2.indexOf("\n", i);
2922
- i = end < 0 ? text2.length : end + 1;
2923
- } else return;
2924
- }
2925
- };
2926
- const quoted = () => {
2927
- i++;
2928
- let out = "";
2929
- for (; ; ) {
2930
- const ch = text2[i++];
2931
- if (ch === void 0) fail("unterminated string");
2932
- if (ch === '"') return out;
2933
- if (ch !== "\\") {
2934
- out += ch;
2935
- continue;
2936
- }
2937
- const next = text2[i++];
2938
- if (next === "n") out += "\n";
2939
- else if (next === "t") out += " ";
2940
- else if (next === "r") out += "\r";
2941
- else if (next === "U") {
2942
- out += String.fromCharCode(parseInt(text2.slice(i, i + 4), 16));
2943
- i += 4;
2944
- } else out += next;
2945
- }
2946
- };
2947
- const value = () => {
2948
- skip();
2949
- const ch = text2[i];
2950
- if (ch === "{") {
2951
- i++;
2952
- const dict = {};
2953
- for (; ; ) {
2954
- skip();
2955
- if (text2[i] === "}") {
2956
- i++;
2957
- return dict;
2958
- }
2959
- const key = value();
2960
- if (typeof key !== "string") fail("dictionary key is not a string");
2961
- skip();
2962
- if (text2[i++] !== "=") fail("expected =");
2963
- dict[key] = value();
2964
- skip();
2965
- if (text2[i++] !== ";") fail("expected ;");
2966
- }
2967
- }
2968
- if (ch === "(") {
2969
- i++;
2970
- const list2 = [];
2971
- for (; ; ) {
2972
- skip();
2973
- if (text2[i] === ")") {
2974
- i++;
2975
- return list2;
2976
- }
2977
- list2.push(value());
2978
- skip();
2979
- if (text2[i] === ",") i++;
2980
- else if (text2[i] !== ")") fail("expected , or )");
2981
- }
2982
- }
2983
- if (ch === '"') return quoted();
2984
- const start = i;
2985
- while (i < text2.length && /[A-Za-z0-9_$+/:.\-<>]/.test(text2[i])) i++;
2986
- if (i === start) fail(`unexpected ${JSON.stringify(ch ?? "end of file")}`);
2987
- return text2.slice(start, i);
2988
- };
2989
- if (text2.startsWith("// !$*UTF8*$!")) i = text2.indexOf("\n") + 1;
2990
- const root = value();
2991
- skip();
2992
- if (i !== text2.length) fail("trailing content");
2993
- return root;
2994
- }
2995
- var isDict = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2996
- var str = (value) => typeof value === "string" ? value : void 0;
2997
- var list = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
2998
3158
  var APPLICATION = "com.apple.product-type.application";
2999
3159
  var MODULE_PRODUCTS = /* @__PURE__ */ new Set([
3000
3160
  "com.apple.product-type.framework",
@@ -3021,9 +3181,9 @@ function walkFiles(dir) {
3021
3181
  return out;
3022
3182
  }
3023
3183
  var isDirectory = (dir) => import_node_fs4.default.existsSync(dir) && import_node_fs4.default.statSync(dir).isDirectory();
3024
- function readXcconfig(file, seen = /* @__PURE__ */ new Set()) {
3025
- if (seen.has(file) || !import_node_fs4.default.existsSync(file)) return {};
3026
- seen.add(file);
3184
+ function readXcconfig(file, read) {
3185
+ if (read.includes(file) || !import_node_fs4.default.existsSync(file)) return {};
3186
+ read.push(file);
3027
3187
  const settings = {};
3028
3188
  for (const raw of import_node_fs4.default.readFileSync(file, "utf8").split("\n")) {
3029
3189
  const line = raw.replace(/\/\/.*$/, "").trim();
@@ -3031,7 +3191,7 @@ function readXcconfig(file, seen = /* @__PURE__ */ new Set()) {
3031
3191
  if (include) {
3032
3192
  Object.assign(
3033
3193
  settings,
3034
- readXcconfig(import_node_path4.default.resolve(import_node_path4.default.dirname(file), include[1]), seen)
3194
+ readXcconfig(import_node_path4.default.resolve(import_node_path4.default.dirname(file), include[1]), read)
3035
3195
  );
3036
3196
  continue;
3037
3197
  }
@@ -3179,17 +3339,30 @@ function loadProject(xcodeproj) {
3179
3339
  loaded.set(projectFile, { mtimeMs, project: result });
3180
3340
  return result;
3181
3341
  }
3182
- function targetSettings(ref, builtins) {
3342
+ function defaultConfiguration(project) {
3343
+ const configList = project.object(str(project.project.buildConfigurationList));
3344
+ const names = list(configList?.buildConfigurations).flatMap(
3345
+ (id) => str(project.object(id)?.name) ?? []
3346
+ );
3347
+ return names.includes("Debug") ? "Debug" : str(configList?.defaultConfigurationName) ?? names[0] ?? "Debug";
3348
+ }
3349
+ function targetSettings(ref, configuration, builtins) {
3183
3350
  const { project, target } = ref;
3351
+ const xcconfigs = [];
3184
3352
  const level = (listId) => {
3185
- const configs = list(project.object(listId)?.buildConfigurations).map(project.object);
3186
- const config = configs.find((entry) => entry?.name === "Debug") ?? configs.find(Boolean);
3353
+ const configList = project.object(listId);
3354
+ const configs = list(configList?.buildConfigurations).map(project.object);
3355
+ const config = configs.find((entry) => entry?.name === configuration) ?? configs.find((entry) => entry?.name === str(configList?.defaultConfigurationName));
3187
3356
  if (!config) return [];
3188
- const name2 = str(config.name) ?? "Debug";
3357
+ const name2 = str(config.name) ?? configuration;
3189
3358
  const base = str(config.baseConfigurationReference);
3190
3359
  const own = isDict(config.buildSettings) ? config.buildSettings : {};
3360
+ const baseFile = base ? project.resolvePath(base) : null;
3361
+ const read = [];
3362
+ const fromFile = baseFile ? readXcconfig(baseFile, read) : {};
3363
+ xcconfigs.push(...read);
3191
3364
  return [
3192
- applyConditions(base ? readXcconfig(project.resolvePath(base) ?? "") : {}, name2),
3365
+ applyConditions(fromFile, name2),
3193
3366
  applyConditions(
3194
3367
  Object.fromEntries(
3195
3368
  Object.entries(own).flatMap(
@@ -3201,7 +3374,7 @@ function targetSettings(ref, builtins) {
3201
3374
  ];
3202
3375
  };
3203
3376
  const levels = [
3204
- builtins,
3377
+ { ...builtins, CONFIGURATION: configuration },
3205
3378
  ...level(str(project.project.buildConfigurationList)),
3206
3379
  ...level(str(target.buildConfigurationList))
3207
3380
  ];
@@ -3240,9 +3413,30 @@ function targetSettings(ref, builtins) {
3240
3413
  };
3241
3414
  return {
3242
3415
  get: (key) => valueAt(key, levels.length - 1),
3243
- keys: new Set(levels.flatMap((values) => Object.keys(values)))
3416
+ keys: new Set(levels.flatMap((values) => Object.keys(values))),
3417
+ xcconfigs
3244
3418
  };
3245
3419
  }
3420
+ function settingList(value) {
3421
+ const items2 = [];
3422
+ for (const [, quoted, plain] of value.matchAll(
3423
+ /"((?:\\.|[^"\\])*)"|((?:\\.|[^\s"])+)/g
3424
+ ))
3425
+ items2.push((quoted ?? plain).replace(/\\(.)/g, "$1"));
3426
+ return items2;
3427
+ }
3428
+ function compilationConditions(settings) {
3429
+ const flags = settingList(settings("OTHER_SWIFT_FLAGS"));
3430
+ const defined = flags.flatMap(
3431
+ (flag, index) => flag === "-D" ? flags[index + 1] ?? [] : flag.startsWith("-D") ? flag.slice(2) : []
3432
+ );
3433
+ return [
3434
+ .../* @__PURE__ */ new Set([
3435
+ ...settingList(settings("SWIFT_ACTIVE_COMPILATION_CONDITIONS")),
3436
+ ...defined
3437
+ ])
3438
+ ];
3439
+ }
3246
3440
  function expand(value, lookup) {
3247
3441
  return value.replace(
3248
3442
  /\$(?:\(([A-Za-z_][A-Za-z0-9_]*)((?::[^)]*)?)\)|\{([A-Za-z_][A-Za-z0-9_]*)((?::[^}]*)?)\}|([A-Za-z_][A-Za-z0-9_]*))/g,
@@ -3253,8 +3447,9 @@ function expand(value, lookup) {
3253
3447
  }
3254
3448
  );
3255
3449
  }
3256
- function targetMembers(ref) {
3450
+ function targetMembers(ref, settings, options = {}) {
3257
3451
  const { project, target, id: targetId } = ref;
3452
+ const targetName = str(target.name) ?? targetId;
3258
3453
  const sources = /* @__PURE__ */ new Set();
3259
3454
  const allSources = /* @__PURE__ */ new Set();
3260
3455
  const resources = /* @__PURE__ */ new Set();
@@ -3275,6 +3470,29 @@ function targetMembers(ref) {
3275
3470
  const resolved = project.resolvePath(refId);
3276
3471
  return resolved ? [resolved] : [];
3277
3472
  };
3473
+ const scriptForOutput = /* @__PURE__ */ new Map();
3474
+ const noteScriptOutput = (raw, script) => {
3475
+ const expanded = expand(raw, settings);
3476
+ if (!expanded.endsWith(".swift")) return;
3477
+ const absolute = import_node_path4.default.isAbsolute(expanded) ? import_node_path4.default.normalize(expanded) : import_node_path4.default.resolve(project.projectDir, expanded);
3478
+ if (!scriptForOutput.has(absolute)) scriptForOutput.set(absolute, script);
3479
+ };
3480
+ for (const phaseId of list(target.buildPhases)) {
3481
+ const phase = project.object(phaseId);
3482
+ if (phase?.isa !== "PBXShellScriptBuildPhase") continue;
3483
+ const script = str(phase.name) ?? phaseId;
3484
+ for (const raw of list(phase.outputPaths)) noteScriptOutput(raw, script);
3485
+ for (const listPath of list(phase.outputFileListPaths)) {
3486
+ const expandedList = expand(listPath, settings);
3487
+ const absoluteList = import_node_path4.default.isAbsolute(expandedList) ? expandedList : import_node_path4.default.resolve(project.projectDir, expandedList);
3488
+ if (!import_node_fs4.default.existsSync(absoluteList)) continue;
3489
+ for (const line of import_node_fs4.default.readFileSync(absoluteList, "utf8").split("\n")) {
3490
+ const trimmed = line.trim();
3491
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
3492
+ noteScriptOutput(trimmed, script);
3493
+ }
3494
+ }
3495
+ }
3278
3496
  for (const phaseId of list(target.buildPhases)) {
3279
3497
  const phase = project.object(phaseId);
3280
3498
  if (phase?.isa !== "PBXSourcesBuildPhase" && phase?.isa !== "PBXResourcesBuildPhase")
@@ -3282,13 +3500,30 @@ function targetMembers(ref) {
3282
3500
  for (const buildFileId of list(phase.files)) {
3283
3501
  for (const file of fileRefPaths(str(project.object(buildFileId)?.fileRef) ?? "")) {
3284
3502
  if (phase.isa === "PBXSourcesBuildPhase") {
3285
- if (!import_node_fs4.default.existsSync(file)) continue;
3503
+ if (!import_node_fs4.default.existsSync(file)) {
3504
+ if (options.requireSources === false) continue;
3505
+ const script = scriptForOutput.get(import_node_path4.default.normalize(file));
3506
+ throw new Error(
3507
+ script ? `${targetName}: missing generated source ${file} (Run Script "${script}" declares it in outputPaths; run the script or check in its output)` : `${targetName}: missing source ${file}`
3508
+ );
3509
+ }
3286
3510
  allSources.add(file);
3287
3511
  if (file.endsWith(".swift")) sources.add(file);
3288
3512
  } else if (phase.isa === "PBXResourcesBuildPhase") addResource(file);
3289
3513
  }
3290
3514
  }
3291
3515
  }
3516
+ for (const [file, script] of scriptForOutput) {
3517
+ if (sources.has(file) || allSources.has(file)) continue;
3518
+ if (!import_node_fs4.default.existsSync(file)) {
3519
+ if (options.requireSources === false) continue;
3520
+ throw new Error(
3521
+ `${targetName}: missing generated source ${file} (Run Script "${script}" declares it in outputPaths; run the script or check in its output)`
3522
+ );
3523
+ }
3524
+ allSources.add(file);
3525
+ sources.add(file);
3526
+ }
3292
3527
  const addSynchronized = (folder, relative2) => {
3293
3528
  const file = import_node_path4.default.join(folder, relative2);
3294
3529
  if (NEVER_MEMBER.test(relative2)) return;
@@ -3391,7 +3626,7 @@ function nativeTargets(project) {
3391
3626
  function listXcodeAppTargets(xcodeprojOrWorkspace) {
3392
3627
  return workspaceProjects(xcodeprojOrWorkspace).projects.flatMap(nativeTargets).filter((ref) => ref.target.productType === APPLICATION).map((ref) => str(ref.target.name) ?? ref.id);
3393
3628
  }
3394
- function readXcodeAppTarget(input, targetName) {
3629
+ function readXcodeAppTarget(input, targetName, configurationName, options = {}) {
3395
3630
  const xcodeprojOrWorkspace = import_node_fs4.default.realpathSync(input);
3396
3631
  const workspace = xcodeprojOrWorkspace.endsWith(".xcworkspace") ? xcodeprojOrWorkspace : null;
3397
3632
  const { listed, projects, projectAt } = workspaceProjects(xcodeprojOrWorkspace);
@@ -3406,6 +3641,7 @@ function readXcodeAppTarget(input, targetName) {
3406
3641
  );
3407
3642
  }
3408
3643
  const app = named[0];
3644
+ const configuration = configurationName ?? defaultConfiguration(app.project);
3409
3645
  const byProduct = /* @__PURE__ */ new Map();
3410
3646
  for (const ref of allTargets) {
3411
3647
  const product = ref.project.object(str(ref.target.productReference));
@@ -3456,9 +3692,14 @@ function readXcodeAppTarget(input, targetName) {
3456
3692
  order.push(ref);
3457
3693
  };
3458
3694
  visit(app);
3695
+ const xcconfigs = /* @__PURE__ */ new Set();
3459
3696
  const moduleTarget = (ref) => {
3460
3697
  const name2 = str(ref.target.name) ?? ref.id;
3461
- const { get: settings2, keys } = targetSettings(ref, {
3698
+ const {
3699
+ get: settings2,
3700
+ keys,
3701
+ xcconfigs: read
3702
+ } = targetSettings(ref, configuration, {
3462
3703
  TARGET_NAME: name2,
3463
3704
  PROJECT_NAME: import_node_path4.default.basename(ref.project.xcodeproj, ".xcodeproj"),
3464
3705
  SRCROOT: ref.project.projectDir,
@@ -3466,6 +3707,7 @@ function readXcodeAppTarget(input, targetName) {
3466
3707
  PROJECT_DIR: ref.project.projectDir,
3467
3708
  DEVELOPMENT_LANGUAGE: str(ref.project.project.developmentRegion) ?? "en"
3468
3709
  });
3710
+ for (const file of read) xcconfigs.add(file);
3469
3711
  const swiftVersion = Number.parseFloat(settings2("SWIFT_VERSION") || "5");
3470
3712
  return {
3471
3713
  settings: settings2,
@@ -3473,9 +3715,10 @@ function readXcodeAppTarget(input, targetName) {
3473
3715
  module: {
3474
3716
  name: name2,
3475
3717
  moduleName: applyOperator(settings2("PRODUCT_MODULE_NAME"), "c99extidentifier"),
3476
- ...targetMembers(ref),
3718
+ ...targetMembers(ref, settings2, options),
3477
3719
  languageMode: swiftVersion >= 6 ? 6 : 5,
3478
- mainActorIsolation: settings2("SWIFT_DEFAULT_ACTOR_ISOLATION") === "MainActor"
3720
+ mainActorIsolation: settings2("SWIFT_DEFAULT_ACTOR_ISOLATION") === "MainActor",
3721
+ defines: compilationConditions(settings2)
3479
3722
  }
3480
3723
  };
3481
3724
  };
@@ -3581,7 +3824,9 @@ function readXcodeAppTarget(input, targetName) {
3581
3824
  )
3582
3825
  ].map((dir) => import_node_fs4.default.realpathSync(dir))
3583
3826
  ),
3584
- projectFiles: [...new Set(used.map((project) => project.projectFile))].sort(),
3827
+ projectFiles: [
3828
+ .../* @__PURE__ */ new Set([...used.map((project) => project.projectFile), ...xcconfigs])
3829
+ ].sort(),
3585
3830
  appIconName: settings("ASSETCATALOG_COMPILER_APPICON_NAME"),
3586
3831
  infoPlist: import_plist2.default.build(info),
3587
3832
  infoPlistFile,
@@ -3592,59 +3837,216 @@ function readXcodeAppTarget(input, targetName) {
3592
3837
  ].sort(),
3593
3838
  binaryFrameworks: [...binaryFrameworks].map(([name2, file]) => ({ name: name2, path: file })).sort((left, right) => left.name.localeCompare(right.name)),
3594
3839
  packageResolved: import_node_fs4.default.existsSync(resolvedFile) ? resolvedFile : null,
3595
- appTargets: appTargetNames
3840
+ appTargets: appTargetNames,
3841
+ configuration,
3842
+ settings
3843
+ };
3844
+ }
3845
+
3846
+ // src/native-app-identity-project.ts
3847
+ function isRecord2(value) {
3848
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3849
+ }
3850
+ function nonEmptyString2(value) {
3851
+ return typeof value === "string" && value.length > 0 ? value : void 0;
3852
+ }
3853
+ function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSource) {
3854
+ const dictionary = parseInfoPlist(app.infoPlist);
3855
+ if (!isRecord2(dictionary)) throw new Error("native app Info.plist is not a dictionary");
3856
+ const settings = app.settings;
3857
+ const bundleIdentifier = nonEmptyString2(dictionary.CFBundleIdentifier) ?? nonEmptyString2(settings?.("PRODUCT_BUNDLE_IDENTIFIER"));
3858
+ if (!bundleIdentifier) throw new Error("native app has no bundle identifier");
3859
+ const appVersion = nonEmptyString2(dictionary.CFBundleShortVersionString) ?? nonEmptyString2(settings?.("MARKETING_VERSION"));
3860
+ const buildVersion = nonEmptyString2(dictionary.CFBundleVersion) ?? nonEmptyString2(settings?.("CURRENT_PROJECT_VERSION"));
3861
+ if (!appVersion || !buildVersion) {
3862
+ throw new Error("native app has no version or build version");
3863
+ }
3864
+ const bundleName = nonEmptyString2(dictionary.CFBundleName) ?? nonEmptyString2(settings?.("PRODUCT_NAME")) ?? app.name;
3865
+ const applicationDisplayName = nonEmptyString2(dictionary.CFBundleDisplayName);
3866
+ const applicationName = applicationDisplayName ?? bundleName;
3867
+ const declaredBackgroundColor = dictionary.RCTRootViewBackgroundColor;
3868
+ const rootViewBackgroundColor = typeof declaredBackgroundColor === "number" && Number.isInteger(declaredBackgroundColor) ? declaredBackgroundColor : void 0;
3869
+ const alternateIconNames = /* @__PURE__ */ new Set();
3870
+ const icons = dictionary.CFBundleIcons;
3871
+ const alternates = isRecord2(icons) ? icons.CFBundleAlternateIcons : void 0;
3872
+ if (isRecord2(alternates)) {
3873
+ for (const name2 of Object.keys(alternates)) {
3874
+ if (name2) alternateIconNames.add(name2);
3875
+ }
3876
+ }
3877
+ const alternateSetting = settings?.("ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES") ?? "";
3878
+ for (const match of alternateSetting.replace(/\\"/g, '"').matchAll(/"([^"]*)"|([^\s(),]+)/g)) {
3879
+ const val = match[1] ?? match[2];
3880
+ if (val) alternateIconNames.add(val);
3881
+ }
3882
+ const permissionUsageDescriptions = {};
3883
+ for (const [key, value] of Object.entries(dictionary)) {
3884
+ if (!/^NS.*UsageDescription$/.test(key) && key !== "NSLocationTemporaryUsageDescriptionDictionary") {
3885
+ continue;
3886
+ }
3887
+ permissionUsageDescriptions[key] = value;
3888
+ }
3889
+ const querySchemes = dictionary.LSApplicationQueriesSchemes;
3890
+ const urlQuerySchemes = Array.isArray(querySchemes) ? querySchemes : [];
3891
+ const intentIds = dictionary.OneAppIntentIdentifiers;
3892
+ const appIntentIdentifiers = Array.isArray(intentIds) && intentIds.every((v) => typeof v === "string") ? intentIds : [];
3893
+ const backgroundIds = dictionary.BGTaskSchedulerPermittedIdentifiers;
3894
+ const backgroundTaskIdentifiers = Array.isArray(backgroundIds) && backgroundIds.every((v) => typeof v === "string") ? backgroundIds : [];
3895
+ const declaredModes = dictionary.UIBackgroundModes;
3896
+ const backgroundModes = Array.isArray(declaredModes) && declaredModes.every((v) => typeof v === "string") ? declaredModes : [];
3897
+ const supportedInterfaceOrientations = Array.isArray(dictionary.UISupportedInterfaceOrientations) && dictionary.UISupportedInterfaceOrientations.every((v) => typeof v === "string") ? dictionary.UISupportedInterfaceOrientations : [];
3898
+ const ipadSupportedInterfaceOrientations = Array.isArray(dictionary["UISupportedInterfaceOrientations~ipad"]) && dictionary["UISupportedInterfaceOrientations~ipad"].every(
3899
+ (v) => typeof v === "string"
3900
+ ) ? dictionary["UISupportedInterfaceOrientations~ipad"] : [];
3901
+ const defaultScreenOrientationMask = nonEmptyString2(
3902
+ dictionary.EXDefaultScreenOrientationMask
3903
+ );
3904
+ const shareIntoAppGroupId = nonEmptyString2(dictionary.ExpoShareIntoAppGroupId);
3905
+ return {
3906
+ applicationName,
3907
+ ...applicationDisplayName ? { applicationDisplayName } : {},
3908
+ ...rootViewBackgroundColor !== void 0 ? { rootViewBackgroundColor } : {},
3909
+ bundleName,
3910
+ appVersion,
3911
+ buildVersion,
3912
+ bundleIdentifier,
3913
+ platform: "ios",
3914
+ supportedInterfaceOrientations,
3915
+ ipadSupportedInterfaceOrientations,
3916
+ ...defaultScreenOrientationMask ? { defaultScreenOrientationMask } : {},
3917
+ alternateIconNames: [...alternateIconNames],
3918
+ permissionUsageDescriptions,
3919
+ urlQuerySchemes,
3920
+ ...shareIntoAppGroupId ? { shareIntoAppGroupId } : {},
3921
+ backgroundTaskIdentifiers,
3922
+ backgroundModes,
3923
+ appIntentIdentifiers
3596
3924
  };
3597
3925
  }
3926
+ function readNativeAppIdentityFromProject(projectRoot, platform, parseInfoPlist = parsePlistSource, iosTarget) {
3927
+ if (!canExtractNativeAppIdentity(platform)) return null;
3928
+ const iosRoot = import_node_path5.default.join(projectRoot, "ios");
3929
+ if (!import_node_fs5.default.existsSync(iosRoot)) return null;
3930
+ const projects = import_node_fs5.default.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
3931
+ if (projects.length === 0) return null;
3932
+ if (projects.length > 1 && !iosTarget) {
3933
+ throw new Error("native app identity requires a selected Xcode project");
3934
+ }
3935
+ let project = projects[0];
3936
+ if (iosTarget && projects.length > 1) {
3937
+ const matches = projects.filter(
3938
+ (entry) => listXcodeAppTargets(import_node_path5.default.join(iosRoot, entry.name)).includes(iosTarget)
3939
+ );
3940
+ if (matches.length === 0) {
3941
+ throw new Error(`native app identity has no application target ${iosTarget}`);
3942
+ }
3943
+ if (matches.length > 1) {
3944
+ throw new Error(
3945
+ `native app identity target ${iosTarget} is ambiguous across ${matches.map((entry) => entry.name).join(", ")}`
3946
+ );
3947
+ }
3948
+ project = matches[0];
3949
+ }
3950
+ const xcodeproj = import_node_path5.default.join(iosRoot, project.name);
3951
+ const appTargets = listXcodeAppTargets(xcodeproj);
3952
+ if (!iosTarget && appTargets.length > 1) {
3953
+ throw new Error("native app identity requires a selected app target");
3954
+ }
3955
+ const app = readXcodeAppTarget(xcodeproj, iosTarget ?? appTargets[0], "Release", {
3956
+ requireSources: false
3957
+ });
3958
+ return readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist);
3959
+ }
3598
3960
 
3599
3961
  // src/native-firebase-config.ts
3600
- function readNativeFirebaseConfig(projectRoot, platforms = ["ios", "android"]) {
3962
+ var import_node_child_process = require("node:child_process");
3963
+ var import_node_fs6 = __toESM(require("node:fs"), 1);
3964
+ var import_node_os = __toESM(require("node:os"), 1);
3965
+ var import_node_path6 = __toESM(require("node:path"), 1);
3966
+ init_is_record();
3967
+ function readNativeFirebaseConfig(projectRoot, platforms = ["ios", "android"], iosTarget) {
3601
3968
  const result = {};
3602
3969
  let config = {};
3603
- const appJsonPath = import_node_path5.default.join(projectRoot, "app.json");
3604
- const appJson = import_node_fs5.default.existsSync(appJsonPath) ? JSON.parse(import_node_fs5.default.readFileSync(appJsonPath, "utf8")) : null;
3605
- const staticExpo = isRecord2(appJson) && (isRecord2(appJson.expo) || [appJson.ios, appJson.android].some(
3606
- (value) => isRecord2(value) && typeof value.googleServicesFile === "string"
3970
+ const appJsonPath = import_node_path6.default.join(projectRoot, "app.json");
3971
+ const appJson = import_node_fs6.default.existsSync(appJsonPath) ? JSON.parse(import_node_fs6.default.readFileSync(appJsonPath, "utf8")) : null;
3972
+ const staticExpo = isRecord3(appJson) && (isRecord3(appJson.expo) || [appJson.ios, appJson.android].some(
3973
+ (value) => isRecord3(value) && typeof value.googleServicesFile === "string"
3607
3974
  ));
3608
3975
  const dynamicExpo = [
3609
3976
  "app.config.js",
3610
3977
  "app.config.ts",
3611
3978
  "app.config.cjs",
3612
3979
  "app.config.mjs"
3613
- ].some((name2) => import_node_fs5.default.existsSync(import_node_path5.default.join(projectRoot, name2)));
3980
+ ].some((name2) => import_node_fs6.default.existsSync(import_node_path6.default.join(projectRoot, name2)));
3614
3981
  if (staticExpo || dynamicExpo) {
3615
- const require2 = (0, import_node_module.createRequire)(import_node_path5.default.join(projectRoot, "package.json"));
3616
- const configModule = require2("@expo/config");
3617
- if (!isRecord2(configModule) || typeof configModule.getConfig !== "function")
3618
- throw new Error("Expo native configuration is unavailable.");
3619
- const resolved = Reflect.apply(configModule.getConfig, configModule, [
3620
- projectRoot,
3621
- { skipSDKVersionRequirement: true }
3622
- ]);
3623
- config = isRecord2(resolved) && isRecord2(resolved.exp) ? resolved.exp : {};
3982
+ const directory = import_node_fs6.default.mkdtempSync(import_node_path6.default.join(import_node_os.default.tmpdir(), "peach-expo-config-"));
3983
+ const resultPath = import_node_path6.default.join(directory, "config.json");
3984
+ try {
3985
+ const child = (0, import_node_child_process.spawnSync)(
3986
+ "node",
3987
+ [
3988
+ "--input-type=commonjs",
3989
+ "-e",
3990
+ `const { createRequire } = require('node:module');
3991
+ const { writeFileSync } = require('node:fs');
3992
+ const { join } = require('node:path');
3993
+ const root = process.argv[1];
3994
+ const { getConfig } = createRequire(join(root, 'package.json'))('@expo/config');
3995
+ const result = JSON.stringify(getConfig(root, { skipSDKVersionRequirement: true }).exp);
3996
+ if (Buffer.byteLength(result) > 1024 * 1024) throw new Error('Expo native configuration exceeds 1 MiB.');
3997
+ writeFileSync(process.argv[2], result, { mode: 0o600 });`,
3998
+ import_node_path6.default.resolve(projectRoot),
3999
+ resultPath
4000
+ ],
4001
+ {
4002
+ cwd: projectRoot,
4003
+ encoding: "utf8",
4004
+ stdio: ["ignore", "ignore", "pipe"],
4005
+ timeout: 3e4,
4006
+ maxBuffer: 1024 * 1024
4007
+ }
4008
+ );
4009
+ if (child.error) throw child.error;
4010
+ if (child.status !== 0)
4011
+ throw new Error(child.stderr || "Expo native configuration evaluation failed.");
4012
+ const resolved = JSON.parse(import_node_fs6.default.readFileSync(resultPath, "utf8"));
4013
+ if (!isRecord3(resolved))
4014
+ throw new Error("Expo native configuration is unavailable.");
4015
+ config = resolved;
4016
+ } finally {
4017
+ import_node_fs6.default.rmSync(directory, { recursive: true, force: true });
4018
+ }
3624
4019
  }
3625
4020
  const ios = config.ios;
3626
- if (platforms.includes("ios") && (!isRecord2(ios) || typeof ios.googleServicesFile !== "string")) {
3627
- const iosRoot = import_node_path5.default.join(projectRoot, "ios");
3628
- if (import_node_fs5.default.existsSync(iosRoot)) {
3629
- const projects = import_node_fs5.default.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
4021
+ if (platforms.includes("ios") && (!isRecord3(ios) || typeof ios.googleServicesFile !== "string")) {
4022
+ const iosRoot = import_node_path6.default.join(projectRoot, "ios");
4023
+ if (import_node_fs6.default.existsSync(iosRoot)) {
4024
+ const projects = import_node_fs6.default.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
3630
4025
  if (projects.length > 1)
3631
4026
  throw new Error("native Firebase configuration requires a selected Xcode project");
3632
4027
  if (projects.length === 1) {
3633
- const xcodeproj = import_node_path5.default.join(iosRoot, projects[0].name);
4028
+ const xcodeproj = import_node_path6.default.join(iosRoot, projects[0].name);
3634
4029
  const appTargets = listXcodeAppTargets(xcodeproj);
3635
- if (appTargets.length > 1)
4030
+ if (!iosTarget && appTargets.length > 1)
3636
4031
  throw new Error("native Firebase configuration requires a selected app target");
3637
- if (appTargets.length === 1) {
3638
- const app = readXcodeAppTarget(xcodeproj, appTargets[0]);
4032
+ if (iosTarget || appTargets.length === 1) {
4033
+ const app = readXcodeAppTarget(
4034
+ xcodeproj,
4035
+ iosTarget ?? appTargets[0],
4036
+ void 0,
4037
+ {
4038
+ requireSources: false
4039
+ }
4040
+ );
3639
4041
  const delegates = app.allSources.filter(
3640
- (file) => /^AppDelegate\.(swift|mm|m)$/.test(import_node_path5.default.basename(file))
4042
+ (file) => /^AppDelegate\.(swift|mm|m)$/.test(import_node_path6.default.basename(file))
3641
4043
  );
3642
4044
  const defaultConfigured = delegates.some((file) => {
3643
- const source = import_node_fs5.default.readFileSync(file, "utf8").replace(
4045
+ const source = import_node_fs6.default.readFileSync(file, "utf8").replace(
3644
4046
  /\/\*[\s\S]*?\*\/|\/\/[^\n]*|"(?:\\.|[^"\\])*"/g,
3645
4047
  (token) => token.startsWith('"') ? '""' : token.replace(/[^\n]/g, " ")
3646
4048
  );
3647
- const launch = /(?:\bfunc\s+application\s*\([\s\S]*?didFinishLaunchingWithOptions[\s\S]*?\)\s*->\s*Bool|^-\s*\(BOOL\)\s*application\s*:[\s\S]*?didFinishLaunchingWithOptions[^\{]*)\s*\{/m.exec(
4049
+ const launch = /(?:\bfunc\s+application\s*\([\s\S]*?didFinishLaunchingWithOptions[\s\S]*?\)\s*->\s*Bool|^-\s*\(BOOL\)\s*application\s*:[\s\S]*?didFinishLaunchingWithOptions[^{]*)\s*\{/m.exec(
3648
4050
  source
3649
4051
  );
3650
4052
  if (!launch) return false;
@@ -3660,7 +4062,21 @@ function readNativeFirebaseConfig(projectRoot, platforms = ["ios", "android"]) {
3660
4062
  if (token === "}") depth -= 1;
3661
4063
  if (depth === 0) return false;
3662
4064
  }
3663
- if (depth !== 1 || /\b(?:return|throw)\b|^\s*#(?:if|elseif|else)/m.test(before))
4065
+ let conditionalDepth = 0;
4066
+ for (const directive of before.matchAll(
4067
+ /^\s*#\s*(if|ifdef|ifndef|elseif|elif|else|endif)\b/gm
4068
+ )) {
4069
+ const kind = directive[1];
4070
+ if (kind === "if" || kind === "ifdef" || kind === "ifndef") {
4071
+ conditionalDepth += 1;
4072
+ } else if (conditionalDepth === 0) {
4073
+ conditionalDepth = -1;
4074
+ break;
4075
+ } else if (kind === "endif") {
4076
+ conditionalDepth -= 1;
4077
+ }
4078
+ }
4079
+ if (depth !== 1 || conditionalDepth !== 0 || /\b(?:return|throw)\b/.test(before))
3664
4080
  throw new Error(
3665
4081
  "native Firebase initialization must be unconditional in the app launch method"
3666
4082
  );
@@ -3668,15 +4084,15 @@ function readNativeFirebaseConfig(projectRoot, platforms = ["ios", "android"]) {
3668
4084
  });
3669
4085
  if (defaultConfigured) {
3670
4086
  const resources = app.resources.filter(
3671
- (file) => /^GoogleService-Info\.plist$/.test(import_node_path5.default.basename(file))
4087
+ (file) => /^GoogleService-Info\.plist$/.test(import_node_path6.default.basename(file))
3672
4088
  );
3673
4089
  if (resources.length !== 1)
3674
4090
  throw new Error(
3675
4091
  "native Firebase default initialization requires one GoogleService-Info.plist build resource"
3676
4092
  );
3677
4093
  config.ios = {
3678
- googleServicesFile: import_node_path5.default.relative(
3679
- import_node_fs5.default.realpathSync(projectRoot),
4094
+ googleServicesFile: import_node_path6.default.relative(
4095
+ import_node_fs6.default.realpathSync(projectRoot),
3680
4096
  resources[0]
3681
4097
  )
3682
4098
  };
@@ -3687,14 +4103,14 @@ function readNativeFirebaseConfig(projectRoot, platforms = ["ios", "android"]) {
3687
4103
  }
3688
4104
  for (const platform of platforms) {
3689
4105
  const native = config[platform];
3690
- if (!isRecord2(native) || typeof native.googleServicesFile !== "string") continue;
4106
+ if (!isRecord3(native) || typeof native.googleServicesFile !== "string") continue;
3691
4107
  try {
3692
- const source = import_node_fs5.default.readFileSync(
3693
- import_node_path5.default.resolve(projectRoot, native.googleServicesFile),
4108
+ const source = import_node_fs6.default.readFileSync(
4109
+ import_node_path6.default.resolve(projectRoot, native.googleServicesFile),
3694
4110
  "utf8"
3695
4111
  );
3696
4112
  const parsed = platform === "ios" ? parsePlistSource(source) : JSON.parse(source);
3697
- if (!isRecord2(parsed)) throw new Error("Invalid Google services file.");
4113
+ if (!isRecord3(parsed)) throw new Error("Invalid Google services file.");
3698
4114
  if (platform === "ios") {
3699
4115
  result[platform] = {
3700
4116
  apiKey: parsed.API_KEY,
@@ -3709,31 +4125,31 @@ function readNativeFirebaseConfig(projectRoot, platforms = ["ios", "android"]) {
3709
4125
  deepLinkUrlScheme: parsed.REVERSED_CLIENT_ID
3710
4126
  };
3711
4127
  } else {
3712
- const project = isRecord2(parsed.project_info) ? parsed.project_info : {};
4128
+ const project = isRecord3(parsed.project_info) ? parsed.project_info : {};
3713
4129
  const clients = Array.isArray(parsed.client) ? parsed.client : [];
3714
4130
  const client = clients.find((value) => {
3715
- if (!isRecord2(value) || !isRecord2(value.client_info)) return false;
4131
+ if (!isRecord3(value) || !isRecord3(value.client_info)) return false;
3716
4132
  const android = value.client_info.android_client_info;
3717
- return isRecord2(android) && android.package_name === native.package;
4133
+ return isRecord3(android) && android.package_name === native.package;
3718
4134
  });
3719
- if (!isRecord2(client) || !isRecord2(client.client_info))
4135
+ if (!isRecord3(client) || !isRecord3(client.client_info))
3720
4136
  throw new Error("No Google services client matches the Android package.");
3721
4137
  const apiKeys = Array.isArray(client.api_key) ? client.api_key : [];
3722
4138
  const apiKey = apiKeys.find(
3723
- (value) => isRecord2(value) && typeof value.current_key === "string"
4139
+ (value) => isRecord3(value) && typeof value.current_key === "string"
3724
4140
  );
3725
4141
  const oauthClients = Array.isArray(client.oauth_client) ? client.oauth_client : [];
3726
4142
  const oauth = oauthClients.find(
3727
- (value) => isRecord2(value) && value.client_type === 3
4143
+ (value) => isRecord3(value) && value.client_type === 3
3728
4144
  );
3729
4145
  result[platform] = {
3730
- apiKey: isRecord2(apiKey) ? apiKey.current_key : void 0,
4146
+ apiKey: isRecord3(apiKey) ? apiKey.current_key : void 0,
3731
4147
  appId: client.client_info.mobilesdk_app_id,
3732
4148
  projectId: project.project_id,
3733
4149
  databaseURL: project.firebase_url,
3734
4150
  storageBucket: project.storage_bucket,
3735
4151
  messagingSenderId: project.project_number,
3736
- clientId: isRecord2(oauth) ? oauth.client_id : void 0
4152
+ clientId: isRecord3(oauth) ? oauth.client_id : void 0
3737
4153
  };
3738
4154
  }
3739
4155
  } catch (error) {
@@ -3830,28 +4246,28 @@ var import_url = require("url");
3830
4246
  init_version();
3831
4247
 
3832
4248
  // src/home-paths.ts
3833
- var import_node_fs6 = __toESM(require("node:fs"), 1);
3834
- var import_node_os = require("node:os");
3835
- var import_node_path6 = __toESM(require("node:path"), 1);
4249
+ var import_node_fs7 = __toESM(require("node:fs"), 1);
4250
+ var import_node_os2 = require("node:os");
4251
+ var import_node_path7 = __toESM(require("node:path"), 1);
3836
4252
  var PEACH_HOME_ENV = "PEACH_HOME";
3837
4253
  var ACTIVE_RUNTIME_FILE = "active";
3838
4254
  function rnxHomeDir() {
3839
4255
  const override = process.env[PEACH_HOME_ENV];
3840
- if (override && override.length > 0) return import_node_path6.default.resolve(override);
3841
- return import_node_path6.default.join((0, import_node_os.homedir)(), ".peach");
4256
+ if (override && override.length > 0) return import_node_path7.default.resolve(override);
4257
+ return import_node_path7.default.join((0, import_node_os2.homedir)(), ".peach");
3842
4258
  }
3843
4259
  function runtimesDir() {
3844
- return import_node_path6.default.join(rnxHomeDir(), "runtimes");
4260
+ return import_node_path7.default.join(rnxHomeDir(), "runtimes");
3845
4261
  }
3846
4262
  function runtimeDir(version) {
3847
- return import_node_path6.default.join(runtimesDir(), version);
4263
+ return import_node_path7.default.join(runtimesDir(), version);
3848
4264
  }
3849
4265
  function activeRuntimeFile() {
3850
- return import_node_path6.default.join(runtimesDir(), ACTIVE_RUNTIME_FILE);
4266
+ return import_node_path7.default.join(runtimesDir(), ACTIVE_RUNTIME_FILE);
3851
4267
  }
3852
4268
  function readActiveRuntime() {
3853
4269
  try {
3854
- const value = import_node_fs6.default.readFileSync(activeRuntimeFile(), "utf8").trim();
4270
+ const value = import_node_fs7.default.readFileSync(activeRuntimeFile(), "utf8").trim();
3855
4271
  return value.length > 0 ? value : null;
3856
4272
  } catch {
3857
4273
  return null;
@@ -4044,7 +4460,7 @@ function streamFile(res, stream) {
4044
4460
  }
4045
4461
 
4046
4462
  // src/metro-plugin.ts
4047
- var prefix = "/__soot";
4463
+ var prefix = "/__peachsim";
4048
4464
  function readCallableMetroExport(moduleValue, label) {
4049
4465
  const callable = typeof moduleValue === "function" ? moduleValue : typeof moduleValue === "object" && moduleValue !== null ? Reflect.get(moduleValue, "default") : void 0;
4050
4466
  if (typeof callable !== "function") {
@@ -4052,8 +4468,8 @@ function readCallableMetroExport(moduleValue, label) {
4052
4468
  }
4053
4469
  return (...args) => Reflect.apply(callable, void 0, args);
4054
4470
  }
4055
- function createMetroDefaultSerializer(projectRoot) {
4056
- const projectRequire = (0, import_module.createRequire)(import_path2.default.join(projectRoot, "package.json"));
4471
+ function createMetroDefaultSerializer(asyncRequireModulePath) {
4472
+ const projectRequire = (0, import_module.createRequire)(asyncRequireModulePath);
4057
4473
  const metroRoot = import_path2.default.dirname(projectRequire.resolve("metro/package.json"));
4058
4474
  const baseJSBundle = readCallableMetroExport(
4059
4475
  projectRequire(import_path2.default.join(metroRoot, "src/DeltaBundler/Serializers/baseJSBundle.js")),
@@ -4112,7 +4528,7 @@ function appendRNXModulePaths(result, graph, options, projectRoot) {
4112
4528
  };
4113
4529
  return typeof result === "string" ? appendRNXMetroModuleIdentityFooter(result, identity) : { ...result, code: appendRNXMetroModuleIdentityFooter(result.code, identity) };
4114
4530
  }
4115
- function withRNX(config) {
4531
+ function withPeach(config, options = {}) {
4116
4532
  const cfgProjectRoot = config.projectRoot || process.cwd();
4117
4533
  const configuredBundleUrl = "/index.bundle?platform=ios&dev=true&hot=true&minify=false";
4118
4534
  const cfgServer = config.server;
@@ -4132,7 +4548,9 @@ function withRNX(config) {
4132
4548
  serializer: {
4133
4549
  ...cfgSerializer,
4134
4550
  customSerializer: async (entryPoint, preModules, graph, serializerOptions) => {
4135
- const serializer = existingSerializer || (defaultSerializer ||= createMetroDefaultSerializer(cfgProjectRoot));
4551
+ const serializer = existingSerializer || (defaultSerializer ||= createMetroDefaultSerializer(
4552
+ serializerOptions.asyncRequireModulePath
4553
+ ));
4136
4554
  const result = await serializer(entryPoint, preModules, graph, serializerOptions);
4137
4555
  let annotated = appendRNXModulePaths(
4138
4556
  result,
@@ -4143,21 +4561,36 @@ function withRNX(config) {
4143
4561
  const iosRoot = import_path2.default.join(cfgProjectRoot, "ios");
4144
4562
  const bundlePlatform = graph.transformOptions?.platform;
4145
4563
  if (canExtractNativeAppIdentity(bundlePlatform) && import_fs2.default.existsSync(iosRoot)) {
4146
- const files = {};
4147
- for (const entry of import_fs2.default.readdirSync(iosRoot, { withFileTypes: true })) {
4148
- if (!entry.isDirectory() || entry.name === "Pods") continue;
4149
- const names = entry.name.endsWith(".xcodeproj") ? ["project.pbxproj"] : ["Info.plist", "AppDelegate.swift", "AppDelegate.mm", "AppDelegate.m"];
4150
- for (const name2 of names) {
4151
- const relative2 = `ios/${entry.name}/${name2}`;
4152
- const file = import_path2.default.join(cfgProjectRoot, relative2);
4153
- if (import_fs2.default.existsSync(file)) files[relative2] = import_fs2.default.readFileSync(file, "utf8");
4154
- }
4155
- }
4156
- const identity = extractNativeAppIdentityFromFiles(
4157
- files,
4564
+ let identity = readNativeAppIdentityFromProject(
4565
+ cfgProjectRoot,
4158
4566
  bundlePlatform,
4159
- parsePlistSource
4567
+ parsePlistSource,
4568
+ options.iosTarget
4160
4569
  );
4570
+ if (!identity) {
4571
+ const files = {};
4572
+ for (const entry of import_fs2.default.readdirSync(iosRoot, { withFileTypes: true })) {
4573
+ if (entry.name === "Pods") continue;
4574
+ if (entry.isDirectory()) {
4575
+ const names = entry.name.endsWith(".xcodeproj") ? ["project.pbxproj"] : ["Info.plist", "AppDelegate.swift", "AppDelegate.mm", "AppDelegate.m"];
4576
+ for (const name2 of names) {
4577
+ const relative2 = `ios/${entry.name}/${name2}`;
4578
+ const file = import_path2.default.join(cfgProjectRoot, relative2);
4579
+ if (import_fs2.default.existsSync(file)) files[relative2] = import_fs2.default.readFileSync(file, "utf8");
4580
+ }
4581
+ } else if (/AppDelegate\.(?:swift|mm|m)$/.test(entry.name)) {
4582
+ const relative2 = `ios/${entry.name}`;
4583
+ const file = import_path2.default.join(cfgProjectRoot, relative2);
4584
+ if (import_fs2.default.existsSync(file)) files[relative2] = import_fs2.default.readFileSync(file, "utf8");
4585
+ }
4586
+ }
4587
+ identity = extractNativeAppIdentityFromFiles(
4588
+ files,
4589
+ bundlePlatform,
4590
+ parsePlistSource,
4591
+ options.iosTarget
4592
+ );
4593
+ }
4161
4594
  if (identity) {
4162
4595
  annotated = typeof annotated === "string" ? insertNativeAppIdentityFooter(annotated, identity) : {
4163
4596
  ...annotated,
@@ -4171,7 +4604,8 @@ function withRNX(config) {
4171
4604
  const firebase = readNativeFirebaseMetadata(
4172
4605
  readNativeFirebaseConfig(
4173
4606
  cfgProjectRoot,
4174
- typeof bundlePlatform === "string" ? [bundlePlatform] : void 0
4607
+ typeof bundlePlatform === "string" ? [bundlePlatform] : void 0,
4608
+ options.iosTarget
4175
4609
  )
4176
4610
  );
4177
4611
  if (firebase)
@@ -4236,7 +4670,11 @@ function withRNX(config) {
4236
4670
  res.setHeader("Content-Type", "application/json");
4237
4671
  res.setHeader("Cache-Control", "no-store");
4238
4672
  res.setHeader("Access-Control-Allow-Origin", "*");
4239
- res.end(JSON.stringify(readNativeFirebaseConfig(cfgProjectRoot)));
4673
+ res.end(
4674
+ JSON.stringify(
4675
+ readNativeFirebaseConfig(cfgProjectRoot, void 0, options.iosTarget)
4676
+ )
4677
+ );
4240
4678
  } catch (error) {
4241
4679
  res.statusCode = 400;
4242
4680
  res.end(
@@ -4312,10 +4750,10 @@ function resolveMetroPort(server) {
4312
4750
  }
4313
4751
  return port;
4314
4752
  }
4315
- var metro_plugin_default = withRNX;
4753
+ var metro_plugin_default = withPeach;
4316
4754
  // Annotate the CommonJS export names for ESM import in node:
4317
4755
  0 && (module.exports = {
4318
- toRNXDevelopmentBundleUrl,
4319
- toRNXProductionBundleUrl,
4320
- withRNX
4756
+ toPeachDevelopmentBundleUrl,
4757
+ toPeachProductionBundleUrl,
4758
+ withPeach
4321
4759
  });