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
@@ -0,0 +1,1257 @@
1
+ /*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
+
3
+ // src/native-app-identity-project.ts
4
+ import fs2 from "node:fs";
5
+ import path3 from "node:path";
6
+
7
+ // src/openstep-plist.ts
8
+ var isDict = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
9
+ var str = (value) => typeof value === "string" ? value : void 0;
10
+ var list = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
11
+ function parseOpenStepPlist(text2) {
12
+ let i = 0;
13
+ const fail = (message) => {
14
+ const line = text2.slice(0, i).split("\n").length;
15
+ throw new Error(`project.pbxproj line ${line}: ${message}`);
16
+ };
17
+ const skip = () => {
18
+ for (; ; ) {
19
+ const ch = text2[i];
20
+ if (ch === " " || ch === " " || ch === "\n" || ch === "\r") i++;
21
+ else if (ch === "/" && text2[i + 1] === "*") {
22
+ const end = text2.indexOf("*/", i + 2);
23
+ if (end < 0) fail("unterminated comment");
24
+ i = end + 2;
25
+ } else if (ch === "/" && text2[i + 1] === "/") {
26
+ const end = text2.indexOf("\n", i);
27
+ i = end < 0 ? text2.length : end + 1;
28
+ } else return;
29
+ }
30
+ };
31
+ const quoted = () => {
32
+ i++;
33
+ let out = "";
34
+ for (; ; ) {
35
+ const ch = text2[i++];
36
+ if (ch === void 0) fail("unterminated string");
37
+ if (ch === '"') return out;
38
+ if (ch !== "\\") {
39
+ out += ch;
40
+ continue;
41
+ }
42
+ const next = text2[i++];
43
+ if (next === "n") out += "\n";
44
+ else if (next === "t") out += " ";
45
+ else if (next === "r") out += "\r";
46
+ else if (next === "U") {
47
+ out += String.fromCharCode(parseInt(text2.slice(i, i + 4), 16));
48
+ i += 4;
49
+ } else out += next;
50
+ }
51
+ };
52
+ const value = () => {
53
+ skip();
54
+ const ch = text2[i];
55
+ if (ch === "{") {
56
+ i++;
57
+ const dict = {};
58
+ for (; ; ) {
59
+ skip();
60
+ if (text2[i] === "}") {
61
+ i++;
62
+ return dict;
63
+ }
64
+ const key = value();
65
+ if (typeof key !== "string") fail("dictionary key is not a string");
66
+ skip();
67
+ if (text2[i++] !== "=") fail("expected =");
68
+ if (Object.hasOwn(dict, key)) fail(`duplicate key ${key}`);
69
+ dict[key] = value();
70
+ skip();
71
+ if (text2[i++] !== ";") fail("expected ;");
72
+ }
73
+ }
74
+ if (ch === "(") {
75
+ i++;
76
+ const list2 = [];
77
+ for (; ; ) {
78
+ skip();
79
+ if (text2[i] === ")") {
80
+ i++;
81
+ return list2;
82
+ }
83
+ list2.push(value());
84
+ skip();
85
+ if (text2[i] === ",") i++;
86
+ else if (text2[i] !== ")") fail("expected , or )");
87
+ }
88
+ }
89
+ if (ch === '"') return quoted();
90
+ const start = i;
91
+ while (i < text2.length && /[A-Za-z0-9_$+/:.\-<>]/.test(text2[i])) i++;
92
+ if (i === start) fail(`unexpected ${JSON.stringify(ch ?? "end of file")}`);
93
+ return text2.slice(start, i);
94
+ };
95
+ if (text2.startsWith("// !$*UTF8*$!")) i = text2.indexOf("\n") + 1;
96
+ const root = value();
97
+ skip();
98
+ if (i !== text2.length) fail("trailing content");
99
+ return root;
100
+ }
101
+
102
+ // src/native-app-identity.ts
103
+ function canExtractNativeAppIdentity(platform) {
104
+ return platform === "ios";
105
+ }
106
+
107
+ // src/plist.ts
108
+ import plist from "plist";
109
+ function parsePlistSource(source) {
110
+ return plist.parse(source);
111
+ }
112
+
113
+ // src/xcode-project.ts
114
+ import fs from "node:fs";
115
+ import path2 from "node:path";
116
+ import plist2 from "plist";
117
+
118
+ // src/xcode-json-project.ts
119
+ import path from "node:path";
120
+ import JSON5 from "json5";
121
+ var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
122
+ var text = (value) => typeof value === "string" ? value : void 0;
123
+ var items = (value) => Array.isArray(value) ? value : [];
124
+ var PHASE_ISA = {
125
+ "compile-sources": "PBXSourcesBuildPhase",
126
+ resources: "PBXResourcesBuildPhase",
127
+ frameworks: "PBXFrameworksBuildPhase",
128
+ headers: "PBXHeadersBuildPhase",
129
+ copy: "PBXCopyFilesBuildPhase",
130
+ script: "PBXShellScriptBuildPhase"
131
+ };
132
+ function readXcodeJsonProject(xcodeproj, source) {
133
+ const json = JSON5.parse(source);
134
+ if (!isJsonObject(json)) throw new Error(`${xcodeproj}/project.xcproj is not an object`);
135
+ const projectDir = path.dirname(xcodeproj);
136
+ const objects = {};
137
+ let next = 0;
138
+ const add = (entry, id) => {
139
+ const key = id ?? `XCPROJ${(next++).toString(16).toUpperCase().padStart(18, "0")}`;
140
+ objects[key] = entry;
141
+ return key;
142
+ };
143
+ const locate = (raw, groupDir) => {
144
+ if (raw.startsWith("<USER:")) return null;
145
+ const base = /^<([A-Z]+)>\/(.*)$/.exec(raw);
146
+ if (base) {
147
+ if (base[1] === "PROJECT")
148
+ return { sourceTree: "<absolute>", path: path.join(projectDir, base[2]) };
149
+ if (base[1] === "PRODUCTS")
150
+ return { sourceTree: "BUILT_PRODUCTS_DIR", path: base[2] };
151
+ return null;
152
+ }
153
+ const unescaped = raw.replaceAll("\\<", "<");
154
+ if (unescaped.startsWith("/")) return { sourceTree: "<absolute>", path: unescaped };
155
+ if (unescaped.startsWith("~")) return null;
156
+ return groupDir === null ? null : { sourceTree: "<absolute>", path: path.join(groupDir, unescaped) };
157
+ };
158
+ const memberships = [];
159
+ const folders = [];
160
+ const projectFiles = [];
161
+ const root = { id: "", name: "", dir: projectDir, parent: null, children: [] };
162
+ const walk = (entries, parent) => entries.flatMap((entry) => {
163
+ if (!isObject(entry)) return [];
164
+ const kind = text(entry.kind) ?? "file-reference";
165
+ const raw = text(entry.path) ?? "";
166
+ const located = raw === "" ? null : locate(raw, parent.dir);
167
+ const name = text(entry.name) ?? path.basename(raw);
168
+ const node = { id: "", name, dir: null, parent, children: [] };
169
+ if (kind === "group" || kind === "variant-group" || kind === "version-group") {
170
+ node.dir = raw === "" ? parent.dir : located?.sourceTree === "<absolute>" ? located.path : null;
171
+ const childIds = walk(items(entry.children), node);
172
+ node.id = add(
173
+ kind === "version-group" && located ? {
174
+ isa: "PBXFileReference",
175
+ ...located,
176
+ lastKnownFileType: "wrapper.xcdatamodel"
177
+ } : {
178
+ isa: kind === "variant-group" ? "PBXVariantGroup" : "PBXGroup",
179
+ children: childIds,
180
+ ...kind === "variant-group" ? {} : { sourceTree: "<absolute>", path: node.dir ?? "" },
181
+ name
182
+ },
183
+ text(entry.id)
184
+ );
185
+ } else if (kind === "folder") {
186
+ node.id = add(
187
+ {
188
+ isa: "PBXFileSystemSynchronizedRootGroup",
189
+ ...located ?? { sourceTree: "SDKROOT", path: raw }
190
+ },
191
+ text(entry.id)
192
+ );
193
+ folders.push({ id: node.id, folder: entry });
194
+ } else {
195
+ node.id = add(
196
+ {
197
+ isa: "PBXFileReference",
198
+ ...located ?? { sourceTree: "SDKROOT", path: raw },
199
+ name
200
+ },
201
+ text(entry.id)
202
+ );
203
+ if (located?.sourceTree === "<absolute>" && located.path.endsWith(".xcodeproj"))
204
+ projectFiles.push(node.id);
205
+ }
206
+ parent.children.push(node);
207
+ for (const membership of items(entry["target-membership"])) {
208
+ if (kind !== "folder") memberships.push({ refId: node.id, entry: membership });
209
+ }
210
+ return [node.id];
211
+ });
212
+ const mainGroupChildren = walk(items(json.files), root);
213
+ const mainGroup = add({
214
+ isa: "PBXGroup",
215
+ children: mainGroupChildren,
216
+ sourceTree: "<absolute>",
217
+ path: projectDir
218
+ });
219
+ root.id = mainGroup;
220
+ const lookup = (reference, from = root) => {
221
+ if (isObject(reference)) {
222
+ const anchor = lookupNode(reference.anchor, root);
223
+ return anchor ? lookup(reference["relative-path"], anchor) : void 0;
224
+ }
225
+ if (Array.isArray(reference)) {
226
+ return lookupNode(
227
+ reference.map(
228
+ (component) => isObject(component) ? text(component.name) ?? "" : text(component) ?? ""
229
+ ).join("/"),
230
+ from
231
+ )?.id;
232
+ }
233
+ return lookupNode(reference, from)?.id;
234
+ };
235
+ const lookupNode = (reference, from) => {
236
+ const value = text(reference);
237
+ if (value === void 0) return void 0;
238
+ if (value.startsWith("id:")) {
239
+ const id = value.slice(3);
240
+ const find = (node2) => node2.id === id ? node2 : node2.children.map(find).find(Boolean);
241
+ return find(root);
242
+ }
243
+ let node = from;
244
+ for (const component of value.split("/")) {
245
+ if (!node) return void 0;
246
+ node = component === "." ? node : component === ".." ? node.parent ?? void 0 : node.children.find((child) => child.name === component);
247
+ }
248
+ return node;
249
+ };
250
+ const configurations = items(json.configurations).flatMap((entry) => {
251
+ const name = isObject(entry) ? text(entry.name) : text(entry);
252
+ return name ? [{ name, file: isObject(entry) ? entry.file : void 0 }] : [];
253
+ });
254
+ const settingsOf = (value) => Object.fromEntries(
255
+ Object.entries(isObject(value) ? value : {}).flatMap(
256
+ ([key, setting]) => typeof setting === "string" ? [[key, setting]] : Array.isArray(setting) ? [
257
+ [
258
+ key,
259
+ setting.filter((item) => typeof item === "string")
260
+ ]
261
+ ] : []
262
+ )
263
+ );
264
+ const configurationList = (settings, specialized) => add({
265
+ isa: "XCConfigurationList",
266
+ defaultConfigurationName: text(json["default-configuration"]) ?? "Debug",
267
+ buildConfigurations: configurations.map(({ name, file }) => {
268
+ const base = lookup(specialized.has(name) ? specialized.get(name) : file);
269
+ return add({
270
+ isa: "XCBuildConfiguration",
271
+ name,
272
+ buildSettings: settings,
273
+ ...base ? { baseConfigurationReference: base } : {}
274
+ });
275
+ })
276
+ });
277
+ const packageIds = /* @__PURE__ */ new Map();
278
+ for (const entry of items(json.packages)) {
279
+ if (!isObject(entry)) continue;
280
+ const repository = text(entry.repository);
281
+ const local = text(entry.path);
282
+ const name = local !== void 0 ? path.basename(path.resolve(path.dirname(xcodeproj), local)) : path.basename(repository ?? "").replace(/\.git$/, "");
283
+ const id = text(entry.kind) === "local" && local !== void 0 ? add({ isa: "XCLocalSwiftPackageReference", relativePath: local }) : add({ isa: "XCRemoteSwiftPackageReference", repositoryURL: repository ?? "" });
284
+ packageIds.set(name.toLowerCase(), id);
285
+ }
286
+ const productDependency = (entry) => add({
287
+ isa: "XCSwiftPackageProductDependency",
288
+ productName: text(entry["product-name"]) ?? "",
289
+ // xcode finds a product by name across packages when none is named
290
+ ...packageIds.has(text(entry.package)?.toLowerCase() ?? "") ? { package: packageIds.get(text(entry.package).toLowerCase()) } : {}
291
+ });
292
+ const proxy = (entry, remote, proxyType) => add({
293
+ isa: "PBXContainerItemProxy",
294
+ containerPortal: lookup(entry.project) ?? "",
295
+ proxyType,
296
+ remoteGlobalIDString: remote ?? "",
297
+ remoteInfo: text(entry.target) ?? ""
298
+ });
299
+ const phases = /* @__PURE__ */ new Map();
300
+ const targetIds = /* @__PURE__ */ new Map();
301
+ const targets = [];
302
+ for (const entry of items(json.targets)) {
303
+ if (!isObject(entry)) continue;
304
+ const name = text(entry.name) ?? "";
305
+ const productType = text(entry["product-type"]);
306
+ const target = {
307
+ isa: text(entry.kind) === "aggregate" ? "PBXAggregateTarget" : "PBXNativeTarget",
308
+ name,
309
+ productName: name,
310
+ productType: productType ? `com.apple.product-type.${productType}` : text(entry["full-product-type"]) ?? "",
311
+ buildPhases: [],
312
+ dependencies: [],
313
+ packageProductDependencies: [],
314
+ fileSystemSynchronizedGroups: []
315
+ };
316
+ const product = lookup(entry.product);
317
+ if (product) target.productReference = product;
318
+ const id = add(target, text(entry.id));
319
+ targetIds.set(name, id);
320
+ targets.push({ id, target, entry });
321
+ for (const phase of items(entry["build-phases"])) {
322
+ const kind = isObject(phase) ? text(phase.kind) : text(phase);
323
+ const isa = kind ? PHASE_ISA[kind] : void 0;
324
+ if (!kind || !isa) continue;
325
+ const phaseName = isObject(phase) ? text(phase.name) : void 0;
326
+ const phaseId = add(
327
+ { isa, files: [] },
328
+ isObject(phase) ? text(phase.id) : void 0
329
+ );
330
+ target.buildPhases.push(phaseId);
331
+ phases.set([name, kind, phaseName].filter(Boolean).join("/"), phaseId);
332
+ phases.set(`id:${phaseId}`, phaseId);
333
+ }
334
+ }
335
+ const phaseFiles = (reference, targetName) => {
336
+ const value = text(reference);
337
+ if (value === void 0) return null;
338
+ const key = value.startsWith("id:") || !targetName ? value : `${targetName}/${value}`;
339
+ const phase = objects[phases.get(key) ?? ""];
340
+ return phase && typeof phase === "object" && !Array.isArray(phase) && Array.isArray(phase.files) ? phase.files : null;
341
+ };
342
+ for (const { refId, entry } of memberships) {
343
+ const files = phaseFiles(isObject(entry) ? entry["build-phase"] : entry);
344
+ files?.push(add({ isa: "PBXBuildFile", fileRef: refId }));
345
+ }
346
+ for (const { target, entry } of targets) {
347
+ const name = text(entry.name) ?? "";
348
+ target.buildConfigurationList = configurationList(
349
+ settingsOf(entry["build-settings"]),
350
+ new Map(
351
+ items(entry["specialized-configurations"]).flatMap(
352
+ (configuration) => isObject(configuration) && text(configuration.name) ? [[text(configuration.name), configuration.file]] : []
353
+ )
354
+ )
355
+ );
356
+ for (const dependency of items(entry.dependencies)) {
357
+ const kind = isObject(dependency) ? text(dependency.kind) ?? "localTarget" : "localTarget";
358
+ if (kind === "package" && isObject(dependency)) {
359
+ ;
360
+ target.dependencies.push(
361
+ add({ isa: "PBXTargetDependency", productRef: productDependency(dependency) })
362
+ );
363
+ } else if (kind === "remoteTarget" && isObject(dependency)) {
364
+ ;
365
+ target.dependencies.push(
366
+ add({
367
+ isa: "PBXTargetDependency",
368
+ targetProxy: proxy(dependency, text(dependency["target-id"]), "1")
369
+ })
370
+ );
371
+ } else {
372
+ const local = isObject(dependency) ? text(dependency.target) : text(dependency);
373
+ const id = local ? targetIds.get(local) : void 0;
374
+ if (id)
375
+ target.dependencies.push(
376
+ add({ isa: "PBXTargetDependency", target: id })
377
+ );
378
+ }
379
+ }
380
+ for (const member of items(entry["package-product-members"])) {
381
+ if (!isObject(member)) continue;
382
+ const dependency = productDependency(member);
383
+ target.packageProductDependencies.push(dependency);
384
+ const buildFile = member["build-phase"];
385
+ phaseFiles(isObject(buildFile) ? buildFile["build-phase"] : buildFile, name)?.push(
386
+ add({ isa: "PBXBuildFile", productRef: dependency })
387
+ );
388
+ }
389
+ }
390
+ for (const imported of items(json["imported-products"])) {
391
+ if (!isObject(imported)) continue;
392
+ const reference = add({
393
+ isa: "PBXReferenceProxy",
394
+ path: text(imported.name) ?? text(imported.path) ?? "",
395
+ sourceTree: "BUILT_PRODUCTS_DIR",
396
+ remoteRef: proxy(imported, text(imported["product-id"]), "2")
397
+ });
398
+ for (const membership of items(imported["target-membership"])) {
399
+ phaseFiles(isObject(membership) ? membership["build-phase"] : membership)?.push(
400
+ add({ isa: "PBXBuildFile", fileRef: reference })
401
+ );
402
+ }
403
+ }
404
+ for (const { id, folder } of folders) {
405
+ const exceptions = [];
406
+ for (const exception of items(folder["membership-exceptions"])) {
407
+ if (!isObject(exception)) continue;
408
+ const target = targetIds.get(text(exception.target) ?? "");
409
+ if (!target) continue;
410
+ exceptions.push(
411
+ add({
412
+ isa: "PBXFileSystemSynchronizedBuildFileExceptionSet",
413
+ target,
414
+ membershipExceptions: [
415
+ ...items(exception.exclusions),
416
+ ...items(exception.inclusions)
417
+ ].flatMap((member) => typeof member === "string" ? [member] : [])
418
+ })
419
+ );
420
+ }
421
+ const group = objects[id];
422
+ if (group && typeof group === "object" && !Array.isArray(group))
423
+ group.exceptions = exceptions;
424
+ for (const owner of items(folder["target-membership"])) {
425
+ const target = targets.find(
426
+ (candidate) => candidate.id === targetIds.get(text(owner) ?? "")
427
+ );
428
+ target?.target.fileSystemSynchronizedGroups?.push(id);
429
+ }
430
+ }
431
+ const localizations = isObject(json.localizations) ? json.localizations : {};
432
+ const project = add({
433
+ isa: "PBXProject",
434
+ mainGroup,
435
+ projectDirPath: "",
436
+ developmentRegion: text(localizations.development) ?? "en",
437
+ buildConfigurationList: configurationList(
438
+ settingsOf(json["build-settings"]),
439
+ /* @__PURE__ */ new Map()
440
+ ),
441
+ targets: targets.map((entry) => entry.id),
442
+ packageReferences: [...packageIds.values()],
443
+ projectReferences: projectFiles.map((ProjectRef) => ({ ProjectRef }))
444
+ });
445
+ return { objects, rootObject: project };
446
+ }
447
+ function isJsonObject(value) {
448
+ return typeof value === "object" && value !== null && !Array.isArray(value);
449
+ }
450
+
451
+ // src/xcode-project.ts
452
+ var APPLICATION = "com.apple.product-type.application";
453
+ var MODULE_PRODUCTS = /* @__PURE__ */ new Set([
454
+ "com.apple.product-type.framework",
455
+ "com.apple.product-type.framework.static",
456
+ "com.apple.product-type.library.static",
457
+ "com.apple.product-type.library.dynamic"
458
+ ]);
459
+ var NEVER_MEMBER = /(?:^|\/)(?:Info\.plist|[^/]+\.entitlements|[^/]+\.xcconfig|\.DS_Store)$/;
460
+ var BUNDLE_DIR = /\.(xcassets|bundle|lproj|xcdatamodeld|scnassets|spriteatlas|rcproject|storyboardc|icon)$/;
461
+ var CONDITIONS = {
462
+ sdk: "iphonesimulator",
463
+ arch: "arm64",
464
+ variant: "normal"
465
+ };
466
+ function walkFiles(dir) {
467
+ if (!fs.existsSync(dir)) return [];
468
+ const out = [];
469
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name))) {
470
+ if (entry.name.startsWith(".")) continue;
471
+ const full = path2.join(dir, entry.name);
472
+ if (entry.isDirectory()) out.push(...walkFiles(full));
473
+ else if (entry.isFile()) out.push(full);
474
+ }
475
+ return out;
476
+ }
477
+ var isDirectory = (dir) => fs.existsSync(dir) && fs.statSync(dir).isDirectory();
478
+ function readXcconfig(file, read) {
479
+ if (read.includes(file) || !fs.existsSync(file)) return {};
480
+ read.push(file);
481
+ const settings = {};
482
+ for (const raw of fs.readFileSync(file, "utf8").split("\n")) {
483
+ const line = raw.replace(/\/\/.*$/, "").trim();
484
+ const include = /^#include\??\s+"([^"]+)"/.exec(line);
485
+ if (include) {
486
+ Object.assign(
487
+ settings,
488
+ readXcconfig(path2.resolve(path2.dirname(file), include[1]), read)
489
+ );
490
+ continue;
491
+ }
492
+ const setting = /^([A-Za-z_][A-Za-z0-9_]*(?:\[[^\]]*\])*)\s*=\s*(.*)$/.exec(line);
493
+ if (setting)
494
+ settings[setting[1].replace(/\s+/g, "")] = setting[2].replace(/;$/, "").trim();
495
+ }
496
+ return settings;
497
+ }
498
+ function applyConditions(raw, configuration) {
499
+ const plain = {};
500
+ const conditional = {};
501
+ for (const [key, value] of Object.entries(raw)) {
502
+ const bracket = key.indexOf("[");
503
+ if (bracket === -1) {
504
+ plain[key] = value;
505
+ continue;
506
+ }
507
+ const matches = [...key.slice(bracket).matchAll(/\[([^=\]]+)=([^\]]*)\]/g)].every(
508
+ ([, name, pattern]) => {
509
+ const actual = name === "config" ? configuration : CONDITIONS[name];
510
+ return actual !== void 0 && new RegExp(
511
+ `^${pattern.replace(/[.+^${}()|\\]/g, "\\$&").replaceAll("*", ".*").replaceAll("?", ".")}$`
512
+ ).test(actual);
513
+ }
514
+ );
515
+ if (matches) conditional[key.slice(0, bracket)] = value;
516
+ }
517
+ return { ...plain, ...conditional };
518
+ }
519
+ function applyOperator(value, operator) {
520
+ if (operator.startsWith("default=")) return value === "" ? operator.slice(8) : value;
521
+ switch (operator) {
522
+ case "lower":
523
+ return value.toLowerCase();
524
+ case "upper":
525
+ return value.toUpperCase();
526
+ case "rfc1034identifier":
527
+ return value.replace(/[^A-Za-z0-9-]/g, "-").replace(/^[0-9]/, "-");
528
+ case "identifier":
529
+ case "c99extidentifier":
530
+ return value.replace(/[^A-Za-z0-9_]/g, "_").replace(/^[0-9]/, "_");
531
+ }
532
+ throw new Error(`unsupported build setting operator :${operator}`);
533
+ }
534
+ function decodeXml(text2) {
535
+ return text2.replaceAll("&quot;", '"').replaceAll("&apos;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
536
+ }
537
+ function workspaceReferences(workspace) {
538
+ const data = path2.join(workspace, "contents.xcworkspacedata");
539
+ if (!fs.existsSync(data))
540
+ throw new Error(`${workspace} has no contents.xcworkspacedata`);
541
+ const container = path2.dirname(workspace);
542
+ const locate = (location, base) => {
543
+ const colon = location.indexOf(":");
544
+ const kind = location.slice(0, colon);
545
+ const rest = location.slice(colon + 1);
546
+ if (kind === "group") return path2.resolve(base, rest);
547
+ if (kind === "container" || kind === "self") return path2.resolve(container, rest);
548
+ if (kind === "absolute") return path2.resolve(rest);
549
+ throw new Error(`${path2.basename(workspace)} has an unsupported location ${location}`);
550
+ };
551
+ const groups = [container];
552
+ const references = [];
553
+ for (const [, closing, tag, attributes, selfClosing] of fs.readFileSync(data, "utf8").matchAll(/<(\/?)(Group|FileRef)\b([^>]*?)(\/?)>/g)) {
554
+ if (closing) {
555
+ if (tag === "Group") groups.pop();
556
+ continue;
557
+ }
558
+ const base = groups.at(-1);
559
+ const location = /\blocation\s*=\s*"([^"]*)"/.exec(attributes)?.[1];
560
+ const resolved = location ? locate(decodeXml(location), base) : base;
561
+ if (tag === "FileRef") references.push(resolved);
562
+ else if (!selfClosing) groups.push(resolved);
563
+ }
564
+ return references;
565
+ }
566
+ var loaded = /* @__PURE__ */ new Map();
567
+ function xcodeProjectFile(xcodeproj) {
568
+ for (const name of ["project.pbxproj", "project.xcproj"]) {
569
+ const file = path2.join(xcodeproj, name);
570
+ if (fs.existsSync(file)) return file;
571
+ }
572
+ return null;
573
+ }
574
+ function loadProject(xcodeproj) {
575
+ const projectFile = xcodeProjectFile(xcodeproj);
576
+ if (!projectFile)
577
+ throw new Error(`${xcodeproj} has no project.pbxproj or project.xcproj`);
578
+ const mtimeMs = fs.statSync(projectFile).mtimeMs;
579
+ const cached = loaded.get(projectFile);
580
+ if (cached?.mtimeMs === mtimeMs) return cached.project;
581
+ const source = fs.readFileSync(projectFile, "utf8");
582
+ const root = projectFile.endsWith(".xcproj") ? readXcodeJsonProject(xcodeproj, source) : parseOpenStepPlist(source);
583
+ if (!isDict(root) || !isDict(root.objects)) {
584
+ throw new Error(`${projectFile} has no objects table`);
585
+ }
586
+ const objects = root.objects;
587
+ const object = (id) => {
588
+ const found = id === void 0 ? void 0 : objects[id];
589
+ return isDict(found) ? found : void 0;
590
+ };
591
+ const project = object(str(root.rootObject));
592
+ if (!project || project.isa !== "PBXProject") {
593
+ throw new Error(`${projectFile} has no PBXProject root`);
594
+ }
595
+ const projectDir = fs.realpathSync(
596
+ path2.resolve(path2.dirname(xcodeproj), str(project.projectDirPath) ?? "")
597
+ );
598
+ const parent = /* @__PURE__ */ new Map();
599
+ for (const [id, entry] of Object.entries(objects)) {
600
+ if (!isDict(entry)) continue;
601
+ if (entry.isa === "PBXGroup" || entry.isa === "PBXVariantGroup") {
602
+ for (const child of list(entry.children)) parent.set(child, id);
603
+ }
604
+ }
605
+ const resolvedPaths = /* @__PURE__ */ new Map();
606
+ const resolvePath = (id) => {
607
+ if (resolvedPaths.has(id)) return resolvedPaths.get(id);
608
+ const entry = object(id);
609
+ let result2 = null;
610
+ if (entry) {
611
+ const own = str(entry.path) ?? "";
612
+ const tree = str(entry.sourceTree) ?? "<group>";
613
+ if (tree === "<absolute>") result2 = own;
614
+ else if (tree === "SOURCE_ROOT") result2 = path2.join(projectDir, own);
615
+ else if (tree === "<group>") {
616
+ const up = parent.get(id);
617
+ const base = up ? resolvePath(up) : projectDir;
618
+ result2 = base === null ? null : path2.join(base, own);
619
+ }
620
+ }
621
+ resolvedPaths.set(id, result2);
622
+ return result2;
623
+ };
624
+ const result = {
625
+ xcodeproj,
626
+ projectFile,
627
+ objects,
628
+ project,
629
+ projectDir,
630
+ object,
631
+ resolvePath
632
+ };
633
+ loaded.set(projectFile, { mtimeMs, project: result });
634
+ return result;
635
+ }
636
+ function defaultConfiguration(project) {
637
+ const configList = project.object(str(project.project.buildConfigurationList));
638
+ const names = list(configList?.buildConfigurations).flatMap(
639
+ (id) => str(project.object(id)?.name) ?? []
640
+ );
641
+ return names.includes("Debug") ? "Debug" : str(configList?.defaultConfigurationName) ?? names[0] ?? "Debug";
642
+ }
643
+ function targetSettings(ref, configuration, builtins) {
644
+ const { project, target } = ref;
645
+ const xcconfigs = [];
646
+ const level = (listId) => {
647
+ const configList = project.object(listId);
648
+ const configs = list(configList?.buildConfigurations).map(project.object);
649
+ const config = configs.find((entry) => entry?.name === configuration) ?? configs.find((entry) => entry?.name === str(configList?.defaultConfigurationName));
650
+ if (!config) return [];
651
+ const name = str(config.name) ?? configuration;
652
+ const base = str(config.baseConfigurationReference);
653
+ const own = isDict(config.buildSettings) ? config.buildSettings : {};
654
+ const baseFile = base ? project.resolvePath(base) : null;
655
+ const read = [];
656
+ const fromFile = baseFile ? readXcconfig(baseFile, read) : {};
657
+ xcconfigs.push(...read);
658
+ return [
659
+ applyConditions(fromFile, name),
660
+ applyConditions(
661
+ Object.fromEntries(
662
+ Object.entries(own).flatMap(
663
+ ([key, value]) => typeof value === "string" ? [[key, value]] : Array.isArray(value) ? [[key, list(value).join(" ")]] : []
664
+ )
665
+ ),
666
+ name
667
+ )
668
+ ];
669
+ };
670
+ const levels = [
671
+ { ...builtins, CONFIGURATION: configuration },
672
+ ...level(str(project.project.buildConfigurationList)),
673
+ ...level(str(target.buildConfigurationList))
674
+ ];
675
+ const resolving = /* @__PURE__ */ new Set();
676
+ const valueAt = (key, top) => {
677
+ let at = top;
678
+ while (at >= 0 && levels[at][key] === void 0) at--;
679
+ if (at < 0) return derived(key);
680
+ const marker = `${key}@${at}`;
681
+ if (resolving.has(marker))
682
+ throw new Error(`${str(target.name)} has a cyclic build setting ${key}`);
683
+ resolving.add(marker);
684
+ const value = expand(
685
+ levels[at][key],
686
+ (name) => name === "inherited" ? valueAt(key, at - 1) : valueAt(name, levels.length - 1)
687
+ );
688
+ resolving.delete(marker);
689
+ return value;
690
+ };
691
+ const derived = (key) => {
692
+ const get = (name) => valueAt(name, levels.length - 1);
693
+ switch (key) {
694
+ case "PRODUCT_NAME":
695
+ return get("TARGET_NAME");
696
+ case "PRODUCT_MODULE_NAME":
697
+ return applyOperator(get("PRODUCT_NAME"), "c99extidentifier");
698
+ case "EXECUTABLE_NAME":
699
+ return get("PRODUCT_NAME");
700
+ case "AppIdentifierPrefix":
701
+ case "TeamIdentifierPrefix": {
702
+ const team = get("DEVELOPMENT_TEAM");
703
+ return get("CODE_SIGNING_ALLOWED") !== "NO" && team ? `${team}.` : "";
704
+ }
705
+ }
706
+ return "";
707
+ };
708
+ return {
709
+ get: (key) => valueAt(key, levels.length - 1),
710
+ keys: new Set(levels.flatMap((values) => Object.keys(values))),
711
+ xcconfigs
712
+ };
713
+ }
714
+ function settingList(value) {
715
+ const items2 = [];
716
+ for (const [, quoted, plain] of value.matchAll(
717
+ /"((?:\\.|[^"\\])*)"|((?:\\.|[^\s"])+)/g
718
+ ))
719
+ items2.push((quoted ?? plain).replace(/\\(.)/g, "$1"));
720
+ return items2;
721
+ }
722
+ function compilationConditions(settings) {
723
+ const flags = settingList(settings("OTHER_SWIFT_FLAGS"));
724
+ const defined = flags.flatMap(
725
+ (flag, index) => flag === "-D" ? flags[index + 1] ?? [] : flag.startsWith("-D") ? flag.slice(2) : []
726
+ );
727
+ return [
728
+ .../* @__PURE__ */ new Set([
729
+ ...settingList(settings("SWIFT_ACTIVE_COMPILATION_CONDITIONS")),
730
+ ...defined
731
+ ])
732
+ ];
733
+ }
734
+ function expand(value, lookup) {
735
+ return value.replace(
736
+ /\$(?:\(([A-Za-z_][A-Za-z0-9_]*)((?::[^)]*)?)\)|\{([A-Za-z_][A-Za-z0-9_]*)((?::[^}]*)?)\}|([A-Za-z_][A-Za-z0-9_]*))/g,
737
+ (_match, paren, parenOps, brace, braceOps, bare) => {
738
+ const name = paren ?? brace ?? bare;
739
+ const operators = parenOps ?? braceOps ?? "";
740
+ return operators.split(":").slice(1).reduce((current, operator) => applyOperator(current, operator), lookup(name));
741
+ }
742
+ );
743
+ }
744
+ function targetMembers(ref, settings, options = {}) {
745
+ const { project, target, id: targetId } = ref;
746
+ const targetName = str(target.name) ?? targetId;
747
+ const sources = /* @__PURE__ */ new Set();
748
+ const allSources = /* @__PURE__ */ new Set();
749
+ const resources = /* @__PURE__ */ new Set();
750
+ const addResource = (file) => {
751
+ if (isDirectory(file)) {
752
+ for (const inner of walkFiles(file)) resources.add(inner);
753
+ } else if (fs.existsSync(file)) resources.add(file);
754
+ };
755
+ const fileRefPaths = (refId) => {
756
+ const entry = project.object(refId);
757
+ if (!entry) return [];
758
+ if (entry.isa === "PBXVariantGroup") {
759
+ return list(entry.children).flatMap((child) => {
760
+ const resolved2 = project.resolvePath(child);
761
+ return resolved2 ? [resolved2] : [];
762
+ });
763
+ }
764
+ const resolved = project.resolvePath(refId);
765
+ return resolved ? [resolved] : [];
766
+ };
767
+ const scriptForOutput = /* @__PURE__ */ new Map();
768
+ const noteScriptOutput = (raw, script) => {
769
+ const expanded = expand(raw, settings);
770
+ if (!expanded.endsWith(".swift")) return;
771
+ const absolute = path2.isAbsolute(expanded) ? path2.normalize(expanded) : path2.resolve(project.projectDir, expanded);
772
+ if (!scriptForOutput.has(absolute)) scriptForOutput.set(absolute, script);
773
+ };
774
+ for (const phaseId of list(target.buildPhases)) {
775
+ const phase = project.object(phaseId);
776
+ if (phase?.isa !== "PBXShellScriptBuildPhase") continue;
777
+ const script = str(phase.name) ?? phaseId;
778
+ for (const raw of list(phase.outputPaths)) noteScriptOutput(raw, script);
779
+ for (const listPath of list(phase.outputFileListPaths)) {
780
+ const expandedList = expand(listPath, settings);
781
+ const absoluteList = path2.isAbsolute(expandedList) ? expandedList : path2.resolve(project.projectDir, expandedList);
782
+ if (!fs.existsSync(absoluteList)) continue;
783
+ for (const line of fs.readFileSync(absoluteList, "utf8").split("\n")) {
784
+ const trimmed = line.trim();
785
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
786
+ noteScriptOutput(trimmed, script);
787
+ }
788
+ }
789
+ }
790
+ for (const phaseId of list(target.buildPhases)) {
791
+ const phase = project.object(phaseId);
792
+ if (phase?.isa !== "PBXSourcesBuildPhase" && phase?.isa !== "PBXResourcesBuildPhase")
793
+ continue;
794
+ for (const buildFileId of list(phase.files)) {
795
+ for (const file of fileRefPaths(str(project.object(buildFileId)?.fileRef) ?? "")) {
796
+ if (phase.isa === "PBXSourcesBuildPhase") {
797
+ if (!fs.existsSync(file)) {
798
+ if (options.requireSources === false) continue;
799
+ const script = scriptForOutput.get(path2.normalize(file));
800
+ throw new Error(
801
+ 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}`
802
+ );
803
+ }
804
+ allSources.add(file);
805
+ if (file.endsWith(".swift")) sources.add(file);
806
+ } else if (phase.isa === "PBXResourcesBuildPhase") addResource(file);
807
+ }
808
+ }
809
+ }
810
+ for (const [file, script] of scriptForOutput) {
811
+ if (sources.has(file) || allSources.has(file)) continue;
812
+ if (!fs.existsSync(file)) {
813
+ if (options.requireSources === false) continue;
814
+ throw new Error(
815
+ `${targetName}: missing generated source ${file} (Run Script "${script}" declares it in outputPaths; run the script or check in its output)`
816
+ );
817
+ }
818
+ allSources.add(file);
819
+ sources.add(file);
820
+ }
821
+ const addSynchronized = (folder, relative) => {
822
+ const file = path2.join(folder, relative);
823
+ if (NEVER_MEMBER.test(relative)) return;
824
+ if (file.endsWith(".swift")) {
825
+ if (!relative.split("/").some((segment) => BUNDLE_DIR.test(segment))) {
826
+ sources.add(file);
827
+ allSources.add(file);
828
+ }
829
+ } else if (/\.(h|m|mm|c|cpp|metal)$/.test(file)) {
830
+ if (!file.endsWith(".h")) allSources.add(file);
831
+ } else resources.add(file);
832
+ };
833
+ const owned = new Set(list(target.fileSystemSynchronizedGroups));
834
+ for (const [groupId, group] of Object.entries(project.objects)) {
835
+ if (!isDict(group) || group.isa !== "PBXFileSystemSynchronizedRootGroup") continue;
836
+ const folder = project.resolvePath(groupId);
837
+ if (!folder) continue;
838
+ const exceptions = /* @__PURE__ */ new Set();
839
+ for (const exceptionId of list(group.exceptions)) {
840
+ const exception = project.object(exceptionId);
841
+ if (exception?.target !== targetId) continue;
842
+ for (const relative of list(exception.membershipExceptions))
843
+ exceptions.add(relative);
844
+ }
845
+ if (owned.has(groupId)) {
846
+ for (const file of walkFiles(folder)) {
847
+ const relative = path2.relative(folder, file).split(path2.sep).join("/");
848
+ if ([...exceptions].some(
849
+ (exception) => relative === exception || relative.startsWith(`${exception}/`)
850
+ ))
851
+ continue;
852
+ addSynchronized(folder, relative);
853
+ }
854
+ } else {
855
+ for (const relative of exceptions) {
856
+ const file = path2.join(folder, relative);
857
+ if (isDirectory(file)) {
858
+ for (const inner of walkFiles(file))
859
+ addSynchronized(
860
+ folder,
861
+ path2.relative(folder, inner).split(path2.sep).join("/")
862
+ );
863
+ } else if (fs.existsSync(file)) addSynchronized(folder, relative);
864
+ }
865
+ }
866
+ }
867
+ return {
868
+ sources: [...sources].sort(),
869
+ resources: [...resources].sort(),
870
+ allSources: [...allSources].sort()
871
+ };
872
+ }
873
+ function commonAncestor(dirs) {
874
+ let common = dirs[0];
875
+ for (const dir of dirs) {
876
+ while (common !== path2.dirname(common) && path2.relative(common, dir).startsWith(".."))
877
+ common = path2.dirname(common);
878
+ }
879
+ return common;
880
+ }
881
+ function workspaceProjects(xcodeprojOrWorkspace) {
882
+ const listed = xcodeprojOrWorkspace.endsWith(".xcworkspace") ? workspaceReferences(xcodeprojOrWorkspace) : [xcodeprojOrWorkspace];
883
+ const projects = [];
884
+ const projectAt = /* @__PURE__ */ new Map();
885
+ const addProject = (xcodeproj) => {
886
+ if (!xcodeProjectFile(xcodeproj)) return;
887
+ const key = fs.realpathSync(xcodeproj);
888
+ if (projectAt.has(key) || key.split(path2.sep).includes("Pods")) return;
889
+ const project = loadProject(key);
890
+ projectAt.set(key, project);
891
+ projects.push(project);
892
+ const nested = project.project.projectReferences;
893
+ if (Array.isArray(nested)) {
894
+ for (const entry of nested) {
895
+ const ref = isDict(entry) ? str(entry.ProjectRef) : void 0;
896
+ const resolved = ref ? project.resolvePath(ref) : null;
897
+ if (resolved) addProject(resolved);
898
+ }
899
+ }
900
+ };
901
+ for (const reference of listed)
902
+ if (reference.endsWith(".xcodeproj")) addProject(reference);
903
+ if (projects.length === 0) {
904
+ throw new Error(`${path2.basename(xcodeprojOrWorkspace)} lists no Xcode project`);
905
+ }
906
+ return { listed, projects, projectAt };
907
+ }
908
+ var targetRefs = /* @__PURE__ */ new WeakMap();
909
+ function nativeTargets(project) {
910
+ let refs = targetRefs.get(project);
911
+ if (!refs) {
912
+ refs = list(project.project.targets).flatMap((id) => {
913
+ const target = project.object(id);
914
+ return target?.isa === "PBXNativeTarget" ? [{ project, id, target }] : [];
915
+ });
916
+ targetRefs.set(project, refs);
917
+ }
918
+ return refs;
919
+ }
920
+ function listXcodeAppTargets(xcodeprojOrWorkspace) {
921
+ return workspaceProjects(xcodeprojOrWorkspace).projects.flatMap(nativeTargets).filter((ref) => ref.target.productType === APPLICATION).map((ref) => str(ref.target.name) ?? ref.id);
922
+ }
923
+ function readXcodeAppTarget(input, targetName, configurationName, options = {}) {
924
+ const xcodeprojOrWorkspace = fs.realpathSync(input);
925
+ const workspace = xcodeprojOrWorkspace.endsWith(".xcworkspace") ? xcodeprojOrWorkspace : null;
926
+ const { listed, projects, projectAt } = workspaceProjects(xcodeprojOrWorkspace);
927
+ const allTargets = projects.flatMap(nativeTargets);
928
+ const appTargets = allTargets.filter((ref) => ref.target.productType === APPLICATION);
929
+ const appTargetNames = appTargets.map((ref) => str(ref.target.name) ?? ref.id);
930
+ const container = path2.basename(xcodeprojOrWorkspace);
931
+ const named = targetName ? appTargets.filter((ref) => ref.target.name === targetName) : appTargets;
932
+ if (named.length !== 1) {
933
+ throw new Error(
934
+ targetName && named.length === 0 ? `${container} has no application target ${targetName}; it has ${appTargetNames.join(", ") || "none"}` : targetName ? `${container} has ${named.length} application targets named ${targetName}; open its .xcodeproj` : `${container} has ${appTargetNames.length} application targets (${appTargetNames.join(", ") || "none"}); pass --target`
935
+ );
936
+ }
937
+ const app = named[0];
938
+ const configuration = configurationName ?? defaultConfiguration(app.project);
939
+ const byProduct = /* @__PURE__ */ new Map();
940
+ for (const ref of allTargets) {
941
+ const product = ref.project.object(str(ref.target.productReference));
942
+ const file = str(product?.path);
943
+ if (file && !byProduct.has(path2.basename(file)))
944
+ byProduct.set(path2.basename(file), ref);
945
+ }
946
+ const proxied = (project, proxyId) => {
947
+ const proxy = project.object(proxyId);
948
+ if (proxy?.isa !== "PBXContainerItemProxy") return void 0;
949
+ const portal = str(proxy.containerPortal);
950
+ const portalPath = project.resolvePath(portal ?? "");
951
+ const owner = project.object(portal)?.isa === "PBXProject" ? project : portalPath && fs.existsSync(portalPath) ? projectAt.get(fs.realpathSync(portalPath)) : void 0;
952
+ const remote = str(proxy.remoteGlobalIDString);
953
+ if (!owner || !remote) return void 0;
954
+ return nativeTargets(owner).find(
955
+ (ref) => ref.id === remote || str(ref.target.productReference) === remote
956
+ );
957
+ };
958
+ const dependenciesOf = (ref) => {
959
+ const { project, target } = ref;
960
+ const found = [];
961
+ for (const dependencyId of list(target.dependencies)) {
962
+ const dependency = project.object(dependencyId);
963
+ const direct = str(dependency?.target);
964
+ const resolved = direct ? nativeTargets(project).find((candidate) => candidate.id === direct) : proxied(project, str(dependency?.targetProxy));
965
+ if (resolved) found.push(resolved);
966
+ }
967
+ for (const phaseId of list(target.buildPhases)) {
968
+ const phase = project.object(phaseId);
969
+ if (phase?.isa !== "PBXFrameworksBuildPhase") continue;
970
+ for (const buildFileId of list(phase.files)) {
971
+ const file = project.object(str(project.object(buildFileId)?.fileRef));
972
+ const resolved = file?.isa === "PBXReferenceProxy" ? proxied(project, str(file.remoteRef)) : file && str(file.sourceTree) === "BUILT_PRODUCTS_DIR" ? byProduct.get(path2.basename(str(file.path) ?? "")) : void 0;
973
+ if (resolved) found.push(resolved);
974
+ }
975
+ }
976
+ return found.filter(
977
+ (candidate) => MODULE_PRODUCTS.has(str(candidate.target.productType) ?? "")
978
+ );
979
+ };
980
+ const order = [];
981
+ const visited = /* @__PURE__ */ new Set();
982
+ const visit = (ref) => {
983
+ if (visited.has(ref)) return;
984
+ visited.add(ref);
985
+ for (const dependency of dependenciesOf(ref)) visit(dependency);
986
+ order.push(ref);
987
+ };
988
+ visit(app);
989
+ const xcconfigs = /* @__PURE__ */ new Set();
990
+ const moduleTarget = (ref) => {
991
+ const name = str(ref.target.name) ?? ref.id;
992
+ const {
993
+ get: settings2,
994
+ keys,
995
+ xcconfigs: read
996
+ } = targetSettings(ref, configuration, {
997
+ TARGET_NAME: name,
998
+ PROJECT_NAME: path2.basename(ref.project.xcodeproj, ".xcodeproj"),
999
+ SRCROOT: ref.project.projectDir,
1000
+ SOURCE_ROOT: ref.project.projectDir,
1001
+ PROJECT_DIR: ref.project.projectDir,
1002
+ DEVELOPMENT_LANGUAGE: str(ref.project.project.developmentRegion) ?? "en"
1003
+ });
1004
+ for (const file of read) xcconfigs.add(file);
1005
+ const swiftVersion = Number.parseFloat(settings2("SWIFT_VERSION") || "5");
1006
+ return {
1007
+ settings: settings2,
1008
+ keys,
1009
+ module: {
1010
+ name,
1011
+ moduleName: applyOperator(settings2("PRODUCT_MODULE_NAME"), "c99extidentifier"),
1012
+ ...targetMembers(ref, settings2, options),
1013
+ languageMode: swiftVersion >= 6 ? 6 : 5,
1014
+ mainActorIsolation: settings2("SWIFT_DEFAULT_ACTOR_ISOLATION") === "MainActor",
1015
+ defines: compilationConditions(settings2)
1016
+ }
1017
+ };
1018
+ };
1019
+ const { settings, keys: settingKeys, module } = moduleTarget(app);
1020
+ const frameworks = order.slice(0, -1).map((ref) => moduleTarget(ref).module);
1021
+ const expandValue = (value) => {
1022
+ if (typeof value === "string") return expand(value, settings);
1023
+ if (Array.isArray(value)) return value.map(expandValue);
1024
+ if (typeof value === "object" && !(value instanceof Date) && !Buffer.isBuffer(value)) {
1025
+ return Object.fromEntries(
1026
+ Object.entries(value).map(([key, value2]) => [key, expandValue(value2)])
1027
+ );
1028
+ }
1029
+ return value;
1030
+ };
1031
+ const infoPlistFile = settings("INFOPLIST_FILE") ? path2.resolve(app.project.projectDir, settings("INFOPLIST_FILE")) : null;
1032
+ const sourceInfo = infoPlistFile ? plist2.parse(fs.readFileSync(infoPlistFile, "utf8")) : {};
1033
+ if (!sourceInfo || typeof sourceInfo !== "object" || Array.isArray(sourceInfo) || sourceInfo instanceof Date || Buffer.isBuffer(sourceInfo)) {
1034
+ throw new Error(`${module.name} Info.plist must contain a dictionary`);
1035
+ }
1036
+ const info = {};
1037
+ for (const [key, value] of Object.entries(sourceInfo)) info[key] = expandValue(value);
1038
+ for (const key of settingKeys) {
1039
+ if (!key.startsWith("INFOPLIST_KEY_") || key.endsWith("_Generation")) continue;
1040
+ const value = settings(key);
1041
+ info[key.slice("INFOPLIST_KEY_".length)] = value === "YES" ? true : value === "NO" ? false : value;
1042
+ }
1043
+ if (settings("INFOPLIST_KEY_UIApplicationSceneManifest_Generation") === "YES" && info.UIApplicationSceneManifest === void 0) {
1044
+ info.UIApplicationSceneManifest = {
1045
+ UIApplicationSupportsMultipleScenes: true,
1046
+ UISceneConfigurations: {}
1047
+ };
1048
+ }
1049
+ const localPackageDirs = [
1050
+ ...listed.filter((reference) => fs.existsSync(path2.join(reference, "Package.swift"))),
1051
+ ...projects.flatMap(
1052
+ (project) => Object.entries(project.objects).flatMap(([id, entry]) => {
1053
+ if (!isDict(entry)) return [];
1054
+ const candidate = entry.isa === "XCLocalSwiftPackageReference" ? path2.resolve(project.projectDir, str(entry.relativePath) ?? "") : entry.isa === "PBXFileReference" ? project.resolvePath(id) : null;
1055
+ return candidate && fs.existsSync(path2.join(candidate, "Package.swift")) ? [candidate] : [];
1056
+ })
1057
+ )
1058
+ ];
1059
+ const linkedProducts = [];
1060
+ const binaryFrameworks = /* @__PURE__ */ new Map();
1061
+ for (const { project, target } of order) {
1062
+ const productDependencies = [
1063
+ ...list(target.packageProductDependencies),
1064
+ ...list(target.dependencies).flatMap((id) => {
1065
+ const productRef = str(project.object(id)?.productRef);
1066
+ return productRef ? [productRef] : [];
1067
+ })
1068
+ ];
1069
+ for (const dependencyId of productDependencies) {
1070
+ const dependency = project.object(dependencyId);
1071
+ const product = str(dependency?.productName)?.replace(/^plugin:/, "");
1072
+ if (!dependency || !product || linkedProducts.some((entry) => entry.product === product))
1073
+ continue;
1074
+ const reference = project.object(str(dependency.package));
1075
+ linkedProducts.push({
1076
+ product,
1077
+ source: reference?.isa === "XCRemoteSwiftPackageReference" ? { kind: "remote", url: str(reference.repositoryURL) ?? "" } : reference?.isa === "XCLocalSwiftPackageReference" ? {
1078
+ kind: "local",
1079
+ dir: path2.resolve(
1080
+ project.projectDir,
1081
+ str(reference.relativePath) ?? ""
1082
+ )
1083
+ } : { kind: "unnamed" }
1084
+ });
1085
+ }
1086
+ for (const phaseId of list(target.buildPhases)) {
1087
+ const phase = project.object(phaseId);
1088
+ if (phase?.isa !== "PBXFrameworksBuildPhase") continue;
1089
+ for (const buildFileId of list(phase.files)) {
1090
+ const fileId = str(project.object(buildFileId)?.fileRef);
1091
+ const file = project.object(fileId);
1092
+ const tree = str(file?.sourceTree);
1093
+ const name = /([^/]+)\.(xc)?framework$/.exec(str(file?.path) ?? "")?.[1];
1094
+ if (file?.isa !== "PBXFileReference" || !name) continue;
1095
+ if (tree === "BUILT_PRODUCTS_DIR" || tree === "SDKROOT" || tree === "DEVELOPER_DIR")
1096
+ continue;
1097
+ const resolved = fileId ? project.resolvePath(fileId) : null;
1098
+ if (!binaryFrameworks.get(name)) binaryFrameworks.set(name, resolved);
1099
+ }
1100
+ }
1101
+ }
1102
+ const resolvedFile = path2.join(
1103
+ workspace ?? path2.join(xcodeprojOrWorkspace, "project.xcworkspace"),
1104
+ "xcshareddata",
1105
+ "swiftpm",
1106
+ "Package.resolved"
1107
+ );
1108
+ const used = order.map((ref) => ref.project);
1109
+ return {
1110
+ ...module,
1111
+ rootDir: commonAncestor(
1112
+ [
1113
+ workspace ? path2.dirname(workspace) : app.project.projectDir,
1114
+ ...used.map((project) => project.projectDir),
1115
+ ...localPackageDirs,
1116
+ ...linkedProducts.flatMap(
1117
+ ({ source }) => source.kind === "local" && fs.existsSync(source.dir) ? [source.dir] : []
1118
+ )
1119
+ ].map((dir) => fs.realpathSync(dir))
1120
+ ),
1121
+ projectFiles: [
1122
+ .../* @__PURE__ */ new Set([...used.map((project) => project.projectFile), ...xcconfigs])
1123
+ ].sort(),
1124
+ appIconName: settings("ASSETCATALOG_COMPILER_APPICON_NAME"),
1125
+ infoPlist: plist2.build(info),
1126
+ infoPlistFile,
1127
+ frameworks,
1128
+ linkedProducts,
1129
+ localPackageDirs: [
1130
+ ...new Set(localPackageDirs.map((dir) => fs.realpathSync(dir)))
1131
+ ].sort(),
1132
+ binaryFrameworks: [...binaryFrameworks].map(([name, file]) => ({ name, path: file })).sort((left, right) => left.name.localeCompare(right.name)),
1133
+ packageResolved: fs.existsSync(resolvedFile) ? resolvedFile : null,
1134
+ appTargets: appTargetNames,
1135
+ configuration,
1136
+ settings
1137
+ };
1138
+ }
1139
+
1140
+ // src/native-app-identity-project.ts
1141
+ function isRecord(value) {
1142
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1143
+ }
1144
+ function nonEmptyString(value) {
1145
+ return typeof value === "string" && value.length > 0 ? value : void 0;
1146
+ }
1147
+ function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSource) {
1148
+ const dictionary = parseInfoPlist(app.infoPlist);
1149
+ if (!isRecord(dictionary)) throw new Error("native app Info.plist is not a dictionary");
1150
+ const settings = app.settings;
1151
+ const bundleIdentifier = nonEmptyString(dictionary.CFBundleIdentifier) ?? nonEmptyString(settings?.("PRODUCT_BUNDLE_IDENTIFIER"));
1152
+ if (!bundleIdentifier) throw new Error("native app has no bundle identifier");
1153
+ const appVersion = nonEmptyString(dictionary.CFBundleShortVersionString) ?? nonEmptyString(settings?.("MARKETING_VERSION"));
1154
+ const buildVersion = nonEmptyString(dictionary.CFBundleVersion) ?? nonEmptyString(settings?.("CURRENT_PROJECT_VERSION"));
1155
+ if (!appVersion || !buildVersion) {
1156
+ throw new Error("native app has no version or build version");
1157
+ }
1158
+ const bundleName = nonEmptyString(dictionary.CFBundleName) ?? nonEmptyString(settings?.("PRODUCT_NAME")) ?? app.name;
1159
+ const applicationDisplayName = nonEmptyString(dictionary.CFBundleDisplayName);
1160
+ const applicationName = applicationDisplayName ?? bundleName;
1161
+ const declaredBackgroundColor = dictionary.RCTRootViewBackgroundColor;
1162
+ const rootViewBackgroundColor = typeof declaredBackgroundColor === "number" && Number.isInteger(declaredBackgroundColor) ? declaredBackgroundColor : void 0;
1163
+ const alternateIconNames = /* @__PURE__ */ new Set();
1164
+ const icons = dictionary.CFBundleIcons;
1165
+ const alternates = isRecord(icons) ? icons.CFBundleAlternateIcons : void 0;
1166
+ if (isRecord(alternates)) {
1167
+ for (const name of Object.keys(alternates)) {
1168
+ if (name) alternateIconNames.add(name);
1169
+ }
1170
+ }
1171
+ const alternateSetting = settings?.("ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES") ?? "";
1172
+ for (const match of alternateSetting.replace(/\\"/g, '"').matchAll(/"([^"]*)"|([^\s(),]+)/g)) {
1173
+ const val = match[1] ?? match[2];
1174
+ if (val) alternateIconNames.add(val);
1175
+ }
1176
+ const permissionUsageDescriptions = {};
1177
+ for (const [key, value] of Object.entries(dictionary)) {
1178
+ if (!/^NS.*UsageDescription$/.test(key) && key !== "NSLocationTemporaryUsageDescriptionDictionary") {
1179
+ continue;
1180
+ }
1181
+ permissionUsageDescriptions[key] = value;
1182
+ }
1183
+ const querySchemes = dictionary.LSApplicationQueriesSchemes;
1184
+ const urlQuerySchemes = Array.isArray(querySchemes) ? querySchemes : [];
1185
+ const intentIds = dictionary.OneAppIntentIdentifiers;
1186
+ const appIntentIdentifiers = Array.isArray(intentIds) && intentIds.every((v) => typeof v === "string") ? intentIds : [];
1187
+ const backgroundIds = dictionary.BGTaskSchedulerPermittedIdentifiers;
1188
+ const backgroundTaskIdentifiers = Array.isArray(backgroundIds) && backgroundIds.every((v) => typeof v === "string") ? backgroundIds : [];
1189
+ const declaredModes = dictionary.UIBackgroundModes;
1190
+ const backgroundModes = Array.isArray(declaredModes) && declaredModes.every((v) => typeof v === "string") ? declaredModes : [];
1191
+ const supportedInterfaceOrientations = Array.isArray(dictionary.UISupportedInterfaceOrientations) && dictionary.UISupportedInterfaceOrientations.every((v) => typeof v === "string") ? dictionary.UISupportedInterfaceOrientations : [];
1192
+ const ipadSupportedInterfaceOrientations = Array.isArray(dictionary["UISupportedInterfaceOrientations~ipad"]) && dictionary["UISupportedInterfaceOrientations~ipad"].every(
1193
+ (v) => typeof v === "string"
1194
+ ) ? dictionary["UISupportedInterfaceOrientations~ipad"] : [];
1195
+ const defaultScreenOrientationMask = nonEmptyString(
1196
+ dictionary.EXDefaultScreenOrientationMask
1197
+ );
1198
+ const shareIntoAppGroupId = nonEmptyString(dictionary.ExpoShareIntoAppGroupId);
1199
+ return {
1200
+ applicationName,
1201
+ ...applicationDisplayName ? { applicationDisplayName } : {},
1202
+ ...rootViewBackgroundColor !== void 0 ? { rootViewBackgroundColor } : {},
1203
+ bundleName,
1204
+ appVersion,
1205
+ buildVersion,
1206
+ bundleIdentifier,
1207
+ platform: "ios",
1208
+ supportedInterfaceOrientations,
1209
+ ipadSupportedInterfaceOrientations,
1210
+ ...defaultScreenOrientationMask ? { defaultScreenOrientationMask } : {},
1211
+ alternateIconNames: [...alternateIconNames],
1212
+ permissionUsageDescriptions,
1213
+ urlQuerySchemes,
1214
+ ...shareIntoAppGroupId ? { shareIntoAppGroupId } : {},
1215
+ backgroundTaskIdentifiers,
1216
+ backgroundModes,
1217
+ appIntentIdentifiers
1218
+ };
1219
+ }
1220
+ function readNativeAppIdentityFromProject(projectRoot, platform, parseInfoPlist = parsePlistSource, iosTarget) {
1221
+ if (!canExtractNativeAppIdentity(platform)) return null;
1222
+ const iosRoot = path3.join(projectRoot, "ios");
1223
+ if (!fs2.existsSync(iosRoot)) return null;
1224
+ const projects = fs2.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
1225
+ if (projects.length === 0) return null;
1226
+ if (projects.length > 1 && !iosTarget) {
1227
+ throw new Error("native app identity requires a selected Xcode project");
1228
+ }
1229
+ let project = projects[0];
1230
+ if (iosTarget && projects.length > 1) {
1231
+ const matches = projects.filter(
1232
+ (entry) => listXcodeAppTargets(path3.join(iosRoot, entry.name)).includes(iosTarget)
1233
+ );
1234
+ if (matches.length === 0) {
1235
+ throw new Error(`native app identity has no application target ${iosTarget}`);
1236
+ }
1237
+ if (matches.length > 1) {
1238
+ throw new Error(
1239
+ `native app identity target ${iosTarget} is ambiguous across ${matches.map((entry) => entry.name).join(", ")}`
1240
+ );
1241
+ }
1242
+ project = matches[0];
1243
+ }
1244
+ const xcodeproj = path3.join(iosRoot, project.name);
1245
+ const appTargets = listXcodeAppTargets(xcodeproj);
1246
+ if (!iosTarget && appTargets.length > 1) {
1247
+ throw new Error("native app identity requires a selected app target");
1248
+ }
1249
+ const app = readXcodeAppTarget(xcodeproj, iosTarget ?? appTargets[0], "Release", {
1250
+ requireSources: false
1251
+ });
1252
+ return readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist);
1253
+ }
1254
+ export {
1255
+ readNativeAppIdentityFromProject,
1256
+ readNativeAppIdentityFromXcodeTarget
1257
+ };