stim 1.20.2 → 1.22.0

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 (231) hide show
  1. package/README.md +141 -8
  2. package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
  3. package/dist/act-DsuqEkiM.mjs +2801 -0
  4. package/dist/activity-CMLmzp7o.mjs +1397 -0
  5. package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
  6. package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
  7. package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
  8. package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
  9. package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
  10. package/dist/android-cas-compiler.mjs +2 -2
  11. package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
  12. package/dist/android-project-BCAAmMwz.mjs +12 -0
  13. package/dist/android-project-DVWyCbWU.d.mts +391 -0
  14. package/dist/api.d.mts +810 -64
  15. package/dist/api.mjs +782 -1
  16. package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
  17. package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
  18. package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
  19. package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
  20. package/dist/budget-Cvwn54qV.mjs +9285 -0
  21. package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
  22. package/dist/build-cache-Dv7RN200.mjs +602 -0
  23. package/dist/build-plan-DUC8Ka9y.mjs +248 -0
  24. package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
  25. package/dist/cache-manifest.mjs +1 -1
  26. package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
  27. package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
  28. package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
  29. package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
  30. package/dist/cli.mjs +1 -1
  31. package/dist/client-OyRoEuSr.mjs +1577 -0
  32. package/dist/collector-run.d.mts +4 -40
  33. package/dist/collector-run.mjs +9 -8
  34. package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
  35. package/dist/config-DlrsduwG.mjs +955 -0
  36. package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
  37. package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
  38. package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
  39. package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
  40. package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
  41. package/dist/device-DklWZLqb.mjs +1068 -0
  42. package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
  43. package/dist/device-host-worker.mjs +76 -79
  44. package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
  45. package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
  46. package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
  47. package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
  48. package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
  49. package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
  50. package/dist/doctor-fingerprint.mjs +19 -0
  51. package/dist/doctor-thjWAV0z.mjs +2 -0
  52. package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
  53. package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
  54. package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
  55. package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
  56. package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
  57. package/dist/exec-DEoAhcze.mjs +858 -0
  58. package/dist/exec-DnYc4HGH.d.mts +78 -0
  59. package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
  60. package/dist/gc-DnNDQyaP.mjs +3 -0
  61. package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
  62. package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
  63. package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
  64. package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
  65. package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
  66. package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
  67. package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
  68. package/dist/idle-C4cZ757K.d.mts +24 -0
  69. package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
  70. package/dist/ios-CDvlmUs7.d.mts +24 -0
  71. package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
  72. package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
  73. package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
  74. package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
  75. package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
  76. package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
  77. package/dist/ios-signing-BtAffm0A.mjs +489 -0
  78. package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
  79. package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
  80. package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
  81. package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
  82. package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
  83. package/dist/logs-BfwwadsZ.mjs +479 -0
  84. package/dist/logs-jTS_lHSo.mjs +248 -0
  85. package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
  86. package/dist/macos-NfV2D7dO.mjs +694 -0
  87. package/dist/macos-run.mjs +1 -1
  88. package/dist/maintenance-run.mjs +123 -248
  89. package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
  90. package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
  91. package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
  92. package/dist/native-android-CqgnOgsT.mjs +645 -0
  93. package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
  94. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
  95. package/dist/native-inputs-TRTTTRxt.mjs +91 -0
  96. package/dist/native-run-NwUuxbkg.mjs +276 -0
  97. package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
  98. package/dist/native-source-Y0yLhFyQ.mjs +133 -0
  99. package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
  100. package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
  101. package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
  102. package/dist/offload-worker.d.mts +59 -41
  103. package/dist/offload-worker.mjs +478 -115
  104. package/dist/operation-exec-BW0em61G.mjs +171 -0
  105. package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
  106. package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
  107. package/dist/paths-BsJMoPP2.mjs +12 -0
  108. package/dist/paths-DQtTgsBf.mjs +42 -0
  109. package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
  110. package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
  111. package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
  112. package/dist/prebuild-D4JoEAEs.mjs +484 -0
  113. package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
  114. package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
  115. package/dist/pull-request-eODyIqZF.d.mts +124 -0
  116. package/dist/pull-requests.d.mts +2 -120
  117. package/dist/pull-requests.mjs +2 -2
  118. package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
  119. package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
  120. package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
  121. package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
  122. package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
  123. package/dist/registration-BcRgF6Ox.mjs +51 -0
  124. package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
  125. package/dist/reload-D7AVlb8N.mjs +2 -0
  126. package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
  127. package/dist/result-D2Ykz_iD.mjs +435 -0
  128. package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
  129. package/dist/selection-DSMbWEX2.mjs +620 -0
  130. package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
  131. package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
  132. package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
  133. package/dist/server-expo-D58c9L0M.mjs +2 -0
  134. package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
  135. package/dist/settings-DpR-1Wnn.mjs +114 -0
  136. package/dist/settings-write-CzD60rOD.mjs +360 -0
  137. package/dist/settings.schema.json +176 -16
  138. package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
  139. package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
  140. package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
  141. package/dist/stage-Bps5oius.mjs +200 -0
  142. package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
  143. package/dist/start-EojN4WFz.mjs +1364 -0
  144. package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
  145. package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
  146. package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
  147. package/dist/stats-report-BzaPrRm6.mjs +16 -0
  148. package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
  149. package/dist/status-EvrK72L2.mjs +2 -0
  150. package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
  151. package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
  152. package/dist/status-worker.d.mts +1 -0
  153. package/dist/status-worker.mjs +19 -0
  154. package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
  155. package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
  156. package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
  157. package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
  158. package/dist/supervisor-run.d.mts +8 -17
  159. package/dist/supervisor-run.mjs +56 -28
  160. package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
  161. package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
  162. package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
  163. package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
  164. package/dist/toolchain-BY8X8HXx.mjs +2 -0
  165. package/dist/toolchain-DpJMHq0n.mjs +876 -0
  166. package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
  167. package/dist/trigger-yb_nFzPF.mjs +2 -0
  168. package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
  169. package/dist/web-CZ07gd77.mjs +2 -0
  170. package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
  171. package/dist/web-run.mjs +13 -12
  172. package/dist/windows-report.d.mts +1 -0
  173. package/dist/windows-report.mjs +18 -0
  174. package/dist/windows-report.ps1 +43 -0
  175. package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
  176. package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
  177. package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
  178. package/dist/worktree-ZqZVjD9K.mjs +2 -0
  179. package/dist/xcode-BXn9-xYx.mjs +896 -0
  180. package/package.json +7 -5
  181. package/shim/android-audio/Main.java +24 -0
  182. package/shim/android-audio/README.md +17 -0
  183. package/shim/android-audio.jar +0 -0
  184. package/shim/android-optimizations.gradle +7 -5
  185. package/dist/activity-BSV745Kz.mjs +0 -629
  186. package/dist/api-qvOzWyfO.mjs +0 -154
  187. package/dist/api-run.mjs +0 -294
  188. package/dist/app-install-BIKtMfPq.mjs +0 -896
  189. package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
  190. package/dist/budget-f7516Zk0.mjs +0 -4106
  191. package/dist/build-facts-DcLv2HSd.d.mts +0 -111
  192. package/dist/cancellation-C_22VQTH.mjs +0 -24
  193. package/dist/client-qQAaXSUs.mjs +0 -1771
  194. package/dist/config-BYDxlMY3.mjs +0 -562
  195. package/dist/device-DuiPJQSn.mjs +0 -290
  196. package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
  197. package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
  198. package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
  199. package/dist/exec-DqKo9GKJ.mjs +0 -268
  200. package/dist/git-DDfFzkMm.mjs +0 -45
  201. package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
  202. package/dist/logs-BGrEUaEs.mjs +0 -383
  203. package/dist/macos-Ch5VJmcS.mjs +0 -584
  204. package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
  205. package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
  206. package/dist/native-android-D5qc3-_v.mjs +0 -226
  207. package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
  208. package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
  209. package/dist/plan-C4TjdPsR.mjs +0 -260
  210. package/dist/prebuild-DYbucPXy.mjs +0 -212
  211. package/dist/preview-78a9kR_-.mjs +0 -1011
  212. package/dist/react-native-build-CtCccJtb.mjs +0 -239
  213. package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
  214. package/dist/remote-cache-OyOyVIS3.mjs +0 -526
  215. package/dist/result-CaJg5Iat.mjs +0 -186
  216. package/dist/server-expo-Bigriskl.mjs +0 -2
  217. package/dist/settings-BORNaaCO.mjs +0 -402
  218. package/dist/settings-vk3mJGSm.d.mts +0 -13
  219. package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
  220. package/dist/stage-KNTQopqv.mjs +0 -157
  221. package/dist/start-BWqzODpb.mjs +0 -1116
  222. package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
  223. package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
  224. package/dist/tailnet-Dh-qiYzG.mjs +0 -265
  225. package/dist/toolchain-BFkAcstd.mjs +0 -2
  226. package/dist/toolchain-DxSsNssu.mjs +0 -1657
  227. package/dist/trigger-9_USgmxz.mjs +0 -2
  228. package/dist/web-Dq-i3wzJ.mjs +0 -2
  229. package/dist/worktree-DpLdCHga.mjs +0 -2
  230. package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
  231. package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
