(options: SelfhostBootOptions)
| 24 | } |
| 25 | |
| 26 | export const bootSelfhost = async (options: SelfhostBootOptions): Promise<BootedProcesses> => { |
| 27 | const dataDir = options.dataDir ?? resolve(selfhostDir, ".e2e-data"); |
| 28 | if (options.fresh ?? true) rmSync(dataDir, { recursive: true, force: true }); |
| 29 | |
| 30 | const procs = bootProcesses( |
| 31 | [ |
| 32 | { |
| 33 | cmd: "bunx", |
| 34 | args: [ |
| 35 | "--bun", |
| 36 | "vite", |
| 37 | "dev", |
| 38 | "--port", |
| 39 | String(options.port), |
| 40 | "--strictPort", |
| 41 | ...(options.host ? ["--host", options.host] : []), |
| 42 | ], |
| 43 | cwd: selfhostDir, |
| 44 | env: { |
| 45 | EXECUTOR_DATA_DIR: dataDir, |
| 46 | BETTER_AUTH_SECRET: "executor-selfhost-e2e-secret-0123456789", |
| 47 | EXECUTOR_BOOTSTRAP_ADMIN_EMAIL: options.admin.email, |
| 48 | EXECUTOR_BOOTSTRAP_ADMIN_PASSWORD: options.admin.password, |
| 49 | EXECUTOR_WEB_BASE_URL: options.webBaseUrl, |
| 50 | // The harness boots loopback MCP/OAuth test servers and points the |
| 51 | // instance at them; the hosted SSRF guard would otherwise block |
| 52 | // outbound probes/dials to localhost. Hermetic test instance only. |
| 53 | EXECUTOR_ALLOW_LOCAL_NETWORK: "true", |
| 54 | }, |
| 55 | logFile: options.logFile, |
| 56 | }, |
| 57 | ], |
| 58 | { label: "selfhost" }, |
| 59 | ); |
| 60 | |
| 61 | try { |
| 62 | // Probe via `localhost`, not 127.0.0.1 — without --host, vite binds the |
| 63 | // resolver's first answer for localhost (::1 on macOS), so the IPv4 |
| 64 | // loopback literal never answers. |
| 65 | await waitForHttp(`http://localhost:${options.port}`); |
| 66 | } catch (error) { |
| 67 | await procs.teardown(); |
| 68 | throw error; |
| 69 | } |
| 70 | return procs; |
| 71 | }; |
no test coverage detected