/** * Versioned schema migrations, shared by the Postgres and SQLite adapters. * * Each adapter's tables form a component, such as `operations:nexus_operations`, with numbered * migrations. The database records which ran, with a checksum of their statements, so an upgrade * applies only what is new and an edited migration is refused instead of silently ignored. */ /** One numbered schema change to one adapter's tables. */ export interface SchemaMigration { /** * The tables it belongs to, such as `operations:nexus_operations`. Versions count per component, * so two operation stores on two tables migrate independently. */ component: string; /** Its number, from 1, in the order it applies. */ version: number; /** What it does, in a few words. */ name: string; /** * Its statements, in order. Every bundled statement is idempotent (`IF NOT EXISTS`), so a migration * interrupted between statements on a database without transactional DDL runs again safely. */ statements: readonly string[]; } /** A migration the database has recorded as applied. */ export interface AppliedMigration { /** Its component. */ component: string; /** Its version. */ version: number; /** Its name when it ran. */ name: string; /** The checksum of its statements when it ran. */ checksum: string; /** ISO-8601 time it was applied. */ appliedAt: string; } /** Where a database stands against the migrations this code knows. */ export interface MigrationStatus { /** Recorded migrations, oldest first. */ applied: AppliedMigration[]; /** Known migrations not yet applied, in the order `migrate()` would apply them. */ pending: SchemaMigration[]; /** * Applied migrations whose statements have changed since: an edited migration, or adapter options, * such as a vector width, that differ from those it ran with. `migrate()` refuses to run while any * remain. */ changed: Array<{ migration: SchemaMigration; applied: AppliedMigration; }>; /** * Recorded migrations this code does not know, written by a newer release. Expected while a rollout * runs two versions side by side, since every migration only adds. */ unknown: AppliedMigration[]; /** True when nothing is pending or changed. */ current: boolean; } /** What one `migrate()` call did, or with `dryRun`, would do. */ export interface MigrationResult { /** Migrations applied, or with `dryRun`, pending. */ applied: SchemaMigration[]; /** The statements run, or with `dryRun`, that would run, in order. */ statements: string[]; /** Whether nothing was written. */ dryRun: boolean; } /** Raised when migrations cannot run safely: a changed migration, a bad list, or a lock held too long. */ export declare class SchemaMigrationError extends Error { /** A stable code: `MIGRATION_CHANGED`, `MIGRATION_INVALID`, or `MIGRATION_LOCKED`. */ readonly code: 'MIGRATION_CHANGED' | 'MIGRATION_INVALID' | 'MIGRATION_LOCKED'; constructor(code: SchemaMigrationError['code'], message: string); } /** The default table that records applied migrations. */ export declare const MIGRATIONS_TABLE = "nexus_schema_migrations"; /** * A checksum of a migration's statements: cyrb53, a fast 53-bit hash, as 14 hex digits. * * It detects a migration edited after it ran; it is not a security boundary, so it needs no crypto * module and runs anywhere a driver does. Line endings are normalized, so a checkout on Windows * computes the same value as one on Linux. */ export declare function migrationChecksum(migration: Pick): string; /** @internal Refuses a list with a gap, a duplicate, or an empty migration, before anything runs. */ export declare function validateMigrations(migrations: readonly SchemaMigration[]): void; /** @internal Compares known migrations with recorded ones. */ export declare function planMigrations(known: readonly SchemaMigration[], applied: readonly AppliedMigration[]): MigrationStatus; /** @internal Refuses to migrate while an applied migration has changed. */ export declare function assertUnchanged(status: MigrationStatus): void; /** @internal A SQL string literal. Values here are component names and checksums, never user input. */ export declare function sqlLiteral(value: string): string; /** @internal */ export declare function label(migration: Pick): string; /** @internal Waits, for lock polling. */ export declare function delay(ms: number): Promise;