Loading...
Loading...
Authoring, building, validating, and running PostgreSQL database migrations with the @schemavaults/dbh package. Use when a project depends on @schemavaults/dbh and you are creating or editing Kysely migration files, setting up a migrations/ directory, or when the user mentions migrations, up()/down(), schema changes, or the dbh CLI's migrate / build-db-migrations / validate-migration-directory commands.
npx skill4agent add schemavaults/dbh database-migrations@schemavaults/dbhdbhup()down()bunx @schemavaults/dbhbuild-db-migrationsnpx @schemavaults/dbhmigratereversesql@/sqlsql./src/db/sql.ts// src/db/sql.ts
export { sql, sql as default } from "@schemavaults/dbh/sql";
export type * from "@schemavaults/dbh/sql";@/sqltsconfig.json{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/sql": ["./src/db/sql.ts"]
}
}
}./src/db/migrations/00000-template-migration.ts00001-create-users-table.tsup(db)down(db)up()down()00040-*.tsupdownKysely<any>PromiseKyselyimport type { Kysely } from "@schemavaults/dbh"Kysely<any>// 00001-create-users-table.ts
import type { Kysely } from "@schemavaults/dbh";
export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.createTable("users")
.addColumn("user_id", "uuid", (col) => col.primaryKey())
.addColumn("email", "text", (col) => col.notNull().unique())
.addColumn("created_at", "bigint", (col) => col.notNull())
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema.dropTable("users").execute();
}sqlsql@/sqlsql.execute(db)// 00002-create-squirrels-table.ts
import type { Kysely } from "@schemavaults/dbh";
import { sql } from "@/sql";
export async function up(db: Kysely<any>): Promise<void> {
await sql`
CREATE TABLE IF NOT EXISTS EXAMPLE_SQUIRRELS (
squirrel_id UUID PRIMARY KEY,
squirrel_name TEXT NOT NULL,
created_at BIGINT NOT NULL
);
`.execute(db);
// Always interpolate values via ${...}; the sql tag parameterizes them.
await sql`CREATE INDEX squirrels_name_idx ON EXAMPLE_SQUIRRELS (squirrel_name);`.execute(
db,
);
}
export async function down(db: Kysely<any>): Promise<void> {
await sql`DROP TABLE IF EXISTS EXAMPLE_SQUIRRELS;`.execute(db);
}Important: migration files must always importfromsql, never directly from@/sql. The@schemavaults/dbh/sqlstep rewrites the literalbuild-db-migrationsimport specifier to a relative path pointing at the built, standalone@/sql, so the import must be written exactly assql.jsfor the build to work. (This is why the one-time setup configures the@/sqlalias.)@/sql
// 00000-template-migration.ts
import type { Kysely } from "@schemavaults/dbh";
export async function up(
db: Kysely<any>, // eslint-disable-line @typescript-eslint/no-unused-vars
): Promise<void> {}
export async function down(
db: Kysely<any>, // eslint-disable-line @typescript-eslint/no-unused-vars
): Promise<void> {}validate-migration-directory0bunx @schemavaults/dbh validate-migration-directory ./src/db/migrations[ERROR][WARN]up()down()--duplicates-as-warnings@/sqltsconfig.jsoncompilerOptions.pathsextends--tsconfig <path>migrate.jsbuild-db-migrationssql--sql-modulesql.tsbunx @schemavaults/dbh build-db-migrations ./src/db/migrations \
--outdir ./dist/migrations \
--sql-module ./src/db/sql.ts \
--sql-outdir ./dist<migrations-src>.ts--outdir <dir>.js--sql-module <path>sql.ts--sql-outdir <dir>sql.js--outdir--external <pkg...>@schemavaults/dbhkyselybuild-db-migrationsbunmigratereverse--environmentprocess.env--env-filenpx# Apply all pending migrations (to latest):
npx @schemavaults/dbh migrate ./dist/migrations --environment production --env-file ./.env.production
# Apply up to a specific version (the migration name w/o extension):
npx @schemavaults/dbh migrate ./dist/migrations 00001-create-users-table --environment staging
# Roll back down to a target version:
npx @schemavaults/dbh reverse ./dist/migrations 00000-template-migration --environment stagingmigratereverse<folder>[version]<version>migratereverse-e, --environment <env>development | test | staging | production--ws-proxy-url <url>--env-file <path>.env[Up|Down] <migrationName>: <Success|Error|NotExecuted>@schemavaults/dbh/migrateimport { migrate, reverse } from "@schemavaults/dbh/migrate";
await migrate({ db: adapter.db, migrationFolder, version /* optional */ });
await reverse({ db: adapter.db, migrationFolder, version });# 1. Validate the source migrations directory.
bunx @schemavaults/dbh validate-migration-directory ./src/db/migrations
# 2. Build .ts migrations (+ sql module) to .js.
bunx @schemavaults/dbh build-db-migrations ./src/db/migrations \
--outdir ./dist/migrations --sql-module ./src/db/sql.ts --sql-outdir ./dist
# 3. Apply the built migrations (npx / Node.js — pg drivers target Node).
npx @schemavaults/dbh migrate ./dist/migrations --environment production --env-file ./.env.productionPOSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_URLPOSTGRES_HOSTPOSTGRES_PORTPOSTGRES_DATABASEPOSTGRES_URL_NON_POOLINGSCHEMAVAULTS_DBH_DEBUG=true