| @@ -76,6 +76,30 @@ const binaryName = (t: Target) => · 75 unmodified lines |
| 76 | 76 | const isCurrentPlatform = (t: Target) => |
| 77 | 77 | t.os === process.platform && t.arch === process.arch && !t.abi; |
| 78 | 78 | |
| 79 | +/** Resolve the platform-specific secure-exec-v8 binary for a given target. */ |
| 80 | +const resolveSecureExecV8 = (t: Target): string | null => { |
| 81 | + const platformMap: Record<string, string> = { |
| 82 | + "darwin-arm64": "@secure-exec/v8-darwin-arm64", |
| 83 | + "darwin-x64": "@secure-exec/v8-darwin-x64", |
| 84 | + "linux-arm64": "@secure-exec/v8-linux-arm64-gnu", |
| 85 | + "linux-x64": "@secure-exec/v8-linux-x64-gnu", |
| 86 | + }; |
| 87 | + const key = `${t.os}-${t.arch}`; |
| 88 | + const pkg = platformMap[key]; |
| 89 | + if (!pkg) return null; |
| 90 | + try { |
| 91 | + // Resolve from @secure-exec/v8 which has these as optional deps |
| 92 | + const req = createRequire(join(repoRoot, "node_modules", "secure-exec", "package.json")); |
| 93 | + const pkgJson = req.resolve(`${pkg}/package.json`); |
| 94 | + return join(dirname(pkgJson), "secure-exec-v8"); |
| 95 | + } catch { |
| 96 | + // Try bun's flat node_modules layout |
| 97 | + const bunPath = join(repoRoot, `node_modules/.bun/${pkg.replace("/", "+")}@0.2.1/node_modules/${pkg}/secure-exec-v8`); |
| 98 | + if (existsSync(bunPath)) return bunPath; |
| 99 | + return null; |
| 100 | + } |
| 101 | +}; |
| 102 | + |
| 79 | 103 | // --------------------------------------------------------------------------- |
| 80 | 104 | // Build web app |
| 81 | 105 | // --------------------------------------------------------------------------- |
| @@ -231,6 +255,14 @@ const buildBinaries = async (targets: Target[]) => { · 149 unmodified lines |
| 231 | 255 | // Copy QuickJS WASM next to binary — loaded at runtime by the server |
| 232 | 256 | await cp(quickJsWasmPath, join(binDir, "emscripten-module.wasm")); |
| 233 | 257 | |
| 258 | + // Copy secure-exec-v8 binary next to executor — needed for code execution |
| 259 | + const secureExecBin = resolveSecureExecV8(target); |
| 260 | + if (secureExecBin && existsSync(secureExecBin)) { |
| 261 | + const destName = target.os === "win32" ? "secure-exec-v8.exe" : "secure-exec-v8"; |
| 262 | + await cp(secureExecBin, join(binDir, destName)); |
| 263 | + await chmod(join(binDir, destName), 0o755); |
| 264 | + } |
| 265 | + |
| 234 | 266 | // Smoke test on current platform |
| 235 | 267 | if (isCurrentPlatform(target)) { |
| 236 | 268 | const bin = join(binDir, binaryName(target)); |