(targets: Target[], mode: BuildMode)
| 392 | const EMBEDDED_MIGRATIONS_STUB = `const migrations: Record<string, string> | null = null;\n\nexport default migrations;\n`; |
| 393 | |
| 394 | const buildBinaries = async (targets: Target[], mode: BuildMode) => { |
| 395 | const meta = await readMetadata(); |
| 396 | const binaries: Record<string, string> = {}; |
| 397 | const embeddedWebUIPath = join(cliRoot, "src/embedded-web-ui.gen.ts"); |
| 398 | const embeddedMigrationsPath = join(webRoot, "src/db/embedded-migrations.gen.ts"); |
| 399 | |
| 400 | await rm(distDir, { recursive: true, force: true }); |
| 401 | |
| 402 | // Cross-platform builds need every target's optional native packages |
| 403 | // (e.g. @napi-rs/keyring-darwin-arm64) so we can copy the right .node next |
| 404 | // to each target's executor. `bun install --frozen-lockfile --cpu=* --os=*` |
| 405 | // extracts them all without modifying the lockfile. |
| 406 | const needsCrossPlatform = targets.some((t) => !isCurrentPlatform(t)); |
| 407 | if (needsCrossPlatform) { |
| 408 | console.log("Installing optional native deps for all platforms..."); |
| 409 | const proc = Bun.spawn(["bun", "install", "--frozen-lockfile", "--cpu=*", "--os=*"], { |
| 410 | cwd: repoRoot, |
| 411 | stdio: ["ignore", "inherit", "inherit"], |
| 412 | }); |
| 413 | if ((await proc.exited) !== 0) { |
| 414 | throw new Error("bun install --cpu=* --os=* failed"); |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | console.log(`Generating embedded web UI bundle (${mode})...`); |
| 419 | const embeddedWebUI = await createEmbeddedWebUISource(mode); |
| 420 | await writeFile(embeddedWebUIPath, `${embeddedWebUI}\n`); |
| 421 | |
| 422 | console.log("Generating embedded drizzle migrations..."); |
| 423 | const embeddedMigrations = await createEmbeddedMigrationsSource(); |
| 424 | await writeFile(embeddedMigrationsPath, `${embeddedMigrations}\n`); |
| 425 | |
| 426 | const quickJsWasmPath = resolveQuickJsWasmPath(); |
| 427 | const mcpAppsShellPath = await ensureMcpAppsShell(); |
| 428 | const onePasswordCoreWasmPath = resolveOnePasswordCoreWasmPath(); |
| 429 | const workerBundlerDistPath = resolveWorkerBundlerDistPath(); |
| 430 | const packedWorkerBundlerSource = await createPackedWorkerBundlerSource(workerBundlerDistPath); |
| 431 | |
| 432 | try { |
| 433 | for (const target of targets) { |
| 434 | const name = targetPackageName(target); |
| 435 | const outDir = join(distDir, name); |
| 436 | const binDir = join(outDir, "bin"); |
| 437 | await mkdir(binDir, { recursive: true }); |
| 438 | |
| 439 | console.log(`Building ${name}...`); |
| 440 | |
| 441 | await Bun.build({ |
| 442 | entrypoints: [join(cliRoot, "src/main.ts")], |
| 443 | minify: mode === "production", |
| 444 | compile: { |
| 445 | target: bunTarget(target), |
| 446 | outfile: join(binDir, binaryName(target)), |
| 447 | }, |
| 448 | }); |
| 449 | |
| 450 | // Copy QuickJS WASM next to binary — loaded at runtime by the server |
| 451 | await cp(quickJsWasmPath, join(binDir, "emscripten-module.wasm")); |
no test coverage detected