/** * Neon canary target resolution — the "resolve a target environment → Neon * branch + project" seam. * * This is the one coordination point with the `environments` config work. The * environments block lives on the database PROVIDER entry (owned by that * track), NOT at the top level of quickback.config.ts: * * providers.database.environments?: { * [name: string]: { * branch?: string; // Neon branch this env deploys against * }; * } * * `providers.database` can also be the split-services form * (`{ auth, features }`) — two separate provider entries with no single * `environments` map. That shape has no environments to read, so resolution * returns `null` (see below). * * The Neon PROJECT id is NOT part of that block — it comes from `NEON_PROJECT_ID` * (env), falling back to a project-level `neon.projectId` in the config. The API * key always comes from `NEON_API_KEY` and is never persisted in config. * * When the resolver returns `null`, branching is not configured for this env and * the caller MUST fall back to the plain (unchanged) deploy path — the canary is * strictly additive and opt-in. */ import type { LoadedConfig } from './file-loader.js'; export interface ResolvedNeonTarget { /** Neon project id (from NEON_PROJECT_ID or config.neon.projectId). */ projectId: string; /** Neon API key (from NEON_API_KEY). */ apiKey: string; /** The environment name being deployed (e.g. `production`, `staging`). */ env: string; /** The parent Neon branch this env maps to (from environments[env].neonBranch). */ parentBranch: string; /** Optional Postgres role/database overrides for connection strings + diffs. */ role?: string; database?: string; /** Optional REST base override (NEON_API_BASE), passed through to NeonClient. */ baseUrl?: string; } /** * Config shape this resolver reads. Kept structurally narrow (and optional) so * it composes with `LoadedConfig`'s index signature without fighting the * environments track's own typings. */ export interface NeonCanaryConfigView { neon?: { projectId?: string; role?: string; database?: string; }; providers?: { /** * The database provider entry. In the single-provider form it carries an * `environments` map (`{ : { branch } }`). In the split-services form * it's `{ auth, features }` — two separate entries with no `environments`, * which resolution treats as "not configured" (→ null). */ database?: { environments?: Record; }; }; } export interface ResolveNeonTargetInput { env: string; config: LoadedConfig | NeonCanaryConfigView; /** Process env, injectable for tests. Defaults to `process.env`. */ processEnv?: NodeJS.ProcessEnv; } /** * Resolve a target environment to a concrete Neon canary target, or `null` * when branching is not configured (missing env mapping, missing project id, * or missing API key). Returning `null` — never throwing — is what keeps the * feature behavior-preserving: an unconfigured project sails straight past the * canary into the existing deploy path. */ export declare function resolveNeonTarget(input: ResolveNeonTargetInput): ResolvedNeonTarget | null; /** * Deterministic-ish canary branch name for an env. Timestamped so repeated * canaries don't collide, and prefixed so they're easy to spot (and sweep) in * the Neon console. */ export declare function canaryBranchName(env: string, now?: Date): string; //# sourceMappingURL=neon-target.d.ts.map