@@ -1,349 +0,0 @@
1
- import { t as git } from "./git-DDfFzkMm.mjs";
2
- import { existsSync, lstatSync, readFileSync, readdirSync, readlinkSync, realpathSync } from "node:fs";
3
- import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
4
- import { createHash } from "node:crypto";
5
- //#region src/offload/manifest.ts
6
- function manifestDigest(entries) {
7
- const hash = createHash("sha256");
8
- for (const entry of entries.toSorted((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0)) hash.update(`${entry.path}\0${entry.kind}\0${entry.sha256}\n`);
9
- return hash.digest("hex");
10
- }
11
- //#endregion
12
- //#region src/integrations/native-inputs.ts
13
- var NativeInputError = class extends Error {};
14
- function fingerprintNativeInputs(inputs, { excluded = [], ignoredDirectoryMarkers = [], parameters }) {
15
- const exclusions = excluded.map((path) => resolve(path));
16
- const directoryMarkers = new Set(ignoredDirectoryMarkers.map((path) => resolve(path)));
17
- const entries = [];
18
- const names = /* @__PURE__ */ new Set();
19
- const isExcluded = (path) => exclusions.some((output) => path === output || path.startsWith(`${output}${sep}`));
20
- let admit;
21
- const record = (path, kind, content = "") => {
22
- entries.push({
23
- path,
24
- kind,
25
- sha256: createHash("sha256").update(content).digest("hex")
26
- });
27
- };
28
- const walk = (absolute, logical, ancestors, optional = false, relative = null) => {
29
- let stat;
30
- try {
31
- stat = lstatSync(absolute);
32
- } catch (error) {
33
- if (optional && error.code === "ENOENT") {
34
- record(logical, "absent");
35
- return;
36
- }
37
- throw error;
38
- }
39
- if (stat.isSymbolicLink()) {
40
- const target = readlinkSync(absolute);
41
- const resolved = resolve(dirname(absolute), target);
42
- if (isExcluded(resolved)) throw new NativeInputError(`Native input ${logical} links into an excluded output.`);
43
- if (ancestors.has(absolute)) throw new NativeInputError(`Native input ${logical} contains a link cycle.`);
44
- record(logical, "link", target);
45
- walk(resolved, `${logical}/@target`, /* @__PURE__ */ new Set([...ancestors, absolute]));
46
- } else if (stat.isDirectory()) {
47
- const canonical = realpathSync(absolute);
48
- if (ancestors.has(canonical)) throw new NativeInputError(`Native input ${logical} contains a directory cycle.`);
49
- if (!directoryMarkers.has(absolute)) record(logical, "directory");
50
- const next = /* @__PURE__ */ new Set([...ancestors, canonical]);
51
- for (const name of readdirSync(absolute).toSorted()) {
52
- const child = join(absolute, name);
53
- const childRelative = relative === null ? null : relative ? `${relative}/${name}` : name;
54
- if (isExcluded(child) || childRelative !== null && admit && !admit(childRelative)) continue;
55
- walk(child, `${logical}/${name}`, next, false, childRelative);
56
- }
57
- } else if (stat.isFile()) record(logical, `file:${stat.mode & 73}`, readFileSync(absolute));
58
- else throw new NativeInputError(`Native input ${logical} is not a file, directory or symbolic link.`);
59
- };
60
- try {
61
- for (const input of inputs) {
62
- if (!input.name || names.has(input.name)) throw new NativeInputError("Native input names must be unique.");
63
- names.add(input.name);
64
- const path = resolve(input.path);
65
- if (isExcluded(path)) throw new NativeInputError(`Native input ${input.name} is also an excluded output.`);
66
- admit = input.admit;
67
- walk(path, input.name, /* @__PURE__ */ new Set(), input.optional, "");
68
- }
69
- } catch (error) {
70
- if (error instanceof NativeInputError) throw error;
71
- throw new NativeInputError(`Could not read native build inputs: ${error.message}`, { cause: error });
72
- }
73
- const sorted = entries.toSorted((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
74
- return {
75
- hash: createHash("sha256").update("stim-native-inputs-v1\0").update(JSON.stringify(parameters)).update("\0").update(manifestDigest(sorted)).digest("hex"),
76
- entries: sorted,
77
- parameters
78
- };
79
- }
80
- //#endregion
81
- //#region src/offload/native-source.ts
82
- function* repositoryInputs(snapshot) {
83
- const links = snapshot.entries.filter((entry) => entry.kind === "link").map((entry) => `${entry.path}/@target`);
84
- for (const entry of snapshot.entries) {
85
- if (entry.path === "repository") continue;
86
- if (!entry.path.startsWith("repository/")) throw new Error("Native offload requires every input to be inside the repository.");
87
- if (links.some((link) => entry.path === link || entry.path.startsWith(`${link}/`))) continue;
88
- yield {
89
- entry,
90
- path: entry.path.slice(11)
91
- };
92
- }
93
- }
94
- const absentInput = (path) => /* @__PURE__ */ new Error(`Native input ${path} is ignored or absent from the source transfer; it was not uploaded.`);
95
- /** Throws the same membership refusal as nativeTransferManifest, from the git-visible paths alone. */
96
- function checkNativeTransferMembership(snapshot, visible) {
97
- for (const { entry, path } of repositoryInputs(snapshot)) {
98
- if (entry.kind === "directory" || visible.has(path)) continue;
99
- for (let index = path.indexOf("/"); index !== -1; index = path.indexOf("/", index + 1)) if (visible.has(path.slice(0, index))) throw new Error(`Native input ${path} is inside the git submodule ${path.slice(0, index)}; submodules are not transferred.`);
100
- throw absentInput(path);
101
- }
102
- }
103
- function nativeTransferManifest(root, snapshot, visible) {
104
- const files = new Map(visible.map((file) => [file.path, file]));
105
- root = realpathSync(root);
106
- const selected = [];
107
- const empty = createHash("sha256").update("").digest("hex");
108
- for (const { entry, path } of repositoryInputs(snapshot)) {
109
- if (entry.kind === "directory") {
110
- selected.push({
111
- path,
112
- kind: "directory",
113
- size: 0,
114
- sha256: empty
115
- });
116
- continue;
117
- }
118
- const file = files.get(path);
119
- if (!file) throw absentInput(path);
120
- const kind = entry.kind === "file:0" ? "file" : entry.kind === "file:73" ? "exec" : entry.kind;
121
- if (kind !== file.kind || entry.sha256 !== file.sha256) throw new Error(`Native input ${path} changed or has an unsupported executable mode.`);
122
- selected.push(file);
123
- if (kind === "link") {
124
- const link = join(root, path);
125
- const target = readlinkSync(link);
126
- const destination = relative(root, realpathSync(resolve(dirname(link), target)));
127
- if (isAbsolute(target) || isAbsolute(destination) || destination === ".." || destination.startsWith(`..${sep}`)) throw new Error(`Native input ${path} has a link that cannot be relocated inside the repository.`);
128
- }
129
- }
130
- return selected.toSorted((a, b) => a.path.localeCompare(b.path));
131
- }
132
- function verifyNativeTransfer(root, files, digest, ignoredDirectoryMarkers = []) {
133
- return manifestDigest(nativeTransferManifest(root, fingerprintNativeInputs([{
134
- name: "repository",
135
- path: root
136
- }], {
137
- excluded: [join(root, ".git")],
138
- ignoredDirectoryMarkers,
139
- parameters: null
140
- }), files)) === digest;
141
- }
142
- /** The exact source a build needs: tracked and untracked, not ignored, as `git ls-files -co --exclude-standard`. */
143
- function sourceManifest(repoRoot, strict = false) {
144
- const files = [];
145
- for (const path of gitVisiblePaths(repoRoot)) {
146
- const absolute = join(repoRoot, path);
147
- let stat;
148
- try {
149
- stat = lstatSync(absolute);
150
- } catch (error) {
151
- if (strict && error.code !== "ENOENT") throw error;
152
- continue;
153
- }
154
- if (stat.isSymbolicLink()) {
155
- const target = Buffer.from(readlinkSync(absolute));
156
- files.push({
157
- path,
158
- kind: "link",
159
- size: target.length,
160
- sha256: createHash("sha256").update(target).digest("hex")
161
- });
162
- } else if (stat.isFile()) {
163
- const content = readFileSync(absolute);
164
- files.push({
165
- path,
166
- kind: stat.mode & 73 ? "exec" : "file",
167
- size: content.length,
168
- sha256: createHash("sha256").update(content).digest("hex")
169
- });
170
- } else if (strict) throw new Error(`Native source ${path} is not a file or link; transfer submodule contents explicitly.`);
171
- }
172
- return files;
173
- }
174
- function gitVisiblePaths(repoRoot) {
175
- const listed = git(repoRoot, [
176
- "ls-files",
177
- "-z",
178
- "-co",
179
- "--exclude-standard"
180
- ], {
181
- untrimmed: true,
182
- timeoutMs: 12e4
183
- });
184
- return new Set(listed.split("\0").filter(Boolean));
185
- }
186
- //#endregion
187
- //#region src/integrations/native-gradle-inputs.ts
188
- function containedPath(path) {
189
- return typeof path === "string" && path.length > 0 && !path.includes("\\") && !path.includes(":") && !path.includes("\0") && !path.split("/").some((part) => !part || part === "." || part === ".." || part.toLowerCase() === ".git");
190
- }
191
- function gradleOffloadInputs(value) {
192
- const input = value;
193
- if (!input || typeof input !== "object" || input.complete !== true || Object.keys(input).some((key) => ![
194
- "complete",
195
- "ignored",
196
- "outputs"
197
- ].includes(key)) || !Array.isArray(input.ignored) || !input.ignored.every(containedPath) || !Array.isArray(input.outputs) || !input.outputs.every(containedPath)) throw new Error("Native Gradle offload requires android.offloadInputs with complete: true, ignored: [exact repository-relative files], and outputs: [generated repository-relative directories].");
198
- const ignored = [...new Set(input.ignored)].toSorted();
199
- const outputs = [...new Set(input.outputs)].toSorted();
200
- if (ignored.some((path) => path.split("/").at(-1) === "local.properties")) throw new Error("local.properties is machine-local; remove it from android.offloadInputs.ignored.");
201
- if (outputs.some((path) => path.split("/").some((part) => part === ".gradle" || part === ".kotlin"))) throw new Error("Gradle project state is worker-owned and cannot be declared as a generated output.");
202
- for (const output of outputs) if (outputs.some((other) => other !== output && output.startsWith(`${other}/`))) throw new Error(`Generated output ${output} is nested inside another output declaration.`);
203
- return {
204
- complete: true,
205
- ignored,
206
- outputs
207
- };
208
- }
209
- const below = (path, directory) => path === directory || path.startsWith(`${directory}/`);
210
- function gradleStateDirectories(project) {
211
- return [".gradle", ".kotlin"].map((name) => project ? `${project}/${name}` : name);
212
- }
213
- function requireRealParents(repository, path) {
214
- const parts = path.split("/");
215
- for (let index = 1; index < parts.length; index++) {
216
- const parent = join(repository, ...parts.slice(0, index));
217
- const stat = lstatSync(parent, { throwIfNoEntry: false });
218
- if (stat && !stat.isDirectory()) throw new Error(`Native input ${path} has a non-directory parent.`);
219
- }
220
- }
221
- function nativeGradleTransfer(root, value) {
222
- const declaration = gradleOffloadInputs(value);
223
- const repository = realpathSync(git(root, ["rev-parse", "--show-toplevel"]));
224
- const project = relative(repository, realpathSync(root)).split(sep).join("/");
225
- if (project && !containedPath(project)) throw new Error("The native Gradle project leaves its repository.");
226
- if (lstatSync(join(repository, project, "buildSrc"), { throwIfNoEntry: false })?.isDirectory()) throw new Error("Native Gradle offload does not support buildSrc: AGP does not report its build directories, so the worker cannot keep them.");
227
- const state = gradleStateDirectories(project);
228
- const files = new Map(sourceManifest(repository, true).map((file) => [file.path, file]));
229
- for (const path of declaration.ignored) {
230
- requireRealParents(repository, path);
231
- const absolute = join(repository, path);
232
- const stat = lstatSync(absolute);
233
- if (!stat.isFile() && !stat.isSymbolicLink()) throw new Error(`Ignored native input ${path} must be an exact file or link, not a directory.`);
234
- const content = stat.isSymbolicLink() ? Buffer.from(readlinkSync(absolute)) : readFileSync(absolute);
235
- files.set(path, {
236
- path,
237
- kind: stat.isSymbolicLink() ? "link" : stat.mode & 73 ? "exec" : "file",
238
- size: content.length,
239
- sha256: createHash("sha256").update(content).digest("hex")
240
- });
241
- }
242
- for (const file of files.values()) {
243
- if (!containedPath(file.path)) throw new Error(`Native input ${file.path} is not a contained relative path.`);
244
- requireRealParents(repository, file.path);
245
- if (state.some((path) => below(file.path, path))) throw new Error("Gradle project state cannot be transferred as source.");
246
- if (declaration.outputs.some((output) => below(file.path, output) || below(output, file.path))) throw new Error(`Native input ${file.path} overlaps a declared generated output.`);
247
- if (file.path.split("/").at(-1) === "local.properties") {
248
- if (file.kind === "link") throw new Error(`Native input ${file.path} is a machine-local properties link.`);
249
- if (readFileSync(join(repository, file.path), "utf8").split(/\r?\n/).some((line) => line.trim() && !/^\s*[#!]/.test(line) && !/^\s*sdk\.dir\s*[:=].*[^\\]$/.test(line))) throw new Error(`Native input ${file.path} contains unsupported machine-local properties.`);
250
- files.delete(file.path);
251
- continue;
252
- }
253
- }
254
- for (const file of files.values()) if (file.kind === "link") {
255
- const absolute = join(repository, file.path);
256
- const target = readlinkSync(absolute);
257
- const resolved = realpathSync(resolve(dirname(absolute), target));
258
- const destination = relative(repository, resolved).split(sep).join("/");
259
- if (isAbsolute(target) || !containedPath(destination) || !files.has(destination)) throw new Error(`Native input ${file.path} links to a target outside the declared source inventory.`);
260
- }
261
- for (const output of declaration.outputs) {
262
- requireRealParents(repository, output);
263
- const stat = lstatSync(join(repository, output), { throwIfNoEntry: false });
264
- if (stat && !stat.isDirectory()) throw new Error(`Generated output ${output} is not a real directory.`);
265
- if (state.some((path) => below(output, path) || below(path, output))) throw new Error(`Generated output ${output} overlaps Gradle project state.`);
266
- }
267
- const empty = createHash("sha256").update("").digest("hex");
268
- for (const path of files.keys()) {
269
- const parts = path.split("/");
270
- for (let index = 1; index < parts.length; index++) {
271
- const directory = parts.slice(0, index).join("/");
272
- files.set(directory, {
273
- path: directory,
274
- kind: "directory",
275
- size: 0,
276
- sha256: empty
277
- });
278
- }
279
- }
280
- const selected = [...files.values()].toSorted((a, b) => a.path.localeCompare(b.path));
281
- return {
282
- repository,
283
- project,
284
- declaration,
285
- files: selected,
286
- digest: manifestDigest(selected)
287
- };
288
- }
289
- function canonicalParent(path) {
290
- const missing = [];
291
- while (!existsSync(path) && dirname(path) !== path) {
292
- missing.unshift(basename(path));
293
- path = dirname(path);
294
- }
295
- return join(realpathSync(path), ...missing);
296
- }
297
- function nativeGradleOutputs(repository, declaration, reported) {
298
- if (!Array.isArray(reported) || !reported.every((path) => typeof path === "string" && isAbsolute(path))) throw new Error("AGP did not report the configured native Gradle build directories.");
299
- const real = realpathSync(repository);
300
- const reportedPaths = /* @__PURE__ */ new Set();
301
- for (const absolute of reported) {
302
- const resolved = resolve(absolute);
303
- const canonical = join(canonicalParent(dirname(resolved)), basename(resolved));
304
- const path = relative(real, canonical).split(sep).join("/");
305
- if (!containedPath(path)) throw new Error("A Gradle build directory leaves the transferred repository.");
306
- requireRealParents(repository, path);
307
- const stat = lstatSync(join(repository, path), { throwIfNoEntry: false });
308
- if (stat && !stat.isDirectory()) throw new Error(`Gradle build directory ${path} is not a real directory.`);
309
- reportedPaths.add(path);
310
- }
311
- for (const output of declaration.outputs) if (!reportedPaths.has(output)) throw new Error(`Declared output ${output} was not reported by AGP.`);
312
- for (const path of reportedPaths) if (lstatSync(join(repository, path), { throwIfNoEntry: false })?.isDirectory() && !declaration.outputs.some((output) => below(path, output))) throw new Error(`Gradle build directory ${path} is not declared; add it to android.offloadInputs.outputs.`);
313
- return declaration.outputs.filter((path) => lstatSync(join(repository, path), { throwIfNoEntry: false })?.isDirectory());
314
- }
315
- function validateGradleManifest(project, declaration, files) {
316
- gradleOffloadInputs(declaration);
317
- if (project && !containedPath(project)) throw new Error("The native Gradle project leaves its repository.");
318
- const excluded = [...declaration.outputs, ...gradleStateDirectories(project)];
319
- for (const file of files) if (!containedPath(file.path) || excluded.some((path) => below(file.path, path) || file.kind !== "directory" && below(path, file.path))) throw new Error(`Native source ${file.path} overlaps worker outputs or leaves the repository.`);
320
- for (const path of declaration.ignored) if (!files.some((file) => file.path === path && file.kind !== "directory")) throw new Error(`Declared ignored input ${path} is missing from the transfer.`);
321
- }
322
- function verifyGradleTransfer(repository, project, declaration, files, digest) {
323
- validateGradleManifest(project, declaration, files);
324
- const excluded = [...declaration.outputs, ...gradleStateDirectories(project)];
325
- for (const path of excluded) {
326
- requireRealParents(repository, path);
327
- const stat = lstatSync(join(repository, path), { throwIfNoEntry: false });
328
- if (stat && !stat.isDirectory()) throw new Error(`Worker output ${path} is not a real directory.`);
329
- }
330
- const markers = excluded.flatMap((path) => path.split("/").slice(0, -1).map((_, index) => join(repository, ...path.split("/").slice(0, index + 1))));
331
- const snapshot = fingerprintNativeInputs([{
332
- name: "repository",
333
- path: repository
334
- }], {
335
- excluded: [join(repository, ".git"), ...excluded.map((path) => join(repository, path))],
336
- ignoredDirectoryMarkers: markers.filter((path) => !files.some((file) => join(repository, file.path) === path)),
337
- parameters: null
338
- });
339
- const known = new Set(files.map((file) => file.path));
340
- for (const entry of snapshot.entries) {
341
- if (!entry.path.startsWith("repository/") || entry.path.includes("/@target")) continue;
342
- const parts = entry.path.slice(11).split("/");
343
- const index = parts.findIndex((_, depth) => !known.has(parts.slice(0, depth + 1).join("/")));
344
- if (index >= 0 && (index < parts.length - 1 || entry.kind === "directory")) throw new Error(`Native Gradle directory ${parts.slice(0, index + 1).join("/")} is outside the source transfer and not a declared output reported by AGP; such directories, for example, included builds or externalNativeBuild staging, are not supported for remote builds.`);
345
- }
346
- return manifestDigest(nativeTransferManifest(repository, snapshot, files)) === digest;
347
- }
348
- //#endregion
349
- export { validateGradleManifest as a, gitVisiblePaths as c, verifyNativeTransfer as d, NativeInputError as f, nativeGradleTransfer as i, nativeTransferManifest as l, manifestDigest as m, gradleStateDirectories as n, verifyGradleTransfer as o, fingerprintNativeInputs as p, nativeGradleOutputs as r, checkNativeTransferMembership as s, gradleOffloadInputs as t, sourceManifest as u };
@@ -1,17 +0,0 @@
1
- import "@stim-cli/core/state";
2
- //#region src/ndjson.d.ts
3
- interface NdjsonWriter {
4
- readonly file: string;
5
- write(record: unknown): boolean;
6
- close(): {
7
- file: string;
8
- written: number;
9
- dropped: number;
10
- lastError: Error | null;
11
- };
12
- readonly written: number;
13
- readonly dropped: number;
14
- readonly lastError: Error | null;
15
- }
16
- //#endregion
17
- export { NdjsonWriter as t };
@@ -1,260 +0,0 @@
1
- import { V as deviceSlotPlatforms, p as getProject } from "./config-BYDxlMY3.mjs";
2
- import { B as remoteAndroidSetting, F as parseIosRemote, Q as settingShapeErrors, U as resolveAndroidLayout, W as resolveCacheProviderConfig, Y as settingFile, Z as settingOriginScope, a as SETTING_SHAPE_REMEDY, d as androidLayoutSetting, et as settingsLayers, f as androidLayoutSettingError, nt as unknownSettingKeys, p as cacheProviderSettingError, s as androidAvdConfigSettingError, u as androidDataPartitionSizeGbSettingError } from "./settings-B717odTD.mjs";
3
- import { _ as detectIsExpo } from "./project-_phNIJfs.mjs";
4
- import { B as ownedAvdSystemImage, F as ownedAvdDeviceProfile, K as profileNeedsFoldFeature, Q as systemImageSupportsFold, W as pickDefaultSystemImage, dt as parkedMaxSetting, j as listInstalledSystemImages, k as listAvdDeviceProfiles, t as DEFAULT_AVD_DEVICE_PROFILE } from "./android-Mz_Inn3w.mjs";
5
- import { d as optimizationBuildProfile, l as artifactCachePolicy, p as resolveOptimizations, u as compilerCacheFallbackMessage } from "./errors-DzkMYh8Q.mjs";
6
- import { r as isPhysicalDeviceRequest } from "./native-runtime-k8dTIrbK.mjs";
7
- import { t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-CBUAcRyQ.mjs";
8
- import { C as remoteAvdFlagRefusal, D as systemImageRefusal, E as resolveVariant, T as resolveSystemImage, m as deviceProfileRefusal, v as foldableImageRefusal, w as resolveDeviceProfile, y as isReleaseVariant } from "./support-DMTqj3Hm.mjs";
9
- import { c as readProductFlavors, s as productFlavorRefusal } from "./react-native-build-CtCccJtb.mjs";
10
- import { n as resolveAndroidCas, r as resolveAndroidCompilerCache } from "./android-cas-Bl-cLJBk.mjs";
11
- import { l as parseDeviceWait } from "./device-lease-run-Cw2M4z51.mjs";
12
- //#region src/integrations/android-project.ts
13
- var AndroidRecipeRefusal = class extends Error {
14
- failure;
15
- missReason;
16
- constructor(failure, missReason) {
17
- super(failure.message ?? failure.code);
18
- this.failure = failure;
19
- this.missReason = missReason;
20
- }
21
- };
22
- //#endregion
23
- //#region src/commands/android/plan.ts
24
- function slotOwnedAvd(projectPath, slot) {
25
- const android = deviceSlotPlatforms(getProject(projectPath), slot)?.android;
26
- if (!android?.owned || !android.avdName || android.setupIncomplete) return null;
27
- const systemImage = ownedAvdSystemImage(android.avdName);
28
- return systemImage ? {
29
- avdName: android.avdName,
30
- systemImage,
31
- deviceProfile: ownedAvdDeviceProfile(android.avdName)
32
- } : null;
33
- }
34
- function fail(code, message, remedy, { lines = [] } = {}) {
35
- return {
36
- ok: false,
37
- code,
38
- message,
39
- remedy,
40
- lines
41
- };
42
- }
43
- function androidLayoutError(settings, root, bound, isExpo) {
44
- const error = androidLayoutSettingError(settings, root, bound);
45
- if (error || !androidLayoutSetting(settings, root, bound).custom || !isExpo()) return error;
46
- return "android.gradleRoot and android.module apply to bare React Native apps only: expo prebuild generates and builds android/. Remove them for this Expo app.";
47
- }
48
- function androidCompilerCache({ root, optimizations, settingsContext, layout }) {
49
- const { cas, optimizations: resolved } = resolveAndroidCompilerCache({
50
- optimizations,
51
- use: (manifest) => resolveAndroidCas(root, {
52
- ...process.env,
53
- STIM_ANDROID_CAS_TOOLCHAIN: manifest
54
- }, layout)
55
- });
56
- const fallback = resolved.android.compilerCacheFallback;
57
- if (!fallback) return {
58
- cas,
59
- optimizations: resolved,
60
- warning: null
61
- };
62
- return {
63
- cas,
64
- optimizations: resolved,
65
- warning: `Warning: ${compilerCacheFallbackMessage({
66
- fallback,
67
- compilerCache: resolved.android.compilerCache === "none" ? "none" : "ccache",
68
- file: settingFile(settingsContext, fallback.key)
69
- })}`
70
- };
71
- }
72
- function resolveAndroidBuildPlan({ settings, settingsContext, easProfile, variant: variantFlag, buildCache: requestedBuildCache }, { warn, runtimeKind, resolveCompilerCache = androidCompilerCache, resolveCacheProvider = resolveCacheProviderConfig, variantProblem, detectExpo = () => detectIsExpo(settingsContext.projectPath) }) {
73
- const root = settingsContext.projectPath;
74
- const [shapeError, ...moreShapeErrors] = settingShapeErrors(settings);
75
- if (shapeError) return fail("STIM_BAD_ARG", shapeError, SETTING_SHAPE_REMEDY, { lines: moreShapeErrors });
76
- const bound = settingsContext.repoRoot ?? root;
77
- const layoutError = androidLayoutError(settings, root, bound, detectExpo);
78
- if (layoutError) return fail("STIM_BAD_ARG", layoutError, SETTING_SHAPE_REMEDY);
79
- const layout = resolveAndroidLayout(settings, root, bound);
80
- for (const key of unknownSettingKeys(settings)) warn("setting", `Warning: setting "${key}" is not read by Stim and will be ignored.`);
81
- let optimizations;
82
- try {
83
- optimizations = resolveOptimizations(settings);
84
- } catch (error) {
85
- return fail("STIM_BAD_ARG", `Could not configure Android build: ${error.message}`, SETTING_SHAPE_REMEDY);
86
- }
87
- const compilerCache = resolveCompilerCache({
88
- root,
89
- optimizations,
90
- settingsContext,
91
- layout
92
- });
93
- const cas = compilerCache.cas;
94
- optimizations = compilerCache.optimizations;
95
- if (compilerCache.warning) warn("cache", compilerCache.warning);
96
- const buildProfile = optimizationBuildProfile("android", optimizations);
97
- const cacheProviderConfig = resolveCacheProvider(settingsContext);
98
- const cacheProviderError = cacheProviderSettingError(settings);
99
- if (cacheProviderError) warn("cache", `${cacheProviderError} Using the local cache.`);
100
- const variant = easProfile !== void 0 ? "debug" : resolveVariant(variantFlag, settings);
101
- const flavorRefusal = variantProblem(variant);
102
- if (flavorRefusal) return fail(flavorRefusal.code, flavorRefusal.reason, flavorRefusal.remedy);
103
- const release = isReleaseVariant(variant);
104
- return {
105
- ok: true,
106
- plan: {
107
- build: {
108
- variant,
109
- release,
110
- profile: buildProfile,
111
- cas,
112
- cache: artifactCachePolicy(optimizations, requestedBuildCache, runtimeKind({ release }) === "embedded-js"),
113
- compilerCache: optimizations.android.compilerCache,
114
- gradleBuildCache: optimizations.android.gradleBuildCache,
115
- pch: optimizations.android.pch,
116
- targetAbiOnly: optimizations.android.targetAbiOnly
117
- },
118
- metroWarmup: optimizations.metroWarmup,
119
- cacheProviderConfig
120
- }
121
- };
122
- }
123
- function resolveAndroidRunPlan({ settings, settingsContext, slot, easProfile, variant: variantFlag, systemImage: systemImageFlag, deviceProfile: deviceProfileFlag, device: deviceFlag, wait: waitFlag, waitConflict, remote: commandRemoteBackend, buildCache: requestedBuildCache }, { warn, runtimeKind, resolveCompilerCache = androidCompilerCache, resolveCacheProvider = resolveCacheProviderConfig, validateAvdConfig = androidAvdConfigSettingError, readFlavors = readProductFlavors, variantProblem = (variant) => productFlavorRefusal({
124
- flavors: readFlavors(resolveAndroidLayout(settings, settingsContext.projectPath, settingsContext.repoRoot ?? settingsContext.projectPath)),
125
- variant
126
- }), detectExpo = () => detectIsExpo(settingsContext.projectPath), listSystemImages = listInstalledSystemImages, listDeviceProfiles = listAvdDeviceProfiles, parkedLimit = parkedMaxSetting, supportsFold = systemImageSupportsFold, ownedAvd = slotOwnedAvd }) {
127
- const root = settingsContext.projectPath;
128
- const [shapeError, ...moreShapeErrors] = [parkedLimit("android").error, ...settingShapeErrors(settings)].filter((error) => Boolean(error));
129
- if (shapeError) return fail("STIM_BAD_ARG", shapeError, SETTING_SHAPE_REMEDY, { lines: moreShapeErrors });
130
- const plannedBuild = resolveAndroidBuildPlan({
131
- settings,
132
- settingsContext,
133
- easProfile,
134
- variant: variantFlag,
135
- buildCache: requestedBuildCache
136
- }, {
137
- warn,
138
- runtimeKind,
139
- resolveCompilerCache,
140
- resolveCacheProvider,
141
- variantProblem,
142
- detectExpo
143
- });
144
- if (!plannedBuild.ok) return plannedBuild;
145
- const dataPartitionSizeError = androidDataPartitionSizeGbSettingError(settings);
146
- if (dataPartitionSizeError) return fail("STIM_BAD_ARG", dataPartitionSizeError, "Set android.dataPartitionSizeGb to a whole number of GiB from 6 through 16384.");
147
- const avdConfigError = validateAvdConfig(settings, root);
148
- if (avdConfigError) return fail("STIM_BAD_ARG", avdConfigError, "Use only documented android.avdConfig keys, or an android.avdConfigFile fragment contained by the app directory.");
149
- const systemImage = resolveSystemImage(systemImageFlag, settings);
150
- const deviceProfile = resolveDeviceProfile(deviceProfileFlag, settings);
151
- const isExpo = detectExpo();
152
- const physical = isPhysicalDeviceRequest(deviceFlag);
153
- if (physical && deviceFlag === "") return fail("STIM_BAD_ARG", "--device was given an empty serial.", "Pass `--device` on its own to take the first connected device this workspace can lease, or `--device <serial>` to name one.");
154
- if (physical && commandRemoteBackend) return fail("STIM_BAD_ARG", "--device installs on a device connected to this machine, and --remote installs on a remote one.", "Pass only one of --device and --remote.");
155
- const noWait = waitFlag === false;
156
- if (waitConflict) return fail("STIM_BAD_ARG", "--wait and --no-wait ask for opposite things.", "Pass only one of `--wait <seconds>` and `--no-wait`.");
157
- const waitParsed = parseDeviceWait(noWait ? void 0 : waitFlag);
158
- if ("error" in waitParsed) return fail("STIM_BAD_ARG", waitParsed.error, "Pass a whole number of seconds, e.g. --wait 90. `--wait 0` refuses a busy lease or device slot at once.");
159
- const waitSeconds = waitParsed.seconds;
160
- const remoteTarget = commandRemoteBackend !== null ? parseIosRemote(commandRemoteBackend) : remoteAndroidSetting(settings);
161
- if (physical && remoteTarget?.kind === "machine") return fail("STIM_BAD_ARG", "--device installs on a phone connected to this machine, and --remote installs on a remote one.", "Pass only one of --device and --remote; unset android.remote for a local phone.");
162
- const machine = remoteTarget?.kind === "machine" ? remoteTarget.machine : null;
163
- const remoteBackend = !physical && remoteTarget?.kind === "backend" ? remoteTarget.backend : null;
164
- if (!machine) {
165
- const refusal = androidDeviceSelectorRefusal({
166
- settingsContext,
167
- slot,
168
- systemImageFlag,
169
- deviceProfileFlag,
170
- systemImage,
171
- deviceProfile,
172
- physical,
173
- remoteBackend
174
- }, {
175
- listSystemImages,
176
- listDeviceProfiles,
177
- supportsFold,
178
- ownedAvd
179
- });
180
- if (refusal) return refusal;
181
- }
182
- const target = physical ? {
183
- kind: "physical",
184
- serial: typeof deviceFlag === "string" ? deviceFlag : null,
185
- lease: {
186
- waitSeconds,
187
- noWait
188
- }
189
- } : machine ? {
190
- kind: "hosted",
191
- machine,
192
- systemImage,
193
- deviceProfile
194
- } : remoteBackend ? {
195
- kind: "remote",
196
- backend: remoteBackend,
197
- systemImage,
198
- deviceProfile
199
- } : {
200
- kind: "emulator",
201
- systemImage,
202
- deviceProfile
203
- };
204
- return {
205
- ok: true,
206
- plan: {
207
- ...plannedBuild.plan,
208
- target,
209
- deviceSlotWaitMs: noWait ? 0 : waitFlag === void 0 && !physical ? DEFAULT_DEVICE_SLOT_WAIT_MS : waitSeconds * 1e3,
210
- isExpo
211
- }
212
- };
213
- }
214
- function androidDeviceSelectorRefusal({ settingsContext, slot, systemImageFlag, deviceProfileFlag, systemImage, deviceProfile, physical, remoteBackend }, { listSystemImages = listInstalledSystemImages, listDeviceProfiles = listAvdDeviceProfiles, supportsFold = systemImageSupportsFold, ownedAvd = slotOwnedAvd } = {}) {
215
- const root = settingsContext.projectPath;
216
- const settingsLayersForOrigin = settingsLayers(settingsContext);
217
- const imageRefusal = systemImageRefusal({
218
- slot,
219
- flag: systemImageFlag,
220
- resolved: systemImage,
221
- origin: settingOriginScope(settingsLayersForOrigin, "android.systemImage"),
222
- physical,
223
- remoteBackend,
224
- listImages: listSystemImages
225
- });
226
- if (imageRefusal) return fail(imageRefusal.code, imageRefusal.message, imageRefusal.remedy);
227
- const profileRefusal = deviceProfileRefusal({
228
- flag: deviceProfileFlag,
229
- resolved: deviceProfile,
230
- origin: settingOriginScope(settingsLayersForOrigin, "android.deviceProfile"),
231
- physical,
232
- remoteBackend,
233
- listProfiles: listDeviceProfiles
234
- });
235
- if (profileRefusal) return fail(profileRefusal.code, profileRefusal.message, profileRefusal.remedy);
236
- const avdFlagRefusal = remoteAvdFlagRefusal({
237
- systemImageFlag,
238
- deviceProfileFlag,
239
- remoteBackend
240
- });
241
- if (avdFlagRefusal) return fail(avdFlagRefusal.code, avdFlagRefusal.message, avdFlagRefusal.remedy);
242
- if (!physical && !remoteBackend) {
243
- const flagImage = typeof systemImageFlag === "string" && systemImageFlag.trim() ? systemImageFlag.trim() : null;
244
- const existing = ownedAvd(root, slot);
245
- const profile = deviceProfile ?? existing?.deviceProfile ?? DEFAULT_AVD_DEVICE_PROFILE;
246
- const image = () => flagImage ?? existing?.systemImage ?? systemImage ?? pickDefaultSystemImage(listSystemImages())?.pkg ?? null;
247
- const checked = profileNeedsFoldFeature(profile) ? image() : null;
248
- const foldRefusal = checked !== null && foldableImageRefusal({
249
- profile,
250
- image: checked,
251
- avdName: existing && existing.systemImage === checked && existing.deviceProfile === profile ? existing.avdName : null,
252
- images: listSystemImages,
253
- supportsFold
254
- });
255
- if (foldRefusal) return fail(foldRefusal.code, foldRefusal.message, foldRefusal.remedy);
256
- }
257
- return null;
258
- }
259
- //#endregion
260
- export { AndroidRecipeRefusal as i, resolveAndroidBuildPlan as n, resolveAndroidRunPlan as r, androidDeviceSelectorRefusal as t };