stim 1.14.0 → 1.15.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 +2 -0
- package/dist/{activity-CYVDcrt3.mjs → activity-B2-kb7k0.mjs} +281 -41
- package/dist/{android-XpvCrV7q.mjs → android-CYmq0jNi.mjs} +2 -2
- package/dist/{android-LbPFRWVL.mjs → android-Cu_L4RpL.mjs} +502 -407
- package/dist/{android-d6rGq1pA.mjs → android-Db2eEMaf.mjs} +152 -65
- package/dist/android-cas-PnKfAdB2.mjs +167 -0
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{app-install-BpgSgkJj.mjs → app-install-CAAplXAt.mjs} +95 -161
- package/dist/{budget-CGDkhvv_.mjs → budget-CMiqghig.mjs} +1038 -73
- package/dist/{build-plan-Dcr-3ie0.mjs → build-plan-aeGMFX7e.mjs} +193 -653
- package/dist/build-progress-C2Jv1AtA.mjs +872 -0
- package/dist/build-slots-Df1ApSuH.mjs +127 -0
- package/dist/{cache-manifest-C68QQ0ua.mjs → cache-manifest-DnUHBJaU.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-BPCiC3ZX.mjs → chrome-BrcVWQyD.mjs} +1 -1
- package/dist/cli-0cX5s4NM.mjs +45 -0
- package/dist/cli.mjs +6 -42
- package/dist/client-C2IS36Qf.mjs +1333 -0
- package/dist/collector-run.mjs +8 -7
- package/dist/{command-output-DVcpw6eE.mjs → command-output-CliHHn7a.mjs} +1 -1
- package/dist/{config-lvc7d3C2.mjs → config-D0DbpZtM.mjs} +28 -29
- package/dist/{created-devices-CllH_8eb.mjs → created-devices-BwVb3liH.mjs} +2 -2
- package/dist/{dependency-state-DsT7aKeo.mjs → dependency-state-BmsjKZ2H.mjs} +2 -2
- package/dist/{deps-D9IcKqXS.mjs → deps-BFlKbOIp.mjs} +3 -3
- package/dist/{detached-entry-DJHoca49.mjs → detached-entry-CiTEgMR1.mjs} +1 -1
- package/dist/dev-client-CjzLoNs0.mjs +80 -0
- package/dist/{device-CjuuAJjQ.mjs → device-BZ1IyS5A.mjs} +7 -7
- package/dist/device-capacity-DMuKC7nx.mjs +136 -0
- package/dist/device-host-worker.d.mts +1 -0
- package/dist/device-host-worker.mjs +769 -0
- package/dist/device-ios-DMQBUPus.mjs +381 -0
- package/dist/{device-lease-5c3WrVRm.mjs → device-lease-W5Pi1q38.mjs} +43 -36
- package/dist/{device-pool-BiyDyPP-.mjs → device-pool-B2r38YjS.mjs} +4 -4
- package/dist/{device-remote-D87zEzaq.mjs → device-remote-9ulPsdhY.mjs} +68 -162
- package/dist/{doctor-x9pnU9fq.mjs → doctor-BcE5xsBn.mjs} +191 -99
- package/dist/{error-diagnostics-C5HzcwCW.mjs → error-diagnostics-Cb0P1WLS.mjs} +12 -11
- package/dist/{exec-DK8KaVHK.mjs → exec-CaErVv7t.mjs} +5 -1
- package/dist/{gc-ko6mUAYD.mjs → gc-BuL1Genr.mjs} +429 -101
- package/dist/{android-cas-iZK3DOCr.mjs → gradle-CmdOBq1d.mjs} +8 -294
- package/dist/{guide-6R0VNFqI.mjs → guide-cCSGRFd3.mjs} +1959 -222
- package/dist/{guide-status-BZrFPIA_.mjs → guide-status-CIoWK6mG.mjs} +3 -3
- package/dist/hosted-macos-DwowNU7W.mjs +447 -0
- package/dist/idle-shutdown-B5LPaNyY.mjs +122 -0
- package/dist/in-use-CndPMilN.mjs +110 -0
- package/dist/{ios-BwDPrnYQ.mjs → ios-3CtCRhwr.mjs} +201 -10
- package/dist/{ios-P1f5nm2n.mjs → ios-Chob8ny7.mjs} +512 -263
- package/dist/{ios-device-DGglU3E_.mjs → ios-device-DERmMmk-.mjs} +12 -7
- package/dist/{ios-device-BiOsSVzd.mjs → ios-device-Ee7sDXfp.mjs} +1 -1
- package/dist/{launch-verify-Deg4tB3Z.mjs → launch-verify-CLlofxRt.mjs} +4 -4
- package/dist/{logs-Civ4gbBH.mjs → logs-h9h6MUvE.mjs} +95 -13
- package/dist/machine-usage-D_YYMzfR.mjs +283 -0
- package/dist/machines-CYtOCqcj.mjs +259 -0
- package/dist/macos-BwtbUtTN.mjs +468 -0
- package/dist/macos-run.d.mts +5 -0
- package/dist/macos-run.mjs +2 -0
- package/dist/{merge-state-ytFQCeh4.mjs → merge-state-BnxLNQiM.mjs} +22 -12
- package/dist/{metro-CcEo8Fl8.mjs → metro-Di8EN2Tb.mjs} +20 -120
- package/dist/{named-ports-Blg8IxOh.mjs → named-ports-Dj_XBNaL.mjs} +6 -59
- package/dist/native-run-DFDoIRbY.mjs +147 -0
- package/dist/{native-runtime-DjBHRg5m.mjs → native-runtime-i6OkVg-w.mjs} +9 -5
- package/dist/offload-worker.d.mts +121 -0
- package/dist/offload-worker.mjs +601 -0
- package/dist/{ownership-DyYDF5ww.mjs → ownership-BkYxUtuj.mjs} +3 -2
- package/dist/{page-BHUzTDFt.mjs → page-QF_Ke10s.mjs} +7 -2
- package/dist/{ports-BguS83ex.mjs → ports-DddwttKM.mjs} +3 -3
- package/dist/prebuild-BvxDlD6C.mjs +213 -0
- package/dist/process-identity-BmRm1qV0.mjs +12 -0
- package/dist/{project-CWlvEaeN.mjs → project-CV3tDFHl.mjs} +9 -18
- package/dist/pull-request-pxnDCQzn.mjs +322 -0
- package/dist/pull-requests.d.mts +120 -0
- package/dist/pull-requests.mjs +2 -0
- package/dist/recordings-GEXp4iBT.mjs +37 -0
- package/dist/{reload-BiniwsSZ.mjs → reload-ChPiwvot.mjs} +70 -22
- package/dist/{remote-cache-CcR6o6lI.mjs → remote-cache-CO2elm_b.mjs} +4 -4
- package/dist/run-B-xqRrsg.mjs +119 -0
- package/dist/{server-bare-DGfgyJ5J.mjs → server-bare-X7PUgizL.mjs} +33 -15
- package/dist/{server-expo-BVuwQ65v.mjs → server-expo-DhtX6bom.mjs} +6 -10
- package/dist/server-expo-KJeD109I.mjs +2 -0
- package/dist/{settings-D61iNOsB.mjs → settings-CduVcoxj.mjs} +77 -26
- package/dist/{settings-B-fsC-Om.mjs → settings-DbL6uhH8.mjs} +16 -10
- package/dist/settings.schema.json +357 -2
- package/dist/{simslim-DrDN4WuV.mjs → simslim-Ciluxlq4.mjs} +8 -132
- package/dist/{slot-launch-D5t8EiMf.mjs → slot-launch-BY0BrOLh.mjs} +6 -6
- package/dist/{spawn-claims-Drw_o-Fb.mjs → spawn-claims-D0XfSe8u.mjs} +1 -1
- package/dist/spawn-entry-DncpJvWL.mjs +16 -0
- package/dist/stage-CzaiwFsI.mjs +143 -0
- package/dist/start-CPO4wRg7.mjs +2 -0
- package/dist/{start-s4RXp1wy.mjs → start-CUD9nasA.mjs} +108 -61
- package/dist/state-B4PQFXMW.d.mts +12 -0
- package/dist/state-BxCgeTQu.mjs +41 -0
- package/dist/{state-DHqvsbqC.mjs → state-CaeaHbDA.mjs} +7 -4
- package/dist/{state-Dk9RVXI7.mjs → state-DFm77wRn.mjs} +67 -5
- package/dist/stats-DBLLFmKd.mjs +66 -0
- package/dist/{status-BsPAnfOI.mjs → status-DYXxNOT0.mjs} +423 -268
- package/dist/{status-BgAuxESg.mjs → status-l84Gbvp2.mjs} +116 -20
- package/dist/stdout-reader-C8yjre1x.mjs +23 -0
- package/dist/stim-desktop-Cnz8CPnl.mjs +63 -0
- package/dist/stim-footprint.swift +32 -0
- package/dist/{stim-installations-CINXy_su.mjs → stim-installations-QMEI32v1.mjs} +1 -1
- package/dist/{stop-BzreOWJp.mjs → stop-Bad61z_2.mjs} +38 -12
- package/dist/stop-Bvf1MflS.mjs +48 -0
- package/dist/{stop-BWIF_6BK.mjs → stop-CceYh1yG.mjs} +2 -2
- package/dist/stop-cause-CZ_Mr-v9.mjs +665 -0
- package/dist/supervisor-run.d.mts +43 -11
- package/dist/supervisor-run.mjs +227 -19
- package/dist/support-CDQbDkL5.mjs +315 -0
- package/dist/support-WLOzVKUv.mjs +176 -0
- package/dist/teardown-BYuQafiA.mjs +718 -0
- package/dist/{xcode-Cp5KvK9x.mjs → toolchain-DmeYjXD9.mjs} +363 -13
- package/dist/warm-progress-DVHLN4uC.mjs +463 -0
- package/dist/{idle-DXtx3RbX.mjs → watchman-Bx0wceoF.mjs} +55 -8
- package/dist/{web-BsQs1WlO.mjs → web-k6w8-HnE.mjs} +37 -20
- package/dist/web-run.mjs +309 -12
- package/dist/workspace-process-lock-BL7Q0HCO.mjs +57 -0
- package/dist/workspace-state-CL2V2Ons.mjs +371 -0
- package/dist/worktree-BT_uULFx.mjs +2 -0
- package/dist/{worktree-BVrHsYZG.mjs → worktree-C0c5Udwa.mjs} +55 -54
- package/dist/{worktree-UrQWXSeb.mjs → worktree-qXKzADSC.mjs} +154 -252
- package/package.json +10 -5
- package/shim/bundle-response.cjs +28 -12
- package/dist/build-progress-DxKpwnaS.mjs +0 -247
- package/dist/in-use-DlqBDKqY.mjs +0 -249
- package/dist/server-expo-DIHDhvGg.mjs +0 -2
- package/dist/start-Cetfvy8l.mjs +0 -2
- package/dist/stats-CFpFGlJV.mjs +0 -62
- package/dist/stats-CX1Z8Tca.mjs +0 -368
- package/dist/stim-desktop-CXt8-Z3J.mjs +0 -40
- package/dist/stop-cause-hjGBOZTG.mjs +0 -1231
- package/dist/worktree-CHWWvm5v.mjs +0 -2
- package/dist/{metro-store-DzeWkfqW.mjs → metro-store-CDDZHtPl.mjs} +1 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { d as getConfigDir } from "./config-D0DbpZtM.mjs";
|
|
2
|
+
import { r as register } from "./cache-manifest-DnUHBJaU.mjs";
|
|
3
|
+
import { E as withDirLock, p as ensureWorkspaceStorage } from "./workspace-state-CL2V2Ons.mjs";
|
|
4
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
5
|
+
import { accessSync, constants, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, statSync, symlinkSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { isJsonObject, readJsonFile } from "@stim-cli/core/state";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
//#region src/engine/android-cas.ts
|
|
10
|
+
const CAS_TOOLCHAIN_FIELDS = [
|
|
11
|
+
"clang",
|
|
12
|
+
"clangxx",
|
|
13
|
+
"lld",
|
|
14
|
+
"ar",
|
|
15
|
+
"ranlib",
|
|
16
|
+
"ndk",
|
|
17
|
+
"resourceDir"
|
|
18
|
+
];
|
|
19
|
+
const CAS_TOOLCHAIN_BINARIES = [
|
|
20
|
+
"clang",
|
|
21
|
+
"clangxx",
|
|
22
|
+
"lld",
|
|
23
|
+
"ar",
|
|
24
|
+
"ranlib"
|
|
25
|
+
];
|
|
26
|
+
function executableFile(path) {
|
|
27
|
+
try {
|
|
28
|
+
accessSync(path, constants.X_OK);
|
|
29
|
+
return statSync(path).isFile();
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function directory(path) {
|
|
35
|
+
try {
|
|
36
|
+
return statSync(path).isDirectory();
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function isAndroidCasToolchain(value) {
|
|
42
|
+
return CAS_TOOLCHAIN_FIELDS.every((field) => typeof value[field] === "string");
|
|
43
|
+
}
|
|
44
|
+
function readAndroidCasToolchain(manifest) {
|
|
45
|
+
const parsed = readJsonFile(manifest);
|
|
46
|
+
const toolchain = isJsonObject(parsed) ? parsed : {};
|
|
47
|
+
if (!isAndroidCasToolchain(toolchain)) {
|
|
48
|
+
const missing = CAS_TOOLCHAIN_FIELDS.filter((field) => typeof toolchain[field] !== "string");
|
|
49
|
+
throw new Error(`${manifest} declares no ${missing.join(", ")}.`);
|
|
50
|
+
}
|
|
51
|
+
const notExecutable = CAS_TOOLCHAIN_BINARIES.filter((field) => !executableFile(toolchain[field]));
|
|
52
|
+
if (notExecutable.length > 0) throw new Error(`${manifest} names no executable ${notExecutable.join(", ")}.`);
|
|
53
|
+
if (!directory(toolchain.resourceDir)) throw new Error(`${manifest} names resourceDir ${toolchain.resourceDir}, which is not a directory.`);
|
|
54
|
+
const ndkProperties = readFileSync(join(toolchain.ndk, "source.properties"), "utf8");
|
|
55
|
+
const ndkVersion = /Pkg.Revision\s*=\s*([^\r\n]+)/.exec(ndkProperties)?.[1]?.trim();
|
|
56
|
+
if (!ndkVersion) throw new Error(`Missing NDK version in ${toolchain.ndk}/source.properties.`);
|
|
57
|
+
return {
|
|
58
|
+
toolchain,
|
|
59
|
+
ndkVersion,
|
|
60
|
+
ndkProperties
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function resolveAndroidCompilerCache({ optimizations, use, env = process.env }) {
|
|
64
|
+
if (optimizations.android.compilerCache !== "cas") return {
|
|
65
|
+
cas: null,
|
|
66
|
+
optimizations
|
|
67
|
+
};
|
|
68
|
+
const manifest = optimizations.android.casToolchain;
|
|
69
|
+
try {
|
|
70
|
+
return {
|
|
71
|
+
cas: use(manifest),
|
|
72
|
+
optimizations
|
|
73
|
+
};
|
|
74
|
+
} catch (error) {
|
|
75
|
+
const fromEnvironment = Boolean(env.STIM_ANDROID_CAS_TOOLCHAIN);
|
|
76
|
+
return {
|
|
77
|
+
cas: null,
|
|
78
|
+
optimizations: {
|
|
79
|
+
...optimizations,
|
|
80
|
+
android: {
|
|
81
|
+
...optimizations.android,
|
|
82
|
+
compilerCache: "ccache",
|
|
83
|
+
compilerCacheFallback: {
|
|
84
|
+
key: fromEnvironment ? "STIM_ANDROID_CAS_TOOLCHAIN" : "optimizations.android.casToolchain",
|
|
85
|
+
reason: `could not be used: ${error.message.replace(/\.$/, "")}`,
|
|
86
|
+
fromEnvironment,
|
|
87
|
+
manifest
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function resolveAndroidCas(root, env = process.env) {
|
|
95
|
+
const manifest = env.STIM_ANDROID_CAS_TOOLCHAIN;
|
|
96
|
+
if (!manifest) return null;
|
|
97
|
+
const { toolchain, ndkVersion, ndkProperties } = readAndroidCasToolchain(manifest);
|
|
98
|
+
const scripts = [
|
|
99
|
+
"shim/android-cas.gradle",
|
|
100
|
+
"shim/android-cas.toolchain.cmake",
|
|
101
|
+
"shim/android-cas-pch.cmake",
|
|
102
|
+
"dist/android-cas-compiler.mjs"
|
|
103
|
+
].map((name) => {
|
|
104
|
+
const path = [`../${name}`, `../../${name}`].map((candidate) => fileURLToPath(new URL(candidate, import.meta.url))).find((candidate) => existsSync(candidate));
|
|
105
|
+
if (!path) throw new Error(`Stim installation is missing ${name}.`);
|
|
106
|
+
return path;
|
|
107
|
+
});
|
|
108
|
+
const hash = createHash("sha256").update(JSON.stringify(toolchain));
|
|
109
|
+
for (const path of [
|
|
110
|
+
...scripts,
|
|
111
|
+
toolchain.clang,
|
|
112
|
+
toolchain.clangxx,
|
|
113
|
+
toolchain.lld,
|
|
114
|
+
toolchain.ar,
|
|
115
|
+
toolchain.ranlib
|
|
116
|
+
]) hash.update(readFileSync(path));
|
|
117
|
+
hash.update(ndkProperties);
|
|
118
|
+
const id = `apple-cas-${hash.digest("hex")}`;
|
|
119
|
+
const dir = join(getConfigDir(), "android-cas", id);
|
|
120
|
+
const state = join(ensureWorkspaceStorage(root), "android-cas", id);
|
|
121
|
+
const context = join(state, "context.json");
|
|
122
|
+
mkdirSync(state, { recursive: true });
|
|
123
|
+
mkdirSync(dir, { recursive: true });
|
|
124
|
+
withDirLock(join(state, "setup.lock"), () => {
|
|
125
|
+
for (const name of ["clang", "clang++"]) {
|
|
126
|
+
const path = join(state, name);
|
|
127
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
128
|
+
symlinkSync(scripts[3], temporary);
|
|
129
|
+
renameSync(temporary, path);
|
|
130
|
+
}
|
|
131
|
+
const temporary = `${context}.${process.pid}.tmp`;
|
|
132
|
+
writeFileSync(temporary, JSON.stringify({
|
|
133
|
+
...toolchain,
|
|
134
|
+
source: realpathSync(root),
|
|
135
|
+
state,
|
|
136
|
+
cache: dir
|
|
137
|
+
}));
|
|
138
|
+
renameSync(temporary, context);
|
|
139
|
+
});
|
|
140
|
+
register({
|
|
141
|
+
dir,
|
|
142
|
+
name: "android-cas",
|
|
143
|
+
prune: "atomic",
|
|
144
|
+
note: "Experimental Android compiler CAS"
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
id,
|
|
148
|
+
dir,
|
|
149
|
+
initScript: scripts[0],
|
|
150
|
+
env: {
|
|
151
|
+
STIM_ANDROID_CAS_CONTEXT: context,
|
|
152
|
+
STIM_ANDROID_CAS_SOURCE_ROOT: realpathSync(root),
|
|
153
|
+
STIM_ANDROID_CAS_STATE: state,
|
|
154
|
+
STIM_ANDROID_CAS_NDK: toolchain.ndk,
|
|
155
|
+
STIM_ANDROID_CAS_NDK_VERSION: ndkVersion,
|
|
156
|
+
STIM_ANDROID_CAS_AR: toolchain.ar,
|
|
157
|
+
STIM_ANDROID_CAS_RANLIB: toolchain.ranlib,
|
|
158
|
+
STIM_ANDROID_CAS_CMAKE_TOOLCHAIN: scripts[1],
|
|
159
|
+
STIM_ANDROID_CAS_CMAKE_PCH: scripts[2],
|
|
160
|
+
CMAKE_C_COMPILER_LAUNCHER: "",
|
|
161
|
+
CMAKE_CXX_COMPILER_LAUNCHER: "",
|
|
162
|
+
CCACHE_DISABLE: "1"
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
//#endregion
|
|
167
|
+
export { resolveAndroidCas as n, resolveAndroidCompilerCache as r, readAndroidCasToolchain as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
+
import { t as getExecutor } from "./exec-CaErVv7t.mjs";
|
|
3
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
4
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
4
5
|
import { join } from "node:path";
|
|
5
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
6
6
|
import { once } from "node:events";
|
|
7
7
|
//#region bin/android-cas-compiler.ts
|
|
8
8
|
const context = process.env.STIM_ANDROID_CAS_CONTEXT;
|
|
@@ -1,138 +1,6 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isAbsolute, join } from "node:path";
|
|
5
|
-
import { createHash } from "node:crypto";
|
|
6
|
-
//#region src/engine/installed-artifact.ts
|
|
7
|
-
const READ_CHUNK_BYTES = 1048576;
|
|
8
|
-
const DEVICE_PATH_TIMEOUT_MS = 3e4;
|
|
9
|
-
const DEVICE_HASH_TIMEOUT_MS = 12e4;
|
|
10
|
-
const SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
11
|
-
function parseInstalledApkPath(text) {
|
|
12
|
-
if (typeof text !== "string") return null;
|
|
13
|
-
const paths = [];
|
|
14
|
-
for (const raw of text.split("\n")) {
|
|
15
|
-
const line = raw.trim();
|
|
16
|
-
if (!line.startsWith("package:")) continue;
|
|
17
|
-
const path = line.slice(8);
|
|
18
|
-
if (path.startsWith("/")) paths.push(path);
|
|
19
|
-
}
|
|
20
|
-
return paths.length === 1 ? paths[0] : null;
|
|
21
|
-
}
|
|
22
|
-
function parseDeviceSha256(text) {
|
|
23
|
-
if (typeof text !== "string") return null;
|
|
24
|
-
const first = text.trim().split(/\s+/)[0] ?? "";
|
|
25
|
-
return SHA256_HEX.test(first) ? first : null;
|
|
26
|
-
}
|
|
27
|
-
function parseAppContainerPath(text) {
|
|
28
|
-
if (typeof text !== "string") return null;
|
|
29
|
-
const lines = text.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
30
|
-
return lines.length === 1 && isAbsolute(lines[0]) ? lines[0] : null;
|
|
31
|
-
}
|
|
32
|
-
function artifactsMatch(local, installed) {
|
|
33
|
-
return Boolean(local) && local === installed;
|
|
34
|
-
}
|
|
35
|
-
function hashFile(file) {
|
|
36
|
-
let fd = null;
|
|
37
|
-
try {
|
|
38
|
-
fd = openSync(file, "r");
|
|
39
|
-
const digest = createHash("sha256");
|
|
40
|
-
const buffer = Buffer.allocUnsafe(READ_CHUNK_BYTES);
|
|
41
|
-
for (;;) {
|
|
42
|
-
const read = readSync(fd, buffer, 0, READ_CHUNK_BYTES, null);
|
|
43
|
-
if (read <= 0) break;
|
|
44
|
-
digest.update(buffer.subarray(0, read));
|
|
45
|
-
}
|
|
46
|
-
return digest.digest("hex");
|
|
47
|
-
} catch {
|
|
48
|
-
return null;
|
|
49
|
-
} finally {
|
|
50
|
-
if (fd !== null) try {
|
|
51
|
-
closeSync(fd);
|
|
52
|
-
} catch {}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
function hashBundle(dir) {
|
|
56
|
-
const digest = createHash("sha256");
|
|
57
|
-
const walk = (abs, rel) => {
|
|
58
|
-
let names;
|
|
59
|
-
try {
|
|
60
|
-
names = readdirSync(abs);
|
|
61
|
-
} catch {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
for (const name of names.toSorted()) {
|
|
65
|
-
const child = join(abs, name);
|
|
66
|
-
const path = rel === "" ? name : `${rel}/${name}`;
|
|
67
|
-
let stat;
|
|
68
|
-
try {
|
|
69
|
-
stat = lstatSync(child);
|
|
70
|
-
} catch {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
if (stat.isDirectory()) {
|
|
74
|
-
if (!walk(child, path)) return false;
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
if (!stat.isFile()) return false;
|
|
78
|
-
const file = hashFile(child);
|
|
79
|
-
if (file === null) return false;
|
|
80
|
-
digest.update(`${path}\0${file}\n`);
|
|
81
|
-
}
|
|
82
|
-
return true;
|
|
83
|
-
};
|
|
84
|
-
return walk(dir, "") ? digest.digest("hex") : null;
|
|
85
|
-
}
|
|
86
|
-
function deviceHoldsApk({ serial, packageName, apkPath }, { exec = null } = {}) {
|
|
87
|
-
const e = exec || getExecutor();
|
|
88
|
-
let path;
|
|
89
|
-
try {
|
|
90
|
-
path = parseInstalledApkPath(e.runFile("adb", [
|
|
91
|
-
"-s",
|
|
92
|
-
serial,
|
|
93
|
-
"shell",
|
|
94
|
-
"pm",
|
|
95
|
-
"path",
|
|
96
|
-
packageName
|
|
97
|
-
], { timeoutMs: DEVICE_PATH_TIMEOUT_MS }));
|
|
98
|
-
} catch {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
if (!path) return false;
|
|
102
|
-
let installed;
|
|
103
|
-
try {
|
|
104
|
-
installed = parseDeviceSha256(e.runFile("adb", [
|
|
105
|
-
"-s",
|
|
106
|
-
serial,
|
|
107
|
-
"shell",
|
|
108
|
-
"sha256sum",
|
|
109
|
-
path
|
|
110
|
-
], { timeoutMs: DEVICE_HASH_TIMEOUT_MS }));
|
|
111
|
-
} catch {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
if (!installed) return false;
|
|
115
|
-
return artifactsMatch(hashFile(apkPath), installed);
|
|
116
|
-
}
|
|
117
|
-
function deviceHoldsBundle({ udid, bundleId, appPath }, { exec = null } = {}) {
|
|
118
|
-
const e = exec || getExecutor();
|
|
119
|
-
let container;
|
|
120
|
-
try {
|
|
121
|
-
container = parseAppContainerPath(e.runFile("xcrun", [
|
|
122
|
-
"simctl",
|
|
123
|
-
"get_app_container",
|
|
124
|
-
udid,
|
|
125
|
-
bundleId
|
|
126
|
-
], { timeoutMs: DEVICE_PATH_TIMEOUT_MS }));
|
|
127
|
-
} catch {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
if (!container) return false;
|
|
131
|
-
const installed = hashBundle(container);
|
|
132
|
-
if (!installed) return false;
|
|
133
|
-
return artifactsMatch(hashBundle(appPath), installed);
|
|
134
|
-
}
|
|
135
|
-
//#endregion
|
|
1
|
+
import { t as getExecutor } from "./exec-CaErVv7t.mjs";
|
|
2
|
+
import { D as uninstallIosApp, M as deviceHoldsApk, N as deviceHoldsBundle, l as iosSimulatorFailureAdvice, m as listUserApps } from "./ios-3CtCRhwr.mjs";
|
|
3
|
+
import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-Ee7sDXfp.mjs";
|
|
136
4
|
//#region src/engine/app-install.ts
|
|
137
5
|
const INSTALL_ERROR = "STIM_INSTALL_FAILED";
|
|
138
6
|
const LAUNCH_ERROR = "STIM_LAUNCH_FAILED";
|
|
@@ -142,12 +10,37 @@ const IOS_SCHEME_APPROVAL_OPENER = "com.apple.CoreSimulator.CoreSimulatorBridge"
|
|
|
142
10
|
const IOS_DEV_MENU_OFF_KEYS = ["EXDevMenuShowsAtLaunch", "EXDevMenuShowFloatingActionButton"];
|
|
143
11
|
const DEV_CLIENT_ONBOARDING_QUERY = "disableOnboarding=1";
|
|
144
12
|
const DEV_CLIENT_DISABLE_FAB_QUERY = "disableFab=1";
|
|
13
|
+
const DEV_CLIENT_DEV_MENU_OFF_QUERY = "disableFab=1&disableAutoLaunch=1";
|
|
14
|
+
const DEV_CLIENT_RESERVED_DEV_MENU_OFF_QUERY = "__expo_disable_fab=1&__expo_disable_auto_launch=1";
|
|
145
15
|
const ANDROID_DISABLE_AUTO_LAUNCH_EXTRA = "EXDevMenuDisableAutoLaunch";
|
|
16
|
+
const IOS_DEV_MENU_OFF_DEFAULTS_PLIST = [
|
|
17
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
|
|
18
|
+
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">",
|
|
19
|
+
"<plist version=\"1.0\">",
|
|
20
|
+
"<dict>",
|
|
21
|
+
...IOS_DEV_MENU_OFF_KEYS.flatMap((key) => [` <key>${key}</key>`, " <false/>"]),
|
|
22
|
+
"</dict>",
|
|
23
|
+
"</plist>",
|
|
24
|
+
""
|
|
25
|
+
].join("\n");
|
|
26
|
+
function writeIosDevMenuOffDefaults(udid, bundleId, exec) {
|
|
27
|
+
for (const key of IOS_DEV_MENU_OFF_KEYS) exec.runFile("xcrun", [
|
|
28
|
+
"simctl",
|
|
29
|
+
"spawn",
|
|
30
|
+
udid,
|
|
31
|
+
"defaults",
|
|
32
|
+
"write",
|
|
33
|
+
bundleId,
|
|
34
|
+
key,
|
|
35
|
+
"-bool",
|
|
36
|
+
"false"
|
|
37
|
+
], { timeoutMs: 6e4 });
|
|
38
|
+
}
|
|
146
39
|
function describeIosSimulatorFailure(error, exec) {
|
|
147
40
|
const detail = describe(error);
|
|
148
41
|
return error?.code === "ETIMEDOUT" ? `${detail}. ${iosSimulatorFailureAdvice(exec)}` : detail;
|
|
149
42
|
}
|
|
150
|
-
function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null, proveInstalled = true }, { exec = null, now = null } = {}) {
|
|
43
|
+
function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null, schemeApprovals = [], proveInstalled = true }, { exec = null, now = null } = {}) {
|
|
151
44
|
const e = exec || getExecutor();
|
|
152
45
|
const artifactStartedAt = now?.();
|
|
153
46
|
const skipped = bundleId && proveInstalled ? deviceHoldsBundle({
|
|
@@ -174,20 +67,13 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
174
67
|
}
|
|
175
68
|
const artifactFinishedAt = now?.();
|
|
176
69
|
const artifactDurationMs = artifactStartedAt !== void 0 && artifactFinishedAt !== void 0 ? artifactFinishedAt - artifactStartedAt : void 0;
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
"write",
|
|
185
|
-
bundleId,
|
|
186
|
-
key,
|
|
187
|
-
"-bool",
|
|
188
|
-
"false"
|
|
189
|
-
], { timeoutMs: 6e4 });
|
|
190
|
-
for (const key of iosSchemeApprovalKeys(bundleId, devClientScheme)) e.runFile("xcrun", [
|
|
70
|
+
const devMenuKeys = bundleId && devClientScheme && !skipped ? IOS_DEV_MENU_OFF_KEYS : [];
|
|
71
|
+
const missingApprovals = (bundleId && devClientScheme ? iosSchemeApprovalKeys(bundleId, devClientScheme) : []).filter((key) => !schemeApprovals.includes(`${key}=${bundleId}`));
|
|
72
|
+
const preparing = bundleId && (devMenuKeys.length > 0 || missingApprovals.length > 0);
|
|
73
|
+
const preparationStartedAt = preparing ? artifactFinishedAt : void 0;
|
|
74
|
+
if (bundleId && preparing) try {
|
|
75
|
+
if (devMenuKeys.length > 0) writeIosDevMenuOffDefaults(udid, bundleId, e);
|
|
76
|
+
for (const key of missingApprovals) e.runFile("xcrun", [
|
|
191
77
|
"simctl",
|
|
192
78
|
"spawn",
|
|
193
79
|
udid,
|
|
@@ -208,7 +94,8 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
208
94
|
const devClientPreparationDurationMs = now && preparationStartedAt !== void 0 ? now() - preparationStartedAt : void 0;
|
|
209
95
|
const timing = {
|
|
210
96
|
...artifactDurationMs === void 0 ? {} : { artifactDurationMs },
|
|
211
|
-
...devClientPreparationDurationMs === void 0 ? {} : { devClientPreparationDurationMs }
|
|
97
|
+
...devClientPreparationDurationMs === void 0 ? {} : { devClientPreparationDurationMs },
|
|
98
|
+
...missingApprovals.length > 0 ? { schemeApprovals: [...schemeApprovals, ...missingApprovals.map((key) => `${key}=${bundleId}`)] } : {}
|
|
212
99
|
};
|
|
213
100
|
return skipped ? {
|
|
214
101
|
ok: true,
|
|
@@ -230,6 +117,7 @@ function clearOtherUserApps({ udid, keep }, { list = listUserApps, uninstall = u
|
|
|
230
117
|
} catch {
|
|
231
118
|
return {
|
|
232
119
|
listed: false,
|
|
120
|
+
kept: false,
|
|
233
121
|
removed,
|
|
234
122
|
failed
|
|
235
123
|
};
|
|
@@ -245,6 +133,7 @@ function clearOtherUserApps({ udid, keep }, { list = listUserApps, uninstall = u
|
|
|
245
133
|
}
|
|
246
134
|
return {
|
|
247
135
|
listed: true,
|
|
136
|
+
kept: keep ? installed.includes(keep) : false,
|
|
248
137
|
removed,
|
|
249
138
|
failed
|
|
250
139
|
};
|
|
@@ -252,12 +141,13 @@ function clearOtherUserApps({ udid, keep }, { list = listUserApps, uninstall = u
|
|
|
252
141
|
function jsLocationValue(metroPort) {
|
|
253
142
|
return `localhost:${metroPort}`;
|
|
254
143
|
}
|
|
255
|
-
function devClientDeepLink(scheme, projectOrigin) {
|
|
256
|
-
const
|
|
257
|
-
|
|
144
|
+
function devClientDeepLink(scheme, projectOrigin, { devMenuParams = false } = {}) {
|
|
145
|
+
const projectQuery = devMenuParams ? `${DEV_CLIENT_ONBOARDING_QUERY}&${DEV_CLIENT_DEV_MENU_OFF_QUERY}&${DEV_CLIENT_RESERVED_DEV_MENU_OFF_QUERY}` : DEV_CLIENT_ONBOARDING_QUERY;
|
|
146
|
+
const projectUrl = `${projectOrigin.replace(/\/+$/, "")}/?${projectQuery}`;
|
|
147
|
+
return `${scheme}://expo-development-client/?url=${encodeURIComponent(projectUrl)}&${devMenuParams ? DEV_CLIENT_DEV_MENU_OFF_QUERY : DEV_CLIENT_DISABLE_FAB_QUERY}`;
|
|
258
148
|
}
|
|
259
|
-
function devClientUrl(scheme, metroPort, host = "localhost") {
|
|
260
|
-
return devClientDeepLink(scheme, `http://${host}:${metroPort}
|
|
149
|
+
function devClientUrl(scheme, metroPort, host = "localhost", options = {}) {
|
|
150
|
+
return devClientDeepLink(scheme, `http://${host}:${metroPort}`, options);
|
|
261
151
|
}
|
|
262
152
|
function iosSchemeApprovalKeys(bundleId, devClientScheme) {
|
|
263
153
|
return [.../* @__PURE__ */ new Set([bundleId, devClientScheme])].map((target) => `${IOS_SCHEME_APPROVAL_OPENER}-->${target}`);
|
|
@@ -299,7 +189,7 @@ function launchedIosAppAfterNoHandle(error, udid, bundleId, exec) {
|
|
|
299
189
|
if (!stderr.includes("domain=NSPOSIXErrorDomain, code=3") || !stderr.includes(`Application launch for '${bundleId}' did not return a process handle nor launch error.`)) return null;
|
|
300
190
|
return iosAppProcess(udid, bundleId, { exec }) ?? null;
|
|
301
191
|
}
|
|
302
|
-
function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, consolePaths }, { exec = null } = {}) {
|
|
192
|
+
function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, devMenuParams = false, consolePaths }, { exec = null } = {}) {
|
|
303
193
|
const e = exec || getExecutor();
|
|
304
194
|
const launchArgs = [
|
|
305
195
|
"simctl",
|
|
@@ -348,16 +238,27 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
348
238
|
};
|
|
349
239
|
}
|
|
350
240
|
if (devClientScheme) {
|
|
351
|
-
const url = devClientUrl(devClientScheme, metroPort);
|
|
241
|
+
const url = devClientUrl(devClientScheme, metroPort, "localhost", { devMenuParams });
|
|
242
|
+
const viaInitialUrl = Boolean(consolePaths) && runningPid === null;
|
|
243
|
+
if (!viaInitialUrl) try {
|
|
244
|
+
writeIosDevMenuOffDefaults(udid, bundleId, e);
|
|
245
|
+
} catch (err) {
|
|
246
|
+
return {
|
|
247
|
+
failed: true,
|
|
248
|
+
code: LAUNCH_ERROR,
|
|
249
|
+
reason: `Could not turn off ${bundleId}'s dev menu before opening it (defaults write): ${describeIosSimulatorFailure(err, e)}`
|
|
250
|
+
};
|
|
251
|
+
}
|
|
352
252
|
let launchedWithInitialUrl = false;
|
|
353
253
|
try {
|
|
354
|
-
if (
|
|
254
|
+
if (viaInitialUrl) {
|
|
355
255
|
const initialUrl = new URL(url).searchParams.get("url");
|
|
356
256
|
launchedWithInitialUrl = true;
|
|
357
257
|
const pid = parseLaunchedPid(e.runFile("xcrun", [
|
|
358
258
|
...launchArgs,
|
|
359
259
|
"--initialUrl",
|
|
360
|
-
initialUrl
|
|
260
|
+
initialUrl,
|
|
261
|
+
...DEV_MENU_LAUNCH_ARGS
|
|
361
262
|
], { timeoutMs: 6e4 }));
|
|
362
263
|
return {
|
|
363
264
|
ok: true,
|
|
@@ -560,6 +461,39 @@ function reverseMetroPorts({ serial, metroPort, devicePorts = null }, { exec = n
|
|
|
560
461
|
reversed: pairs.map(([device, host]) => `tcp:${device}->tcp:${host}`)
|
|
561
462
|
};
|
|
562
463
|
}
|
|
464
|
+
function hasMetroReverse(listing, metroPort) {
|
|
465
|
+
return String(listing ?? "").split("\n").some((line) => {
|
|
466
|
+
const cols = line.trim().split(/\s+/);
|
|
467
|
+
return cols[1] === `tcp:${metroPort}` && cols[2] === `tcp:${metroPort}`;
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
/** Re-applies the launch's `metroPort` reverse when the device no longer has it. */
|
|
471
|
+
function ensureMetroReverse({ serial, metroPort }, { exec = null } = {}) {
|
|
472
|
+
const e = exec || getExecutor();
|
|
473
|
+
let listing;
|
|
474
|
+
try {
|
|
475
|
+
listing = e.runFile("adb", [
|
|
476
|
+
"-s",
|
|
477
|
+
serial,
|
|
478
|
+
"reverse",
|
|
479
|
+
"--list"
|
|
480
|
+
], ADB_SHELL_OPTIONS);
|
|
481
|
+
} catch {
|
|
482
|
+
return {
|
|
483
|
+
failed: true,
|
|
484
|
+
reason: `adb reverse --list failed on ${serial}`
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
if (hasMetroReverse(listing, metroPort)) return { restored: false };
|
|
488
|
+
const reversed = reverseMetroPorts({
|
|
489
|
+
serial,
|
|
490
|
+
metroPort
|
|
491
|
+
}, { exec: e });
|
|
492
|
+
return reversed.failed ? {
|
|
493
|
+
failed: true,
|
|
494
|
+
reason: reversed.reason ?? "adb reverse failed"
|
|
495
|
+
} : { restored: true };
|
|
496
|
+
}
|
|
563
497
|
const EMULATOR_HOST_LOOPBACK = "127.0.0.1";
|
|
564
498
|
const PHYSICAL_HOST_LOOPBACK = "localhost";
|
|
565
499
|
function androidMetroHost(physical) {
|
|
@@ -871,4 +805,4 @@ function androidAppProcess(serial, packageName, { exec = null } = {}) {
|
|
|
871
805
|
}
|
|
872
806
|
}
|
|
873
807
|
//#endregion
|
|
874
|
-
export {
|
|
808
|
+
export { restartedAppNote as S, installIosApp as _, IOS_DEV_MENU_OFF_DEFAULTS_PLIST as a, launchAndroidReleaseApp as b, androidDevClientUrl as c, devClientUrl as d, deviceShellArg as f, installConflictKind as g, installAndroidApp as h, INSTALL_ERROR as i, clearOtherUserApps as l, hasMetroReverse as m, ANDROID_DISABLE_AUTO_LAUNCH_EXTRA as n, LAUNCH_ERROR as o, ensureMetroReverse as p, DEFAULT_METRO_PORT as r, androidAppProcess as s, ADB_INSTALL_TIMEOUT_MS as t, devClientDeepLink as u, iosAppProcess as v, launchIosApp as x, launchAndroidApp as y };
|