/** * Bake `migrations/` into a TypeScript module so the migrator can be a single * self-contained binary. * * `drizzle-kit migrate` reads the folder at runtime, which is the right shape * on a laptop and the wrong one on a server: the deploy agent ships flat, * checksummed files into `bin/`, and a migrator that needs a directory beside * it is a migrator that can be run against the wrong directory. Embedding * removes the question — the binary *is* the migration set, and its checksum * covers every statement it will run. * * Run before `bun build --compile`. It runs on every build rather than being * committed, so the embedded set cannot drift from the folder. * * bun run packages/core/scripts/embed-migrations.ts */ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; const here = path.dirname(new URL(import.meta.url).pathname); const folder = path.join(here, '..', 'migrations'); const out = path.join(here, '..', 'src', 'migrations.generated.ts'); type JournalEntry = { idx: number; when: number; tag: string; breakpoints: boolean }; const journal = JSON.parse(fs.readFileSync(path.join(folder, 'meta', '_journal.json'), 'utf8')) as { entries: JournalEntry[]; }; // Deliberately identical to drizzle-orm's own `readMigrationFiles`: the same // `--> statement-breakpoint` split, the same sha256 over the whole file, the // same `when` as the ordering key. The live database was migrated by // drizzle-kit, so anything else here would re-apply migrations that have // already run. const migrations = journal.entries.map((e) => { const sql = fs.readFileSync(path.join(folder, `${e.tag}.sql`), 'utf8'); return { tag: e.tag, sql: sql.split('--> statement-breakpoint'), bps: e.breakpoints, folderMillis: e.when, hash: crypto.createHash('sha256').update(sql).digest('hex') }; }); fs.writeFileSync( out, `// Generated by scripts/embed-migrations.ts. Do not edit.\n` + `// ${migrations.length} migrations, ${migrations.at(-1)?.tag ?? 'none'} last.\n` + `export type Embedded = {\n` + `\ttag: string;\n\tsql: string[];\n\tbps: boolean;\n\tfolderMillis: number;\n\thash: string;\n};\n\n` + `export const MIGRATIONS: Embedded[] = ${JSON.stringify(migrations, null, '\t')};\n` ); console.log(`embedded ${migrations.length} migrations -> ${path.relative(process.cwd(), out)}`);