/** * Runs one statement in a repository's or account's Durable Object database through the dev server's * `/__dev/scoped-sql` route (enabled with EMAIL_DEV_SINK=kv on a loopback forge), the scoped counterpart of * `wrangler d1 execute`. Synchronous like the D1 helpers, so it shells out to a one-line fetch. */ export function scopedSqlRows>( base: string, scope: "repo" | "account", id: string, sql: string, ): T[] { const script = `const url = process.argv[1]; const r = await fetch(url, { method: "POST", headers: { "content-type": "application/json", origin: new URL(url).origin, "sec-fetch-site": "same-origin" }, body: process.argv[2] }); if (!r.ok) { console.error(r.status, await r.text()); process.exit(1); } process.stdout.write(await r.text());`; const result = Bun.spawnSync(["bun", "-e", script, `${base}/__dev/scoped-sql`, JSON.stringify({ scope, id, sql })], { stderr: "pipe", stdout: "pipe", }); if (result.exitCode !== 0) throw new Error(`scoped sql failed: ${result.stderr.toString()}`); return JSON.parse(result.stdout.toString()) as T[]; } /** Runs a command from `root`, returning stdout; throws with stderr on failure. */ export function sh(root: string, cmd: string[]): string { const result = Bun.spawnSync(cmd, { cwd: root, stdout: "pipe", stderr: "pipe" }); if (result.exitCode !== 0) throw new Error(`${cmd.join(" ")} failed: ${result.stderr.toString()}`); return result.stdout.toString(); } /** `wrangler d1 execute --local` against the checkout at `root`, for the directory tables that stay in D1. */ export function d1Rows(root: string, sql: string): Array> { const out = sh(root, ["bunx", "wrangler", "d1", "execute", "gitfor", "--local", "--json", "--command", sql]); return (JSON.parse(out) as Array<{ results: Array> }>)[0]?.results ?? []; }