import { QualifiedName } from '@pgsql/semantics'; import { CategoryProfile, ChangeCategory } from './categorize'; /** * A change plus its deploy SQL. Optional plan `dependencies` (from `pgpm.plan`) * are followed as authoritative prerequisites in addition to AST-derived edges. */ export interface ClosureInputChange { name: string; sql: string; dependencies?: string[]; } /** Why a change ended up in the closure. */ export type ClosureReason = 'selected' | 'prerequisite' | 'fixture'; /** * A change included in the closure, with its category and the reason it was pulled. */ export interface ClosureChange { name: string; category: ChangeCategory; reason: ClosureReason; } /** * The fixture closure of a schema slice. * * Everything the selected changes need to actually *work*: schema/functionality * prerequisites they depend on, plus the fixtures that attach to them (policies, * grants, RLS enables, role bindings, seed rows / SPRT-style support changes). * References that nothing in the input produces are surfaced in `unresolved` * rather than silently dropped. */ export interface FixtureClosure { /** Full closure (selection + prerequisites + fixtures) in input/plan order. */ order: string[]; /** Per-change detail in the same order as {@link order}. */ changes: ClosureChange[]; /** Closure members categorized as security/fixtures (attached fixtures). */ fixtures: string[]; /** Non-selected schema/functionality members pulled in as prerequisites. */ prerequisites: string[]; /** Roles required across the closure. */ roles: string[]; /** Requirements no input change produces — explicit, never dropped. */ unresolved: { objects: QualifiedName[]; schemas: string[]; roles: string[]; }; } export interface ResolveFixtureClosureOptions { /** Category profile used to label changes (default {@link TIER_PROFILE}). */ profile?: CategoryProfile; /** * When false, do not follow AST references from selected changes to their * schema/functionality producers (only pull attached fixtures + plan deps). * Default true. */ includePrerequisites?: boolean; } /** * Resolve the fixture closure of a schema slice. * * Pure and deterministic — no I/O — and runs to a fixpoint in both directions: * - forward: a selected change pulls in the producers of the objects/schemas/ * roles it references, plus its declared plan dependencies (prerequisites); * - reverse: any fixture (security/fixtures-tier change) that attaches to an * object already in the closure is pulled in (attached fixtures), and then * resolved for its own prerequisites. * * Output order follows the input (plan) order, so it stays deploy-safe. */ export declare function resolveFixtureClosure(allChanges: ClosureInputChange[], selection: string[], options?: ResolveFixtureClosureOptions): FixtureClosure;