/** * Neon branch-canary orchestration. * * Verifies pending drizzle migrations against a real copy of the target * environment's database (a Neon copy-on-write branch) BEFORE touching the * real database: * * 1. Branch the target env's Neon branch (copy-on-write, instant). * 2. Apply the pending drizzle migrations against the branch's connection. * 3. Diff the branch schema vs its parent → the DDL that WOULD land. * 4. Surface the DDL. If `apply` is set (flag / approval), run the same * migrations against the real env connection. * 5. Always delete the branch — success or failure. * * Everything with a side effect is injected: the Neon HTTP client (mockable), * the migration runner, and the logger. That's what lets the whole flow be * unit-tested with zero network and no live NEON_API_KEY. */ import type { NeonClient } from './neon.js'; import { type ResolvedNeonTarget } from './neon-target.js'; /** * Applies the pending drizzle migrations against a given connection string. * Injected so tests observe "which connection got migrated" without spawning * drizzle-kit, and so production can wire it to the real runner. */ export type MigrationRunner = (args: { connectionString: string; /** `branch` for the canary copy, `target` for the real env DB. */ phase: 'branch' | 'target'; }) => Promise; export interface CanaryLogger { info(message: string): void; warn(message: string): void; ddl(diff: string): void; } export interface RunCanaryOptions { client: NeonClient; target: ResolvedNeonTarget; runMigrations: MigrationRunner; /** When true, apply the verified migrations to the real env after the diff. */ apply?: boolean; logger?: CanaryLogger; /** Injectable clock for branch naming, so tests get deterministic names. */ now?: () => Date; } export interface CanaryResult { /** The canary branch that was created (id), if creation succeeded. */ branchId?: string; branchName: string; /** The schema DDL diff between the canary branch and its parent. */ ddl: string; /** Whether the diff was non-empty (real schema change detected). */ hasChanges: boolean; /** Whether migrations were applied to the REAL env DB. */ applied: boolean; /** Whether the canary branch was cleaned up. */ cleanedUp: boolean; } /** * Run the branch-canary flow. Throws on any orchestration failure AFTER * attempting branch cleanup; the thrown error is the original cause. The * returned result's `cleanedUp` reflects the actual teardown outcome. */ export declare function runNeonCanary(options: RunCanaryOptions): Promise; //# sourceMappingURL=neon-canary.d.ts.map