/** * Reading validation rules out of CHECK constraints. * * A CHECK constraint is the schema author stating a rule the database already * enforces. Introspection has never read them, so a generated form let the user * type a value the database was always going to reject — the rule was written * down, in the schema, and the UI asked anyway. * * Everything here parses the *normalized* text `pg_get_constraintdef` produces, * not what the author typed: Postgres re-renders the expression from its parse * tree, so `CHECK (price > 0)` on a `numeric` column always comes back as * `CHECK ((price > (0)::numeric))`. That normalization is what makes a * string-level parser tractable — the input is generated, and the shapes are * few. * * Constraints this cannot read are skipped in full. A partially-understood * constraint is worse than an unread one: it would produce validation that * *narrows* differently from the database, so a value the UI accepts still * fails on write, or — worse — a value the database allows is refused in the * form with no way to see why. * * Pure module: no I/O, no logging. */ import type { CheckConstraintRow } from "./introspect-db-logic"; /** What a table's CHECK constraints say about one column. */ export interface ColumnCheckFacts { /** Allowed values, from `IN (…)` / `= ANY (ARRAY[…])` / `= 'literal'`. */ enumValues?: string[]; /** `x >= n` */ min?: number; /** `x <= n` */ max?: number; /** `x > n` */ moreThan?: number; /** `x < n` */ lessThan?: number; /** `length(x) >= n` */ lengthMin?: number; /** `length(x) <= n` */ lengthMax?: number; } /** Per-table, per-column facts. */ export type CheckFactsByTable = Map>; /** Removes one layer of wrapping parentheses, repeatedly, when balanced. */ export declare function unwrapParens(input: string): string; /** Drops trailing `::type` casts, including array and quoted forms. */ export declare function stripCasts(input: string): string; /** * Reads one constraint definition into per-column facts. * * Returns an empty map for anything not understood — including a constraint * that is understood but spans two columns (`start_date < end_date`), which no * per-property validation rule can express. */ export declare function parseCheckDefinition(definition: string): Map; /** Merges every readable CHECK in the schema into per-table, per-column facts. */ export declare function parseCheckConstraints(rows: CheckConstraintRow[]): CheckFactsByTable;