import { ColumnBuilder, ColumnConfig } from './column-builder'; import { DbCollection, DbReference, DbNavigationCollection, DbNavigation } from './navigation'; /** * Relation types */ export type RelationType = 'one' | 'many'; /** * Relation configuration */ export interface RelationConfig { type: RelationType; targetTable: string; targetTableBuilder?: TableBuilder; foreignKey?: string; foreignKeys?: string[]; matches?: string[]; references?: string; isMandatory?: boolean; } /** * Index definition */ export type IndexMethod = 'btree' | 'gin' | 'gist' | 'hash' | 'brin' | 'spgist'; export interface IndexDefinition { name: string; columns: string[]; isUnique?: boolean; using?: IndexMethod; operatorClass?: string; /** * If true, the index is created with `CREATE INDEX CONCURRENTLY`. Must run * outside of a transaction block. */ concurrent?: boolean; /** Raw SQL expressions for expression-based index columns (e.g., 'lower(unaccent(name))') */ expressions?: string[]; /** Raw SQL WHERE clause for partial indexes (e.g., 'active = true') */ where?: string; /** * Opt-in `NULLS NOT DISTINCT` (PostgreSQL 15+) for a UNIQUE index: treat NULLs * as equal so at most one row may hold NULL in the indexed column(s). Only * meaningful on unique indexes; ignored when the index is not unique. */ nullsNotDistinct?: boolean; /** * Set when the index contains an `ixNormalized` expression. Tells the schema * manager to create the `unaccent` extension + `search_normalize` function * (and `pg_trgm` when `using === 'gin'`) before building the index. */ requiresSearchNormalize?: boolean; } /** * PostgreSQL extended-statistics object declared on a table * (`CREATE STATISTICS … ON FROM `), covering univariate * expression statistics (a single parenthesized expression entry) and * multivariate statistics (2+ column/expression entries, optionally with an * explicit kinds list). * * Reconciled by NAME only: the schema manager creates a declared object when * no same-named one exists on the table and never drops or rebuilds — rename * the object to change its definition. */ export interface StatisticsDefinition { name: string; /** * Raw SQL entries of the `ON` list, in declaration order — quoted column * references (`"flags"`) and/or parenthesized expressions * (`("flags" & 1::smallint)`). */ expressions: string[]; /** * Optional multivariate kinds (`ndistinct` / `dependencies` / `mcv`). * Must be omitted for a single-expression declaration — PostgreSQL builds * univariate expression statistics there and rejects a kinds list. */ kinds?: Array<'ndistinct' | 'dependencies' | 'mcv'>; } /** * PostgreSQL declarative-partitioning strategy. * - `'range'` — partition by ranges of the key (e.g. dates). * - `'list'` — partition by an explicit list of key values. * - `'hash'` — partition by hash of the key (even distribution). */ export type PartitionStrategy = 'range' | 'list' | 'hash'; /** * Declarative table-partitioning configuration — describes the parent table's * `PARTITION BY ()` clause. Child partitions (`PARTITION OF ... * FOR VALUES ...`) are managed separately (they are typically created/rotated at * runtime), so they are not part of this declaration. * * PostgreSQL requires every partition-key column to be included in the table's * PRIMARY KEY / UNIQUE constraints. */ export interface PartitioningConfig { /** Partitioning strategy: RANGE, LIST, or HASH. */ strategy: PartitionStrategy; /** * Partition-key columns (database column names). Mutually exclusive with * {@link expression}. */ columns?: string[]; /** * Raw partition-key expression — the contents of the `PARTITION BY * (...)` parentheses, e.g. `date_trunc('month', created_at)`. Mutually * exclusive with {@link columns}. */ expression?: string; } /** * Foreign key action type */ export type ForeignKeyAction = 'cascade' | 'restrict' | 'no action' | 'set null' | 'set default'; /** * Foreign key constraint definition */ export interface ForeignKeyConstraint { name: string; columns: string[]; referencedTable: string; referencedColumns: string[]; onDelete?: ForeignKeyAction; onUpdate?: ForeignKeyAction; } /** * Cached column metadata for performance optimization */ export interface ColumnMetadataCache { /** The database column name */ dbName: string; /** Whether this column has a mapper */ hasMapper: boolean; /** The mapper if present */ mapper?: any; /** Full column config (cached to avoid repeated build() calls) */ config: ColumnConfig; } /** * Table schema definition */ export interface TableSchema = any> { name: string; schema?: string; columns: TColumns; relations: Record; indexes: IndexDefinition[]; foreignKeys: ForeignKeyConstraint[]; /** Extended-statistics objects declared on this table (`CREATE STATISTICS`). */ statistics?: StatisticsDefinition[]; /** Declarative partitioning config for this table (parent `PARTITION BY`). */ partitioning?: PartitioningConfig; /** * Performance optimization: Pre-computed map of property names to database column names * Avoids repeated .build().name calls during query building */ columnNameMap?: Map; /** * Performance optimization: Pre-computed array of relation entries * Avoids repeated Object.entries() calls during query building */ relationEntries?: Array<[string, RelationConfig]>; /** * Performance optimization: Cache of built target schemas for relations * Avoids repeated targetTableBuilder.build() calls */ relationSchemaCache?: Map; /** * Performance optimization: Pre-computed column metadata including mappers * Avoids repeated column.build() calls during result transformation * Key is property name, value is cached metadata */ columnMetadataCache?: Map; } /** * Extract TypeScript type from column builders */ export type InferColumnType = T extends ColumnBuilder ? U : never; /** * Infer table row type from schema */ export type InferTableType = { [K in keyof T['columns']]: InferColumnType; }; /** * Schema definition can include both columns and navigation properties */ export type SchemaDefinition = Record | DbReference | DbNavigationCollection | DbNavigation>; /** * Extract only column builders from schema definition */ export type ExtractColumns = { [K in keyof T as T[K] extends ColumnBuilder ? K : never]: T[K]; }; /** * Extract only navigation properties from schema definition */ export type ExtractNavigations = { [K in keyof T as T[K] extends DbCollection | DbReference | DbNavigationCollection | DbNavigation ? K : never]: T[K]; }; /** * Table builder - fluent API for defining tables with columns and navigation properties */ export declare class TableBuilder { private tableName; private schemaName?; private schemaDef; private columnDefs; private relationDefs; private indexDefs; private foreignKeyDefs; private statisticsDefs; private partitioningDef?; constructor(name: string, schema: TSchema, indexes?: IndexDefinition[], foreignKeys?: ForeignKeyConstraint[], schemaName?: string); private _cachedSchema?; /** * Configure declarative table partitioning (the parent `PARTITION BY` clause). * @example * builder.partitionBy({ strategy: 'range', columns: ['created_at'] }); */ partitionBy(config: PartitioningConfig): this; /** * Build the final table schema */ build(): TableSchema; /** * Declare the table's extended-statistics objects (`CREATE STATISTICS`). * Mirrors how indexes/foreign keys arrive from entity metadata; replaces any * previously set list. */ withStatistics(statistics: StatisticsDefinition[]): this; /** * Get table name */ getName(): string; /** * Get columns */ getColumns(): Record; /** * Get relations */ getRelations(): Record; /** * Get full schema definition (columns + navigations) */ getSchema(): TSchema; /** * Get a typed field reference for a column (for use in navigation definitions) * @example table.field('id') returns FieldRef<'id', number> */ field>(columnName: K): any; } /** * Table factory function * Supports both columns and navigation properties */ export declare function table(name: string, schema: TSchema): TableBuilder; //# sourceMappingURL=table-builder.d.ts.map