/** * Opt-in qualification of unqualified object references. * * Handwritten SQL is typically unqualified — objects implicitly land in (and * resolve against) the `public` schema. The core schema transform only * rewrites *explicitly* qualified references, so ingesting such code into * named schemas needs a prior pass that pins every unqualified reference to a * schema first. This module provides that pass. * * Safety model: only routed names are qualified — either everything in an * {@link ObjectInventory} to a single schema, or per-object routes via * `targets`. Builtin functions (`now()`, `count(...)`), builtin types, and * column references are never touched because they are not routed. Names * defined by a CTE in the same statement are excluded even when they collide * with a routed relation. */ /** Named objects eligible for qualification, bucketed by namespace. */ export interface ObjectInventory { /** Tables, views, sequences — anything a RangeVar can reference. */ relations: Set; /** Function and procedure names. */ functions: Set; /** Enum/domain/range/composite type names. */ types: Set; } /** The objects a target schema should receive, by namespace. */ export interface QualifyTargetSelector { relations?: Iterable; functions?: Iterable; types?: Iterable; } export interface QualifyUnqualifiedOptions { /** * Single-target form: schema to pin unqualified references to (e.g. * `'public'`). Mutually exclusive with `targets`. */ schema?: string; /** * Names eligible for qualification (single-target form only). Defaults to * the objects created by the content itself ({@link collectCreatedObjects}). * When qualifying scripts that reference objects created elsewhere (e.g. * the scripts of a whole module), collect the inventory across all scripts * and pass it here. */ inventory?: ObjectInventory; /** * Multi-target form: route specific objects to specific schemas in one * pass. Mutually exclusive with `schema`/`inventory`. * * ```ts * qualifyUnqualified(sql, { * targets: { * auth: { relations: ['users'] }, * shop: { relations: ['products'], functions: ['get_products'] }, * shared: { types: ['widget'] } * } * }); * ``` * * Routing a name to two schemas in the same namespace is a conflict and * throws. */ targets?: Record; /** * Prepend `CREATE SCHEMA IF NOT EXISTS ;` for every target schema * the content does not already create. Useful when ingesting standalone * handwritten SQL whose target schemas may not exist. */ injectCreateSchema?: boolean; } export interface QualifyResult { /** Count of references qualified, keyed by object name. */ qualified: Map; /** Schema each qualified object was routed to. */ routed: Map; } /** Resolved name → schema routing, by namespace. */ export interface QualifyRoutes { relations: Map; functions: Map; types: Map; } /** * Collect the objects a SQL script creates, bucketed for qualification. * Only unqualified (schema-less) creations are collected — an explicitly * qualified creation already declares where it lives. */ export declare function collectCreatedObjects(sql: string): ObjectInventory; /** Merge inventories collected from multiple scripts. */ export declare function mergeInventories(inventories: ObjectInventory[]): ObjectInventory; /** * Create a SQL AST visitor that qualifies unqualified references against a * routing table. Composable with the walkers used by the core transform. */ export declare function createQualifyVisitor(options: { routes: QualifyRoutes; cteNames?: Set; }, result: QualifyResult): { RangeVar: (path: any) => void; FuncCall: (path: any) => void; CallStmt: (path: any) => void; TypeName: (path: any) => void; CreateFunctionStmt: (path: any) => void; CreateTrigStmt: (path: any) => void; ObjectWithArgs: (path: any) => void; CreateEnumStmt: (path: any) => void; CreateRangeStmt: (path: any) => void; CreateDomainStmt: (path: any) => void; }; /** * Qualify unqualified references in a SQL string. * * Two forms: * - `{ schema, inventory? }` — pin every inventoried name to one schema. * - `{ targets }` — route specific objects to specific schemas in one pass. * * Runs as a standalone AST pass (parse → qualify → deparse). To combine with * a schema rename, run this first (typically with `schema: 'public'`) and * then map via the core transform — or use the `qualifyUnqualified` option on * `transformSql`, which does exactly that. */ export declare function qualifyUnqualified(sql: string, options: QualifyUnqualifiedOptions): { sql: string; result: QualifyResult; };