| 1 | import { DatabaseSync } from "node:sqlite"; |
| 2 | import { readdirSync, readFileSync } from "node:fs"; |
| 3 | import { join } from "node:path"; |
| 4 | |
| 5 | /** A D1Database over node:sqlite with every migration applied: enough for prepare/bind/first/all/run and batch. */ |
| 6 | export function testD1(): D1Database & { sqlite: DatabaseSync } { |
| 7 | const db = new DatabaseSync(":memory:"); |
| 8 | const dir = join(import.meta.dirname, "../../../migrations"); |
| 9 | for (const f of readdirSync(dir).filter((f) => f.endsWith(".sql")).sort()) db.exec(readFileSync(join(dir, f), "utf8")); |
| 10 | const statement = (query: string, bindings: unknown[] = []) => ({ |
| 11 | bind: (...b: unknown[]) => statement(query, b), |
| 12 | first: async <T>() => (db.prepare(query).get(...(bindings as never[])) as T | undefined) ?? null, |
| 13 | all: async <T>() => ({ results: db.prepare(query).all(...(bindings as never[])) as T[], success: true, meta: {} }), |
| 14 | run: async () => { |
| 15 | const r = db.prepare(query).run(...(bindings as never[])); |
| 16 | return { success: true, meta: { changes: Number(r.changes) } }; |
| 17 | }, |
| 18 | }); |
| 19 | return { |
| 20 | sqlite: db, |
| 21 | prepare: (q: string) => statement(q), |
| 22 | batch: async (stmts: Array<{ run: () => Promise<unknown> }>) => Promise.all(stmts.map((s) => s.run())), |
| 23 | } as unknown as D1Database & { sqlite: DatabaseSync }; |
| 24 | } |