peachsim 0.1.1625 → 0.1.1640
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/LICENSE +1 -1
- package/README.md +15 -2
- package/cli/app-config.ts +18 -6
- package/cli/app-fonts.ts +37 -17
- package/cli/app-stubs.ts +284 -20
- package/cli/bridge-flow-runner.ts +66 -45
- package/cli/cloud-client.ts +60 -40
- package/cli/command-registry.ts +1 -0
- package/cli/commands/control.ts +283 -49
- package/cli/commands/doctor.ts +30 -189
- package/cli/commands/flow.ts +79 -11
- package/cli/commands/inspect/core.ts +10 -5
- package/cli/commands/inspect/settling.ts +14 -2
- package/cli/commands/inspect/shared.ts +9 -4
- package/cli/commands/inspect/wait-ready.ts +12 -0
- package/cli/commands/inspect.ts +91 -50
- package/cli/commands/install-desktop.ts +1 -0
- package/cli/commands/maestro-compare.ts +97 -38
- package/cli/commands/maestro.ts +9 -1
- package/cli/commands/preview.ts +1 -1
- package/cli/commands/record.ts +118 -48
- package/cli/commands/screenshot.ts +23 -1
- package/cli/commands/serve.ts +7 -2
- package/cli/commands/setup.ts +19 -42
- package/cli/commands/swift.ts +14 -3
- package/cli/commands/upload.ts +93 -48
- package/cli/desktop-companion.ts +102 -17
- package/cli/drivers/desktop.ts +14 -1
- package/cli/drivers/playwright-sim-host.ts +103 -45
- package/cli/drivers/playwright.ts +9 -8
- package/cli/drivers/types.ts +5 -0
- package/cli/maestro-accessibility.ts +1 -1
- package/cli/maestro-compare.ts +84 -12
- package/cli/main.ts +3 -2
- package/cli/outbound-endpoints.ts +20 -6
- package/cli/pause-aware-timeout.ts +106 -0
- package/cli/scene-video.ts +89 -0
- package/cli/ws-bridge.ts +37 -19
- package/detox/attempt-events.cjs +66 -5
- package/detox/attempt-events.d.cts +7 -0
- package/detox/expectations.ts +7 -3
- package/detox/index.ts +269 -170
- package/detox/motion-change.cjs +206 -21
- package/detox/motion-change.d.cts +39 -2
- package/detox/navigation-lifecycle.ts +35 -3
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +8 -7
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +13 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +14 -8
- package/dist-lib/bridge-contract.mjs +13 -7
- package/dist-lib/bundle-channel.cjs +11887 -7900
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +6 -3
- package/dist-lib/config.mjs +6 -3
- package/dist-lib/detox/index.cjs +1379 -725
- package/dist-lib/dev-bundle-resolution.cjs +14 -2
- package/dist-lib/expo-swift-bundle.cjs +9341 -5462
- package/dist-lib/expo-swift-metadata.cjs +11 -7
- package/dist-lib/expo-swift-metadata.mjs +11 -7
- package/dist-lib/home-paths.cjs +32 -3
- package/dist-lib/host/bridge-host.cjs +50204 -7258
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +3541 -448
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +2931 -104
- package/dist-lib/native-app-identity-project.cjs +289 -49
- package/dist-lib/native-app-identity-project.mjs +289 -49
- package/dist-lib/native-app-identity.cjs +77 -26
- package/dist-lib/native-app-identity.mjs +76 -26
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +6 -2
- package/dist-lib/react-native-host-modules.mjs +6 -2
- package/dist-lib/scripts/dev-server-scanner.cjs +22 -8
- package/dist-lib/sdk.cjs +27 -11
- package/dist-lib/sdk.mjs +27 -10
- package/dist-lib/skills.cjs +72201 -26208
- package/dist-lib/swift-compile.cjs +1007 -140
- package/dist-lib/swift-compile.mjs +1049 -174
- package/dist-lib/swift-package.cjs +12 -3
- package/dist-lib/swift-package.mjs +12 -3
- package/dist-lib/swift-submit.cjs +13 -5
- package/dist-lib/swift-submit.mjs +11 -5
- package/dist-lib/swift-toolchain.cjs +423 -33
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +8628 -5268
- package/dist-lib/vite.cjs +2859 -12
- package/dist-lib/worklet-executable.cjs +14 -2
- package/dist-lib/worklet-executable.mjs +14 -2
- package/kotlin/AppSources/dev/peach/app/PeachDrawable.kt +21 -14
- package/kotlin/Sources/androidx/annotation/DrawableRes.kt +14 -0
- package/package.json +1 -1
- package/scripts/dev-server-scanner.ts +2 -1
- package/skills/peach-perf/SKILL.md +11 -5
- package/skills/peach-setup/SKILL.md +16 -19
- package/src/backend-origin.ts +13 -6
- package/src/bridge-constants.ts +11 -0
- package/src/bridge-contract.ts +22 -34
- package/src/config.ts +15 -0
- package/src/desktop-host-delivery.ts +5 -1
- package/src/dev-bundle-resolution.ts +2 -1
- package/src/expo-manifest-body.ts +13 -0
- package/src/expo-swift-host.ts +196 -49
- package/src/expo-swift-ready.ts +78 -0
- package/src/expoKotlinContract.ts +4 -7
- package/src/expoSwiftContract.ts +17 -6
- package/src/home-paths.ts +48 -2
- package/src/host/bridge-host.ts +5 -2
- package/src/host/staged-host-files.ts +9 -0
- package/src/native-app-identity-project.ts +27 -6
- package/src/native-app-identity.ts +91 -4
- package/src/native-firebase-config.ts +209 -13
- package/src/nativeAppIconContract.ts +1 -4
- package/src/output-lock-stdio.ts +36 -0
- package/src/process-group.ts +25 -2
- package/src/react-native-bridge-modules.ts +431 -0
- package/src/react-native-host-modules.ts +8 -1
- package/src/settings-bundle.ts +1 -4
- package/src/swift-binary-modules.ts +2 -2
- package/src/swift-compile.ts +918 -109
- package/src/swift-compiler-digest.ts +14 -0
- package/src/swift-distribution.lock.json +24 -12
- package/src/swift-distribution.ts +103 -4
- package/src/swift-host.ts +180 -55
- package/src/swift-icu.ts +27 -13
- package/src/swift-objc-compile.ts +355 -0
- package/src/swift-objc-sdk.ts +821 -27
- package/src/swift-objc-standin.ts +148 -14
- package/src/swift-package-manifest.ts +60 -7
- package/src/swift-package.ts +15 -1
- package/src/swift-packages.ts +154 -81
- package/src/swift-standin-emit.ts +96 -15
- package/src/swift-standins.ts +530 -116
- package/src/swift-submit.ts +13 -5
- package/src/swift-toolchain.ts +500 -42
- package/src/vite-plugin.ts +12 -1
- package/src/worker-system-chunks.ts +11 -12
- package/src/worklet-executable.ts +19 -1
- package/src/xcode-project.ts +270 -30
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -32,18 +32,70 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
// src/swift-toolchain.ts
|
|
33
33
|
var swift_toolchain_exports = {};
|
|
34
34
|
__export(swift_toolchain_exports, {
|
|
35
|
+
SWIFT_HOST_COMPILER_ID: () => SWIFT_HOST_COMPILER_ID,
|
|
36
|
+
SWIFT_HOST_COMPILER_RELEASE: () => SWIFT_HOST_COMPILER_RELEASE,
|
|
37
|
+
confineSwiftScratch: () => confineSwiftScratch,
|
|
38
|
+
installSwiftWasmSdk: () => installSwiftWasmSdk,
|
|
39
|
+
swiftCompiler: () => swiftCompiler,
|
|
40
|
+
swiftCompilerInstallSteps: () => swiftCompilerInstallSteps,
|
|
35
41
|
swiftCompilerRelease: () => swiftCompilerRelease,
|
|
42
|
+
swiftEnvironment: () => swiftEnvironment,
|
|
43
|
+
swiftFileChecksum: () => swiftFileChecksum,
|
|
44
|
+
swiftHostCompilerArchive: () => swiftHostCompilerArchive,
|
|
36
45
|
swiftInstallSteps: () => swiftInstallSteps,
|
|
46
|
+
swiftSdkInstallStep: () => swiftSdkInstallStep,
|
|
47
|
+
swiftSdkOptions: () => swiftSdkOptions,
|
|
37
48
|
swiftToolchain: () => swiftToolchain,
|
|
38
|
-
swiftToolchainBin: () => swiftToolchainBin
|
|
49
|
+
swiftToolchainBin: () => swiftToolchainBin,
|
|
50
|
+
swiftUpstreamRelease: () => swiftUpstreamRelease,
|
|
51
|
+
verifySwiftHostCompiler: () => verifySwiftHostCompiler
|
|
39
52
|
});
|
|
40
53
|
module.exports = __toCommonJS(swift_toolchain_exports);
|
|
41
54
|
var import_node_child_process = require("node:child_process");
|
|
55
|
+
var import_node_crypto = require("node:crypto");
|
|
42
56
|
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
43
57
|
var import_node_os = __toESM(require("node:os"), 1);
|
|
44
58
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
59
|
+
var import_node_url = require("node:url");
|
|
60
|
+
function swiftSdkOptions() {
|
|
61
|
+
const directory = process.env.PEACH_SWIFT_SDKS_PATH;
|
|
62
|
+
return directory ? ["--swift-sdks-path", import_node_path.default.resolve(directory)] : [];
|
|
63
|
+
}
|
|
64
|
+
var SWIFT_HOST_COMPILER_RELEASE = "swift-6.4.0-RELEASE-custom-0d775d32d7c74eae";
|
|
65
|
+
var SWIFT_HOST_COMPILER_ID = "0d775d32d7c74eae";
|
|
66
|
+
var compilerArchives = {
|
|
67
|
+
"darwin-arm64": {
|
|
68
|
+
checksum: "957e85486f92327ee5cf8d3c5bb9336d17ab80145c87645c637c49130a50477a",
|
|
69
|
+
manifest: "c63e2f81694e8d8ad046d10c71d0638dbae4e5a36601294ed670988d1cb5b6f1"
|
|
70
|
+
},
|
|
71
|
+
"linux-x64": {
|
|
72
|
+
checksum: "6302230fb126b79c9af5fc2bc0208a936bb573c343da7ae949c5c1687e761cd2",
|
|
73
|
+
manifest: "31b507a6a8648a2266a187b9fed092e29a63cae99d57c5defdf2e82a7cbbc113"
|
|
74
|
+
},
|
|
75
|
+
"linux-arm64": {
|
|
76
|
+
checksum: "9b40d39ea5ba82fd9a417868f0a449f5e98e37cf83acaac9cedd3a8b8d91a218",
|
|
77
|
+
manifest: "fe07a29d4f4374cad47b29de70e90aa2e3b7664e08c8b53d304585e65637da24"
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
function swiftHostCompilerArchive(release, host = `${process.platform}-${process.arch}`) {
|
|
81
|
+
if (release !== SWIFT_HOST_COMPILER_RELEASE)
|
|
82
|
+
throw new Error(`unqualified host compiler ${release}`);
|
|
83
|
+
const archive = compilerArchives[host];
|
|
84
|
+
if (!archive) throw new Error(`unsupported Swift compiler host ${host}`);
|
|
85
|
+
return {
|
|
86
|
+
...archive,
|
|
87
|
+
identity: SWIFT_HOST_COMPILER_ID,
|
|
88
|
+
url: `https://r2.sootsim.com/swift-host-compiler/${SWIFT_HOST_COMPILER_ID}/${release}-${host}.tar.gz`
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function swiftUpstreamRelease(release) {
|
|
92
|
+
return release.replace(/-custom-[a-f0-9]{16}$/, "");
|
|
93
|
+
}
|
|
45
94
|
function swiftCompilerRelease(release) {
|
|
46
|
-
return release.replace(
|
|
95
|
+
return swiftUpstreamRelease(release).replace(
|
|
96
|
+
/^swift-(\d+\.\d+)\.0-RELEASE$/,
|
|
97
|
+
"swift-$1-RELEASE"
|
|
98
|
+
);
|
|
47
99
|
}
|
|
48
100
|
function swiftToolchainBin(release) {
|
|
49
101
|
if (process.platform === "darwin") {
|
|
@@ -57,64 +109,402 @@ function swiftToolchainBin(release) {
|
|
|
57
109
|
}
|
|
58
110
|
const image = import_node_path.default.join("/opt/swift", release, "usr/bin");
|
|
59
111
|
if (import_node_fs.default.existsSync(import_node_path.default.join(image, "swift"))) return image;
|
|
112
|
+
if (release.includes("-custom-"))
|
|
113
|
+
return import_node_path.default.join(peachHome(), "swift", "toolchains", release, "usr/bin");
|
|
60
114
|
return (process.env.PATH ?? "").split(import_node_path.default.delimiter).find((dir) => dir && import_node_fs.default.existsSync(import_node_path.default.join(dir, "swift"))) ?? image;
|
|
61
115
|
}
|
|
62
|
-
|
|
116
|
+
function peachHome() {
|
|
117
|
+
const override = process.env.PEACH_HOME;
|
|
118
|
+
return override ? import_node_path.default.resolve(override) : import_node_path.default.join(import_node_os.default.homedir(), ".peach");
|
|
119
|
+
}
|
|
120
|
+
var scratch;
|
|
121
|
+
var swiftHome;
|
|
122
|
+
function confineSwiftScratch(root) {
|
|
123
|
+
if (scratch) return;
|
|
124
|
+
import_node_fs.default.mkdirSync(root, { recursive: true });
|
|
125
|
+
for (const name of import_node_fs.default.readdirSync(root)) {
|
|
126
|
+
const pid = Number(name);
|
|
127
|
+
if (Number.isInteger(pid) && pid > 0 && !processRuns(pid))
|
|
128
|
+
import_node_fs.default.rmSync(import_node_path.default.join(root, name), { recursive: true, force: true });
|
|
129
|
+
}
|
|
130
|
+
const dir = import_node_path.default.join(root, String(process.pid));
|
|
131
|
+
import_node_fs.default.mkdirSync(dir, { recursive: true });
|
|
132
|
+
scratch = dir;
|
|
133
|
+
if (process.platform === "linux") {
|
|
134
|
+
swiftHome = import_node_path.default.join(root, "home");
|
|
135
|
+
import_node_fs.default.mkdirSync(swiftHome, { recursive: true });
|
|
136
|
+
}
|
|
137
|
+
const seeded = import_node_path.default.join(import_node_os.default.homedir(), ".swiftpm");
|
|
138
|
+
const dirAbsentBefore = lstatIfKnown(seeded) === null;
|
|
139
|
+
const absentBefore = swiftpmSeeds.filter(
|
|
140
|
+
(name) => lstatIfKnown(import_node_path.default.join(seeded, name)) === null
|
|
141
|
+
);
|
|
142
|
+
process.once("exit", () => {
|
|
143
|
+
import_node_fs.default.rmSync(dir, { recursive: true, force: true });
|
|
144
|
+
for (const name of absentBefore) removeSwiftpmSeed(import_node_path.default.join(seeded, name), name);
|
|
145
|
+
if (dirAbsentBefore && lstatIfKnown(seeded)?.isDirectory())
|
|
146
|
+
try {
|
|
147
|
+
import_node_fs.default.rmdirSync(seeded);
|
|
148
|
+
} catch {
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
var swiftpmSeeds = ["cache", "configuration", "security"];
|
|
153
|
+
function lstatIfKnown(entry) {
|
|
154
|
+
try {
|
|
155
|
+
return import_node_fs.default.lstatSync(entry);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
|
|
158
|
+
return void 0;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function removeSwiftpmSeed(entry, name) {
|
|
162
|
+
const stat = lstatIfKnown(entry);
|
|
163
|
+
if (!stat) return;
|
|
164
|
+
try {
|
|
165
|
+
if (name === "cache") {
|
|
166
|
+
if (stat.isSymbolicLink() && import_node_fs.default.readlinkSync(entry).endsWith("/.cache/org.swift.swiftpm"))
|
|
167
|
+
import_node_fs.default.unlinkSync(entry);
|
|
168
|
+
} else if (stat.isDirectory()) {
|
|
169
|
+
import_node_fs.default.rmdirSync(entry);
|
|
170
|
+
}
|
|
171
|
+
} catch {
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function processRuns(pid) {
|
|
175
|
+
try {
|
|
176
|
+
process.kill(pid, 0);
|
|
177
|
+
return true;
|
|
178
|
+
} catch (error) {
|
|
179
|
+
return error instanceof Error && "code" in error && error.code === "EPERM";
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function swiftEnvironment(base = process.env) {
|
|
183
|
+
if (!scratch) return base;
|
|
184
|
+
return swiftHome ? { ...base, TMPDIR: scratch, HOME: swiftHome } : { ...base, TMPDIR: scratch };
|
|
185
|
+
}
|
|
63
186
|
function swiftToolchain(release, sdk) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
71
|
-
}) : "";
|
|
72
|
-
if (!version.includes(`(${swiftCompilerRelease(release)})`)) {
|
|
73
|
-
const found = version ? `found ${version.split("\n")[0]?.trim()} at ${swift}` : process.platform === "darwin" ? `found no ${release}.xctoolchain in ~/Library/Developer/Toolchains or /Library/Developer/Toolchains` : "found no swift on PATH";
|
|
187
|
+
validateSwiftSdkIdentity(sdk);
|
|
188
|
+
let bin;
|
|
189
|
+
try {
|
|
190
|
+
bin = swiftCompiler(release);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
74
193
|
throw new Error(
|
|
75
|
-
`
|
|
194
|
+
`Swift compiler ${release} is unavailable or differs from its pin: ${reason}
|
|
76
195
|
${swiftInstallSteps(release, sdk)}`
|
|
77
196
|
);
|
|
78
197
|
}
|
|
79
|
-
const
|
|
198
|
+
const swift = import_node_path.default.join(bin, "swift");
|
|
199
|
+
const sdks = (0, import_node_child_process.execFileSync)(swift, ["sdk", "list", ...swiftSdkOptions()], {
|
|
80
200
|
encoding: "utf8",
|
|
201
|
+
env: swiftEnvironment(),
|
|
81
202
|
stdio: ["ignore", "pipe", "pipe"]
|
|
82
203
|
});
|
|
83
204
|
if (!sdks.split("\n").some((line) => line.trim() === sdk.wasmSdkId)) {
|
|
84
205
|
throw new Error(
|
|
85
206
|
`peach compiles Swift with the ${sdk.wasmSdkId} SDK, which ${swift} does not have.
|
|
86
|
-
${
|
|
207
|
+
${swiftSdkInstallStep(release, sdk)}`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
verifySwiftSdk(swift, sdk);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
214
|
+
throw new Error(`${reason}
|
|
215
|
+
${swiftSdkInstallStep(release, sdk)}`);
|
|
216
|
+
}
|
|
217
|
+
return bin;
|
|
218
|
+
}
|
|
219
|
+
function validateSwiftSdkIdentity(sdk) {
|
|
220
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(sdk.wasmSdkId) || !/^[a-f0-9]{64}$/.test(sdk.wasmSdkChecksum))
|
|
221
|
+
throw new Error("invalid Swift SDK identity or checksum");
|
|
222
|
+
}
|
|
223
|
+
function swiftSdkBundle(swift, id, options) {
|
|
224
|
+
const configuration = (0, import_node_child_process.execFileSync)(
|
|
225
|
+
swift,
|
|
226
|
+
["sdk", "configure", ...options, "--show-configuration", id, "wasm32-unknown-wasip1"],
|
|
227
|
+
{ encoding: "utf8", env: swiftEnvironment(), stdio: ["ignore", "pipe", "pipe"] }
|
|
228
|
+
);
|
|
229
|
+
const sysroot = /^sdkRootPath: (.+)$/m.exec(configuration)?.[1]?.trim();
|
|
230
|
+
if (!sysroot || !import_node_path.default.isAbsolute(sysroot))
|
|
231
|
+
throw new Error(`Swift SDK ${id} reports no absolute sdkRootPath`);
|
|
232
|
+
let bundle = sysroot;
|
|
233
|
+
while (!bundle.endsWith(".artifactbundle")) {
|
|
234
|
+
const parent = import_node_path.default.dirname(bundle);
|
|
235
|
+
if (parent === bundle)
|
|
236
|
+
throw new Error(`Swift SDK ${id} is outside an artifact bundle`);
|
|
237
|
+
bundle = parent;
|
|
238
|
+
}
|
|
239
|
+
return import_node_fs.default.realpathSync(bundle);
|
|
240
|
+
}
|
|
241
|
+
var sdkFileHashes = /* @__PURE__ */ new Map();
|
|
242
|
+
function swiftSdkPayloadChecksum(bundle) {
|
|
243
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
244
|
+
function visit(relative) {
|
|
245
|
+
const file = import_node_path.default.join(bundle, relative);
|
|
246
|
+
const stat = import_node_fs.default.lstatSync(file, { bigint: true });
|
|
247
|
+
if (stat.isSymbolicLink()) {
|
|
248
|
+
const resolved = import_node_path.default.relative(bundle, import_node_fs.default.realpathSync(file));
|
|
249
|
+
if (resolved === ".." || resolved.startsWith(`..${import_node_path.default.sep}`) || import_node_path.default.isAbsolute(resolved))
|
|
250
|
+
throw new Error(`Swift SDK symlink escapes its bundle: ${relative}`);
|
|
251
|
+
hash.update(JSON.stringify([relative, "link", import_node_fs.default.readlinkSync(file)]) + "\n");
|
|
252
|
+
} else if (stat.isDirectory()) {
|
|
253
|
+
hash.update(JSON.stringify([relative, "directory"]) + "\n");
|
|
254
|
+
for (const name of import_node_fs.default.readdirSync(file).sort()) visit(import_node_path.default.join(relative, name));
|
|
255
|
+
} else if (stat.isFile()) {
|
|
256
|
+
const stamp = [stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(":");
|
|
257
|
+
let cached = sdkFileHashes.get(file);
|
|
258
|
+
if (cached?.stamp !== stamp) {
|
|
259
|
+
cached = { stamp, checksum: swiftFileChecksum(file) };
|
|
260
|
+
sdkFileHashes.set(file, cached);
|
|
261
|
+
}
|
|
262
|
+
hash.update(
|
|
263
|
+
JSON.stringify([relative, "file", Number(stat.mode & 0o111n), cached.checksum]) + "\n"
|
|
264
|
+
);
|
|
265
|
+
} else throw new Error(`unsupported Swift SDK payload entry: ${relative}`);
|
|
266
|
+
}
|
|
267
|
+
visit("");
|
|
268
|
+
return hash.digest("hex");
|
|
269
|
+
}
|
|
270
|
+
function swiftSdkVerificationFile(bundle, sdk) {
|
|
271
|
+
return import_node_path.default.join(
|
|
272
|
+
import_node_path.default.dirname(bundle),
|
|
273
|
+
".peach-sdk-checksums",
|
|
274
|
+
`${sdk.wasmSdkId}-${sdk.wasmSdkChecksum}.json`
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
function verifySwiftSdk(swift, sdk) {
|
|
278
|
+
const bundle = swiftSdkBundle(swift, sdk.wasmSdkId, swiftSdkOptions());
|
|
279
|
+
const file = swiftSdkVerificationFile(bundle, sdk);
|
|
280
|
+
if (!import_node_fs.default.existsSync(file))
|
|
281
|
+
throw new Error(
|
|
282
|
+
`Swift SDK ${sdk.wasmSdkId} has no verified archive binding for ${sdk.wasmSdkChecksum}. Hydrate it with installSwiftWasmSdk before compiling.`
|
|
283
|
+
);
|
|
284
|
+
const receipt = JSON.parse(import_node_fs.default.readFileSync(file, "utf8"));
|
|
285
|
+
if (!receipt || typeof receipt !== "object" || !("wasmSdkId" in receipt) || receipt.wasmSdkId !== sdk.wasmSdkId || !("wasmSdkChecksum" in receipt) || receipt.wasmSdkChecksum !== sdk.wasmSdkChecksum || !("payloadChecksum" in receipt) || receipt.payloadChecksum !== swiftSdkPayloadChecksum(bundle))
|
|
286
|
+
throw new Error(
|
|
287
|
+
`Swift SDK ${sdk.wasmSdkId} installed payload differs from its verified archive ${sdk.wasmSdkChecksum}`
|
|
87
288
|
);
|
|
289
|
+
}
|
|
290
|
+
function installSwiftSdkArchive(swift, sdk, archive) {
|
|
291
|
+
validateSwiftSdkIdentity(sdk);
|
|
292
|
+
const staging = import_node_fs.default.realpathSync(
|
|
293
|
+
import_node_fs.default.mkdtempSync(import_node_path.default.join(scratch ?? import_node_os.default.tmpdir(), "peach-sdk-verification-"))
|
|
294
|
+
);
|
|
295
|
+
try {
|
|
296
|
+
if (swiftFileChecksum(archive) !== sdk.wasmSdkChecksum)
|
|
297
|
+
throw new Error("declared Swift SDK archive checksum mismatch");
|
|
298
|
+
const store = import_node_path.default.join(staging, "sdks");
|
|
299
|
+
import_node_fs.default.mkdirSync(store);
|
|
300
|
+
(0, import_node_child_process.execFileSync)(
|
|
301
|
+
swift,
|
|
302
|
+
[
|
|
303
|
+
"sdk",
|
|
304
|
+
"install",
|
|
305
|
+
archive,
|
|
306
|
+
"--checksum",
|
|
307
|
+
sdk.wasmSdkChecksum,
|
|
308
|
+
"--swift-sdks-path",
|
|
309
|
+
store
|
|
310
|
+
],
|
|
311
|
+
{ env: swiftEnvironment(), stdio: "inherit" }
|
|
312
|
+
);
|
|
313
|
+
const stagedBundle = swiftSdkBundle(swift, sdk.wasmSdkId, [
|
|
314
|
+
"--swift-sdks-path",
|
|
315
|
+
store
|
|
316
|
+
]);
|
|
317
|
+
const expected = swiftSdkPayloadChecksum(stagedBundle);
|
|
318
|
+
const directory = process.env.PEACH_SWIFT_SDKS_PATH;
|
|
319
|
+
const locks = directory ? import_node_path.default.join(import_node_path.default.resolve(directory), ".peach-locks") : import_node_path.default.join(import_node_os.default.homedir(), ".swiftpm", "builder-locks");
|
|
320
|
+
import_node_fs.default.mkdirSync(locks, { recursive: true });
|
|
321
|
+
(0, import_node_child_process.execFileSync)(
|
|
322
|
+
"perl",
|
|
323
|
+
[
|
|
324
|
+
"-e",
|
|
325
|
+
'use Fcntl qw(:flock); my ($lock, $id, $bundle, $swift, @options) = @ARGV; open(my $fd, ">>", $lock) or die $!; flock($fd, LOCK_EX) or die $!; open(my $list, "-|", $swift, "sdk", "list", @options) or die $!; my $found = 0; while (<$list>) { s/^\\s+|\\s+$//g; $found = 1 if $_ eq $id; } close($list) or die "swift sdk list failed"; unless ($found) { system($swift, "sdk", "install", $bundle, @options); exit(($? & 127) ? 128 + ($? & 127) : $? >> 8); }',
|
|
326
|
+
import_node_path.default.join(locks, "wasm-sdk.lock"),
|
|
327
|
+
sdk.wasmSdkId,
|
|
328
|
+
stagedBundle,
|
|
329
|
+
swift,
|
|
330
|
+
...swiftSdkOptions()
|
|
331
|
+
],
|
|
332
|
+
{ env: swiftEnvironment(), stdio: "inherit" }
|
|
333
|
+
);
|
|
334
|
+
const bundle = swiftSdkBundle(swift, sdk.wasmSdkId, swiftSdkOptions());
|
|
335
|
+
if (swiftSdkPayloadChecksum(bundle) !== expected)
|
|
336
|
+
throw new Error(
|
|
337
|
+
`Swift SDK ${sdk.wasmSdkId} already exists with different payload bytes; select a separate --swift-sdks-path. No installed SDK was replaced.`
|
|
338
|
+
);
|
|
339
|
+
const file = swiftSdkVerificationFile(bundle, sdk);
|
|
340
|
+
import_node_fs.default.mkdirSync(import_node_path.default.dirname(file), { recursive: true });
|
|
341
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
342
|
+
try {
|
|
343
|
+
import_node_fs.default.writeFileSync(
|
|
344
|
+
temporary,
|
|
345
|
+
JSON.stringify({
|
|
346
|
+
wasmSdkId: sdk.wasmSdkId,
|
|
347
|
+
wasmSdkChecksum: sdk.wasmSdkChecksum,
|
|
348
|
+
payloadChecksum: expected
|
|
349
|
+
}) + "\n"
|
|
350
|
+
);
|
|
351
|
+
import_node_fs.default.renameSync(temporary, file);
|
|
352
|
+
} finally {
|
|
353
|
+
import_node_fs.default.rmSync(temporary, { force: true });
|
|
354
|
+
}
|
|
355
|
+
} finally {
|
|
356
|
+
import_node_fs.default.rmSync(staging, { recursive: true, force: true });
|
|
357
|
+
for (const file of sdkFileHashes.keys())
|
|
358
|
+
if (file.startsWith(staging + import_node_path.default.sep)) sdkFileHashes.delete(file);
|
|
88
359
|
}
|
|
89
|
-
|
|
360
|
+
}
|
|
361
|
+
function installSwiftWasmSdk(release, sdk) {
|
|
362
|
+
validateSwiftSdkIdentity(sdk);
|
|
363
|
+
try {
|
|
364
|
+
swiftToolchain(release, sdk);
|
|
365
|
+
return;
|
|
366
|
+
} catch {
|
|
367
|
+
}
|
|
368
|
+
const swift = import_node_path.default.join(swiftCompiler(release), "swift");
|
|
369
|
+
const staging = import_node_fs.default.mkdtempSync(import_node_path.default.join(scratch ?? import_node_os.default.tmpdir(), "builder-swift-sdk-"));
|
|
370
|
+
const archive = import_node_path.default.join(staging, "sdk.artifactbundle.tar.gz");
|
|
371
|
+
try {
|
|
372
|
+
if (sdk.wasmSdkUrl.startsWith("file:"))
|
|
373
|
+
import_node_fs.default.copyFileSync((0, import_node_url.fileURLToPath)(sdk.wasmSdkUrl), archive);
|
|
374
|
+
else
|
|
375
|
+
(0, import_node_child_process.execFileSync)("curl", ["-fsSL", sdk.wasmSdkUrl, "-o", archive], { stdio: "inherit" });
|
|
376
|
+
installSwiftSdkArchive(swift, sdk, archive);
|
|
377
|
+
swiftToolchain(release, sdk);
|
|
378
|
+
} finally {
|
|
379
|
+
import_node_fs.default.rmSync(staging, { recursive: true, force: true });
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
function swiftFileChecksum(file) {
|
|
383
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
384
|
+
const fd = import_node_fs.default.openSync(file, "r");
|
|
385
|
+
const buffer = Buffer.allocUnsafe(1024 * 1024);
|
|
386
|
+
try {
|
|
387
|
+
let size = import_node_fs.default.readSync(fd, buffer, 0, buffer.length, null);
|
|
388
|
+
while (size > 0) {
|
|
389
|
+
hash.update(buffer.subarray(0, size));
|
|
390
|
+
size = import_node_fs.default.readSync(fd, buffer, 0, buffer.length, null);
|
|
391
|
+
}
|
|
392
|
+
} finally {
|
|
393
|
+
import_node_fs.default.closeSync(fd);
|
|
394
|
+
}
|
|
395
|
+
return hash.digest("hex");
|
|
396
|
+
}
|
|
397
|
+
function verifySwiftHostCompiler(release, root) {
|
|
398
|
+
const pin = swiftHostCompilerArchive(release);
|
|
399
|
+
const file = import_node_path.default.join(root, "compiler.json");
|
|
400
|
+
if (swiftFileChecksum(file) !== pin.manifest)
|
|
401
|
+
throw new Error(`Swift compiler manifest mismatch at ${root}`);
|
|
402
|
+
const manifest = JSON.parse(import_node_fs.default.readFileSync(file, "utf8"));
|
|
403
|
+
if (!manifest || typeof manifest !== "object" || !("identity" in manifest) || manifest.identity !== pin.identity || !("host" in manifest) || manifest.host !== `${process.platform}-${process.arch}` || !("files" in manifest) || !manifest.files || typeof manifest.files !== "object") {
|
|
404
|
+
throw new Error(`Swift compiler identity mismatch at ${root}`);
|
|
405
|
+
}
|
|
406
|
+
const files = Object.entries(manifest.files);
|
|
407
|
+
if (files.length !== 16) throw new Error("incomplete Swift compiler manifest");
|
|
408
|
+
for (const [relative, checksum] of files) {
|
|
409
|
+
if (relative.startsWith("/") || relative.split("/").includes("..") || typeof checksum !== "string" || swiftFileChecksum(import_node_path.default.join(root, relative)) !== checksum) {
|
|
410
|
+
throw new Error(`Swift compiler binary mismatch: ${relative}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
var verifiedCompilers = /* @__PURE__ */ new Map();
|
|
415
|
+
function swiftCompiler(release) {
|
|
416
|
+
const cached = verifiedCompilers.get(release);
|
|
417
|
+
if (cached) return cached;
|
|
418
|
+
const bin = swiftToolchainBin(release);
|
|
419
|
+
if (release.includes("-custom-"))
|
|
420
|
+
verifySwiftHostCompiler(release, import_node_path.default.resolve(bin, "../.."));
|
|
421
|
+
const version = (0, import_node_child_process.execFileSync)(import_node_path.default.join(bin, "swift"), ["--version"], {
|
|
422
|
+
encoding: "utf8",
|
|
423
|
+
env: swiftEnvironment(),
|
|
424
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
425
|
+
});
|
|
426
|
+
if (!version.includes(`(${swiftCompilerRelease(release)})`))
|
|
427
|
+
throw new Error(`compiler release mismatch at ${bin}`);
|
|
428
|
+
verifiedCompilers.set(release, bin);
|
|
90
429
|
return bin;
|
|
91
430
|
}
|
|
431
|
+
function swiftSdkInstallStep(release, wasmSdk) {
|
|
432
|
+
return `install the pinned SDK:
|
|
433
|
+
${swiftSdkInstallCommand(release, wasmSdk)}`;
|
|
434
|
+
}
|
|
435
|
+
function swiftSdkInstallCommand(release, wasmSdk) {
|
|
436
|
+
const { wasmSdkId, wasmSdkUrl, wasmSdkChecksum } = wasmSdk;
|
|
437
|
+
const program = `import { installSwiftWasmSdk } from "peachsim/swift-toolchain"; installSwiftWasmSdk(${JSON.stringify(release)}, ${JSON.stringify({ wasmSdkId, wasmSdkUrl, wasmSdkChecksum })})`;
|
|
438
|
+
const directory = process.env.PEACH_SWIFT_SDKS_PATH;
|
|
439
|
+
const environment = directory ? `PEACH_SWIFT_SDKS_PATH='${import_node_path.default.resolve(directory).replaceAll("'", "'\\''")}' ` : "";
|
|
440
|
+
return `${environment}node --input-type=module -e '${program.replaceAll("'", "'\\''")}'`;
|
|
441
|
+
}
|
|
92
442
|
function swiftInstallSteps(release, wasmSdk) {
|
|
443
|
+
const { note, commands } = swiftCompilerInstall(release);
|
|
444
|
+
return [
|
|
445
|
+
`install the pinned compiler and SDK${note}:`,
|
|
446
|
+
...[...commands, swiftSdkInstallCommand(release, wasmSdk)].map((line) => ` ${line}`)
|
|
447
|
+
].join("\n");
|
|
448
|
+
}
|
|
449
|
+
function swiftCompilerInstallSteps(release) {
|
|
450
|
+
const { note, commands } = swiftCompilerInstall(release);
|
|
451
|
+
return [
|
|
452
|
+
`install the pinned compiler${note}:`,
|
|
453
|
+
...commands.map((line) => ` ${line}`)
|
|
454
|
+
].join("\n");
|
|
455
|
+
}
|
|
456
|
+
function swiftCompilerInstall(release) {
|
|
457
|
+
if (release.includes("-custom-")) {
|
|
458
|
+
const archive = swiftHostCompilerArchive(release);
|
|
459
|
+
const directory = import_node_path.default.resolve(swiftToolchainBin(release), "../..");
|
|
460
|
+
return {
|
|
461
|
+
note: "",
|
|
462
|
+
commands: [
|
|
463
|
+
`curl -fsSL ${archive.url} -o compiler.tar.gz`,
|
|
464
|
+
`echo '${archive.checksum} compiler.tar.gz' | shasum -a 256 -c -`,
|
|
465
|
+
`mkdir -p '${directory}'`,
|
|
466
|
+
`tar -xzf compiler.tar.gz --strip-components=1 -C '${directory}'`
|
|
467
|
+
]
|
|
468
|
+
};
|
|
469
|
+
}
|
|
93
470
|
const version = release.replace(/^swift-/, "").toLowerCase();
|
|
94
471
|
const downloads = `https://download.swift.org/swift-${version}`;
|
|
95
|
-
const sdk = `swift sdk install ${wasmSdk.wasmSdkUrl} --checksum ${wasmSdk.wasmSdkChecksum}`;
|
|
96
472
|
if (process.platform === "darwin") {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
473
|
+
return {
|
|
474
|
+
note: "",
|
|
475
|
+
commands: [
|
|
476
|
+
`curl -fsSLO ${downloads}/xcode/${release}/${release}-osx.pkg`,
|
|
477
|
+
`installer -pkg ${release}-osx.pkg -target CurrentUserHomeDirectory`
|
|
478
|
+
]
|
|
479
|
+
};
|
|
104
480
|
}
|
|
105
481
|
const platform = `debian12${process.arch === "arm64" ? "-aarch64" : ""}`;
|
|
106
482
|
const name = `${release}-${platform}`;
|
|
107
|
-
return
|
|
108
|
-
"
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
483
|
+
return {
|
|
484
|
+
note: " (Debian 12 shown; other distributions: https://www.swift.org/install/linux/)",
|
|
485
|
+
commands: [
|
|
486
|
+
`curl -fsSL ${downloads}/${platform}/${release}/${name}.tar.gz | tar -xz -C /opt`,
|
|
487
|
+
`export PATH=/opt/${name}/usr/bin:$PATH`
|
|
488
|
+
]
|
|
489
|
+
};
|
|
113
490
|
}
|
|
114
491
|
// Annotate the CommonJS export names for ESM import in node:
|
|
115
492
|
0 && (module.exports = {
|
|
493
|
+
SWIFT_HOST_COMPILER_ID,
|
|
494
|
+
SWIFT_HOST_COMPILER_RELEASE,
|
|
495
|
+
confineSwiftScratch,
|
|
496
|
+
installSwiftWasmSdk,
|
|
497
|
+
swiftCompiler,
|
|
498
|
+
swiftCompilerInstallSteps,
|
|
116
499
|
swiftCompilerRelease,
|
|
500
|
+
swiftEnvironment,
|
|
501
|
+
swiftFileChecksum,
|
|
502
|
+
swiftHostCompilerArchive,
|
|
117
503
|
swiftInstallSteps,
|
|
504
|
+
swiftSdkInstallStep,
|
|
505
|
+
swiftSdkOptions,
|
|
118
506
|
swiftToolchain,
|
|
119
|
-
swiftToolchainBin
|
|
507
|
+
swiftToolchainBin,
|
|
508
|
+
swiftUpstreamRelease,
|
|
509
|
+
verifySwiftHostCompiler
|
|
120
510
|
});
|
package/dist-lib/swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|