Repository Public
1import { readFile, readdir } from "node:fs/promises";2import path from "node:path";3import { createHash } from "node:crypto";4import "./_env";5import { sql } from "../src/lib/db";67/** Applies db/migrations/*.sql in order, once each (checksummed). */8async function main() {9 await sql`CREATE TABLE IF NOT EXISTS schema_migrations (name text PRIMARY KEY, checksum text NOT NULL, applied_at timestamptz NOT NULL DEFAULT now())`;10 const dir = path.join(process.cwd(), "db/migrations");11 for (const name of (await readdir(dir)).filter((f) => f.endsWith(".sql")).sort()) {12 const body = await readFile(path.join(dir, name), "utf8");13 const checksum = createHash("sha256").update(body).digest("hex");14 const [done] = await sql<{ checksum: string }[]>`SELECT checksum FROM schema_migrations WHERE name = ${name}`;15 if (done) { if (done.checksum !== checksum) throw new Error(`Migration ${name} was modified after being applied`); continue; }16 await sql.begin(async (tx) => { await tx.unsafe(body); await tx`INSERT INTO schema_migrations (name, checksum) VALUES (${name}, ${checksum})`; });17 console.log(`applied ${name}`);18 }19 await sql.end();20}21main().catch((e) => { console.error(e.message); process.exit(1); });22