// Adapts better-sqlite3 to the Cloudflare Durable Object SQL interface, so the // DO adapter's SQL and logic can run under plain vitest. This does NOT exercise // the DO runtime itself — that is covered by the PLATFORM=cloudflare e2e path // once later phases add endpoints touching space storage. /** * @typedef {Object} D1ShimCursor * @property {() => any[]} toArray */ /** * @param {import('better-sqlite3').Database} db * @returns {{ * sql: {exec: (query: string, ...params: any[]) => D1ShimCursor}, * storage: {transactionSync: (fn: () => any) => any}, * }} */ export function createD1Shim(db) { return { sql: { /** * @param {string} query * @param {...any} params * @returns {D1ShimCursor} */ exec(query, ...params) { const trimmed = query.trim(); // The DO's exec accepts multi-statement DDL; better-sqlite3 needs // .exec() for that, and .prepare() rejects it. if (params.length === 0 && trimmed.includes(';')) { db.exec(query); return { toArray: () => [] }; } const stmt = db.prepare(query); if (/^\s*select/i.test(trimmed)) { const rows = stmt.all(...params); return { toArray: () => rows }; } stmt.run(...params); return { toArray: () => [] }; }, }, storage: { /** * @param {() => any} fn * @returns {any} */ transactionSync(fn) { db.exec('BEGIN'); try { const result = fn(); db.exec('COMMIT'); return result; } catch (err) { db.exec('ROLLBACK'); throw err; } }, }, }; }