stim 1.19.0 → 1.20.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.
- package/README.md +20 -3
- package/dist/{activity-BSw0x84R.mjs → activity-BrGh9EAI.mjs} +3 -3
- package/dist/{agent-device-usage-output-Bjxu_VmX.mjs → agent-device-usage-output-DVyv_hWj.mjs} +7 -7
- package/dist/android-0vv-OruW.mjs +6 -0
- package/dist/android-Brx6EKvJ.mjs +1258 -0
- package/dist/{android-BdQC6zs1.mjs → android-BsYNR81W.mjs} +103 -45
- package/dist/{android-DE5g_5gv.mjs → android-CK3fpEyZ.mjs} +2 -2
- package/dist/{android-cas-C87geAg-.mjs → android-cas-DCAuXryb.mjs} +9 -5
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/api-run.mjs +159 -8
- package/dist/{api-DIf_s86s.mjs → api-zuX3ynYN.mjs} +5 -1
- package/dist/api.d.mts +98 -4
- package/dist/api.mjs +1 -1
- package/dist/{app-install-CFI4ptUL.mjs → app-install-0LgaQRT7.mjs} +9 -8
- package/dist/artifact-CnC0mfov.mjs +807 -0
- package/dist/artifact-DClXJNWx.mjs +772 -0
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
- package/dist/{browser-web-CDhqQxhv.mjs → browser-web-CzBmhmgs.mjs} +19 -19
- package/dist/{budget-Dz-kyXLv.mjs → budget-BONq9vXY.mjs} +3101 -3062
- package/dist/build-BixRI6sB.mjs +462 -0
- package/dist/{build-facts-B87vo-Im.d.mts → build-facts-DcLv2HSd.d.mts} +1 -32
- package/dist/build-plan-CP0tckNU.mjs +553 -0
- package/dist/{cache-manifest-DiwKSyv9.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{manifest-CX0d1IkZ.mjs → ccache-CjHQ5F8g.mjs} +13 -19
- package/dist/{chrome-BTUOo8p2.mjs → chrome-Dp2lMLBe.mjs} +1 -1
- package/dist/{cli-C9Zvgbdc.mjs → cli-B2R8wH1F.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-CuUo8Nvg.mjs → client-BLy1Pw2V.mjs} +89 -307
- package/dist/collector-run.d.mts +4 -0
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-Bt8ygHE7.mjs → command-output-BjPN99ZB.mjs} +2 -2
- package/dist/{config-DC5jEtd1.mjs → config-D0LhTY3S.mjs} +8 -12
- package/dist/{created-devices-D0s26Hx5.mjs → created-devices-HU_DAb_Q.mjs} +7 -6
- package/dist/{dependency-state-DKaS1OM9.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
- package/dist/{detached-entry-pB_IPfV4.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
- package/dist/{dev-client-CDY_zAmD.mjs → dev-client-ClATaJoH.mjs} +2 -2
- package/dist/{device-BHw0WlHl.mjs → device-B7lsC0K1.mjs} +8 -8
- package/dist/device-DVCwAFlX.mjs +727 -0
- package/dist/{device-capacity-BoN1jQkO.mjs → device-capacity-Ca_ke1LE.mjs} +13 -14
- package/dist/device-host-worker.mjs +38 -18
- package/dist/device-ios-CRUqPxKw.mjs +413 -0
- package/dist/{device-lease-Cu7PtQpZ.mjs → device-lease-DHOBXGgS.mjs} +135 -22
- package/dist/{device-lease-run-D38SnZtt.mjs → device-lease-run-CvDeHTkG.mjs} +4 -4
- package/dist/{device-pool-CP4rAsHx.mjs → device-pool-L2-5GxMy.mjs} +3 -3
- package/dist/{device-remote-B5GiUifk.mjs → device-remote-Bmg42063.mjs} +17 -68
- package/dist/doctor-C2MSuMMg.mjs +515 -0
- package/dist/{doctor-PRJH94v6.mjs → doctor-DPAqhVCK.mjs} +333 -744
- package/dist/{doctor-watchman-wZhyTdp4.mjs → doctor-watchman-CB4NnVZm.mjs} +13 -12
- package/dist/{simslim-D9LkJxIO.mjs → eas-build-Dw_ec2Km.mjs} +6 -152
- package/dist/{stim-installations-DbmUjsLv.mjs → eas-session-ledger-DZlC-Fq3.mjs} +57 -4
- package/dist/{error-diagnostics--v5HGOU0.mjs → error-diagnostics-Du7I_GuY.mjs} +17 -12
- package/dist/errors-DzkMYh8Q.mjs +205 -0
- package/dist/{exec-i8GDPwq9.mjs → exec-B81Qodjn.mjs} +40 -10
- package/dist/{gc-CyHMcKcn.mjs → gc-PWp34zGb.mjs} +21 -20
- package/dist/{device-ios-B2ruohE-.mjs → gradle-C2OEKCCI.mjs} +21 -650
- package/dist/{guide-dRaQJJk9.mjs → guide-Dai9lphv.mjs} +504 -117
- package/dist/{hosted-android-Bs7fytj7.mjs → hosted-android-DQ-Agsd8.mjs} +5 -5
- package/dist/{hosted-client-C5G4h_OJ.mjs → hosted-client-Io01s5By.mjs} +9 -3
- package/dist/{hosted-ios-Bik035eL.mjs → hosted-ios-DIxFnYp-.mjs} +3 -3
- package/dist/{hosted-logs-CI9Az9a4.mjs → hosted-logs-DP-ABU_M.mjs} +8 -8
- package/dist/{hosted-macos-DABm3ScO.mjs → hosted-macos-Aziw9T_9.mjs} +7 -6
- package/dist/{hosted-native-DbV2aUVw.mjs → hosted-native-BdAQi21M.mjs} +17 -14
- package/dist/{idle-shutdown-DYiMBn34.mjs → idle-shutdown-DdMqoSUB.mjs} +7 -7
- package/dist/{ios-DYUr9LGc.mjs → ios-BZ9dg2Fr.mjs} +8 -7
- package/dist/{ios-BWbHFZVz.mjs → ios-CXLIUxXJ.mjs} +180 -24
- package/dist/ios-CZuv6gRv.mjs +1112 -0
- package/dist/{ios-DCrkgXEM.mjs → ios-VGvNdsv2.mjs} +1 -1
- package/dist/{ios-device-CrW8aMb5.mjs → ios-device-B1B14xND.mjs} +1 -1
- package/dist/{ios-device-CJ_ZOGky.mjs → ios-device-BreZOpM0.mjs} +3 -3
- package/dist/ios-project-B9drt_aY.mjs +197 -0
- package/dist/{ios-state-By0XuLTQ.mjs → ios-state-CjrL2qv-.mjs} +1 -1
- package/dist/js-swap-C8icNYIY.mjs +432 -0
- package/dist/launch-DxH0THLP.mjs +745 -0
- package/dist/{react-native-ios-CSpIxexZ.mjs → launch-YrbqaIFj.mjs} +59 -612
- package/dist/{launch-verify-DCveSE6d.mjs → launch-verify-BzRdbuO1.mjs} +26 -7
- package/dist/{logs-Bao1HOMy.mjs → logs-DHaRNfg7.mjs} +11 -11
- package/dist/macos-C0iljhsN.mjs +2 -0
- package/dist/{macos-ciyBdTY5.mjs → macos-V_3Ui7g4.mjs} +42 -50
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +13 -10
- package/dist/{metro-DI2AjPF_.mjs → metro-D_j9sN-B.mjs} +18 -5
- package/dist/{metro-gateway-BxpJLIwh.mjs → metro-gateway-BBJldOdi.mjs} +2 -2
- package/dist/miss-reason-BPAzZS0r.mjs +238 -0
- package/dist/{named-ports-B4iWH4E-.mjs → named-ports-C2lvoPsb.mjs} +3 -3
- package/dist/native-android-lHzaew7r.mjs +226 -0
- package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
- package/dist/{native-runtime-BGxsbfny.mjs → native-runtime-BRmWL7ru.mjs} +9 -8
- package/dist/native-xcode-inputs-eutS19jU.mjs +307 -0
- package/dist/native-xcode-ios-DP3cHLwu.mjs +434 -0
- package/dist/{ndjson-LGZAMsqa.mjs → ndjson-GOnbyvso.mjs} +6 -6
- package/dist/offload-worker.d.mts +41 -7
- package/dist/offload-worker.mjs +409 -74
- package/dist/{ownership-EB0ySdGK.mjs → ownership-DXzMMSx6.mjs} +2 -2
- package/dist/{placement-log-Dxe34rJm.mjs → placement-log-reFbjqEr.mjs} +1 -1
- package/dist/plan-BDk2AeY_.mjs +260 -0
- package/dist/plan-placement-D_YYlE6N.mjs +73 -0
- package/dist/{ports-ByPc0_97.mjs → ports-jzvAJXXL.mjs} +3 -3
- package/dist/{prebuild-BKJ3wJI1.mjs → prebuild-Bw44QxVh.mjs} +4 -4
- package/dist/{preview-BbSottmO.mjs → preview-BaBJ72Al.mjs} +50 -32
- package/dist/project-B8_duAzW.mjs +1067 -0
- package/dist/project-plan-BPwbLwQu.mjs +10 -0
- package/dist/{pull-request-IHNdMnG8.mjs → pull-request-vOhLNmIb.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/react-native-android-chm1DMlA.mjs +921 -0
- package/dist/react-native-build-oAw6gQeW.mjs +239 -0
- package/dist/react-native-doctor-DYXoh-6I.mjs +78 -0
- package/dist/react-native-ios-SCTK_CT5.mjs +595 -0
- package/dist/{recordings-Bv8McZN4.mjs → recordings-Bk-VivUV.mjs} +1 -1
- package/dist/{reload-rAPdqeRR.mjs → reload-D34GkY78.mjs} +17 -13
- package/dist/remote-BU9UyhCJ.mjs +192 -0
- package/dist/{remote-cache-N3hAEaAL.mjs → remote-cache-Bsts6f6Y.mjs} +5 -5
- package/dist/result-BDoRk1k3.mjs +186 -0
- package/dist/{run-lAkle1-c.mjs → run-qvff78hv.mjs} +3 -3
- package/dist/{server-bare-CkIjnegq.mjs → server-bare-dWjAarki.mjs} +5 -5
- package/dist/server-command-7XIKlWtO.mjs +69 -0
- package/dist/{server-expo-n3tUi3Em.mjs → server-expo-CsYu2aKL.mjs} +107 -82
- package/dist/server-expo-DV43vep4.mjs +2 -0
- package/dist/{settings-CxgngUZk.mjs → settings-Bbztm4oV.mjs} +179 -129
- package/dist/{settings-2am7TSxp.mjs → settings-CT3E71-i.mjs} +6 -6
- package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
- package/dist/settings.schema.json +84 -0
- package/dist/simslim-ChMfe8rg.mjs +149 -0
- package/dist/{slot-launch-HV_KtPIw.mjs → slot-launch-B9hn96wd.mjs} +6 -6
- package/dist/{stage-BgaZJVZY.mjs → stage-BNKKdDNc.mjs} +6 -3
- package/dist/start-CbQCSnXQ.mjs +2 -0
- package/dist/{start-DtxthMfI.mjs → start-CdvcTaXr.mjs} +97 -68
- package/dist/{state-Tp4uImDS.mjs → state-Boo0IMJq.mjs} +1 -1
- package/dist/{state-D2KtnALG.mjs → state-DI84A-uu.mjs} +29 -10
- package/dist/{stats-8EJ5ivFT.mjs → stats-BIIDrjA8.mjs} +5 -5
- package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
- package/dist/{status-BOyp0CUl.mjs → status-DARMkc9q.mjs} +81 -293
- package/dist/status-watch-DvmI3SmN.mjs +296 -0
- package/dist/{stim-desktop-C65jk_q2.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
- package/dist/{stop-DRipAg-e.mjs → stop-CCZS-C9m.mjs} +2 -2
- package/dist/{stop-D0UIpZuh.mjs → stop-WQPQHLuy.mjs} +5 -5
- package/dist/{stop-zDlknFoz.mjs → stop-iNemHsJC.mjs} +21 -20
- package/dist/supervisor-run.d.mts +7 -2
- package/dist/supervisor-run.mjs +32 -20
- package/dist/{support-DsNaFg6D.mjs → support-CnE_SIjt.mjs} +17 -7
- package/dist/{support-CNqYkV0y.mjs → support-DCco5fut.mjs} +61 -8
- package/dist/{swiftpm-macos-aJzPAj1t.mjs → swiftpm-macos-afeNUExW.mjs} +5 -5
- package/dist/tailnet-CoJUb2tB.mjs +265 -0
- package/dist/toolchain-BIupIro1.mjs +2 -0
- package/dist/{toolchain-C3xSoyUl.mjs → toolchain-DqyDXs30.mjs} +206 -53
- package/dist/{trigger-CAhmG-4s.mjs → trigger-C0MWBi8O.mjs} +2 -2
- package/dist/trigger-SHLOWJ4O.mjs +2 -0
- package/dist/{warm-progress-pFLB2e6P.mjs → warm-progress-C3ASD6z5.mjs} +6 -6
- package/dist/{watchman-BL1IdOtq.mjs → watchman-CQl51YZu.mjs} +6 -6
- package/dist/{web-DbbrPUn0.mjs → web-B3eldHFH.mjs} +9 -13
- package/dist/web-BLXpOe6b.mjs +2 -0
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-CR9X86xJ.mjs → workspace-state-CSIFuuDa.mjs} +33 -33
- package/dist/{workspaces-Djb2gfi9.mjs → workspaces-D2xSHBDY.mjs} +1260 -1258
- package/dist/{worktree-BL4M1rhB.mjs → worktree-BxDqaTev.mjs} +84 -48
- package/dist/worktree-q7_OZNY0.mjs +2 -0
- package/package.json +8 -6
- package/shim/native-android.gradle +101 -0
- package/dist/android-BXc6BmEi.mjs +0 -3732
- package/dist/android-BvV1gGdN.mjs +0 -4
- package/dist/ios-ITYno9rO.mjs +0 -2241
- package/dist/macos-nIOATJmR.mjs +0 -2
- package/dist/metro-store-BAHFcJm6.mjs +0 -106
- package/dist/miss-reason-CjQCOKqq.mjs +0 -1743
- package/dist/plan-placement-BVY59qa8.mjs +0 -290
- package/dist/project-B5eQ1USs.mjs +0 -612
- package/dist/react-native-ios-BMh2i25I.mjs +0 -2
- package/dist/server-expo-DGsdUGX2.mjs +0 -2
- package/dist/start-D8NbxNBb.mjs +0 -2
- package/dist/trigger-CoalsMTV.mjs +0 -2
- package/dist/web-DFpFeZu5.mjs +0 -2
- package/dist/worktree-DV-A0LNL.mjs +0 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { E as upsertProject, d as getConfigDir, p as getProject } from "./config-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { o as runWatchman, r as parseWatchRoots } from "./watchman-
|
|
6
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
2
|
+
import { E as upsertProject, d as getConfigDir, p as getProject } from "./config-D0LhTY3S.mjs";
|
|
3
|
+
import { Et as repoRoot, xt as listWorktrees } from "./settings-Bbztm4oV.mjs";
|
|
4
|
+
import { d as projectRegistry } from "./project-B8_duAzW.mjs";
|
|
5
|
+
import { o as runWatchman, r as parseWatchRoots } from "./watchman-CQl51YZu.mjs";
|
|
6
|
+
import { o as compareStimVersions } from "./eas-session-ledger-DZlC-Fq3.mjs";
|
|
7
7
|
import { mkdirSync, readFileSync, realpathSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
9
9
|
//#region src/guide-status.ts
|
|
@@ -12,17 +12,17 @@ const DOCTOR_STALE_MS = 7 * DAY_MS;
|
|
|
12
12
|
const UPDATE_CHECK_INTERVAL_MS = DAY_MS;
|
|
13
13
|
const UPDATE_CHECK_TIMEOUT_MS = 2e3;
|
|
14
14
|
const LATEST_URL = "https://registry.npmjs.org/stim/latest";
|
|
15
|
-
|
|
16
|
-
function recordDoctorRun(projectRoot, platform, version, now = /* @__PURE__ */ new Date()) {
|
|
15
|
+
function recordDoctorRun(projectRoot, platform, version, now = /* @__PURE__ */ new Date(), platforms) {
|
|
17
16
|
const run = {
|
|
18
17
|
at: now.toISOString(),
|
|
19
18
|
version
|
|
20
19
|
};
|
|
21
20
|
try {
|
|
22
|
-
|
|
21
|
+
const targets = platforms ?? projectRegistry.selectDoctor(projectRoot, platform).platforms;
|
|
22
|
+
if (targets.length === 0) return;
|
|
23
23
|
upsertProject(projectRoot, (existing) => {
|
|
24
24
|
const doctorRuns = { ...existing.doctorRuns };
|
|
25
|
-
for (const target of
|
|
25
|
+
for (const target of targets) doctorRuns[target] = run;
|
|
26
26
|
return { doctorRuns };
|
|
27
27
|
});
|
|
28
28
|
} catch {}
|
|
@@ -102,12 +102,13 @@ function renderGuideStatus({ running, doctor, latest }) {
|
|
|
102
102
|
}
|
|
103
103
|
async function guideStatus({ projectRoot, running, now = /* @__PURE__ */ new Date(), fetch: fetchImpl = fetch }) {
|
|
104
104
|
const doctor = [];
|
|
105
|
-
if (projectRoot
|
|
105
|
+
if (projectRoot) {
|
|
106
|
+
const platforms = projectRegistry.selectDoctor(projectRoot).platforms;
|
|
106
107
|
let runs = null;
|
|
107
108
|
try {
|
|
108
109
|
runs = getProject(projectRoot)?.doctorRuns ?? {};
|
|
109
110
|
} catch {}
|
|
110
|
-
if (runs) for (const platform of
|
|
111
|
+
if (runs) for (const platform of platforms) {
|
|
111
112
|
const reason = doctorDueReason(runs[platform], running, now);
|
|
112
113
|
if (reason) doctor.push({
|
|
113
114
|
platform,
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { n as ownership_claim_exports
|
|
2
|
-
import { t as getExecutor } from "./exec-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { g as
|
|
6
|
-
import { f as resolveEasCliBin } from "./remote-cache-N3hAEaAL.mjs";
|
|
7
|
-
import { s as readInstalledEasCliVersion, v as easCliSupport, y as easCliUpgradeRemedy } from "./device-remote-B5GiUifk.mjs";
|
|
1
|
+
import { n as ownership_claim_exports } from "./process-identity-Biv3arCO.mjs";
|
|
2
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
3
|
+
import { g as releaseBuildLock, m as acquireBuildLock } from "./device-lease-DHOBXGgS.mjs";
|
|
4
|
+
import { f as resolveEasCliBin } from "./remote-cache-Bsts6f6Y.mjs";
|
|
5
|
+
import { g as easCliUpgradeRemedy, h as easCliSupport, s as readInstalledEasCliVersion } from "./device-remote-Bmg42063.mjs";
|
|
8
6
|
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
9
|
-
import { join } from "node:path";
|
|
10
7
|
import { createHash } from "node:crypto";
|
|
11
8
|
//#region src/engine/eas-build.ts
|
|
12
9
|
const MIN_EAS_CLI_BUILD_DOWNLOAD_VERSION = "18.9.0";
|
|
@@ -228,147 +225,4 @@ async function resolveEasDevelopmentBuild(args) {
|
|
|
228
225
|
}
|
|
229
226
|
}
|
|
230
227
|
//#endregion
|
|
231
|
-
|
|
232
|
-
async function reconcileSimSlim({ udid, profile, previouslyManaged = false, out = () => {}, spawn, timeoutMs = 72e4, cleanupMs = 1e4 }) {
|
|
233
|
-
if (!profile && !previouslyManaged) return {
|
|
234
|
-
managed: false,
|
|
235
|
-
profile: null
|
|
236
|
-
};
|
|
237
|
-
const action = profile ? "on" : "off";
|
|
238
|
-
const args = profile ? [
|
|
239
|
-
"on",
|
|
240
|
-
udid,
|
|
241
|
-
"--profile",
|
|
242
|
-
profile
|
|
243
|
-
] : ["off", udid];
|
|
244
|
-
const lines = [];
|
|
245
|
-
const onLine = (raw) => {
|
|
246
|
-
const line = stripAnsi(raw).trim();
|
|
247
|
-
if (!line) return;
|
|
248
|
-
lines.push(line);
|
|
249
|
-
if (lines.length > 20) lines.shift();
|
|
250
|
-
out(`SimSlim: ${line}`);
|
|
251
|
-
};
|
|
252
|
-
const stdout = createLineReader(onLine);
|
|
253
|
-
const stderr = createLineReader(onLine);
|
|
254
|
-
const root = join(getConfigDir(), "simslim-locks", `${encodeURIComponent(udid.toLowerCase())}.lock`);
|
|
255
|
-
const label = `SimSlim for ${udid}`;
|
|
256
|
-
const attempt = (0, ownership_claim_exports.tryAcquireClaim)({
|
|
257
|
-
root,
|
|
258
|
-
mode: "exclusive",
|
|
259
|
-
label
|
|
260
|
-
});
|
|
261
|
-
if (attempt.pending) (0, ownership_claim_exports.releaseClaim)(attempt.pending);
|
|
262
|
-
const claim = attempt.acquired;
|
|
263
|
-
if (!claim) throw new ownership_claim_exports.ClaimRefusedError({
|
|
264
|
-
root,
|
|
265
|
-
claimPath: attempt.held?.path ?? root,
|
|
266
|
-
label,
|
|
267
|
-
reason: "another SimSlim operation is still using this simulator"
|
|
268
|
-
});
|
|
269
|
-
let child;
|
|
270
|
-
let result;
|
|
271
|
-
let identity;
|
|
272
|
-
let cancellation;
|
|
273
|
-
const stopGroup = () => {
|
|
274
|
-
if (child?.pid !== void 0 && identity && (0, process_identity_exports.inspectProcessIdentity)(identity) === "same") try {
|
|
275
|
-
process.kill(-child.pid, "SIGKILL");
|
|
276
|
-
} catch {}
|
|
277
|
-
};
|
|
278
|
-
const cancel = (signal) => {
|
|
279
|
-
cancellation ??= signal;
|
|
280
|
-
stopGroup();
|
|
281
|
-
};
|
|
282
|
-
const onInterrupt = () => cancel("SIGINT");
|
|
283
|
-
const onTerminate = () => cancel("SIGTERM");
|
|
284
|
-
const groupAlive = () => child?.pid !== void 0 && (0, ownership_claim_exports.processGroupAlive)(child.pid);
|
|
285
|
-
const settled = () => result !== void 0 && !groupAlive();
|
|
286
|
-
const waitUntil = async (deadline, cancellable = false) => {
|
|
287
|
-
while (!settled() && Date.now() < deadline) {
|
|
288
|
-
if (cancellable && cancellation) break;
|
|
289
|
-
await new Promise((resolve) => setTimeout(resolve, Math.min(50, deadline - Date.now())));
|
|
290
|
-
}
|
|
291
|
-
return settled();
|
|
292
|
-
};
|
|
293
|
-
process.on("SIGINT", onInterrupt);
|
|
294
|
-
process.on("SIGTERM", onTerminate);
|
|
295
|
-
process.on("exit", stopGroup);
|
|
296
|
-
try {
|
|
297
|
-
(0, ownership_claim_exports.markClaimChildPending)(claim);
|
|
298
|
-
try {
|
|
299
|
-
child = (spawn ?? ((cmd, childArgs, opts) => getExecutor().spawn(cmd, childArgs, opts)))("simslim", args, {
|
|
300
|
-
stdio: [
|
|
301
|
-
"ignore",
|
|
302
|
-
"pipe",
|
|
303
|
-
"pipe"
|
|
304
|
-
],
|
|
305
|
-
detached: true
|
|
306
|
-
});
|
|
307
|
-
} catch (error) {
|
|
308
|
-
throw simslimLaunchError(error);
|
|
309
|
-
}
|
|
310
|
-
child.stdout?.on("data", (chunk) => stdout.push(chunk));
|
|
311
|
-
child.stderr?.on("data", (chunk) => stderr.push(chunk));
|
|
312
|
-
waitForChild(child).then((value) => {
|
|
313
|
-
result = value;
|
|
314
|
-
});
|
|
315
|
-
if (child.pid !== void 0) {
|
|
316
|
-
const captured = (0, process_identity_exports.captureProcessIdentity)(child.pid);
|
|
317
|
-
if (captured.ok) {
|
|
318
|
-
identity = {
|
|
319
|
-
pid: child.pid,
|
|
320
|
-
processToken: captured.token
|
|
321
|
-
};
|
|
322
|
-
try {
|
|
323
|
-
(0, ownership_claim_exports.setClaimChild)(claim, identity);
|
|
324
|
-
} catch {}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
const completed = await waitUntil(Date.now() + timeoutMs, true);
|
|
328
|
-
if (cancellation || !completed) {
|
|
329
|
-
stopGroup();
|
|
330
|
-
const stopped = await waitUntil(Date.now() + cleanupMs);
|
|
331
|
-
const detail = lines.length ? ` ${lines.join(" | ")}` : "";
|
|
332
|
-
const recovery = stopped ? "Its process group has stopped. Retry stim ios to reconcile the retained simulator settings." : `Its process group could not be confirmed stopped. The claim remains at ${claim.path}. Inspect the SimSlim process group ${child.pid ?? "unknown"} before retrying. Only when nothing is using it, remove the claim: ${(0, ownership_claim_exports.claimRemoveCommand)(claim.path)}`;
|
|
333
|
-
const message = `SimSlim ${action} ${cancellation ? `interrupted by ${cancellation}` : `exceeded ${Math.round(timeoutMs / 1e3)}s`}. ${recovery}${detail}`;
|
|
334
|
-
if (cancellation) out(message);
|
|
335
|
-
throw Object.assign(new Error(message), { code: cancellation ? "EINTR" : "ETIMEDOUT" });
|
|
336
|
-
}
|
|
337
|
-
} finally {
|
|
338
|
-
if (!child || settled()) (0, ownership_claim_exports.releaseClaim)(claim);
|
|
339
|
-
else {
|
|
340
|
-
child.stdout?.destroy?.();
|
|
341
|
-
child.stderr?.destroy?.();
|
|
342
|
-
child.unref();
|
|
343
|
-
}
|
|
344
|
-
process.off("SIGINT", onInterrupt);
|
|
345
|
-
process.off("SIGTERM", onTerminate);
|
|
346
|
-
process.off("exit", stopGroup);
|
|
347
|
-
if (cancellation) process.exit(cancellation === "SIGINT" ? 130 : 143);
|
|
348
|
-
}
|
|
349
|
-
stdout.flush();
|
|
350
|
-
stderr.flush();
|
|
351
|
-
if (result?.error) throw simslimLaunchError(result.error);
|
|
352
|
-
if (result?.code !== 0) {
|
|
353
|
-
const detail = lines.length ? ` ${lines.join(" | ")}` : "";
|
|
354
|
-
throw new Error(`SimSlim ${action} failed with exit code ${result?.code ?? "unknown"}.${detail}`);
|
|
355
|
-
}
|
|
356
|
-
return {
|
|
357
|
-
managed: Boolean(profile),
|
|
358
|
-
profile: profile ?? null
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
function simslimLaunchError(error) {
|
|
362
|
-
const cause = error;
|
|
363
|
-
if (cause?.code === "ENOENT") return new Error("SimSlim is configured but the `simslim` command is not installed. Run `brew install mobai-app/tap/simslim`.", { cause });
|
|
364
|
-
return new Error(`Could not start SimSlim: ${String(cause?.message || cause)}`, { cause });
|
|
365
|
-
}
|
|
366
|
-
function simslimIsOnPath() {
|
|
367
|
-
try {
|
|
368
|
-
return Boolean(getExecutor().findExecutable("simslim"));
|
|
369
|
-
} catch {
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
//#endregion
|
|
374
|
-
export { isEasBuildFailure as a, easDeviceBuildRemedy as i, simslimIsOnPath as n, planEasDevelopmentBuild as o, MIN_EAS_CLI_BUILD_DOWNLOAD_VERSION as r, resolveEasDevelopmentBuild as s, reconcileSimSlim as t };
|
|
228
|
+
export { resolveEasDevelopmentBuild as a, planEasDevelopmentBuild as i, easDeviceBuildRemedy as n, isEasBuildFailure as r, MIN_EAS_CLI_BUILD_DOWNLOAD_VERSION as t };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
2
|
+
import { D as withDirLock } from "./workspace-state-CSIFuuDa.mjs";
|
|
3
|
+
import { accessSync, constants, existsSync, mkdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { delimiter, dirname, join, resolve } from "node:path";
|
|
5
|
+
import { easMachineStateRoot, easMachineStateRoot as easMachineStateRoot$1, easSessionLedgerFile, easSessionLedgerLock, readEasSessionLedger, readEasSessionLedger as readEasSessionLedger$1, validEasSessionClaim } from "@stim-cli/core/state";
|
|
4
6
|
//#region src/diagnostics/stim-installations.ts
|
|
5
7
|
const VERSION_OUTPUT_LIMIT = 4096;
|
|
6
8
|
function parsedVersion(version) {
|
|
@@ -149,4 +151,55 @@ async function inspectStimVersions(runningVersion, { pathValue = process.env.PAT
|
|
|
149
151
|
return analyzeStimVersions(runningVersion, canonicalPath(runningPath), installations);
|
|
150
152
|
}
|
|
151
153
|
//#endregion
|
|
152
|
-
|
|
154
|
+
//#region src/engine/eas-machine-root-guard-env.ts
|
|
155
|
+
const EAS_TEST_GUARD_ROOT_ENV = "STIM_TEST_GUARD_REAL_EAS_ROOT";
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/engine/eas-session-ledger.ts
|
|
158
|
+
function assertEasMachineRootWritable(root) {
|
|
159
|
+
const guardedRoot = process.env[EAS_TEST_GUARD_ROOT_ENV];
|
|
160
|
+
if (!guardedRoot || resolve(root) !== resolve(guardedRoot)) return;
|
|
161
|
+
throw new Error(`Refusing to write the real EAS machine root ${root} from a test process. Pass a temporary ledgerRoot, machineRoot, or easLedgerRoot, or point HOME (and USERPROFILE on Windows) at a temporary directory.`);
|
|
162
|
+
}
|
|
163
|
+
function writeLedger(root, ledger) {
|
|
164
|
+
mkdirSync(root, { recursive: true });
|
|
165
|
+
const file = easSessionLedgerFile(root);
|
|
166
|
+
const tmp = `${file}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
167
|
+
writeFileSync(tmp, `${JSON.stringify(ledger, null, 2)}\n`);
|
|
168
|
+
try {
|
|
169
|
+
renameSync(tmp, file);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
rmSync(tmp, { force: true });
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function recordEasSessionClaim(claim, root = easMachineStateRoot()) {
|
|
176
|
+
assertEasMachineRootWritable(root);
|
|
177
|
+
const normalized = validEasSessionClaim(claim.sessionId, claim);
|
|
178
|
+
if (!normalized) throw new Error(`Invalid EAS session claim for ${claim.sessionId}.`);
|
|
179
|
+
withDirLock(easSessionLedgerLock(root), () => {
|
|
180
|
+
const current = readEasSessionLedger(root);
|
|
181
|
+
if (!current.safe) throw new Error(current.notice ?? "EAS ownership ledger is unreadable.");
|
|
182
|
+
current.claims.set(normalized.sessionId, normalized);
|
|
183
|
+
writeLedger(root, {
|
|
184
|
+
version: 1,
|
|
185
|
+
claims: Object.fromEntries(current.claims)
|
|
186
|
+
});
|
|
187
|
+
}, { ensureParent: () => mkdirSync(dirname(easSessionLedgerLock(root)), { recursive: true }) });
|
|
188
|
+
}
|
|
189
|
+
function removeEasSessionClaim(sessionId, root = easMachineStateRoot()) {
|
|
190
|
+
const file = easSessionLedgerFile(root);
|
|
191
|
+
if (!existsSync(file)) return false;
|
|
192
|
+
assertEasMachineRootWritable(root);
|
|
193
|
+
return withDirLock(easSessionLedgerLock(root), () => {
|
|
194
|
+
const current = readEasSessionLedger(root);
|
|
195
|
+
if (!current.safe) return false;
|
|
196
|
+
if (!current.claims.delete(sessionId)) return false;
|
|
197
|
+
writeLedger(root, {
|
|
198
|
+
version: 1,
|
|
199
|
+
claims: Object.fromEntries(current.claims)
|
|
200
|
+
});
|
|
201
|
+
return true;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
export { removeEasSessionClaim as a, recordEasSessionClaim as i, easMachineStateRoot$1 as n, compareStimVersions as o, readEasSessionLedger$1 as r, inspectStimVersions as s, assertEasMachineRootWritable as t };
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { r as deviceConsoleLevel } from "./ios-device-
|
|
10
|
-
import { n as parseLogcatLine, t as androidClockOffset } from "./android-
|
|
1
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
2
|
+
import { R as deviceSlotKey, p as getProject, z as deviceSlotPlatforms } from "./config-D0LhTY3S.mjs";
|
|
3
|
+
import { a as parseLease, n as fileLeaseIo, t as deviceLeasePath } from "./device-lease-DHOBXGgS.mjs";
|
|
4
|
+
import { D as withDirLock, r as readWorkspaceState$1 } from "./workspace-state-CSIFuuDa.mjs";
|
|
5
|
+
import { v as launchErrorPreview } from "./command-output-BjPN99ZB.mjs";
|
|
6
|
+
import { F as readWorkspaceLaunches } from "./project-B8_duAzW.mjs";
|
|
7
|
+
import { o as androidHome, u as androidToolCwd } from "./android-BsYNR81W.mjs";
|
|
8
|
+
import { u as resolveProjectMetro } from "./metro-D_j9sN-B.mjs";
|
|
9
|
+
import { r as deviceConsoleLevel } from "./ios-device-B1B14xND.mjs";
|
|
10
|
+
import { n as parseLogcatLine, t as androidClockOffset } from "./android-CK3fpEyZ.mjs";
|
|
11
11
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
12
12
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
13
13
|
import { NATIVE_CRASH_LOG_PREFIX, attachExpoErrorContext, readLogRecords, readLogTimeline } from "@stim-cli/core/state";
|
|
14
|
-
import { homedir } from "node:os";
|
|
15
14
|
import { createHash, randomUUID } from "node:crypto";
|
|
15
|
+
import { homedir } from "node:os";
|
|
16
16
|
//#region src/diagnostics/diagnostic-store.ts
|
|
17
17
|
/** Publishes an immutable diagnostic snapshot atomically; existing evidence wins. */
|
|
18
18
|
function writeDiagnosticOnce(path, content) {
|
|
@@ -617,7 +617,12 @@ async function errorDiagnostics(input, { root, logsDir, port, allowRequest = fal
|
|
|
617
617
|
"bundle_response_started",
|
|
618
618
|
"bundle_response_finished",
|
|
619
619
|
"bundle_response_failed"
|
|
620
|
-
].includes(String(event.event)) || [
|
|
620
|
+
].includes(String(event.event)) || [
|
|
621
|
+
"expo_stdout",
|
|
622
|
+
"expo_stderr",
|
|
623
|
+
"command_stdout",
|
|
624
|
+
"command_stderr"
|
|
625
|
+
].includes(String(event.event)) && /\bBundl(?:ing|ed)\b/.test(event.msg ?? "")) && Number(event.ts) > Number(record.ts) && (!event.platform || !record.platform || event.platform === record.platform))) {
|
|
621
626
|
rendered[index] = {
|
|
622
627
|
...record,
|
|
623
628
|
symbolicationNote: "Metro rebuilt after this error; captured coordinates retained rather than mapping against a different bundle."
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
3
|
+
import { ANDROID_COMPILER_CACHE_CHOICES, ANDROID_PCH_CHOICES } from "@stim-cli/core/state";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { METRO_NAMED_CACHE_LAYOUT, metroCacheRoot, registerCache, sharedStoreRoot, tagSharedStore } from "@stim-cli/core";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
//#region src/optimizations.ts
|
|
8
|
+
function compilerCacheFallbackMessage({ fallback, compilerCache, file = null }) {
|
|
9
|
+
const origin = fallback.fromEnvironment ? "the environment" : file;
|
|
10
|
+
const backend = compilerCache === "none" ? "Android builds use no compiler cache, because optimizations.android.compilerCache is \"none\"." : "Android builds fall back to ccache when it is available.";
|
|
11
|
+
return `${fallback.key}${origin ? ` in ${origin}` : ""} ${fallback.reason}. ${backend}`;
|
|
12
|
+
}
|
|
13
|
+
function optimizationBuildProfile(platform, options) {
|
|
14
|
+
const selected = platform === "ios" ? {
|
|
15
|
+
...options.ios,
|
|
16
|
+
swiftCompilationCache: options.ios.swiftCompilationCache ?? false
|
|
17
|
+
} : { pch: options.android.pch };
|
|
18
|
+
const defaults = platform === "ios" ? {
|
|
19
|
+
compilationCache: true,
|
|
20
|
+
swiftCompilationCache: false,
|
|
21
|
+
prefixMapping: true
|
|
22
|
+
} : { pch: "auto" };
|
|
23
|
+
if (JSON.stringify(selected) === JSON.stringify(defaults)) return void 0;
|
|
24
|
+
return `opt-${createHash("sha256").update(JSON.stringify(selected)).digest("hex").slice(0, 16)}`;
|
|
25
|
+
}
|
|
26
|
+
function resolveOptimizations(settings = {}, env = process.env) {
|
|
27
|
+
function choice(path, choices, fallback) {
|
|
28
|
+
const raw = optimizationValue(settings, path);
|
|
29
|
+
if (raw === void 0) return fallback;
|
|
30
|
+
if (typeof raw !== "string" || !choices.includes(raw)) throw new Error(`Invalid optimizations.${path}. Expected ${choices.join(", ")}.`);
|
|
31
|
+
return raw;
|
|
32
|
+
}
|
|
33
|
+
const compiler = choice("android.compilerCache", ANDROID_COMPILER_CACHE_CHOICES, "auto");
|
|
34
|
+
const fromEnvironment = Boolean(env.STIM_ANDROID_CAS_TOOLCHAIN);
|
|
35
|
+
const manifest = env.STIM_ANDROID_CAS_TOOLCHAIN || optimizationValue(settings, "android.casToolchain");
|
|
36
|
+
let fallback = null;
|
|
37
|
+
let toolchain = null;
|
|
38
|
+
if (manifest !== void 0) {
|
|
39
|
+
if (typeof manifest === "string" && isAbsolute(manifest) && !/[\r\n\0]/.test(manifest)) toolchain = manifest;
|
|
40
|
+
else fallback = {
|
|
41
|
+
key: fromEnvironment ? "STIM_ANDROID_CAS_TOOLCHAIN" : "optimizations.android.casToolchain",
|
|
42
|
+
reason: `is ${JSON.stringify(manifest)}, which is not an absolute path to a toolchain JSON manifest`,
|
|
43
|
+
fromEnvironment,
|
|
44
|
+
manifest: null
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
let compilerCache = compiler === "auto" ? toolchain ? "cas" : "ccache" : compiler;
|
|
48
|
+
if (compilerCache === "cas" && !toolchain) {
|
|
49
|
+
fallback ??= {
|
|
50
|
+
key: "optimizations.android.compilerCache",
|
|
51
|
+
reason: "is \"cas\", but no optimizations.android.casToolchain or STIM_ANDROID_CAS_TOOLCHAIN names the toolchain manifest",
|
|
52
|
+
fromEnvironment: false,
|
|
53
|
+
manifest: null
|
|
54
|
+
};
|
|
55
|
+
compilerCache = "ccache";
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
buildCache: optimizationBoolean(settings, "buildCache"),
|
|
59
|
+
remoteBuildCache: optimizationBoolean(settings, "remoteBuildCache"),
|
|
60
|
+
releaseBundleSwap: optimizationBoolean(settings, "releaseBundleSwap"),
|
|
61
|
+
metroSharedCache: optimizationBoolean(settings, "metroSharedCache"),
|
|
62
|
+
metroWarmup: optimizationBoolean(settings, "metroWarmup"),
|
|
63
|
+
ios: {
|
|
64
|
+
compilationCache: optimizationBoolean(settings, "ios.compilationCache"),
|
|
65
|
+
swiftCompilationCache: optimizationValue(settings, "ios.swiftCompilationCache") === void 0 ? null : optimizationBoolean(settings, "ios.swiftCompilationCache"),
|
|
66
|
+
prefixMapping: optimizationBoolean(settings, "ios.prefixMapping")
|
|
67
|
+
},
|
|
68
|
+
android: {
|
|
69
|
+
compilerCache,
|
|
70
|
+
casToolchain: toolchain,
|
|
71
|
+
compilerCacheFallback: fallback,
|
|
72
|
+
pch: choice("android.pch", ANDROID_PCH_CHOICES, "auto"),
|
|
73
|
+
gradleBuildCache: optimizationBoolean(settings, "android.gradleBuildCache"),
|
|
74
|
+
targetAbiOnly: optimizationBoolean(settings, "android.targetAbiOnly")
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function artifactCachePolicy(options, reuse, release) {
|
|
79
|
+
return {
|
|
80
|
+
read: reuse && options.buildCache && (!release || options.releaseBundleSwap),
|
|
81
|
+
write: options.buildCache,
|
|
82
|
+
remote: options.buildCache && options.remoteBuildCache
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function optimizationValue(settings, path) {
|
|
86
|
+
let node = settings;
|
|
87
|
+
for (const key of ["optimizations", ...path.split(".")]) {
|
|
88
|
+
if (node === void 0) return void 0;
|
|
89
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) throw new Error("Invalid optimizations setting. Expected nested objects.");
|
|
90
|
+
node = node[key];
|
|
91
|
+
}
|
|
92
|
+
return node;
|
|
93
|
+
}
|
|
94
|
+
function optimizationBoolean(settings, path, fallback = true) {
|
|
95
|
+
const raw = optimizationValue(settings, path);
|
|
96
|
+
if (raw === void 0) return fallback;
|
|
97
|
+
if (typeof raw !== "boolean") throw new Error(`Invalid optimizations.${path}. Expected true or false.`);
|
|
98
|
+
return raw;
|
|
99
|
+
}
|
|
100
|
+
function resolveMetroSharedCache(settings) {
|
|
101
|
+
return optimizationBoolean(settings, "metroSharedCache");
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/supervisor/metro-store.ts
|
|
105
|
+
function metroStoreName(root) {
|
|
106
|
+
try {
|
|
107
|
+
const name = JSON.parse(readFileSync(join(root, "package.json"), "utf-8"))?.name;
|
|
108
|
+
if (typeof name === "string" && name.trim() !== "") return name;
|
|
109
|
+
} catch {}
|
|
110
|
+
return "app";
|
|
111
|
+
}
|
|
112
|
+
function metroStoreRoot(root) {
|
|
113
|
+
return metroCacheRoot(metroStoreName(root));
|
|
114
|
+
}
|
|
115
|
+
function registerMetroStore(storeRoot) {
|
|
116
|
+
const parent = resolve(metroCacheRoot());
|
|
117
|
+
const dir = resolve(storeRoot);
|
|
118
|
+
registerCache({
|
|
119
|
+
dir,
|
|
120
|
+
name: "Metro transform cache",
|
|
121
|
+
prune: "entries",
|
|
122
|
+
entriesDepth: 2,
|
|
123
|
+
layout: METRO_NAMED_CACHE_LAYOUT,
|
|
124
|
+
note: "shared Metro transforms, installed by stim start; no eviction of its own",
|
|
125
|
+
replaces: dir === parent ? [] : [{
|
|
126
|
+
dir: parent,
|
|
127
|
+
name: "Metro transform cache",
|
|
128
|
+
prune: "entries",
|
|
129
|
+
entriesDepth: 2,
|
|
130
|
+
layout: null
|
|
131
|
+
}]
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function hasStoreAt(stores, storeRoot) {
|
|
135
|
+
if (!Array.isArray(stores)) return false;
|
|
136
|
+
return stores.some((s) => sharedStoreRoot(s) === storeRoot);
|
|
137
|
+
}
|
|
138
|
+
function appendCacheStore(config, { storeRoot, FileStore }) {
|
|
139
|
+
if (!config || typeof config !== "object") return {
|
|
140
|
+
added: false,
|
|
141
|
+
storeRoot,
|
|
142
|
+
reason: "no config to add it to"
|
|
143
|
+
};
|
|
144
|
+
const stores = config.cacheStores;
|
|
145
|
+
if (typeof stores === "function") {
|
|
146
|
+
const original = stores;
|
|
147
|
+
config.cacheStores = (cache) => {
|
|
148
|
+
const resolved = original(cache);
|
|
149
|
+
return (Array.isArray(resolved) ? resolved : []).concat([tagSharedStore(new FileStore({ root: storeRoot }), storeRoot)]);
|
|
150
|
+
};
|
|
151
|
+
return {
|
|
152
|
+
added: true,
|
|
153
|
+
storeRoot
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
if (hasStoreAt(stores, storeRoot)) return {
|
|
157
|
+
added: false,
|
|
158
|
+
storeRoot,
|
|
159
|
+
reason: "a store already points at it"
|
|
160
|
+
};
|
|
161
|
+
config.cacheStores = [...Array.isArray(stores) ? stores : [], tagSharedStore(new FileStore({ root: storeRoot }), storeRoot)];
|
|
162
|
+
return {
|
|
163
|
+
added: true,
|
|
164
|
+
storeRoot
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const EXPO_ADAPTER_FILE = "expo-metro-config.cjs";
|
|
168
|
+
function expoMetroConfigPath(fromUrl = import.meta.url) {
|
|
169
|
+
const here = dirname(fileURLToPath(fromUrl));
|
|
170
|
+
for (const rel of ["../shim", "../../shim"]) {
|
|
171
|
+
const candidate = resolve(here, rel, EXPO_ADAPTER_FILE);
|
|
172
|
+
if (existsSync(candidate)) return candidate;
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
const STORE_OK_PREFIX = "stim-metro-store: sharing Metro transforms through ";
|
|
177
|
+
function metroStoreConfirmedRoot(line) {
|
|
178
|
+
if (!line.startsWith(STORE_OK_PREFIX)) return null;
|
|
179
|
+
const root = line.slice(51).trim();
|
|
180
|
+
return root === "" ? null : root;
|
|
181
|
+
}
|
|
182
|
+
function expoMetroStoreEnv({ root, storeRoot, adapterPath, existingOverride }) {
|
|
183
|
+
return {
|
|
184
|
+
EXPO_OVERRIDE_METRO_CONFIG: adapterPath,
|
|
185
|
+
STIM_METRO_STORE: storeRoot,
|
|
186
|
+
STIM_PROJECT_ROOT: root,
|
|
187
|
+
...existingOverride ? { STIM_EXPO_METRO_CONFIG: existingOverride } : {}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/supervisor/errors.ts
|
|
192
|
+
function supervisorError(code, message, remedy) {
|
|
193
|
+
const err = new Error(message);
|
|
194
|
+
err.code = code;
|
|
195
|
+
if (remedy) err.remedy = remedy;
|
|
196
|
+
return err;
|
|
197
|
+
}
|
|
198
|
+
function describeError(err) {
|
|
199
|
+
if (!err) return "unknown error";
|
|
200
|
+
const e = err;
|
|
201
|
+
const message = e.message || String(err);
|
|
202
|
+
return `${e.code ? `${e.code}: ` : ""}${message}${e.remedy ? ` Remedy: ${e.remedy}` : ""}`;
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
export { expoMetroStoreEnv as a, registerMetroStore as c, optimizationBuildProfile as d, resolveMetroSharedCache as f, expoMetroConfigPath as i, artifactCachePolicy as l, supervisorError as n, metroStoreConfirmedRoot as o, resolveOptimizations as p, appendCacheStore as r, metroStoreRoot as s, describeError as t, compilerCacheFallbackMessage as u };
|
|
@@ -12,6 +12,28 @@ function nameTimeout(error, command, timeoutMs) {
|
|
|
12
12
|
if (error?.code === "ETIMEDOUT" && error instanceof Error) error.message = `Command timed out after ${timeoutMs}ms: ${command}`;
|
|
13
13
|
return error;
|
|
14
14
|
}
|
|
15
|
+
const WINDOWS_BATCH_FILE = /\.(?:bat|cmd)$/i;
|
|
16
|
+
const BATCH_UNSAFE_ARGUMENT = /["\r\n]/;
|
|
17
|
+
function isUnsafeBatchSpawn(target, args, platform = process.platform) {
|
|
18
|
+
return platform === "win32" && WINDOWS_BATCH_FILE.test(target) && args.some((arg) => BATCH_UNSAFE_ARGUMENT.test(arg));
|
|
19
|
+
}
|
|
20
|
+
function refuseUnsafeBatchArguments(file, args) {
|
|
21
|
+
if (process.platform !== "win32") return;
|
|
22
|
+
const target = which.sync(file, { nothrow: true }) ?? file;
|
|
23
|
+
if (isUnsafeBatchSpawn(target, args)) throw new Error(`Refusing to run ${basename(target)}: an argument contains a character cmd.exe could misinterpret (a double quote or a line break).`);
|
|
24
|
+
}
|
|
25
|
+
function redactError(error, values) {
|
|
26
|
+
const secrets = values?.filter(Boolean) ?? [];
|
|
27
|
+
if (secrets.length === 0 || !error || typeof error !== "object") return error;
|
|
28
|
+
const scrub = (text) => secrets.reduce((acc, secret) => acc.split(secret).join("***"), text);
|
|
29
|
+
const fields = error;
|
|
30
|
+
for (const key of Object.getOwnPropertyNames(error)) {
|
|
31
|
+
const value = fields[key];
|
|
32
|
+
if (typeof value === "string") fields[key] = scrub(value);
|
|
33
|
+
else if (Array.isArray(value)) fields[key] = value.map((item) => typeof item === "string" ? scrub(item) : item);
|
|
34
|
+
}
|
|
35
|
+
return error;
|
|
36
|
+
}
|
|
15
37
|
const defaultExecutor = {
|
|
16
38
|
run(cmd, { timeoutMs, killSignal, cwd, env } = {}) {
|
|
17
39
|
const opts = {
|
|
@@ -36,16 +58,17 @@ const defaultExecutor = {
|
|
|
36
58
|
throw nameTimeout(error, cmd, timeoutMs);
|
|
37
59
|
}
|
|
38
60
|
},
|
|
39
|
-
runFile(file, args = [], { timeoutMs, killSignal, cwd, env, omitEnv, input, untrimmed, rejectStderr } = {}) {
|
|
61
|
+
runFile(file, args = [], { timeoutMs, killSignal, cwd, env, omitEnv, input, untrimmed, rejectStderr, detachedSilent, redact } = {}) {
|
|
40
62
|
const opts = {
|
|
41
63
|
encoding: "utf-8",
|
|
42
|
-
stdio: [
|
|
64
|
+
stdio: detachedSilent ? "ignore" : [
|
|
43
65
|
"pipe",
|
|
44
66
|
"pipe",
|
|
45
67
|
"pipe"
|
|
46
68
|
],
|
|
47
69
|
maxBuffer: MAX_BUFFER
|
|
48
70
|
};
|
|
71
|
+
if (detachedSilent) opts.detached = true;
|
|
49
72
|
if (timeoutMs) opts.timeout = timeoutMs;
|
|
50
73
|
if (killSignal) opts.killSignal = killSignal;
|
|
51
74
|
if (cwd) opts.cwd = cwd;
|
|
@@ -58,19 +81,25 @@ const defaultExecutor = {
|
|
|
58
81
|
for (const key of omitEnv ?? []) delete childEnv[key];
|
|
59
82
|
opts.env = childEnv;
|
|
60
83
|
}
|
|
84
|
+
refuseUnsafeBatchArguments(file, args);
|
|
61
85
|
const result = spawn.sync(file, args, opts);
|
|
62
|
-
if (result.error) throw nameTimeout(Object.assign(result.error, result), [file, ...args].join(" "), timeoutMs);
|
|
86
|
+
if (result.error) throw redactError(nameTimeout(Object.assign(result.error, result), [file, ...args].join(" "), timeoutMs), redact);
|
|
63
87
|
if (result.status !== 0 || rejectStderr && String(result.stderr ?? "").trim()) {
|
|
64
88
|
const stderr = String(result.stderr ?? "");
|
|
65
89
|
const message = `Command failed: ${[file, ...args].join(" ")}${stderr ? `\n${stderr}` : ""}`;
|
|
66
|
-
throw Object.assign(new Error(message), result);
|
|
90
|
+
throw redactError(Object.assign(new Error(message), result), redact);
|
|
67
91
|
}
|
|
92
|
+
if (detachedSilent) return "";
|
|
68
93
|
return untrimmed ? String(result.stdout) : String(result.stdout).trim();
|
|
69
94
|
},
|
|
70
|
-
runFileAsync(file, args = [], { timeoutMs, killSignal, cwd, env, omitEnv, rejectStderr, onSpawn } = {}) {
|
|
95
|
+
runFileAsync(file, args = [], { timeoutMs, killSignal, cwd, env, omitEnv, rejectStderr, onSpawn, detachedSilent, redact } = {}) {
|
|
71
96
|
const command = [file, ...args].join(" ");
|
|
72
97
|
return new Promise((resolve, reject) => {
|
|
73
|
-
|
|
98
|
+
refuseUnsafeBatchArguments(file, args);
|
|
99
|
+
const opts = detachedSilent ? {
|
|
100
|
+
stdio: "ignore",
|
|
101
|
+
detached: true
|
|
102
|
+
} : { stdio: [
|
|
74
103
|
"ignore",
|
|
75
104
|
"pipe",
|
|
76
105
|
"pipe"
|
|
@@ -103,7 +132,7 @@ const defaultExecutor = {
|
|
|
103
132
|
child.stderr?.on("data", (chunk) => stderr.push(chunk));
|
|
104
133
|
child.on("error", (error) => {
|
|
105
134
|
clearTimeout(timer);
|
|
106
|
-
reject(error);
|
|
135
|
+
reject(redactError(error, redact));
|
|
107
136
|
});
|
|
108
137
|
child.on("close", (status, signal) => {
|
|
109
138
|
clearTimeout(timer);
|
|
@@ -115,9 +144,9 @@ const defaultExecutor = {
|
|
|
115
144
|
stdout: out,
|
|
116
145
|
stderr: err
|
|
117
146
|
};
|
|
118
|
-
if (timedOut) reject(nameTimeout(Object.assign(new Error(command), result, { code: "ETIMEDOUT" }), command, timeoutMs));
|
|
119
|
-
else if (status !== 0 || rejectStderr && err.trim()) reject(Object.assign(/* @__PURE__ */ new Error(`Command failed: ${command}${err ? `\n${err}` : ""}`), result));
|
|
120
|
-
else resolve(out.trim());
|
|
147
|
+
if (timedOut) reject(redactError(nameTimeout(Object.assign(new Error(command), result, { code: "ETIMEDOUT" }), command, timeoutMs), redact));
|
|
148
|
+
else if (status !== 0 || rejectStderr && err.trim()) reject(redactError(Object.assign(/* @__PURE__ */ new Error(`Command failed: ${command}${err ? `\n${err}` : ""}`), result), redact));
|
|
149
|
+
else resolve(detachedSilent ? "" : out.trim());
|
|
121
150
|
});
|
|
122
151
|
});
|
|
123
152
|
},
|
|
@@ -136,6 +165,7 @@ const defaultExecutor = {
|
|
|
136
165
|
}
|
|
137
166
|
},
|
|
138
167
|
spawn(cmd, args = [], opts = {}) {
|
|
168
|
+
refuseUnsafeBatchArguments(cmd, args);
|
|
139
169
|
return spawn(cmd, args, opts);
|
|
140
170
|
},
|
|
141
171
|
findExecutable(name) {
|