import * as mf from "miniflare";
import { getDefaultPersistPath } from "./miniflare/paths.js";
export const applyLocalD1Migrations = async (options) => {
    const miniflare = new mf.Miniflare({
        script: "",
        modules: true,
        defaultPersistRoot: getDefaultPersistPath(options.rootDir),
        d1Persist: true,
        d1Databases: { DB: options.databaseId },
        log: process.env.DEBUG ? new mf.Log(mf.LogLevel.DEBUG) : undefined,
    });
    try {
        await miniflare.ready;
        const db = await miniflare.getD1Database("DB");
        const session = db.withSession("first-primary");
        const tableInfo = await session
            .prepare(`PRAGMA table_info(${options.migrationsTable});`)
            .all();
        if (tableInfo.results.length === 0) {
            await session
                .prepare(`CREATE TABLE ${options.migrationsTable} (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
        type TEXT NOT NULL
    )`)
                .run();
        }
        else if (!tableInfo.results.some((col) => col.name === "type")) {
            await session
                .prepare(`ALTER TABLE ${options.migrationsTable} ADD COLUMN type TEXT NOT NULL DEFAULT 'migration';`)
                .run();
        }
        const applied = await session
            .prepare(`SELECT name, type FROM ${options.migrationsTable} ORDER BY applied_at ASC`)
            .all();
        const insertRecord = session.prepare(`INSERT INTO ${options.migrationsTable} (name, type) VALUES (?, ?)`);
        for (const { id, sql } of options.migrations) {
            if (applied.results.some((m) => m.name === id)) {
                continue;
            }
            const statements = sql
                .split("--> statement-breakpoint")
                .filter((s) => s.trim())
                .map((s) => session.prepare(s));
            statements.push(insertRecord.bind(id, "migration"));
            await session.batch(statements);
        }
        for (const { id, sql, hash } of options.imports) {
            const name = `${id}-${hash}`;
            if (applied.results.some((m) => m.name === name)) {
                continue;
            }
            // Split into statements to prevent D1_ERROR: statement too long: SQLITE_TOOBIG.
            // This is split naively by semicolons followed by newlines - not perfect but should work 99% of the time.
            const statements = sql
                .split(/;\r?\n/)
                .filter((s) => s.trim())
                .map((s) => session.prepare(s));
            statements.push(insertRecord.bind(name, "import"));
            await session.batch(statements);
        }
    }
    finally {
        await miniflare.dispose();
    }
};
//# sourceMappingURL=d1-local-migrations.js.map