import type { Database } from "bun:sqlite";
import type { ScopedDb, ScopedStatement, ScopedValue } from "./scoped-db/types";
/**
* Test double for `~/server/scoped-db` that routes every repository and account to one bun:sqlite database
* (typically the test's full D1 schema). For integration-style tests that seed and assert on one database:
* scoped queries in the code under test always filter by their owner, so sharing the file is equivalent.
* Use `memoryScopes()` from `scoped-db/testing` when isolation between scopes matters.
*/
export function sharedScopes(db: Database) {
const meta = (result: { changes: number; lastInsertRowid: number | bigint }) => ({
meta: { changes: result.changes, last_row_id: Number(result.lastInsertRowid) },
});
const make = (scopeId: string): ScopedDb => ({
scopeId,
async first<T>(sql: string, ...params: ScopedValue[]) {
return (db.query(sql).get(...params) as T | null) ?? null;
},
async all<T>(sql: string, ...params: ScopedValue[]) {
return db.query(sql).all(...params) as T[];
},
async run(sql: string, ...params: ScopedValue[]) {
return meta(db.query(sql).run(...params));
},
async batch(statements: ScopedStatement[]) {
return db.transaction(() =>
statements.map((statement) => meta(db.query(statement.sql).run(...statement.params))),
)();
},
});
return {
repoDb: make,
accountDb: make,
stmt: (sql: string, ...params: ScopedValue[]): ScopedStatement => ({ sql, params }),
};
}