import { type Kysely } from "kysely"; import { type LedgerDialect, type LedgerOptions } from "./ledger.js"; import { splitSqlStatements } from "../sql/split-statements.js"; export { splitSqlStatements }; export interface ApplyPendingOptions { /** When true, compute + return the plan but apply nothing. */ dryRun: boolean; /** * Target dialect. Decides ledger schema-qualification (pg) and whether the * Postgres advisory lock is taken. Defaults to `sqlite` (no schema, no lock) * to preserve the original single-DB behavior for callers that omit it. */ dialect?: LedgerDialect; /** Multi-tenant ledger location + advisory-lock name. Defaults preserve current behavior. */ ledger?: LedgerOptions; } export interface ApplyPendingResult { /** Migration names that were pending (not yet in the ledger), in order. */ pending: string[]; /** Migration names that were applied this run, in order. Empty on dryRun. */ applied: string[]; } /** * A committed migration's SQL failed. Carries WHICH one, because the driver's error says * only what the database refused ("no such table: purchases") and never which file asked. * * The position matters to callers, not just the name: `--replay` prescribes a different * remedy at the HEAD of the chain, where nothing earlier in this chain could have created * what the migration needs, so the base schema must come from outside it. */ export declare class MigrationApplyError extends Error { /** `-` directory name of the migration that failed. */ readonly migration: string; /** 0-based position among the PENDING migrations this run attempted. */ readonly index: number; /** How many migrations were pending when the run started. */ readonly pendingCount: number; readonly cause: unknown; constructor( /** `-` directory name of the migration that failed. */ migration: string, /** 0-based position among the PENDING migrations this run attempted. */ index: number, /** How many migrations were pending when the run started. */ pendingCount: number, cause: unknown); } /** * Apply pending committed migration files in order, tracked by the * migration-history ledger, transactionally. * * Idempotency comes from the LEDGER (skip names already recorded), NOT from * re-diffing — so hand-authored files + data steps replay exactly once. * * For each pending migration (sorted by directory name), the file's SQL and a * `recordApplied` row are run in the SAME Kysely transaction; any failure rolls * back that file's tx, leaving it unrecorded (so a re-run retries it), and * stops the run. Previously-applied files are checksum-compared against the * ledger — a changed file errors (tamper guard). */ export declare function applyPending(db: Kysely>, dir: string, opts: ApplyPendingOptions): Promise; export interface RollbackToOptions { /** Target dialect. Decides ledger schema-qualification + advisory lock. Defaults to `sqlite`. */ dialect?: LedgerDialect; /** Multi-tenant ledger location + advisory-lock name. Defaults preserve current behavior. */ ledger?: LedgerOptions; } export interface RollbackToResult { /** Migration names rolled back, in execution (reverse-chronological) order. */ rolledBack: string[]; } /** * Roll back applied migrations newer than `target` (or all, when `target` is * `null`), in REVERSE lexical order — running each migration's `down.sql` then * deleting its ledger row, in ONE transaction per migration. `target` is itself * retained (only ledger names strictly-greater than it are rolled back; lexical * = chronological given the zero-padded timestamp prefix). * * An empty / whitespace-only `down.sql` THROWS before that migration is * unrecorded — data-migration downs are hand-authored and must never be * silently skipped. `down.sql` is split with the same {@link splitSqlStatements} * the up-path uses. Wrapped in the same Postgres session advisory lock as * {@link applyPending} (no-op on SQLite). */ export declare function rollbackTo(db: Kysely>, dir: string, target: string | null, opts?: RollbackToOptions): Promise; //# sourceMappingURL=apply.d.ts.map