/** * Apply pending Drizzle migrations against the configured Postgres provider. * * Invoked by `pnpm db:migrate`. Branches on environment: * * - **Production / staging** (`DATABASE_URL` set, NODE_ENV=production): uses * `@raredays/postgres-neon` by default. Swap the import if you've migrated * to `@raredays/postgres-js`. * - **Dev with persistent Postgres** (`DATABASE_URL` set, any NODE_ENV): * same path as production — connects to the URL. * - **Dev fallback** (no `DATABASE_URL`): boots PGlite in-process so the * command always exits cleanly. PGlite is ephemeral, so migrations against * it only validate that the SQL parses; nothing is persisted. * * Wraps Drizzle's `migrate()` with `@raredays/postgres/migrations`'s * `safeMigrate` to acquire an advisory lock (preventing concurrent * migration runs) and emit structured logs. * * Exit codes: 0 on success, 1 on any failure. */ import { resolve } from "node:path"; import { safeMigrate } from "@raredays/postgres/migrations"; import * as appSchema from "./schema.ts"; const migrationsFolder = resolve(import.meta.dirname, "migrations"); const appKey = process.env.npm_package_name ?? "raredays-app"; const databaseUrl = process.env.DATABASE_URL; async function main(): Promise { if (databaseUrl) { // Neon HTTP path. If you've swapped to @raredays/postgres-js, change // both imports below to match. const { createDb } = await import("@raredays/postgres-neon"); const { migrate } = await import("drizzle-orm/neon-http/migrator"); const db = createDb(databaseUrl, { schema: appSchema }); await safeMigrate({ db, migrate, migrationsFolder, appKey }); return; } // Dev fallback: PGlite in-process. Migrations apply against an ephemeral // database so this command never fails for missing config. console.warn( "[db:migrate] DATABASE_URL is not set — falling back to in-process PGlite. " + "Set DATABASE_URL to persist migrations.", ); const { createPglite } = await import("@raredays/postgres-pglite"); const { migrate } = await import("drizzle-orm/pglite/migrator"); const handle = await createPglite({ schema: appSchema }); try { await safeMigrate({ db: handle.db, migrate, migrationsFolder, appKey, // PGlite supports advisory locks but they're meaningless in-process. useAdvisoryLock: false, }); } finally { await handle.close(); } } main().catch((err) => { console.error("[db:migrate] failed:", err); process.exit(1); });