/** * Bundle transpile/apply drivers. * * Adapters that plug this package's AST transforms into the pgpm migration * bundle seams (`transpileBundle`'s `renameChange`/`transformScript` and * `applyBundle`'s `validateReferences`). The seams are structurally typed on * purpose — no dependency on `@pgpmjs/bundle`/`@pgpmjs/core` — so the driver * stays a pure function factory over `transformSql` and `classifyStatements`. */ import { ExtensionDefinition, ExtensionRouter, ExtensionRouteSpec, ExtensionTransformResult, RoleRouteSpec, RoleTransformResult, SchemaRouter, SchemaTransformResult, TransformSqlOptions } from '@pgsql/transform'; /** Identity of the script being transformed/validated (matches the bundle seams). */ export interface BundleScriptContext { change: string; kind: 'deploy' | 'revert' | 'verify'; } /** * A single object-level route: send one named object out of a source schema to * a different target schema, independent of the schema-level default. The * object `kind` selects the routing namespace (relation / function / type) so a * table and a function of the same name route independently. */ export interface SchemaObjectRoute { /** Source schema the object is defined in (e.g. `users`). */ fromSchema: string; /** Object namespace. `table`/`view` → relation, `procedure` → function. */ kind: 'table' | 'view' | 'function' | 'procedure' | 'type'; /** Unqualified object name (e.g. `accounts`). */ name: string; /** * Target schema this object is routed to (e.g. `reporting`). `null` strips * qualification (resolve via `search_path`); omitted with `toName` leaves * the schema to the whole-schema default. */ toSchema?: string | null; /** * Target object name — rebinds references to a *different* object (e.g. * point `identity.current_actor()` at `current_user_id()`). At least one of * `toSchema`/`toName` must be given. */ toName?: string; } /** * Extension routing for a transpile: where to install extensions and where the * symbols they provide (functions/types/operators) should resolve. Distinct * from schema routing — the objects are owned by an extension, not declared in * the SQL — so it is driven by a version-aware symbol inventory. See the * upstream `ExtensionRouter` for the full model. `toSchema: null` (or a `routes` * entry with `to: null`) strips qualification — the "rely on search_path" * direction — so the same mechanism moves symbols into a dedicated schema and * back out again. */ export interface ExtensionRoutingInput { /** * Move the matched extensions and their provided symbols to this single * schema (`null` strips qualification). Ignored when `routes` is given. */ toSchema?: string | null; /** With `toSchema`: limit to these extensions (default: every inventoried one). */ only?: string[]; /** * With `toSchema`: which source qualifications to rewrite (a `null` entry * also rewrites bare references). Defaults to `public` + bare. */ from?: (string | null)[]; /** Advanced: explicit per-extension route spec. Overrides `toSchema`/`only`/`from`. */ routes?: ExtensionRouteSpec; /** Target PostgreSQL major version, for core-graduation awareness (e.g. `gen_random_uuid`). */ serverVersion?: number; /** Augmented or replacement symbol inventory (defaults to the curated common set). */ inventory?: ExtensionDefinition[]; } /** * Build an {@link ExtensionRouter} from the declarative {@link ExtensionRoutingInput}: * an explicit `routes` spec when given, otherwise the "move everything matched * to one schema" shortcut via `ExtensionRouter.toSchema`. */ export declare function buildExtensionRouter(input: ExtensionRoutingInput): ExtensionRouter; export interface SchemaTranspilerOptions { /** * Whole-schema default: source schema → target schema. Optional when * `routes` fully cover the objects being moved. */ schemaMap?: Record; /** * Object-level overrides. Each route wins over the schema-level default for * its specific object, letting a single source schema fan out per object. */ routes?: SchemaObjectRoute[]; /** * Route extension installs and provided-symbol references (a dimension * orthogonal to schema routing). See {@link ExtensionRoutingInput}. */ extensions?: ExtensionRoutingInput; /** * Rename role identifiers (source role name → target role name), for * translating between databases that name equivalent roles differently. * Renames identifiers only — never role attributes. */ roles?: RoleRouteSpec | Map; /** Forwarded to {@link transformSql} (round-trip validation, extra passes). */ transform?: TransformSqlOptions; } /** * Build a {@link SchemaRouter} from a schema-level default map plus object * routes. Object routes are grouped into the router's relation/function/type * buckets; schema-level entries become each route's default target. */ export declare function buildSchemaRouter(options: SchemaTranspilerOptions): SchemaRouter; export interface SchemaTranspiler { /** * Change-name/path rewrite (the pgpm structural dimension): rewrites the * schema segment of a change path to the object's routed target. The object * identity is read from the path itself — `schemas///` — * so a table and a function under the same source schema can land in * different target schemas, e.g. `schemas/users/tables/accounts/table` → * `schemas/tenant_a/tables/accounts/table` while * `schemas/users/procedures/account_count` → `schemas/reporting/procedures/account_count`. */ renameChange: (name: string) => string; /** * SQL body rewrite (the AST dimension): full AST transform of every mapped * schema reference via {@link transformSql}, including PL/pgSQL bodies. * Throws if a mapped schema survives untransformed. */ transformScript: (sql: string, ctx: BundleScriptContext) => string; /** * Accumulated report across every script this transpiler has transformed: * schemas found/transformed and any per-script errors. */ result: SchemaTransformResult; /** * Accumulated extension-routing report (installs moved, symbols rewritten). * Present only when `extensions` was configured. */ extensionResult?: ExtensionTransformResult; /** * Accumulated role-routing report (role → rewrite count). Present only when * `roles` was configured. */ roleResult?: RoleTransformResult; } /** * Build the caller-supplied callbacks for `transpileBundle` from a schema map * and/or object routes, so the folder/plan rename (change identity) and the * in-SQL rewrite (AST) stay in lockstep on the exact same {@link SchemaRouter}. */ export declare function makeSchemaTranspiler(options: SchemaTranspilerOptions): SchemaTranspiler; export interface NamespaceValidatorOptions { /** Schemas the bundle is allowed to create objects in or reference. */ allowedSchemas: string[]; /** * Also flag statements whose PL/pgSQL bodies execute dynamic SQL — their * references are invisible to the AST, so containment cannot be proven. * Off by default (dynamic SQL is common in legitimate functions). */ flagDynamicSql?: boolean; } /** * Build an `applyBundle`-compatible `validateReferences` callback: returns a * description of every schema-qualified object a script creates or references * outside the allowed namespace. Unqualified references resolve via * search_path and are not reported. */ export declare function makeNamespaceValidator(options: NamespaceValidatorOptions): (sql: string, ctx: BundleScriptContext) => string[];