@cleverbrush/knex-schema 4.3.2 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/columns.ts","../src/ddl.ts","../src/entity.ts","../src/mappers.ts","../src/migration.ts","../src/raw.ts","../src/operations/select.ts","../src/operations/helpers.ts","../src/operations/state.ts","../src/operations/insert.ts","../src/operations/delete.ts","../src/validate.ts","../src/operations/join.ts","../src/operations/where.ts","../src/operations/pagination.ts","../src/operations/update.ts","../src/SchemaQueryBuilder.ts","../src/snapshot.ts"],"sourcesContent":["// @cleverbrush/knex-schema — Column resolution and mapping\n\nimport type { SchemaBuilder } from '@cleverbrush/schema';\nimport {\n ObjectSchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR\n} from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { getColumnName } from './extension.js';\nimport type { ColumnRef } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Column map cache (schema → { propToCol, colToProp })\n// ---------------------------------------------------------------------------\n\ninterface ColumnMapResult {\n propToCol: Map<string, string>;\n colToProp: Map<string, string>;\n}\n\nconst columnMapCache = new WeakMap<object, ColumnMapResult>();\n\n/**\n * Build a bidirectional column map from an ObjectSchemaBuilder's properties.\n * Uses `getExtension('columnName')` per property, falling back to the property key.\n * Result is cached per schema instance via WeakMap.\n */\nexport function buildColumnMap(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): ColumnMapResult {\n const cached = columnMapCache.get(schema);\n if (cached) return cached;\n\n const introspected = schema.introspect() as any;\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n\n const propToCol = new Map<string, string>();\n const colToProp = new Map<string, string>();\n\n for (const propKey of Object.keys(properties)) {\n const propSchema = properties[propKey];\n const colName = getColumnName(propSchema, propKey);\n\n propToCol.set(propKey, colName);\n colToProp.set(colName, propKey);\n }\n\n const result: ColumnMapResult = { propToCol, colToProp };\n columnMapCache.set(schema, result);\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Resolve a ColumnRef (string | accessor) to a SQL column name or Knex.Raw\n// ---------------------------------------------------------------------------\n\n/**\n * Build a `Knex.Raw` expression for accessing a nested JSON/JSONB path.\n *\n * - Single-key path: `\"col\"->>'key'` (text output, `->>` operator).\n * - Multi-key path: `\"col\"#>>'{a,b,...}'` (text output, `#>>` operator).\n *\n * Both use positional bindings to prevent SQL injection.\n */\nfunction jsonPathRaw(knex: Knex, col: string, jsonPath: string[]): Knex.Raw {\n if (jsonPath.length === 1) {\n return knex.raw('??->>?', [col, jsonPath[0]]);\n }\n // #>> expects a text array literal, e.g. '{address,city}'\n const pathLiteral = `{${jsonPath.join(',')}}`;\n return knex.raw('??#>>?', [col, pathLiteral]);\n}\n\n/**\n * Resolve a ColumnRef to a plain SQL column name (or a Knex.Raw expression for\n * nested JSON paths when `knex` is supplied).\n *\n * - String refs are treated as **property keys** (or dot-separated nested paths\n * such as `'address.city'`) and translated to column names via the column map.\n * - Function refs (property accessor) are resolved via PropertyDescriptorTree,\n * then translated to column names. Nested accessors (e.g. `t => t.address.city`)\n * produce a `Knex.Raw` JSON-path expression when `knex` is provided.\n *\n * @param ref - Column reference (property key, dotted path, or accessor fn).\n * @param schema - Root ObjectSchemaBuilder.\n * @param label - Human-readable label for error messages.\n * @param knex - Knex instance. Required for nested JSON-path refs; when omitted\n * and a nested path is detected, an error is thrown.\n */\nexport function resolveColumnRef(\n ref: ColumnRef<any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n label: string,\n knex: Knex\n): string | Knex.Raw;\nexport function resolveColumnRef(\n ref: ColumnRef<any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n label: string\n): string;\nexport function resolveColumnRef(\n ref: ColumnRef<any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n label: string,\n knex?: Knex\n): string | Knex.Raw {\n if (typeof ref === 'string') {\n if (!ref) throw new Error(`${label} must be a non-empty string`);\n\n // Dotted paths like 'address.city' — first segment is the top-level prop.\n if (ref.includes('.')) {\n const [topProp, ...jsonPath] = ref.split('.');\n const { propToCol } = buildColumnMap(schema);\n const col = propToCol.get(topProp) ?? topProp;\n if (!knex) {\n throw new Error(\n `${label}: a Knex instance is required to resolve nested JSON path '${ref}'`\n );\n }\n return jsonPathRaw(knex, col, jsonPath);\n }\n\n const { propToCol } = buildColumnMap(schema);\n const col = propToCol.get(ref);\n // If the string is a known property key, return its column name;\n // otherwise assume it's already a raw column name and pass through.\n return col ?? ref;\n }\n\n if (typeof ref === 'function') {\n const tree = ObjectSchemaBuilder.getPropertiesFor(schema as any);\n const descriptor = ref(tree as any);\n\n if (\n !descriptor ||\n typeof descriptor !== 'object' ||\n !(SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in descriptor)\n ) {\n throw new Error(\n `${label} accessor must return a valid property descriptor`\n );\n }\n\n const inner = (descriptor as any)[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n const pointer: string = inner.toJsonPointer();\n\n // pointer is an RFC-6901 JSON Pointer, e.g. '' (root), '/name', '/address/city'\n if (!pointer) {\n throw new Error(`${label} accessor returned the root descriptor`);\n }\n\n // Split '/address/city' → ['address', 'city']\n const segments = pointer\n .slice(1)\n .split('/')\n .map((s: string) => s.replace(/~1/g, '/').replace(/~0/g, '~'));\n\n if (segments.length === 0) {\n throw new Error(`${label} accessor returned the root descriptor`);\n }\n\n const [topProp, ...jsonPath] = segments;\n const { propToCol } = buildColumnMap(schema);\n const col = propToCol.get(topProp) ?? topProp;\n\n if (jsonPath.length === 0) {\n // Top-level property — plain column name\n return col;\n }\n\n // Nested path — need Knex.Raw\n if (!knex) {\n throw new Error(\n `${label}: a Knex instance is required to resolve nested JSON path '${pointer}'`\n );\n }\n return jsonPathRaw(knex, col, jsonPath);\n }\n\n throw new Error(\n `${label} must be a string or a property descriptor accessor function`\n );\n}\n\n/**\n * Resolve a ColumnRef to the **property key** (not the column name).\n * Used for result mapping.\n */\nexport function resolvePropertyKey(\n ref: ColumnRef<any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n label: string\n): string {\n if (typeof ref === 'string') {\n if (!ref) throw new Error(`${label} must be a non-empty string`);\n return ref;\n }\n\n if (typeof ref === 'function') {\n const tree = ObjectSchemaBuilder.getPropertiesFor(schema as any);\n const descriptor = ref(tree as any);\n\n if (\n !descriptor ||\n typeof descriptor !== 'object' ||\n !(SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in descriptor)\n ) {\n throw new Error(\n `${label} accessor must return a valid property descriptor`\n );\n }\n\n const inner = (descriptor as any)[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n const pointer: string = inner.toJsonPointer();\n\n if (!pointer) {\n throw new Error(`${label} accessor returned the root descriptor`);\n }\n\n // Return the first segment (top-level property key) for mapping purposes\n const topProp = pointer.slice(1).split('/')[0];\n return topProp.replace(/~1/g, '/').replace(/~0/g, '~');\n }\n\n throw new Error(\n `${label} must be a string or a property descriptor accessor function`\n );\n}\n\n// ---------------------------------------------------------------------------\n// Primary-key introspection\n// ---------------------------------------------------------------------------\n\n/**\n * Result of {@link getPrimaryKeyColumns}.\n *\n * `propertyKeys` are the schema property names (the keys you'd use in\n * `.where(t => t.id, ...)` style accessors); `columnNames` are the SQL\n * column names after applying any `hasColumnName()` overrides. Order is\n * preserved: composite-PK ordering matches the user's `hasPrimaryKey()`\n * declaration; single-PK arrays have length 1.\n *\n * @public\n */\nexport interface PrimaryKeyColumns {\n readonly propertyKeys: readonly string[];\n readonly columnNames: readonly string[];\n}\n\n/**\n * Resolve the primary-key columns of a schema at runtime.\n *\n * Composite primary keys (declared via `.hasPrimaryKey([...])` on the\n * object schema) take precedence over single-column primary keys. The\n * `columns` argument to `.hasPrimaryKey()` may contain either property keys\n * or SQL column names — both forms are accepted and normalised.\n *\n * Returns `{ propertyKeys: [], columnNames: [] }` when no primary key is\n * declared.\n *\n * @public\n */\nexport function getPrimaryKeyColumns(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): PrimaryKeyColumns {\n const introspected = schema.introspect() as {\n properties?: Record<string, SchemaBuilder<any, any, any>>;\n extensions?: Record<string, unknown>;\n };\n const properties = introspected.properties ?? {};\n const extensions = introspected.extensions ?? {};\n const { propToCol, colToProp } = buildColumnMap(schema);\n\n // Composite PK takes precedence.\n const composite = extensions.compositePrimaryKey as\n | readonly string[]\n | undefined;\n if (composite && composite.length > 0) {\n const propertyKeys: string[] = [];\n const columnNames: string[] = [];\n for (const entry of composite) {\n // Accept either column name or property key.\n if (propToCol.has(entry)) {\n propertyKeys.push(entry);\n columnNames.push(propToCol.get(entry) as string);\n } else if (colToProp.has(entry)) {\n columnNames.push(entry);\n propertyKeys.push(colToProp.get(entry) as string);\n } else {\n // Unknown identifier — pass through as both (best effort).\n propertyKeys.push(entry);\n columnNames.push(entry);\n }\n }\n return { propertyKeys, columnNames };\n }\n\n // Single-column PK — first property whose schema carries the\n // `primaryKey` extension wins.\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const propExt =\n (\n propSchema as {\n introspect?: () => {\n extensions?: Record<string, unknown>;\n };\n }\n ).introspect?.().extensions ?? {};\n if (propExt.primaryKey) {\n return {\n propertyKeys: [propKey],\n columnNames: [propToCol.get(propKey) ?? propKey]\n };\n }\n }\n\n return { propertyKeys: [], columnNames: [] };\n}\n\n// ---------------------------------------------------------------------------\n// Row-version introspection\n// ---------------------------------------------------------------------------\n\n/**\n * Concurrency-token strategy stored by `.rowVersion()`.\n * - `'increment'` — ORM increments an integer counter on each UPDATE.\n * - `'timestamp'` — ORM sets the value to `new Date()` on each UPDATE.\n * - `'manual'` — caller supplies the new value; ORM only enforces the check.\n *\n * @public\n */\nexport type RowVersionStrategy = 'increment' | 'timestamp' | 'manual';\n\n/**\n * Resolved row-version column for a schema, returned by\n * {@link getRowVersionColumn}.\n *\n * @public\n */\nexport interface RowVersionColumn {\n /** Schema property name. */\n propertyKey: string;\n /** SQL column name (after any `hasColumnName()` override). */\n columnName: string;\n /** Concurrency-token update strategy. */\n strategy: RowVersionStrategy;\n}\n\n/**\n * Find the first column marked `.rowVersion()` on the schema and return its\n * metadata. Returns `null` when no row-version column is declared.\n *\n * @public\n */\nexport function getRowVersionColumn(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): RowVersionColumn | null {\n const introspected = schema.introspect() as {\n properties?: Record<\n string,\n { introspect?: () => { extensions?: Record<string, unknown> } }\n >;\n };\n const properties = introspected.properties ?? {};\n const { propToCol } = buildColumnMap(schema);\n\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const ext = propSchema.introspect?.()?.extensions ?? {};\n const rv = ext.rowVersion as { strategy?: string } | undefined;\n if (rv) {\n return {\n propertyKey: propKey,\n columnName: propToCol.get(propKey) ?? propKey,\n strategy: (rv.strategy as RowVersionStrategy) ?? 'increment'\n };\n }\n }\n return null;\n}\n","// @cleverbrush/knex-schema — DDL generation from schema introspection\n\nimport type { ObjectSchemaBuilder, SchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport {\n getColumnName,\n getPolymorphicVariantSchemas,\n getTableName\n} from './extension.js';\n\n// ---------------------------------------------------------------------------\n// Type mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the Knex column type from a schema property's introspection data and\n * DDL extensions.\n *\n * Priority:\n * 1. Explicit `columnType` extension (e.g. `'text'`, `'uuid'`, `'jsonb'`).\n * 2. Schema type (`string`, `number`, `boolean`, `date`).\n *\n * @param table - Knex table builder.\n * @param col - SQL column name.\n * @param introspected - Result of `propSchema.introspect()`.\n * @param ext - The property's `extensions` object.\n * @returns A Knex column builder.\n */\nfunction resolveColumnType(\n table: Knex.CreateTableBuilder,\n col: string,\n introspected: any,\n ext: Record<string, any>\n): Knex.ColumnBuilder {\n if (ext.columnType) {\n return table.specificType(col, ext.columnType);\n }\n switch (introspected.type) {\n case 'string': {\n const maxLen = ext.maxLength ?? introspected.maxLength ?? undefined;\n return maxLen ? table.string(col, maxLen) : table.string(col);\n }\n case 'number':\n return introspected.isInteger !== false\n ? table.integer(col)\n : table.float(col);\n case 'boolean':\n return table.boolean(col);\n case 'date':\n return table.timestamp(col);\n case 'object':\n // Nested objects are stored as jsonb by default; override via .columnType()\n return table.specificType(col, 'jsonb');\n default:\n return table.specificType(col, 'text');\n }\n}\n\n/**\n * Apply a default value to a Knex column builder.\n *\n * Handles special values:\n * - `'now'` → `knex.fn.now()`\n * - `'auto_increment'` → no-op (handled by `table.increments()`)\n * - `{ raw: string }` → `knex.raw(expression)`\n * - Otherwise → literal value.\n *\n * @param column - Knex column builder.\n * @param defaultValue - The default value from the `defaultTo` extension.\n * @param knex - Knex instance (needed for `fn.now()` and `raw()`).\n * @returns The column builder with the default applied.\n */\nfunction applyDefault(\n column: Knex.ColumnBuilder,\n defaultValue: any,\n knex: Knex\n): Knex.ColumnBuilder {\n if (defaultValue === 'now') return column.defaultTo(knex.fn.now());\n if (defaultValue === 'auto_increment') return column;\n if (\n typeof defaultValue === 'object' &&\n defaultValue !== null &&\n defaultValue.raw\n ) {\n return column.defaultTo(knex.raw(defaultValue.raw));\n }\n return column.defaultTo(defaultValue);\n}\n\n// ---------------------------------------------------------------------------\n// generateCreateTable\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a Knex `schema.createTable()` call from an ObjectSchemaBuilder's\n * introspected metadata and DDL extensions.\n *\n * Returns a function that accepts a Knex instance and returns a\n * `SchemaBuilder` (thenable). Call it inside a migration or setup script:\n *\n * @param schema - An `ObjectSchemaBuilder` with `.hasTableName()` and\n * column-level DDL extensions (`.primaryKey()`, `.references()`, etc.).\n * @returns `(knex: Knex) => Knex.SchemaBuilder` — a function that creates the\n * table when executed.\n *\n * @example\n * ```ts\n * const createUsersTable = generateCreateTable(UserSchema);\n * await createUsersTable(knex);\n * ```\n */\nexport function generateCreateTable(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): (knex: Knex) => Knex.SchemaBuilder {\n const tableName = getTableName(schema);\n const introspected = schema.introspect() as any;\n const tableExt: Record<string, any> = introspected.extensions ?? {};\n\n // Column names fully managed by table-level extensions; skip them in the\n // property loop to avoid duplicate DDL.\n const extensionManagedCols = new Set<string>();\n if (tableExt.timestamps) {\n extensionManagedCols.add(tableExt.timestamps.createdAt);\n extensionManagedCols.add(tableExt.timestamps.updatedAt);\n }\n if (tableExt.softDelete) {\n extensionManagedCols.add(tableExt.softDelete.column);\n }\n\n return (knex: Knex) => {\n const builder = knex.schema.createTable(\n tableName,\n (table: Knex.CreateTableBuilder) => {\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n\n for (const [propKey, propSchema] of Object.entries(\n properties\n )) {\n const col = getColumnName(propSchema, propKey);\n const propIntrospected = propSchema.introspect() as any;\n const ext: Record<string, any> =\n propIntrospected.extensions ?? {};\n\n // Skip array navigation properties without an explicit\n // columnType override — these are ORM relations. Nested\n // object properties default to jsonb and are NOT skipped.\n if (propIntrospected.type === 'array' && !ext.columnType) {\n continue;\n }\n // Skip columns owned by table-level extensions.\n if (extensionManagedCols.has(col)) {\n continue;\n }\n\n // Determine column builder\n let column: Knex.ColumnBuilder;\n\n if (ext.primaryKey?.autoIncrement) {\n column = table.increments(col);\n } else {\n column = resolveColumnType(\n table,\n col,\n propIntrospected,\n ext\n );\n }\n\n // Primary key (non-auto-increment)\n if (ext.primaryKey && !ext.primaryKey.autoIncrement) {\n column = column.primary();\n }\n\n // Unique constraint\n if (ext.unique) {\n column = column.unique(\n typeof ext.unique === 'string'\n ? { indexName: ext.unique }\n : undefined\n );\n }\n\n // Index\n if (ext.index) {\n column = column.index(\n typeof ext.index === 'string'\n ? ext.index\n : undefined\n );\n }\n\n // Default value\n if (ext.defaultTo !== undefined) {\n column = applyDefault(column, ext.defaultTo, knex);\n }\n\n // Nullability\n if (\n propIntrospected.isRequired &&\n !ext.primaryKey?.autoIncrement\n ) {\n column = column.notNullable();\n } else if (!propIntrospected.isRequired) {\n column = column.nullable();\n }\n\n // Foreign key references\n if (ext.references) {\n const fkBuilder = column\n .references(ext.references.column)\n .inTable(ext.references.table);\n if (ext.onDelete) fkBuilder.onDelete(ext.onDelete);\n if (ext.onUpdate) fkBuilder.onUpdate(ext.onUpdate);\n }\n\n // Column-level CHECK constraint\n if (ext.check) {\n table.check(ext.check);\n }\n }\n\n // ----- Table-level constraints from object extensions -----\n\n // Composite indexes\n for (const idx of tableExt.indexes ?? []) {\n if (idx.unique) {\n table.unique(idx.columns, {\n indexName: idx.name ?? undefined\n });\n } else {\n table.index(idx.columns, idx.name ?? undefined);\n }\n }\n\n // Composite unique constraints\n for (const unq of tableExt.uniques ?? []) {\n table.unique(unq.columns, {\n indexName: unq.name ?? undefined\n });\n }\n\n // Table-level CHECK constraints\n for (const chk of tableExt.checks ?? []) {\n table.check(chk);\n }\n\n // Composite primary key\n if (tableExt.compositePrimaryKey) {\n table.primary(tableExt.compositePrimaryKey);\n }\n\n // Raw columns (not backed by schema properties)\n for (const rawCol of tableExt.rawColumns ?? []) {\n table.specificType(rawCol.name, rawCol.definition);\n }\n\n // Timestamps (auto-added columns)\n if (tableExt.timestamps) {\n table\n .timestamp(tableExt.timestamps.createdAt)\n .defaultTo(knex.fn.now())\n .notNullable();\n table\n .timestamp(tableExt.timestamps.updatedAt)\n .defaultTo(knex.fn.now())\n .notNullable();\n }\n\n // Soft delete column\n if (tableExt.softDelete) {\n table.timestamp(tableExt.softDelete.column).nullable();\n }\n }\n );\n\n // Raw indexes are executed as separate statements after table creation\n const rawIndexes: string[] = tableExt.rawIndexes ?? [];\n if (rawIndexes.length > 0) {\n return builder.then(async () => {\n for (const rawIdx of rawIndexes) {\n await knex.raw(rawIdx);\n }\n }) as any;\n }\n\n return builder;\n };\n}\n\n// ---------------------------------------------------------------------------\n// generateCreateTableSource\n// ---------------------------------------------------------------------------\n\n/**\n * Generate `up` and `down` TypeScript code *strings* (4-space-indented\\n * fragments) for creating a table from a schema.\n *\n * Unlike {@link generateCreateTable} (which returns a Knex callback), the\n * output is plain source text suitable for writing into a migration file. The\n * fragments are designed to be embedded directly inside `up()` / `down()`\n * functions.\n *\n * @param schema - An `ObjectSchemaBuilder` with `.hasTableName()` and column\n * DDL extensions.\n * @returns `{ up, down }` source fragments.\n *\n * @example\n * ```ts\n * const { up, down } = generateCreateTableSource(UserSchema);\n * // up: \" await knex.schema.createTable('users', (table) => { … });\"\n * // down: \" await knex.schema.dropTableIfExists('users');\"\n * ```\n */\nexport function generateCreateTableSource(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): { up: string; down: string } {\n const tableName = getTableName(schema);\n const introspected = schema.introspect() as any;\n const tableExt: Record<string, any> = introspected.extensions ?? {};\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n\n const lines: string[] = [];\n\n // Column names owned by table-level extensions; skip in property loop.\n const extensionManagedCols = new Set<string>();\n if (tableExt.timestamps) {\n extensionManagedCols.add(tableExt.timestamps.createdAt);\n extensionManagedCols.add(tableExt.timestamps.updatedAt);\n }\n if (tableExt.softDelete) {\n extensionManagedCols.add(tableExt.softDelete.column);\n }\n\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const col = getColumnName(propSchema, propKey);\n const propIntrospected = propSchema.introspect() as any;\n const ext: Record<string, any> = propIntrospected.extensions ?? {};\n\n // Skip navigation properties and extension-managed columns.\n if (\n (propIntrospected.type === 'object' ||\n propIntrospected.type === 'array') &&\n !ext.columnType\n ) {\n continue;\n }\n if (extensionManagedCols.has(col)) {\n continue;\n }\n\n let line: string;\n\n if (ext.primaryKey?.autoIncrement) {\n line = ` table.increments('${col}')`;\n } else {\n line = ` ${_colTypeCode(col, propIntrospected, ext)}`;\n }\n\n // Primary key (non-auto-increment)\n if (ext.primaryKey && !ext.primaryKey.autoIncrement) {\n line += '.primary()';\n }\n\n // Unique\n if (ext.unique) {\n if (typeof ext.unique === 'string') {\n line += `.unique({ indexName: '${ext.unique}' })`;\n } else {\n line += '.unique()';\n }\n }\n\n // Index\n if (ext.index) {\n if (typeof ext.index === 'string') {\n line += `.index('${ext.index}')`;\n } else {\n line += '.index()';\n }\n }\n\n // Default value\n if (ext.defaultTo !== undefined) {\n line += `.defaultTo(${_fmtDefault(ext.defaultTo)})`;\n }\n\n // Nullability\n if (propIntrospected.isRequired && !ext.primaryKey?.autoIncrement) {\n line += '.notNullable()';\n } else if (!propIntrospected.isRequired) {\n line += '.nullable()';\n }\n\n // Foreign key references\n if (ext.references) {\n line += `.references('${ext.references.column}').inTable('${ext.references.table}')`;\n if (ext.onDelete) line += `.onDelete('${ext.onDelete}')`;\n if (ext.onUpdate) line += `.onUpdate('${ext.onUpdate}')`;\n }\n\n lines.push(line + ';');\n\n // Column-level CHECK (separate statement after column line)\n if (ext.check) {\n lines.push(` table.check(${JSON.stringify(ext.check)});`);\n }\n }\n\n // Composite indexes\n for (const idx of tableExt.indexes ?? []) {\n const cols = JSON.stringify(idx.columns);\n if (idx.unique) {\n lines.push(\n ` table.unique(${cols}${idx.name ? `, { indexName: '${idx.name}' }` : ''});`\n );\n } else {\n lines.push(\n ` table.index(${cols}${idx.name ? `, '${idx.name}'` : ''});`\n );\n }\n }\n\n // Composite unique constraints\n for (const unq of tableExt.uniques ?? []) {\n const cols = JSON.stringify(unq.columns);\n lines.push(\n ` table.unique(${cols}${unq.name ? `, { indexName: '${unq.name}' }` : ''});`\n );\n }\n\n // Table-level CHECK constraints\n for (const chk of tableExt.checks ?? []) {\n lines.push(` table.check(${JSON.stringify(chk)});`);\n }\n\n // Composite primary key\n if (tableExt.compositePrimaryKey) {\n lines.push(\n ` table.primary(${JSON.stringify(tableExt.compositePrimaryKey)});`\n );\n }\n\n // Raw columns\n for (const rawCol of tableExt.rawColumns ?? []) {\n lines.push(\n ` table.specificType('${rawCol.name}', '${rawCol.definition}');`\n );\n }\n\n // Timestamps\n if (tableExt.timestamps) {\n lines.push(\n ` table.timestamp('${tableExt.timestamps.createdAt}').notNullable().defaultTo(knex.fn.now());`\n );\n lines.push(\n ` table.timestamp('${tableExt.timestamps.updatedAt}').notNullable().defaultTo(knex.fn.now());`\n );\n }\n\n // Soft-delete column\n if (tableExt.softDelete) {\n lines.push(\n ` table.timestamp('${tableExt.softDelete.column}').nullable();`\n );\n }\n\n const rawIndexes: string[] = tableExt.rawIndexes ?? [];\n const rawIndexLines = rawIndexes.map(\n ri => ` await knex.raw(${JSON.stringify(ri)});`\n );\n\n const up =\n ` await knex.schema.createTable('${tableName}', (table) => {\\n${lines.join('\\n')}\\n });` +\n (rawIndexLines.length > 0 ? '\\n' + rawIndexLines.join('\\n') : '');\n\n const down = ` await knex.schema.dropTableIfExists('${tableName}');`;\n\n return { up, down };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers for generateCreateTableSource\n// ---------------------------------------------------------------------------\n\n/** @internal Render a column type expression for code generation. */\nfunction _colTypeCode(\n col: string,\n introspected: any,\n ext: Record<string, any>\n): string {\n if (ext.columnType)\n return `table.specificType('${col}', '${ext.columnType}')`;\n switch (introspected.type) {\n case 'string': {\n const maxLen = ext.maxLength ?? introspected.maxLength ?? undefined;\n return maxLen\n ? `table.string('${col}', ${maxLen})`\n : `table.string('${col}')`;\n }\n case 'number':\n return introspected.isInteger !== false\n ? `table.integer('${col}')`\n : `table.float('${col}')`;\n case 'boolean':\n return `table.boolean('${col}')`;\n case 'date':\n return `table.timestamp('${col}')`;\n case 'object':\n return `table.specificType('${col}', 'jsonb')`;\n default:\n return `table.specificType('${col}', 'text')`;\n }\n}\n\n/** @internal Format a defaultTo value as a code string for migration source. */\nfunction _fmtDefault(value: any): string {\n if (value === 'now') return 'knex.fn.now()';\n if (typeof value === 'object' && value !== null && value.raw) {\n return `knex.raw('${String(value.raw).replace(/'/g, \"\\\\'\")}')`;\n }\n if (typeof value === 'string') return `'${value.replace(/'/g, \"\\\\'\")}'`;\n return String(value);\n}\n\n// ---------------------------------------------------------------------------\n// generateCreatePolymorphicTables\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a series of Knex `schema.createTable()` calls for a polymorphic\n * schema and all its CTI variant tables.\n *\n * Returns an array of `(knex: Knex) => Knex.SchemaBuilder` functions — one\n * for the base table and one for each CTI variant. STI variants add their\n * columns to the base table itself so no extra table is needed.\n *\n * Execute them sequentially in a migration:\n *\n * @param schema - The base `ObjectSchemaBuilder` with `.withVariants()` applied.\n * @returns An array of table-creation functions to execute in order.\n *\n * @example\n * ```ts\n * const creators = generateCreatePolymorphicTables(FileSchema);\n * for (const create of creators) {\n * await create(knex);\n * }\n * ```\n */\nexport function generateCreatePolymorphicTables(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): Array<(knex: Knex) => Knex.SchemaBuilder> {\n const result: Array<(knex: Knex) => Knex.SchemaBuilder> = [\n generateCreateTable(schema)\n ];\n\n const variantSchemas = getPolymorphicVariantSchemas(schema);\n for (const variantSchema of variantSchemas) {\n // Only CTI variants have their own table\n const tableName = variantSchema.getExtension('tableName') as\n | string\n | undefined;\n if (tableName) {\n result.push(generateCreateTable(variantSchema));\n }\n }\n\n return result;\n}\n","// @cleverbrush/knex-schema — Entity wrapper\n//\n// Provides a typed wrapper around an ObjectSchemaBuilder that tracks\n// declared relations as a real generic parameter (TRels). Unlike the\n// brand-based approach, TRels survives method chaining because we own\n// every method's return type.\n//\n// Relations are still stored at runtime in the schema's `relations`\n// extension (compatible with the existing query/include implementation).\n\nimport {\n type ArraySchemaBuilder,\n type InferType,\n ObjectSchemaBuilder,\n type PropertyDescriptorTree,\n type SchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR\n} from '@cleverbrush/schema';\n\nimport { buildColumnMap } from './columns.js';\nimport {\n applyVariantsToSchema,\n getColumnName,\n type VariantInputForResolver\n} from './extension.js';\nimport type { ResolvedVariantRelationSpec } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Type-level helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Phantom info for a single declared relation, stored on `Entity`'s `TRels`\n * generic. `TForeign` is captured so `.include()` can type the customize\n * callback against the correct foreign schema.\n *\n * @public\n */\nexport interface RelationInfo<\n TKind extends 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany' = any,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> {\n readonly kind: TKind;\n readonly foreign: TForeign;\n}\n\n/**\n * Extract the property record `{ [name]: SchemaBuilder }` from any\n * `ObjectSchemaBuilder` regardless of variance positions.\n *\n * @public\n */\nexport type SchemaProps<T> =\n T extends ObjectSchemaBuilder<infer P, any, any, any, any, any, any>\n ? P\n : never;\n\n/**\n * Strips the `withExtensions()` overlay from a schema type, reducing it to a\n * plain `ObjectSchemaBuilder<TProps, TReq>` so `PropertyDescriptorTree<...>`\n * resolves without hitting TypeScript's recursion depth limit.\n *\n * @internal\n */\ntype EntitySchemaBase<\n T extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> =\n T extends ObjectSchemaBuilder<infer P, infer Req, any, any, any, any, any>\n ? ObjectSchemaBuilder<P, Req>\n : never;\n\n/**\n * `PropertyDescriptorTree` overlay that pins each top-level property's\n * literal `propertyName` into its descriptor. Required because\n * `PropertyDescriptorTree` widens `propertyName` to `string` for sub-trees\n * whose property is itself an `ObjectSchemaBuilder` (since\n * `PropertyDescriptorTree` lacks a `TPropertyKey` generic).\n *\n * @internal\n */\ntype EntityTree<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> = PropertyDescriptorTree<\n EntitySchemaBase<TSchema>,\n EntitySchemaBase<TSchema>\n> & {\n readonly [K in keyof SchemaProps<TSchema> & string]: {\n readonly [SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]: {\n readonly propertyName: K;\n };\n };\n};\n\n/**\n * Selector callback that receives a real {@link PropertyDescriptorTree} so\n * `t => t.someProp` navigates to the property definition and preserves its\n * JSDoc in IDE tooltips. The return shape is matched structurally on the\n * `[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR].propertyName` field, which captures\n * the literal property key as `TKey`.\n *\n * @public\n */\nexport type EntityPropSelector<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TKey extends string = string\n> = (t: EntityTree<TSchema>) => {\n readonly [SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]: {\n readonly propertyName: TKey;\n };\n};\n\n/**\n * Peel `.optional()` / `array(...)` wrappers off a navigation property's\n * schema to recover the underlying foreign `ObjectSchemaBuilder`.\n *\n * @public\n */\nexport type UnwrapNavSchema<TProp> =\n TProp extends ArraySchemaBuilder<infer TEl, any, any, any>\n ? TEl extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n ? TEl\n : never\n : TProp extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n ? TProp\n : TProp extends SchemaBuilder<infer T, any, any, any, any>\n ? T extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n ? T\n : never\n : never;\n\n/**\n * Merge type for a single polymorphic variant branch: variant schema fields\n * overlay base schema fields (narrowing the discriminator from `string` to its\n * specific literal value).\n *\n * @public\n */\nexport type VariantBranch<\n TBaseSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TVarSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> = Omit<InferType<TBaseSchema>, keyof InferType<TVarSchema>> &\n InferType<TVarSchema>;\n\n/**\n * Return type for an Entity method that adds a relation: keeps `TSchema`,\n * extends `TRels` with one more entry, and preserves `TVariantUnion`.\n *\n * @public\n */\nexport type WithRelation<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TRels extends Record<string, RelationInfo>,\n TKey extends string,\n TKind extends 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany',\n TForeign extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TVariantUnion = never\n> = Entity<\n TSchema,\n TRels & Record<TKey, RelationInfo<TKind, TForeign>>,\n TVariantUnion\n>;\n\n// ---------------------------------------------------------------------------\n// Entity\n// ---------------------------------------------------------------------------\n\n/**\n * A typed wrapper around an `ObjectSchemaBuilder` that tracks declared\n * relations in its `TRels` generic. Use {@link defineEntity} to create one.\n *\n * Relations are declared via `.hasOne()` / `.hasMany()` / `.belongsTo()` /\n * `.belongsToMany()` on the entity (NOT on the underlying schema). Each\n * call returns a new `Entity` whose `TRels` includes the new relation, so\n * `query(db, entity).include(t => t.assignee)` is fully typed.\n *\n * @public\n */\nexport class Entity<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TRels extends Record<string, RelationInfo> = {},\n TVariantUnion = never\n> {\n /** The underlying schema (relations registered via `withExtension('relations', ...)`). */\n readonly schema: TSchema;\n\n /** @internal Phantom slot to retain `TRels` in inferred types. */\n private declare readonly __relations__: TRels;\n\n /** @internal Phantom slot to retain `TVariantUnion` in inferred types. */\n private declare readonly __variantUnion__: TVariantUnion;\n\n constructor(schema: TSchema) {\n this.schema = schema;\n }\n\n private _addRelation(spec: {\n type: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany';\n name: string;\n schema: any;\n foreignKey?: any;\n through?: { table: string; localKey: string; foreignKey: string };\n optional?: boolean;\n }): Entity<TSchema, any> {\n const existing =\n ((this.schema as any).getExtension?.('relations') as any[]) ?? [];\n const next = (this.schema as any).withExtension('relations', [\n ...existing,\n spec\n ]);\n return new Entity(next);\n }\n\n /**\n * Declare a one-to-one relation where the FK lives on the FOREIGN table.\n * `navSel` selects the navigation property on THIS schema (must hold the\n * foreign schema, typically `.optional()`). The foreign schema is\n * auto-resolved at runtime from that property; provided explicitly here\n * via `opts.foreign` only when peeling fails.\n *\n * @param navSel Selector of nav property: `t => t.author`\n * @param localSel Selector of local-side join key: `l => l.id`\n * @param remoteSel Selector of remote-side FK on foreign schema: `r => r.userId`\n * @param opts Optional `{ optional?: boolean }` (default false).\n */\n hasOne<\n TKey extends keyof SchemaProps<TSchema> & string,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = UnwrapNavSchema<SchemaProps<TSchema>[TKey]>\n >(\n navSel: EntityPropSelector<TSchema, TKey>,\n _localSel: EntityPropSelector<TSchema>,\n remoteSel: EntityPropSelector<TForeign>,\n opts?: { optional?: boolean }\n ): WithRelation<TSchema, TRels, TKey, 'hasOne', TForeign, TVariantUnion> {\n const navName = this._resolvePropName(\n navSel as EntityPropSelector<TSchema>,\n this.schema\n );\n const foreignSchema = this._resolveForeignSchema(navName);\n const remoteKey = this._resolvePropName(\n remoteSel as EntityPropSelector<any>,\n foreignSchema\n );\n // For hasOne the FK is on the FOREIGN table → store remoteKey.\n return this._addRelation({\n type: 'hasOne',\n name: navName,\n schema: foreignSchema,\n foreignKey: remoteKey,\n optional: opts?.optional\n }) as any;\n }\n\n /**\n * Declare a one-to-many relation where the FK lives on the FOREIGN table.\n *\n * @param navSel Selector of nav array property: `t => t.posts`\n * @param localSel Selector of local-side join key: `l => l.id`\n * @param remoteSel Selector of remote-side FK on foreign schema: `r => r.userId`\n */\n hasMany<\n TKey extends keyof SchemaProps<TSchema> & string,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = UnwrapNavSchema<SchemaProps<TSchema>[TKey]>\n >(\n navSel: EntityPropSelector<TSchema, TKey>,\n _localSel: EntityPropSelector<TSchema>,\n remoteSel: EntityPropSelector<TForeign>\n ): WithRelation<TSchema, TRels, TKey, 'hasMany', TForeign, TVariantUnion> {\n const navName = this._resolvePropName(\n navSel as EntityPropSelector<TSchema>,\n this.schema\n );\n const foreignSchema = this._resolveForeignSchema(navName);\n const remoteKey = this._resolvePropName(\n remoteSel as EntityPropSelector<any>,\n foreignSchema\n );\n return this._addRelation({\n type: 'hasMany',\n name: navName,\n schema: foreignSchema,\n foreignKey: remoteKey\n }) as any;\n }\n\n /**\n * Declare a many-to-one relation where the FK lives on THIS table.\n *\n * @param navSel Selector of nav property (foreign schema, usually `.optional()`).\n * @param localSel Selector of local-side FK property: `l => l.userId`\n * @param remoteSel Selector of foreign-side PK property: `r => r.id`\n */\n belongsTo<\n TKey extends keyof SchemaProps<TSchema> & string,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = UnwrapNavSchema<SchemaProps<TSchema>[TKey]>\n >(\n navSel: EntityPropSelector<TSchema, TKey>,\n localSel: EntityPropSelector<TSchema>,\n _remoteSel: EntityPropSelector<TForeign>,\n opts?: { optional?: boolean }\n ): WithRelation<\n TSchema,\n TRels,\n TKey,\n 'belongsTo',\n TForeign,\n TVariantUnion\n > {\n const navName = this._resolvePropName(\n navSel as EntityPropSelector<TSchema>,\n this.schema\n );\n const foreignSchema = this._resolveForeignSchema(navName);\n const localKey = this._resolvePropName(localSel, this.schema);\n // For belongsTo the FK is on THIS table → store localKey.\n return this._addRelation({\n type: 'belongsTo',\n name: navName,\n schema: foreignSchema,\n foreignKey: localKey,\n optional: opts?.optional\n }) as any;\n }\n\n /**\n * Declare a many-to-many relation through a pivot table.\n *\n * @param navSel Selector of nav array property: `t => t.tags`\n * @param through Pivot table config `{ table, localKey, foreignKey }`.\n */\n belongsToMany<\n TKey extends keyof SchemaProps<TSchema> & string,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = UnwrapNavSchema<SchemaProps<TSchema>[TKey]>\n >(\n navSel: EntityPropSelector<TSchema, TKey>,\n through: { table: string; localKey: string; foreignKey: string }\n ): WithRelation<\n TSchema,\n TRels,\n TKey,\n 'belongsToMany',\n TForeign,\n TVariantUnion\n > {\n const navName = this._resolvePropName(\n navSel as EntityPropSelector<TSchema>,\n this.schema\n );\n const foreignSchema = this._resolveForeignSchema(navName);\n return this._addRelation({\n type: 'belongsToMany',\n name: navName,\n schema: foreignSchema,\n through\n }) as any;\n }\n\n /**\n * Mark this entity as polymorphic by selecting the discriminator\n * property. Returns a new `Entity` whose `.ctiVariant()` /\n * `.stiVariant()` methods declare each variant.\n *\n * Declare ordinary relations (`.belongsTo()` etc.) on this entity BEFORE\n * `.discriminator()`. After `.discriminator()` you are in the\n * polymorphic-builder phase: `.hasOne/.hasMany/.belongsTo/.belongsToMany`\n * still work, but the per-variant relations live on the `.ctiVariant()`\n * / `.stiVariant()` calls.\n *\n * @example\n * ```ts\n * const FileEntity = defineEntity(FileSchema)\n * .discriminator(t => t.type)\n * .ctiVariant('image', ImageEntity, t => t.fileId)\n * .ctiVariant('document', DocumentEntity, t => t.fileId);\n * ```\n */\n discriminator<TKey extends keyof SchemaProps<TSchema> & string>(\n sel: TKey | EntityPropSelector<TSchema, TKey>\n ): Entity<TSchema, TRels, never> {\n const discKey =\n typeof sel === 'string'\n ? (sel as string)\n : this._resolvePropName(\n sel as EntityPropSelector<TSchema>,\n this.schema\n );\n const next = new Entity(this.schema) as Entity<TSchema, TRels>;\n // Carry the variant-builder state on the new Entity so subsequent\n // `.ctiVariant()`/`.stiVariant()` calls can extend it. Stored on\n // the instance (not in the schema) so the original schema is\n // unchanged until the first variant is added.\n (next as any)._variantBuilder = {\n discKey,\n variants: {} as Record<string, VariantInputForResolver>\n };\n return next;\n }\n\n /**\n * Declare a CTI (Class Table Inheritance) variant. Only valid after\n * `.discriminator()`. Returns a new `Entity` whose schema carries the\n * updated `'variants'` extension.\n *\n * @param key Discriminator literal (e.g. `'image'`).\n * @param variant Entity wrapping the variant table schema.\n * @param fkSel Accessor returning the FK property on the variant\n * schema that joins back to the base PK.\n * @param opts `{ allowOrphan?: boolean; relations?: ... }` — see CTI docs.\n */\n ctiVariant<\n TVarSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n key: string,\n variant: Entity<TVarSchema, any>,\n fkSel: (t: EntityTree<TVarSchema>) => any,\n opts?: {\n allowOrphan?: boolean;\n relations?: Record<string, VariantRelationInput<TVarSchema>>;\n }\n ): Entity<\n TSchema,\n TRels,\n TVariantUnion | VariantBranch<TSchema, TVarSchema>\n > {\n const builder = (this as any)._variantBuilder as\n | VariantBuilderState\n | undefined;\n if (!builder) {\n throw new Error(\n 'ctiVariant: call `.discriminator(...)` first to begin a polymorphic builder chain'\n );\n }\n const fkColumn = resolveCtiForeignKeyColumn(\n variant.schema,\n fkSel as (t: any) => any\n );\n const nextVariants: Record<string, VariantInputForResolver> = {\n ...builder.variants,\n [key]: {\n schema: variant.schema,\n storage: 'cti',\n foreignKeyColumn: fkColumn,\n allowOrphan: opts?.allowOrphan,\n relations: [\n ...entityRelationsToVariantRelations(variant),\n ...resolveInlineVariantRelations(\n variant.schema,\n opts?.relations\n )\n ]\n }\n };\n return this._withVariantBuilder<\n TVariantUnion | VariantBranch<TSchema, TVarSchema>\n >(builder.discKey, nextVariants);\n }\n\n /**\n * Declare an STI (Single Table Inheritance) variant. Only valid after\n * `.discriminator()`. Accepts either an {@link Entity} or a bare\n * {@link ObjectSchemaBuilder}.\n */\n stiVariant<\n TVarSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n key: string,\n body: Entity<TVarSchema, any> | TVarSchema,\n opts?: {\n enforceCheck?: boolean;\n relations?: Record<string, VariantRelationInput<TVarSchema>>;\n }\n ): Entity<\n TSchema,\n TRels,\n TVariantUnion | VariantBranch<TSchema, TVarSchema>\n > {\n const builder = (this as any)._variantBuilder as\n | VariantBuilderState\n | undefined;\n if (!builder) {\n throw new Error(\n 'stiVariant: call `.discriminator(...)` first to begin a polymorphic builder chain'\n );\n }\n const isEntity = body instanceof Entity;\n const varSchema = (\n isEntity ? (body as Entity<any, any>).schema : body\n ) as ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n const nextVariants: Record<string, VariantInputForResolver> = {\n ...builder.variants,\n [key]: {\n schema: varSchema,\n storage: 'sti',\n enforceCheck: opts?.enforceCheck,\n relations: [\n ...(isEntity\n ? entityRelationsToVariantRelations(\n body as Entity<any, any>\n )\n : []),\n ...resolveInlineVariantRelations(varSchema, opts?.relations)\n ]\n }\n };\n return this._withVariantBuilder<\n TVariantUnion | VariantBranch<TSchema, TVarSchema>\n >(builder.discKey, nextVariants);\n }\n\n /** @internal Apply the variant extension to the schema and return a new Entity. */\n private _withVariantBuilder<TNewUnion>(\n discKey: string,\n variants: Record<string, VariantInputForResolver>\n ): Entity<TSchema, TRels, TNewUnion> {\n let newSchema = applyVariantsToSchema(\n this.schema,\n discKey,\n variants\n ) as any;\n // Preserve any existing `relations` extension across the rebuild.\n const existingRelations =\n (this.schema as any).getExtension?.('relations') ?? [];\n if (existingRelations.length) {\n newSchema = newSchema.withExtension('relations', existingRelations);\n }\n const next = new Entity(newSchema as TSchema) as Entity<\n TSchema,\n TRels,\n TNewUnion\n >;\n (next as any)._variantBuilder = { discKey, variants };\n return next;\n }\n\n /**\n * @internal\n * Resolve a selector callback against the real `PropertyDescriptorTree`\n * of the given schema, returning the top-level property name. Throws if\n * the accessor does not yield a valid descriptor.\n */\n private _resolvePropName(\n selector: (t: any) => any,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n ): string {\n const tree = ObjectSchemaBuilder.getPropertiesFor(schema as any);\n const descriptor = selector(tree as any);\n if (\n !descriptor ||\n typeof descriptor !== 'object' ||\n !(SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in descriptor)\n ) {\n throw new Error(\n 'Entity relation selector must return a property descriptor, e.g. `t => t.author`.'\n );\n }\n const inner = (descriptor as any)[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n if (typeof inner.propertyName !== 'string') {\n throw new Error(\n 'Entity relation selector must return a top-level property descriptor.'\n );\n }\n return inner.propertyName as string;\n }\n\n /** @internal Resolve the foreign schema from a nav property. */\n private _resolveForeignSchema(navName: string): any {\n const props = (this.schema as any).introspect?.()?.properties ?? {};\n const propSchema = props[navName];\n if (!propSchema) {\n throw new Error(\n `Entity.relation: navigation property \"${navName}\" not found on schema`\n );\n }\n const intro = propSchema.introspect?.() ?? propSchema;\n // Array → use elementSchema\n if (intro.type === 'array' && intro.elementSchema) {\n return intro.elementSchema;\n }\n // Object schema directly (with or without optional)\n if (\n intro.type === 'object' ||\n propSchema.constructor?.name === 'ObjectSchemaBuilder'\n ) {\n return propSchema;\n }\n // Fall back: assume it's already the schema\n return propSchema;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Polymorphic variant helpers (used by Entity.discriminator/ctiVariant/stiVariant)\n// ---------------------------------------------------------------------------\n\n/** @internal Variant-builder state carried on an Entity instance during a\n * `.discriminator().ctiVariant()/.stiVariant()` chain. */\ninterface VariantBuilderState {\n discKey: string;\n variants: Record<string, VariantInputForResolver>;\n}\n\n/**\n * @internal Convert an Entity's stored relations (which use property-name\n * foreign keys) into the column-name form required by\n * {@link ResolvedVariantRelationSpec}.\n */\nfunction entityRelationsToVariantRelations(\n varEntity: Entity<any, any>\n): ResolvedVariantRelationSpec[] {\n const rels: any[] =\n (varEntity.schema as any).getExtension?.('relations') ?? [];\n if (rels.length === 0) return [];\n\n const { propToCol } = buildColumnMap(varEntity.schema as any);\n\n return rels.map(r => {\n // belongsToMany has no `foreignKey` on the spec itself (uses through.*).\n const fkPropName: string | undefined =\n typeof r.foreignKey === 'string' ? r.foreignKey : undefined;\n const fkColName = fkPropName\n ? (propToCol.get(fkPropName) ?? fkPropName)\n : undefined;\n return {\n name: r.name,\n type: r.type,\n schema: r.schema,\n foreignKey: fkColName,\n through: r.through\n } satisfies ResolvedVariantRelationSpec;\n });\n}\n\n/**\n * @internal Resolve a foreign-key accessor (`t => t.fileId`) against a\n * variant schema to a SQL column name.\n */\nfunction resolveCtiForeignKeyColumn(\n varSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n fkSel: (t: any) => any\n): string {\n const tree = ObjectSchemaBuilder.getPropertiesFor(varSchema as any);\n const desc = fkSel(tree as any);\n const inner = (desc as any)?.[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n if (!inner?.propertyName) {\n throw new Error(\n 'ctiVariant: foreignKey accessor must return a top-level property descriptor on the variant schema'\n );\n }\n const propKey: string = inner.propertyName;\n const props = (varSchema as any).introspect?.()?.properties ?? {};\n const propSchema = props[propKey];\n if (!propSchema) {\n throw new Error(\n `ctiVariant: foreignKey property \"${propKey}\" not found on variant schema`\n );\n }\n return getColumnName(propSchema, propKey);\n}\n\n/**\n * Inline relation spec accepted by {@link Entity.ctiVariant} /\n * {@link Entity.stiVariant} via `opts.relations`. The `foreignKey`\n * accessor (when given) is typed against the variant's own schema and\n * resolved to a SQL column name.\n *\n * @public\n */\nexport interface VariantRelationInput<\n TVarSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> {\n type: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany';\n /**\n * Foreign side — accept either a bare schema, an Entity wrapper, or a\n * lazy thunk for forward references.\n */\n schema?:\n | ObjectSchemaBuilder<any, any, any, any, any, any, any>\n | (() => ObjectSchemaBuilder<any, any, any, any, any, any, any>);\n entity?: Entity<any, any>;\n foreignKey?: (t: EntityTree<TVarSchema>) => any;\n through?: { table: string; localKey: string; foreignKey: string };\n}\n\n/**\n * @internal Resolve a map of {@link VariantRelationInput} into the\n * column-resolved {@link ResolvedVariantRelationSpec[]} shape stored on a\n * resolved variant spec.\n */\nfunction resolveInlineVariantRelations(\n varSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n relations: Record<string, VariantRelationInput<any>> | undefined\n): ResolvedVariantRelationSpec[] {\n if (!relations) return [];\n const { propToCol } = buildColumnMap(varSchema);\n const result: ResolvedVariantRelationSpec[] = [];\n const tree = ObjectSchemaBuilder.getPropertiesFor(varSchema as any);\n\n for (const [name, spec] of Object.entries(relations)) {\n let foreignKey: string | undefined;\n if (spec.foreignKey) {\n const desc = spec.foreignKey(tree as any);\n const inner = (desc as any)?.[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n if (!inner?.propertyName) {\n throw new Error(\n `variant relation \"${name}\": foreignKey accessor must return a top-level property descriptor on the variant schema`\n );\n }\n const propKey: string = inner.propertyName;\n foreignKey = propToCol.get(propKey) ?? propKey;\n }\n const targetSchema = spec.entity ? spec.entity.schema : spec.schema;\n result.push({\n name,\n type: spec.type,\n schema: targetSchema,\n foreignKey,\n through: spec.through\n });\n }\n return result;\n}\n\n/**\n * Wrap an `ObjectSchemaBuilder` in an {@link Entity}, enabling typed relation\n * declaration via `.hasOne()` / `.hasMany()` / `.belongsTo()` / `.belongsToMany()`.\n *\n * @public\n *\n * @example\n * ```ts\n * const UserEntity = defineEntity(\n * object({\n * id: number().primaryKey(),\n * name: string(),\n * posts: array(PostEntity.schema)\n * }).hasTableName('users')\n * ).hasMany(t => t.posts, l => l.id, r => r.userId);\n * ```\n */\nexport function defineEntity<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(schema: TSchema): Entity<TSchema, {}> {\n return new Entity(schema);\n}\n\n/**\n * Type-level helper: extract `TRels` from any `Entity` type.\n * @public\n */\nexport type EntityRelations<E> =\n E extends Entity<any, infer R, any> ? R : never;\n\n/**\n * Type-level helper: extract the underlying schema type from any `Entity`.\n * @public\n */\nexport type EntitySchema<E> = E extends Entity<infer S, any, any> ? S : never;\n\n/**\n * Type-level helper: extract the accumulated variant union from any `Entity`.\n * Resolves to `never` for non-polymorphic entities.\n * @public\n */\nexport type EntityVariantUnion<E> =\n E extends Entity<any, any, infer U> ? U : never;\n\n/**\n * Type-level helper: union of relation key names declared on an entity.\n * Used by `SchemaQueryBuilder.insert()/update()/upsert()` to omit relation\n * navigation properties from accepted input.\n * @public\n */\nexport type EntityRelationKeys<E> =\n E extends Entity<any, infer R, any> ? keyof R & string : never;\n","// @cleverbrush/knex-schema — Post-load value transformers (from knex-eager)\n\nimport type { ValidatedSpec } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Built-in named mappers\n// ---------------------------------------------------------------------------\n\n/**\n * Built-in named value mapper functions.\n *\n * Each entry maps a string key to a transformation function. Pass the key as\n * the `mapper` argument to {@link mapValue} instead of a custom function.\n *\n * Currently available:\n * - `date_from_json` — converts a JSON date string (`string | null`) to a\n * JavaScript `Date` object (or passes through falsy values unchanged).\n */\nexport const MAPPERS: Record<string, (value: any) => any> = {\n date_from_json: (value: any) => {\n if (!value) return value;\n return new Date(Date.parse(value));\n }\n};\n\n// ---------------------------------------------------------------------------\n// mapValue — apply a mapper (function or built-in name) to a value\n// ---------------------------------------------------------------------------\n\n/**\n * Apply a single mapper to a value.\n *\n * @param mapper - Either a transformation function `(v: any) => any`, or a\n * string key referencing one of the {@link MAPPERS} built-ins (e.g.\n * `'date_from_json'`).\n * @param value - The raw value to transform.\n * @returns The transformed value.\n *\n * @throws If `mapper` is a string that does not exist in {@link MAPPERS}.\n */\nexport function mapValue(mapper: ((v: any) => any) | string, value: any): any {\n if (typeof mapper === 'string') {\n if (typeof MAPPERS[mapper] !== 'function') {\n throw new Error(`unknown mapper \"${mapper}\"`);\n }\n return MAPPERS[mapper](value);\n }\n if (typeof mapper === 'function') {\n return mapper(value);\n }\n throw new Error(\"couldn't map value\");\n}\n\n// ---------------------------------------------------------------------------\n// mapObject — apply mappers to all matching keys of an object\n// ---------------------------------------------------------------------------\n\n/**\n * Apply a map of per-key transformations to an object, returning a new object\n * with the transformed values.\n *\n * Keys not present in `mappers` are copied through unchanged. Keys present in\n * `mappers` are passed through {@link mapValue}.\n *\n * @param obj - The source object (e.g. a raw database row).\n * @param mappers - A `Record` mapping property keys to mapper functions or\n * {@link MAPPERS} built-in names.\n * @returns A shallow copy of `obj` with the specified values transformed.\n *\n * @throws If `obj` is `null` or a non-object, it is returned as-is.\n */\nexport function mapObject<T extends Record<string, any>>(\n obj: T,\n mappers: Record<string, ((v: any) => any) | string>\n): T {\n if (!mappers) throw new Error('mappers should be an object');\n if (!obj || typeof obj !== 'object' || obj === null) return obj;\n\n const result = {} as Record<string, any>;\n for (const key of Object.keys(obj)) {\n result[key] = mappers[key]\n ? mapValue(mappers[key], obj[key])\n : obj[key];\n }\n return result as T;\n}\n\n// ---------------------------------------------------------------------------\n// clearRow — apply mappers to joined data in a result row\n// ---------------------------------------------------------------------------\n\n/**\n * Apply value mappers to the joined fields of a result row in place.\n *\n * After an eager-loaded query resolves, joined objects and arrays may contain\n * raw database values that need transformation (e.g. date strings → `Date`).\n * This function iterates over the one-to-one and one-to-many specs, applies\n * the `mappers` defined on each spec to the nested data, and returns the\n * mutated row.\n *\n * This is an internal helper used by {@link SchemaQueryBuilder}'s result\n * mapping pipeline. Exported to allow custom post-processing if needed.\n *\n * @param row - The raw result row (mutated in place).\n * @param oneSpecs - Validated one-to-one join specs with optional `mappers`.\n * @param manySpecs - Validated one-to-many join specs with optional `mappers`.\n * @returns The mutated `row` object.\n */\nexport function clearRow(\n row: Record<string, any>,\n oneSpecs: Array<ValidatedSpec & { type: 'one' }>,\n manySpecs: Array<ValidatedSpec & { type: 'many' }>\n): Record<string, any> {\n for (const spec of oneSpecs) {\n const fieldName = spec.as;\n if (\n spec.mappers &&\n typeof row[fieldName] !== 'undefined' &&\n row[fieldName] !== null\n ) {\n row[fieldName] = mapObject(row[fieldName], spec.mappers);\n }\n }\n\n for (const spec of manySpecs) {\n const fieldName = spec.as;\n if (Array.isArray(row[fieldName])) {\n for (let k = 0; k < row[fieldName].length; k++) {\n if (row[fieldName][k]) {\n if (spec.mappers) {\n row[fieldName][k] = mapObject(\n row[fieldName][k],\n spec.mappers\n );\n }\n }\n }\n }\n }\n\n return row;\n}\n","// @cleverbrush/knex-schema — Schema diff & migration generation\n\nimport type { ObjectSchemaBuilder, SchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { generateCreateTableSource } from './ddl.js';\nimport type { Entity } from './entity.js';\nimport {\n getColumnName,\n getPolymorphicVariantSchemas,\n getTableName\n} from './extension.js';\nimport type {\n AddColumnDiff,\n AddForeignKeyDiff,\n AddIndexDiff,\n AlterColumnDiff,\n DatabaseCheckInfo,\n DatabaseColumnInfo,\n DatabaseForeignKeyInfo,\n DatabaseIndexInfo,\n DatabaseTableState,\n MigrationDiff,\n SchemaSnapshot\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Database introspection\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize raw database query results into a {@link DatabaseTableState}.\n * @internal\n */\nfunction normalizeDbState(\n columns: any[],\n indexes: any[],\n foreignKeys: any[],\n checks: any[]\n): DatabaseTableState {\n const colMap: Record<string, DatabaseColumnInfo> = {};\n for (const row of columns) {\n colMap[row.column_name] = {\n name: row.column_name,\n type: row.data_type,\n nullable: row.is_nullable === 'YES',\n defaultValue: row.column_default ?? null,\n maxLength: row.character_maximum_length ?? null,\n numericPrecision: row.numeric_precision ?? null\n };\n }\n\n const idxList: DatabaseIndexInfo[] = indexes.map((row: any) => ({\n name: row.indexname,\n columns: Array.isArray(row.columns) ? row.columns : [],\n unique: (row.indexdef ?? '').toUpperCase().includes('UNIQUE'),\n definition: row.indexdef ?? ''\n }));\n\n const fkList: DatabaseForeignKeyInfo[] = foreignKeys.map((row: any) => ({\n constraintName: row.constraint_name,\n columnName: row.column_name,\n foreignTable: row.foreign_table,\n foreignColumn: row.foreign_column,\n deleteRule: row.delete_rule,\n updateRule: row.update_rule\n }));\n\n const chkList: DatabaseCheckInfo[] = checks.map((row: any) => ({\n name: row.conname,\n definition: row.definition\n }));\n\n return {\n columns: colMap,\n indexes: idxList,\n foreignKeys: fkList,\n checks: chkList\n };\n}\n\n/**\n * Introspect a PostgreSQL table and return its current state.\n *\n * Queries `information_schema.columns`, `pg_indexes`, `pg_constraint`, and\n * referential constraint metadata to build a complete picture of the table's\n * columns, indexes, foreign keys, and check constraints.\n *\n * @param knex - A configured Knex instance connected to a PostgreSQL database.\n * @param tableName - The table name to introspect.\n * @returns The current database state for the table.\n *\n * @example\n * ```ts\n * const dbState = await introspectDatabase(knex, 'users');\n * console.log(dbState.columns); // { id: { type: 'integer', ... }, ... }\n * ```\n */\nexport async function introspectDatabase(\n knex: Knex,\n tableName: string\n): Promise<DatabaseTableState> {\n const [columns, indexes, foreignKeys, checks] = await Promise.all([\n knex.raw(\n `SELECT column_name, data_type, is_nullable, column_default,\n character_maximum_length, numeric_precision\n FROM information_schema.columns\n WHERE table_name = ? AND table_schema = 'public'\n ORDER BY ordinal_position`,\n [tableName]\n ),\n knex.raw(\n `SELECT indexname, indexdef,\n array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns\n FROM pg_indexes\n JOIN pg_class t ON t.relname = ?\n JOIN pg_index ix ON ix.indrelid = t.oid\n JOIN pg_class i ON i.oid = ix.indexrelid AND i.relname = pg_indexes.indexname\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)\n WHERE pg_indexes.tablename = ?\n GROUP BY indexname, indexdef`,\n [tableName, tableName]\n ),\n knex.raw(\n `SELECT tc.constraint_name, kcu.column_name,\n ccu.table_name AS foreign_table, ccu.column_name AS foreign_column,\n rc.delete_rule, rc.update_rule\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu USING (constraint_name, table_schema)\n JOIN information_schema.constraint_column_usage ccu USING (constraint_name, table_schema)\n JOIN information_schema.referential_constraints rc USING (constraint_name, constraint_schema)\n WHERE tc.table_name = ? AND tc.constraint_type = 'FOREIGN KEY'`,\n [tableName]\n ),\n knex.raw(\n `SELECT conname, pg_get_constraintdef(oid) as definition\n FROM pg_constraint\n WHERE conrelid = ?::regclass AND contype = 'c'`,\n [tableName]\n )\n ]);\n\n return normalizeDbState(\n columns.rows,\n indexes.rows,\n foreignKeys.rows,\n checks.rows\n );\n}\n\n// ---------------------------------------------------------------------------\n// Schema → column info extraction\n// ---------------------------------------------------------------------------\n\n/** @internal Map a schema type to a PostgreSQL data_type string for comparison. */\nfunction schemaTypeToDbType(\n introspected: any,\n ext: Record<string, any>\n): string {\n if (ext.columnType) return ext.columnType;\n if (ext.primaryKey?.autoIncrement) return 'integer';\n switch (introspected.type) {\n case 'string':\n return 'character varying';\n case 'number':\n return introspected.isInteger !== false\n ? 'integer'\n : 'double precision';\n case 'boolean':\n return 'boolean';\n case 'date':\n return 'timestamp without time zone';\n default:\n return 'text';\n }\n}\n\n// ---------------------------------------------------------------------------\n// entitySchemaToTableState\n// ---------------------------------------------------------------------------\n\n/**\n * Derive a {@link DatabaseTableState} from a code-first `ObjectSchemaBuilder`\n * without connecting to the database.\n *\n * The result mirrors what {@link introspectDatabase} would return after the\n * schema has been fully applied, so it can be fed directly into\n * {@link diffSchema} as the `dbState` argument. This is the foundation of\n * snapshot-based migration generation.\n *\n * @param schema - An `ObjectSchemaBuilder` with DDL extensions.\n * @returns A {@link DatabaseTableState} representing the schema's ideal DB shape.\n *\n * @example\n * ```ts\n * const state = entitySchemaToTableState(UserSchema);\n * // state.columns, state.foreignKeys, state.indexes …\n * ```\n */\nexport function entitySchemaToTableState(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): DatabaseTableState {\n const tableName = getTableName(schema);\n const introspected = schema.introspect() as any;\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n const tableExt: Record<string, any> = introspected.extensions ?? {};\n\n const columns: Record<string, DatabaseColumnInfo> = {};\n const indexes: DatabaseIndexInfo[] = [];\n const foreignKeys: DatabaseForeignKeyInfo[] = [];\n const checks: DatabaseCheckInfo[] = [];\n\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const col = getColumnName(propSchema, propKey);\n const propIntrospected = propSchema.introspect() as any;\n const ext: Record<string, any> = propIntrospected.extensions ?? {};\n\n // Skip navigation properties (object/array without an explicit columnType).\n if (\n (propIntrospected.type === 'object' ||\n propIntrospected.type === 'array') &&\n !ext.columnType\n ) {\n continue;\n }\n\n columns[col] = {\n name: col,\n type: schemaTypeToDbType(propIntrospected, ext),\n nullable: !propIntrospected.isRequired,\n defaultValue: ext.defaultTo ?? null,\n maxLength: ext.maxLength ?? propIntrospected.maxLength ?? null,\n numericPrecision: null\n };\n\n if (ext.references) {\n foreignKeys.push({\n // Use Knex's default FK constraint naming convention\n constraintName: `${tableName}_${col}_foreign`,\n columnName: col,\n foreignTable: ext.references.table,\n foreignColumn: ext.references.column,\n deleteRule: (ext.onDelete ?? 'NO ACTION').toUpperCase(),\n updateRule: (ext.onUpdate ?? 'NO ACTION').toUpperCase()\n });\n }\n }\n\n // Timestamp columns (created_at / updated_at)\n if (tableExt.timestamps) {\n const ts = tableExt.timestamps;\n const createdAtCol: string = ts.createdAt ?? 'created_at';\n const updatedAtCol: string = ts.updatedAt ?? 'updated_at';\n columns[createdAtCol] = {\n name: createdAtCol,\n type: 'timestamp without time zone',\n nullable: false,\n defaultValue: 'now',\n maxLength: null,\n numericPrecision: null\n };\n columns[updatedAtCol] = {\n name: updatedAtCol,\n type: 'timestamp without time zone',\n nullable: false,\n defaultValue: 'now',\n maxLength: null,\n numericPrecision: null\n };\n }\n\n // Soft-delete column\n if (tableExt.softDelete) {\n const delCol: string = tableExt.softDelete.column ?? 'deleted_at';\n columns[delCol] = {\n name: delCol,\n type: 'timestamp without time zone',\n nullable: true,\n defaultValue: null,\n maxLength: null,\n numericPrecision: null\n };\n }\n\n // Non-unique indexes\n for (const idx of tableExt.indexes ?? []) {\n const idxName: string =\n idx.name ?? `idx_${(idx.columns as string[]).join('_')}`;\n indexes.push({\n name: idxName,\n columns: idx.columns,\n unique: idx.unique ?? false,\n definition: ''\n });\n }\n\n // Unique constraints\n for (const unq of tableExt.uniques ?? []) {\n const unqName: string =\n unq.name ?? `unq_${(unq.columns as string[]).join('_')}`;\n indexes.push({\n name: unqName,\n columns: unq.columns,\n unique: true,\n definition: ''\n });\n }\n\n return { columns, indexes, foreignKeys, checks };\n}\n\n// ---------------------------------------------------------------------------\n// diffSchema\n// ---------------------------------------------------------------------------\n\n/**\n * Compare a code-first schema model against a live database table state and\n * produce a diff describing the changes needed to bring the database in sync.\n *\n * @param schema - The code-first `ObjectSchemaBuilder`.\n * @param dbState - The current database state from {@link introspectDatabase}.\n * @returns A {@link MigrationDiff} describing columns, indexes, and foreign\n * keys to add, drop, or alter.\n *\n * @example\n * ```ts\n * const dbState = await introspectDatabase(knex, 'users');\n * const diff = diffSchema(UserSchema, dbState);\n * if (diff.addColumns.length > 0) {\n * const migration = generateMigration(diff, 'users');\n * console.log(migration.up);\n * }\n * ```\n */\nexport function diffSchema(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n dbState: DatabaseTableState\n): MigrationDiff {\n const introspected = schema.introspect() as any;\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n const tableExt: Record<string, any> = introspected.extensions ?? {};\n\n const addColumns: AddColumnDiff[] = [];\n const dropColumns: string[] = [];\n const alterColumns: AlterColumnDiff[] = [];\n const addIndexes: AddIndexDiff[] = [];\n const dropIndexes: string[] = [];\n const addForeignKeys: AddForeignKeyDiff[] = [];\n const dropForeignKeys: string[] = [];\n\n // Columns whose default values are owned by table-level extensions\n // (hasTimestamps, softDelete). Don't compare defaultValue for these —\n // the extension is authoritative.\n const extensionOwnedDefaults = new Set<string>();\n if (tableExt.timestamps) {\n extensionOwnedDefaults.add(tableExt.timestamps.createdAt);\n extensionOwnedDefaults.add(tableExt.timestamps.updatedAt);\n }\n\n // Set of schema-defined column names\n const schemaColumns = new Set<string>();\n\n // --- Column diff ---\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const col = getColumnName(propSchema, propKey);\n const propIntrospected = propSchema.introspect() as any;\n const ext: Record<string, any> = propIntrospected.extensions ?? {};\n\n // Skip navigation properties (object/array without explicit columnType).\n if (\n (propIntrospected.type === 'object' ||\n propIntrospected.type === 'array') &&\n !ext.columnType\n ) {\n continue;\n }\n\n schemaColumns.add(col);\n\n const dbCol = dbState.columns[col];\n if (!dbCol) {\n // Column exists in schema but not in DB → add\n addColumns.push({\n name: col,\n type: schemaTypeToDbType(propIntrospected, ext),\n nullable: !propIntrospected.isRequired,\n defaultValue: ext.defaultTo,\n references: ext.references,\n onDelete: ext.onDelete,\n onUpdate: ext.onUpdate\n });\n } else {\n // Column exists in both → check for alterations\n const changes: Record<string, { from: any; to: any }> = {};\n\n const expectedNullable = !propIntrospected.isRequired;\n if (dbCol.nullable !== expectedNullable) {\n changes.nullable = {\n from: dbCol.nullable,\n to: expectedNullable\n };\n }\n\n // Compare defaultValue (null / undefined both mean \"no default\")\n // Skip columns whose default is controlled by a table-level extension,\n // or auto-increment PKs whose nextval(...) default is DB-managed.\n if (\n !extensionOwnedDefaults.has(col) &&\n !ext.primaryKey?.autoIncrement\n ) {\n const snapshotDefault = dbCol.defaultValue ?? null;\n const schemaDefault = ext.defaultTo ?? null;\n if (snapshotDefault !== schemaDefault) {\n changes.defaultValue = {\n from: snapshotDefault,\n to: schemaDefault\n };\n }\n }\n\n if (Object.keys(changes).length > 0) {\n alterColumns.push({ name: col, changes });\n }\n }\n\n // Foreign key diff\n if (ext.references) {\n const existingFK = dbState.foreignKeys.find(\n fk => fk.columnName === col\n );\n if (!existingFK) {\n addForeignKeys.push({\n column: col,\n foreignTable: ext.references.table,\n foreignColumn: ext.references.column,\n onDelete: ext.onDelete,\n onUpdate: ext.onUpdate\n });\n }\n }\n }\n\n // Include timestamp columns in schema column set\n if (tableExt.timestamps) {\n schemaColumns.add(tableExt.timestamps.createdAt);\n schemaColumns.add(tableExt.timestamps.updatedAt);\n }\n if (tableExt.softDelete) {\n schemaColumns.add(tableExt.softDelete.column);\n }\n\n // Columns in DB but not in schema → drop\n for (const colName of Object.keys(dbState.columns)) {\n if (!schemaColumns.has(colName)) {\n dropColumns.push(colName);\n }\n }\n\n // --- Index diff ---\n const schemaIndexNames = new Set<string>();\n\n for (const idx of tableExt.indexes ?? []) {\n const idxName = idx.name ?? `idx_${idx.columns.join('_')}`;\n schemaIndexNames.add(idxName);\n const existingIdx = dbState.indexes.find(\n dbIdx => dbIdx.name === idxName\n );\n if (!existingIdx) {\n addIndexes.push({\n columns: idx.columns,\n name: idx.name,\n unique: idx.unique\n });\n }\n }\n\n for (const unq of tableExt.uniques ?? []) {\n const unqName = unq.name ?? `unq_${unq.columns.join('_')}`;\n schemaIndexNames.add(unqName);\n const existingIdx = dbState.indexes.find(\n dbIdx => dbIdx.name === unqName\n );\n if (!existingIdx) {\n addIndexes.push({\n columns: unq.columns,\n name: unq.name,\n unique: true\n });\n }\n }\n\n // FK constraints that exist in DB but not in schema → drop\n for (const fk of dbState.foreignKeys) {\n const propSchema = Object.entries(properties).find(([propKey, ps]) => {\n return getColumnName(ps, propKey) === fk.columnName;\n });\n if (propSchema) {\n const ext = (propSchema[1].introspect() as any).extensions ?? {};\n if (!ext.references) {\n dropForeignKeys.push(fk.constraintName);\n }\n } else {\n dropForeignKeys.push(fk.constraintName);\n }\n }\n\n return {\n addColumns,\n dropColumns,\n alterColumns,\n addIndexes,\n dropIndexes,\n addForeignKeys,\n dropForeignKeys\n };\n}\n\n// ---------------------------------------------------------------------------\n// generateMigration\n// ---------------------------------------------------------------------------\n\n/**\n * Generate migration `up` and `down` code strings from a {@link MigrationDiff}.\n *\n * The generated code is valid TypeScript that uses Knex's schema builder API.\n * Write it to a migration file and run via Knex's migration system.\n *\n * @param diff - The schema diff from {@link diffSchema}.\n * @param tableName - The table name to alter.\n * @returns An object with `up` and `down` migration code strings.\n *\n * @example\n * ```ts\n * const diff = diffSchema(UserSchema, dbState);\n * const migration = generateMigration(diff, 'users');\n * fs.writeFileSync('migration.ts', migration.full);\n * ```\n */\nexport function generateMigration(\n diff: MigrationDiff,\n tableName: string\n): { up: string; down: string; full: string } {\n const { up, down } = buildAlterTableFragments(diff, tableName);\n\n const full = `import type { Knex } from 'knex';\n\nexport async function up(knex: Knex): Promise<void> {\n${up}\n}\n\nexport async function down(knex: Knex): Promise<void> {\n${down}\n}\n`;\n\n return { up, down, full };\n}\n\n// ---------------------------------------------------------------------------\n// tableExistsInDb\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether a table exists in the connected PostgreSQL database.\n *\n * @param knex - A configured Knex instance (or transaction).\n * @param tableName - The table name to check.\n * @returns `true` when the table exists.\n *\n * @example\n * ```ts\n * const exists = await tableExistsInDb(knex, 'users');\n * if (!exists) await generateCreateTable(UserSchema)(knex);\n * ```\n */\nexport async function tableExistsInDb(\n knex: Knex,\n tableName: string\n): Promise<boolean> {\n return knex.schema.hasTable(tableName);\n}\n\n// ---------------------------------------------------------------------------\n// isDiffEmpty\n// ---------------------------------------------------------------------------\n\n/**\n * Return `true` when a {@link MigrationDiff} has no operations — i.e. the\n * database table is already in sync with the schema.\n */\nexport function isDiffEmpty(diff: MigrationDiff): boolean {\n return (\n diff.addColumns.length === 0 &&\n diff.dropColumns.length === 0 &&\n diff.alterColumns.length === 0 &&\n diff.addIndexes.length === 0 &&\n diff.dropIndexes.length === 0 &&\n diff.addForeignKeys.length === 0 &&\n diff.dropForeignKeys.length === 0\n );\n}\n\n// ---------------------------------------------------------------------------\n// applyDiff\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a {@link MigrationDiff} directly against a live database without\n * writing a migration file. Intended for `db push` (dev-only schema sync).\n *\n * Foreign-key constraint drops are executed as raw `ALTER TABLE … DROP\n * CONSTRAINT` statements before the main `alterTable` call.\n *\n * @param knex - A configured Knex instance or transaction.\n * @param diff - The diff from {@link diffSchema}.\n * @param tableName - The table to alter.\n *\n * @example\n * ```ts\n * const dbState = await introspectDatabase(knex, 'users');\n * const diff = diffSchema(UserSchema, dbState);\n * if (!isDiffEmpty(diff)) await applyDiff(knex, diff, 'users');\n * ```\n */\nexport async function applyDiff(\n knex: Knex,\n diff: MigrationDiff,\n tableName: string\n): Promise<void> {\n if (isDiffEmpty(diff)) return;\n\n // FK constraint drops require raw SQL (we only have constraint names, not\n // column names, in the diff so Knex's dropForeign helper cannot be used).\n for (const constraintName of diff.dropForeignKeys) {\n await knex.raw('ALTER TABLE ?? DROP CONSTRAINT ??', [\n tableName,\n constraintName\n ]);\n }\n\n const hasTableChanges =\n diff.addColumns.length > 0 ||\n diff.dropColumns.length > 0 ||\n diff.alterColumns.length > 0 ||\n diff.addIndexes.length > 0 ||\n diff.dropIndexes.length > 0 ||\n diff.addForeignKeys.length > 0;\n\n if (!hasTableChanges) return;\n\n await knex.schema.alterTable(tableName, table => {\n // Add columns\n for (const col of diff.addColumns) {\n let column = buildColumnFromDbType(\n table as unknown as Knex.CreateTableBuilder,\n col.name,\n col.type\n );\n if (col.nullable) column = column.nullable();\n else column = column.notNullable();\n if (col.defaultValue !== undefined) {\n if (col.defaultValue === 'now') {\n column = column.defaultTo(knex.fn.now());\n } else if (\n typeof col.defaultValue === 'object' &&\n col.defaultValue !== null &&\n col.defaultValue.raw\n ) {\n column = column.defaultTo(knex.raw(col.defaultValue.raw));\n } else {\n column = column.defaultTo(col.defaultValue);\n }\n }\n if (col.references) {\n const fkBuilder = column\n .references(col.references.column)\n .inTable(col.references.table);\n if (col.onDelete) fkBuilder.onDelete(col.onDelete);\n if (col.onUpdate) fkBuilder.onUpdate(col.onUpdate);\n }\n }\n\n // Drop columns\n for (const colName of diff.dropColumns) {\n table.dropColumn(colName);\n }\n\n // Alter nullable / default\n for (const col of diff.alterColumns) {\n for (const [key, change] of Object.entries(col.changes)) {\n if (key === 'nullable') {\n if (change.to) {\n (table as any).setNullable(col.name);\n } else {\n (table as any).dropNullable(col.name);\n }\n } else if (key === 'defaultValue') {\n if (change.to === null) {\n table.dropColumn(col.name); // fallback — handled in source gen\n } else {\n // ALTER COLUMN SET DEFAULT is not directly in Knex builder;\n // handled via raw in source generation\n }\n }\n }\n }\n\n // Add indexes\n for (const idx of diff.addIndexes) {\n if (idx.unique) {\n table.unique(\n idx.columns,\n idx.name ? { indexName: idx.name } : undefined\n );\n } else {\n table.index(idx.columns, idx.name);\n }\n }\n\n // Drop indexes\n for (const idx of diff.dropIndexes) {\n table.dropIndex([], idx);\n }\n\n // Add foreign keys\n for (const fk of diff.addForeignKeys) {\n let builder = table\n .foreign(fk.column)\n .references(fk.foreignColumn)\n .inTable(fk.foreignTable);\n if (fk.onDelete) builder = builder.onDelete(fk.onDelete);\n if (fk.onUpdate) builder = builder.onUpdate(fk.onUpdate);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// generateMigrationsForContext\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a single combined migration (up + down) for a set of entities by\n * diffing the current code-first schemas against a **serialized snapshot**\n * stored in the repository — no live database connection required.\n *\n * For each entity's table the function:\n * - **New tables** (in entities but not in `prevSnapshot`): emits `CREATE TABLE`.\n * - **Existing tables** (in both): diffs entity schema against the snapshot\n * state via {@link diffSchema} and emits `ALTER TABLE` when changes exist.\n * - **Dropped tables** (in `prevSnapshot` but not in entities): emits\n * `DROP TABLE` with a best-effort `CREATE TABLE` in the `down` direction.\n * - Orders tables topologically by FK dependencies so parent tables are\n * created before child tables in `up` (and dropped after in `down`).\n *\n * @param entities - The entities from your {@link EntityMap}.\n * @param prevSnapshot - The last committed {@link SchemaSnapshot} (empty on first run).\n * @returns `{ up, down, full, isEmpty, nextSnapshot }` where `nextSnapshot`\n * should be written to disk after the migration file is created.\n *\n * @example\n * ```ts\n * const prev = loadSnapshot('./migrations/snapshot.json');\n * const result = generateMigrationsForContext(\n * Object.values({ todos: TodoEntity, users: UserEntity }),\n * prev\n * );\n * if (!result.isEmpty) {\n * fs.writeFileSync('migrations/20260423000000_init.ts', result.full);\n * writeSnapshot('./migrations/snapshot.json', result.nextSnapshot);\n * }\n * ```\n */\nexport function generateMigrationsForContext(\n entities: Entity<any, any>[],\n prevSnapshot: SchemaSnapshot\n): {\n up: string;\n down: string;\n full: string;\n isEmpty: boolean;\n nextSnapshot: SchemaSnapshot;\n} {\n // 1. Collect all (schema, tableName) pairs including CTI variant tables\n const tableEntries: {\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n tableName: string;\n }[] = [];\n\n for (const entity of entities) {\n const schema = entity.schema;\n const tableName = getTableName(schema);\n tableEntries.push({ schema, tableName });\n\n // CTI variant tables each have their own tableName extension set\n for (const vs of getPolymorphicVariantSchemas(schema)) {\n const variantTableName = vs.getExtension('tableName') as\n | string\n | undefined;\n if (variantTableName) {\n tableEntries.push({ schema: vs, tableName: variantTableName });\n }\n }\n }\n\n // 2. Deduplicate (STI variants share the base table)\n const seen = new Set<string>();\n const uniqueEntries = tableEntries.filter(e => {\n if (seen.has(e.tableName)) return false;\n seen.add(e.tableName);\n return true;\n });\n\n // 3. Topological sort by FK dependencies\n const sorted = topologicalSort(uniqueEntries);\n\n // 4. Generate CREATE or ALTER fragment for each current table\n const upParts: string[] = [];\n const downParts: string[] = [];\n\n const currentTableNames = new Set(sorted.map(e => e.tableName));\n\n for (const { schema, tableName } of sorted) {\n const snapshotState = prevSnapshot.tables[tableName];\n if (!snapshotState) {\n // New table — emit CREATE TABLE\n const { up, down } = generateCreateTableSource(schema);\n upParts.push(up);\n downParts.push(down);\n } else {\n // Existing table — diff schema against snapshot (pure, no DB)\n const diff = diffSchema(schema, snapshotState);\n if (!isDiffEmpty(diff)) {\n const { up, down } = buildAlterTableFragments(diff, tableName);\n upParts.push(up);\n downParts.push(down);\n }\n }\n }\n\n // 5. Tables in snapshot but absent from current entities → DROP TABLE\n for (const tableName of Object.keys(prevSnapshot.tables)) {\n if (!currentTableNames.has(tableName)) {\n const state = prevSnapshot.tables[tableName];\n const { up, down } = generateDropTableSource(tableName, state);\n upParts.push(up);\n // Recreate before other downs so FK deps are satisfied\n downParts.unshift(down);\n }\n }\n\n const isEmpty = upParts.length === 0;\n\n // Down reverses creation order so child tables are dropped before parents\n const up = upParts.join('\\n\\n');\n const down = [...downParts].reverse().join('\\n\\n');\n\n const full = `import type { Knex } from 'knex';\n\nexport async function up(knex: Knex): Promise<void> {\n${isEmpty ? ' // No changes needed' : up}\n}\n\nexport async function down(knex: Knex): Promise<void> {\n${isEmpty ? ' // No changes needed' : down}\n}\n`;\n\n // Build the next snapshot from current entity schemas\n const nextTables: Record<string, DatabaseTableState> = {};\n for (const { schema, tableName } of sorted) {\n nextTables[tableName] = entitySchemaToTableState(schema);\n }\n const nextSnapshot: SchemaSnapshot = { version: 1, tables: nextTables };\n\n return { up, down, full, isEmpty, nextSnapshot };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * @internal\n * Emit `DROP TABLE` (up) and a best-effort `CREATE TABLE` reconstruction\n * (down) from a {@link DatabaseTableState} stored in the snapshot.\n * Called for tables that exist in the previous snapshot but are absent from\n * the current entity set.\n */\nfunction generateDropTableSource(\n tableName: string,\n state: DatabaseTableState\n): { up: string; down: string } {\n const up =\n ` // TODO: review destructive change — dropped table '${tableName}'\\n` +\n ` await knex.schema.dropTableIfExists(${JSON.stringify(tableName)});`;\n\n // Reconstruct CREATE TABLE from snapshot state using specificType for\n // all columns so the raw DB types are preserved faithfully.\n const colLines: string[] = [];\n for (const [colName, col] of Object.entries(state.columns)) {\n let line = ` table.specificType(${JSON.stringify(colName)}, ${JSON.stringify(col.type)})`;\n if (col.nullable) line += '.nullable()';\n else line += '.notNullable()';\n if (col.defaultValue !== null && col.defaultValue !== undefined) {\n line += `.defaultTo(${JSON.stringify(col.defaultValue)})`;\n }\n colLines.push(line + ';');\n }\n for (const fk of state.foreignKeys) {\n colLines.push(\n ` table.foreign(${JSON.stringify(fk.columnName)}).references(${JSON.stringify(fk.foreignColumn)}).inTable(${JSON.stringify(fk.foreignTable)}).onDelete(${JSON.stringify(fk.deleteRule)}).onUpdate(${JSON.stringify(fk.updateRule)});`\n );\n }\n for (const idx of state.indexes) {\n if (idx.unique) {\n colLines.push(\n ` table.unique(${JSON.stringify(idx.columns)}, { indexName: ${JSON.stringify(idx.name)} });`\n );\n } else {\n colLines.push(\n ` table.index(${JSON.stringify(idx.columns)}, ${JSON.stringify(idx.name)});`\n );\n }\n }\n\n const down =\n ` await knex.schema.createTable(${JSON.stringify(tableName)}, (table) => {\\n` +\n colLines.join('\\n') +\n '\\n });';\n\n return { up, down };\n}\n\n/**\n * @internal\n * Extract the body of a MigrationDiff into up/down Knex schema code strings\n * (indented 4 spaces, wrapped in `alterTable` when non-empty).\n * Used by both {@link generateMigration} and {@link generateMigrationsForContext}.\n */\nfunction buildAlterTableFragments(\n diff: MigrationDiff,\n tableName: string\n): { up: string; down: string } {\n const upLines: string[] = [];\n const downLines: string[] = [];\n\n // --- ADD COLUMNS ---\n for (const col of diff.addColumns) {\n const typeCall = col.type.includes(' ')\n ? `table.specificType('${col.name}', '${col.type}')`\n : `table.${mapTypeToKnex(col.type)}('${col.name}')`;\n\n let line = ` ${typeCall}`;\n if (col.nullable) line += '.nullable()';\n else line += '.notNullable()';\n if (col.defaultValue !== undefined) {\n line += `.defaultTo(${formatDefault(col.defaultValue)})`;\n }\n line += ';';\n\n upLines.push(line);\n downLines.push(` table.dropColumn('${col.name}');`);\n }\n\n // --- DROP COLUMNS ---\n for (const col of diff.dropColumns) {\n upLines.push(` table.dropColumn('${col}');`);\n downLines.push(\n ` // TODO: recreate column '${col}' with original definition`\n );\n }\n\n // --- ALTER COLUMNS ---\n for (const col of diff.alterColumns) {\n for (const [key, change] of Object.entries(col.changes)) {\n if (key === 'nullable') {\n if (change.to) {\n upLines.push(` table.setNullable('${col.name}');`);\n downLines.push(\n ` table.dropNullable('${col.name}');`\n );\n } else {\n upLines.push(` table.dropNullable('${col.name}');`);\n downLines.push(` table.setNullable('${col.name}');`);\n }\n } else if (key === 'defaultValue') {\n const toVal = change.to;\n const fromVal = change.from;\n if (toVal === null) {\n upLines.push(\n ` table.timestamp('${col.name}').alter(); // DROP DEFAULT`\n );\n downLines.push(\n ` table.timestamp('${col.name}').defaultTo(knex.fn.now()).alter();`\n );\n } else {\n upLines.push(\n ` table.timestamp('${col.name}').notNullable().defaultTo(knex.fn.now()).alter();`\n );\n downLines.push(\n fromVal === null\n ? ` table.timestamp('${col.name}').notNullable().alter();`\n : ` table.timestamp('${col.name}').notNullable().defaultTo(knex.fn.now()).alter();`\n );\n }\n }\n }\n }\n\n // --- ADD INDEXES ---\n for (const idx of diff.addIndexes) {\n const cols = JSON.stringify(idx.columns);\n if (idx.unique) {\n upLines.push(\n ` table.unique(${cols}${idx.name ? `, { indexName: '${idx.name}' }` : ''});`\n );\n downLines.push(\n ` table.dropUnique(${cols}${idx.name ? `, '${idx.name}'` : ''});`\n );\n } else {\n upLines.push(\n ` table.index(${cols}${idx.name ? `, '${idx.name}'` : ''});`\n );\n downLines.push(\n ` table.dropIndex([]${idx.name ? `, '${idx.name}'` : ''});`\n );\n }\n }\n\n // --- DROP INDEXES ---\n for (const idx of diff.dropIndexes) {\n upLines.push(` table.dropIndex([], '${idx}');`);\n downLines.push(\n ` // TODO: recreate index '${idx}' with original definition`\n );\n }\n\n // --- ADD FOREIGN KEYS ---\n for (const fk of diff.addForeignKeys) {\n let line = ` table.foreign('${fk.column}').references('${fk.foreignColumn}').inTable('${fk.foreignTable}')`;\n if (fk.onDelete) line += `.onDelete('${fk.onDelete}')`;\n if (fk.onUpdate) line += `.onUpdate('${fk.onUpdate}')`;\n line += ';';\n upLines.push(line);\n downLines.push(` table.dropForeign('${fk.column}');`);\n }\n\n // --- DROP FOREIGN KEYS ---\n for (const fk of diff.dropForeignKeys) {\n upLines.push(` // TODO: drop foreign key constraint '${fk}'`);\n }\n\n const isEmpty = upLines.length === 0;\n\n const up = isEmpty\n ? ` // No changes needed`\n : ` await knex.schema.alterTable('${tableName}', (table) => {\\n${upLines.join('\\n')}\\n });`;\n\n const down = isEmpty\n ? ` // No changes needed`\n : ` await knex.schema.alterTable('${tableName}', (table) => {\\n${downLines.join('\\n')}\\n });`;\n\n return { up, down };\n}\n\n/** @internal Build a Knex ColumnBuilder from a PostgreSQL data type string (runtime use). */\nfunction buildColumnFromDbType(\n table: Knex.CreateTableBuilder,\n name: string,\n dbType: string\n): Knex.ColumnBuilder {\n switch (dbType) {\n case 'integer':\n return table.integer(name);\n case 'character varying':\n return table.string(name);\n case 'text':\n return table.text(name);\n case 'boolean':\n return table.boolean(name);\n case 'timestamp without time zone':\n case 'timestamp':\n return table.timestamp(name);\n case 'double precision':\n case 'float':\n return table.float(name);\n case 'jsonb':\n case 'json':\n return table.specificType(name, 'jsonb');\n case 'uuid':\n return table.uuid(name);\n default:\n return table.specificType(name, dbType);\n }\n}\n\n/**\n * @internal\n * Topologically sort table entries by FK dependency so parent tables\n * come first in `up` (and last in `down`). Falls back to original order\n * for cycles or external references.\n */\nfunction topologicalSort(\n entries: {\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n tableName: string;\n }[]\n): typeof entries {\n const tableSet = new Set(entries.map(e => e.tableName));\n const deps = new Map<string, Set<string>>();\n\n for (const { schema, tableName } of entries) {\n const depSet = new Set<string>();\n const properties: Record<string, any> =\n (schema.introspect() as any).properties ?? {};\n for (const [, propSchema] of Object.entries(properties)) {\n const ext =\n ((propSchema as any).introspect?.() as any)?.extensions ?? {};\n if (ext.references?.table && tableSet.has(ext.references.table)) {\n depSet.add(ext.references.table);\n }\n }\n deps.set(tableName, depSet);\n }\n\n // Kahn's algorithm\n const inDegree = new Map<string, number>();\n const graph = new Map<string, string[]>(); // dep -> tables that depend on it\n for (const { tableName } of entries) {\n inDegree.set(tableName, 0);\n graph.set(tableName, []);\n }\n for (const { tableName } of entries) {\n for (const dep of deps.get(tableName) ?? []) {\n graph.get(dep)!.push(tableName);\n inDegree.set(tableName, (inDegree.get(tableName) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const [t, deg] of inDegree) {\n if (deg === 0) queue.push(t);\n }\n\n const sortedNames: string[] = [];\n while (queue.length > 0) {\n const t = queue.shift()!;\n sortedNames.push(t);\n for (const dependent of graph.get(t) ?? []) {\n const newDeg = inDegree.get(dependent)! - 1;\n inDegree.set(dependent, newDeg);\n if (newDeg === 0) queue.push(dependent);\n }\n }\n\n // Append any cycles / unresolved entries in their original relative order\n const sortedSet = new Set(sortedNames);\n const remaining = entries.filter(e => !sortedSet.has(e.tableName));\n const byName = new Map(entries.map(e => [e.tableName, e]));\n return [...sortedNames.map(t => byName.get(t)!), ...remaining];\n}\n\n/** @internal Map a PostgreSQL data type string to a Knex column method name. */\nfunction mapTypeToKnex(type: string): string {\n switch (type) {\n case 'integer':\n return 'integer';\n case 'character varying':\n return 'string';\n case 'text':\n return 'text';\n case 'boolean':\n return 'boolean';\n case 'timestamp without time zone':\n case 'timestamp':\n return 'timestamp';\n case 'double precision':\n case 'float':\n return 'float';\n case 'jsonb':\n case 'json':\n return 'jsonb';\n case 'uuid':\n return 'uuid';\n default:\n return `specificType('${type}')` as any;\n }\n}\n\n/** @internal Format a default value for migration code generation. */\nfunction formatDefault(value: any): string {\n if (value === 'now') return 'knex.fn.now()';\n if (typeof value === 'object' && value !== null && value.raw) {\n return `knex.raw('${value.raw.replace(/'/g, \"\\\\'\")}')`;\n }\n if (typeof value === 'string') return `'${value.replace(/'/g, \"\\\\'\")}'`;\n return String(value);\n}\n","// @cleverbrush/knex-schema — Raw query execution with schema result mapping\n\nimport type { InferType, ObjectSchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from './columns.js';\n\n/**\n * Execute a raw SQL query or Knex query builder and map the result rows\n * through the schema's column→property name mapping.\n *\n * This is the escape hatch for complex queries that can't be expressed with\n * the typed `SchemaQueryBuilder` API. The schema is used only for result\n * mapping — column names in the result are converted back to property names.\n * Extra columns (not in the schema) are passed through unchanged.\n *\n * @param knex - A configured Knex instance.\n * @param schema - The `ObjectSchemaBuilder` for result mapping.\n * @param queryOrSql - A raw SQL string or a `Knex.QueryBuilder`.\n * @param bindings - Optional bindings for parameterised SQL queries.\n * @returns Mapped result rows.\n *\n * @example\n * ```ts\n * // Raw SQL with schema result mapping\n * const results = await rawQuery(knex, PostSchema, `\n * SELECT p.*, COUNT(c.id) AS comment_count\n * FROM posts p\n * LEFT JOIN comments c ON c.post_id = p.id\n * GROUP BY p.id\n * ORDER BY comment_count DESC\n * LIMIT ?\n * `, [10]);\n *\n * // Knex query builder as the source\n * const subQuery = knex('posts').select('author_id', knex.raw('COUNT(*) as post_count')).groupBy('author_id');\n * const results = await rawQuery(knex, UserSchema, subQuery);\n * ```\n */\nexport async function rawQuery<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(\n knex: Knex,\n schema: TSchema,\n queryOrSql: string | Knex.QueryBuilder,\n bindings?: any[]\n): Promise<(InferType<TSchema> & Record<string, any>)[]> {\n let rows: any[];\n\n if (typeof queryOrSql === 'string') {\n const result = await knex.raw(queryOrSql, bindings ?? []);\n rows = result.rows ?? result;\n } else {\n rows = await queryOrSql;\n }\n\n if (!rows || !Array.isArray(rows)) return [];\n\n const { colToProp } = buildColumnMap(schema);\n\n return rows.map(row => {\n const mapped: Record<string, any> = {};\n for (const [key, value] of Object.entries(row)) {\n const propName = colToProp.get(key);\n mapped[propName ?? key] = value;\n }\n return mapped;\n }) as any;\n}\n","// @cleverbrush/knex-schema — SELECT / DISTINCT / aggregates / projections / scopes\n\nimport {\n ObjectSchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR\n} from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from '../columns.js';\nimport { getProjections } from '../extension.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type { ColumnRef } from '../types.js';\nimport {\n assertNotExplicitSelect,\n assertNotProjection,\n invalidateCache,\n resolveColumn,\n resolveColumnArg\n} from './helpers.js';\nimport { getState } from './state.js';\n\nexport function selectImpl(\n builder: SchemaQueryBuilder<any, any>,\n ...args: unknown[]\n): any {\n const state = getState(builder);\n\n if (args.length === 1 && typeof args[0] === 'function') {\n const fn = args[0] as (t: any) => unknown;\n const tree = ObjectSchemaBuilder.getPropertiesFor(\n state.localSchema as any\n );\n const result = fn(tree);\n if (\n result &&\n typeof result === 'object' &&\n !(SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in (result as object))\n ) {\n invalidateCache(builder);\n assertNotProjection(builder, 'select');\n state.selectionMode = 'projection';\n state.appliedProjection = '<inline>';\n\n const aliasMap: Record<string, string> = {};\n state.explicitSelects ??= [];\n for (const [alias, descriptor] of Object.entries(\n result as Record<string, unknown>\n )) {\n if (\n !descriptor ||\n typeof descriptor !== 'object' ||\n !(\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in\n (descriptor as object)\n )\n ) {\n throw new Error(\n `select(selector): value for alias \"${alias}\" must be a property descriptor (e.g. \\`t.someProp\\`).`\n );\n }\n const col = resolveColumn(\n builder,\n (() => descriptor) as ColumnRef<any>,\n `select(selector).${alias}`\n );\n aliasMap[alias] = col as string;\n state.explicitSelects.push(col as string);\n }\n state.baseQuery.select(aliasMap);\n return builder;\n }\n }\n\n invalidateCache(builder);\n assertNotProjection(builder, 'select');\n state.selectionMode = 'select';\n const resolved = (args as (ColumnRef<any> | Knex.Raw)[]).map(c =>\n resolveColumnArg(builder, c)\n );\n state.baseQuery.select(...(resolved as string[]));\n state.explicitSelects ??= [];\n for (const r of resolved) {\n if (typeof r === 'string') {\n state.explicitSelects.push(r);\n }\n }\n return builder;\n}\n\nexport function distinctImpl(\n builder: SchemaQueryBuilder<any, any>,\n ...columns: (ColumnRef<any> | Knex.Raw)[]\n): any {\n invalidateCache(builder);\n const resolved = columns.map(c => resolveColumnArg(builder, c));\n getState(builder).baseQuery.distinct(...(resolved as string[]));\n return builder;\n}\n\nexport function countImpl(\n builder: SchemaQueryBuilder<any, any>,\n column?: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'count');\n state.selectionMode = 'aggregate';\n if (column) {\n state.baseQuery.count(resolveColumnArg(builder, column) as string);\n } else {\n state.baseQuery.count();\n }\n return builder;\n}\n\nexport function countDistinctImpl(\n builder: SchemaQueryBuilder<any, any>,\n column?: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'countDistinct');\n state.selectionMode = 'aggregate';\n if (column) {\n state.baseQuery.countDistinct(\n resolveColumnArg(builder, column) as string\n );\n } else {\n state.baseQuery.countDistinct();\n }\n return builder;\n}\n\nexport function minImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'min');\n state.selectionMode = 'aggregate';\n state.baseQuery.min(resolveColumnArg(builder, column) as string);\n return builder;\n}\n\nexport function maxImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'max');\n state.selectionMode = 'aggregate';\n state.baseQuery.max(resolveColumnArg(builder, column) as string);\n return builder;\n}\n\nexport function sumImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'sum');\n state.selectionMode = 'aggregate';\n state.baseQuery.sum(resolveColumnArg(builder, column) as string);\n return builder;\n}\n\nexport function avgImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'avg');\n state.selectionMode = 'aggregate';\n state.baseQuery.avg(resolveColumnArg(builder, column) as string);\n return builder;\n}\n\nexport function selectRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n bindings?: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (bindings) {\n state.baseQuery.select(state.knex.raw(sql, bindings));\n } else {\n state.baseQuery.select(state.knex.raw(sql));\n }\n return builder;\n}\n\nexport function projectedImpl(\n builder: SchemaQueryBuilder<any, any>,\n name: string\n): any {\n const state = getState(builder);\n assertNotExplicitSelect(builder, 'projected');\n if (state.selectionMode === 'projection') {\n throw new Error(\n `Cannot call .projected('${name}') — .projected('${\n state.appliedProjection\n }') was already applied. Only one projection per query.`\n );\n }\n const projections = getProjections(state.localSchema as any);\n const projection = projections[name];\n if (!projection) {\n throw new Error(\n `Unknown projection \"${name}\" on schema for table \"${\n state.tableName\n }\"`\n );\n }\n const { propToCol } = buildColumnMap(state.localSchema as any);\n const sqlCols = projection.keys.map(key => propToCol.get(key) ?? key);\n state.baseQuery.select(...sqlCols);\n state.explicitSelects ??= [];\n for (const col of sqlCols) {\n state.explicitSelects.push(col);\n }\n state.selectionMode = 'projection';\n state.appliedProjection = name;\n invalidateCache(builder);\n return builder;\n}\n\nexport function scopedImpl(\n builder: SchemaQueryBuilder<any, any>,\n name: string\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const scopes = (state.localSchema as any).getExtension?.('scopes') as\n | Record<string, Function>\n | undefined;\n const scopeFn = scopes?.[name];\n if (!scopeFn) {\n throw new Error(\n `Unknown scope \"${name}\" on schema for table \"${state.tableName}\"`\n );\n }\n scopeFn(builder);\n return builder;\n}\n\nexport function unscopedImpl(builder: SchemaQueryBuilder<any, any>): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.skipDefaultScope = true;\n state.includeDeleted = true;\n return builder;\n}\n","// @cleverbrush/knex-schema — Extracted helper functions from SchemaQueryBuilder\n\nimport type { InferType } from '@cleverbrush/schema';\nimport {\n EXTRA_TYPE_BRAND,\n METHOD_LITERAL_BRAND,\n ObjectSchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR\n} from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport {\n buildColumnMap,\n getPrimaryKeyColumns,\n resolveColumnRef\n} from '../columns.js';\nimport {\n getTableName,\n getVariants,\n POLYMORPHIC_TYPE_BRAND\n} from '../extension.js';\nimport { clearRow } from '../mappers.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type {\n ColumnRef,\n ResolvedVariantConfig,\n ResolvedVariantRelationSpec,\n ValidatedSpec\n} from '../types.js';\nimport { getState } from './state.js';\n\n// ---------------------------------------------------------------------------\n// Type-level helpers\n// ---------------------------------------------------------------------------\n\nexport type ScopesOf<S> = S extends {\n readonly [METHOD_LITERAL_BRAND]?: infer N;\n}\n ? Extract<N, string>\n : never;\n\nexport type ProjectionsOf<S> = S extends {\n readonly [EXTRA_TYPE_BRAND]?: infer P;\n}\n ? P extends Record<string, readonly string[]>\n ? P\n : Record<never, never>\n : Record<never, never>;\n\nexport type ProjectionKeysOf<\n S,\n K extends keyof ProjectionsOf<S> & string\n> = ProjectionsOf<S>[K] extends readonly (infer T extends string)[]\n ? T\n : string;\n\nexport type QueryResultType<TLocalSchema> = TLocalSchema extends {\n readonly [POLYMORPHIC_TYPE_BRAND]?: infer U;\n}\n ? NonNullable<U>\n : InferType<TLocalSchema>;\n\n// ---------------------------------------------------------------------------\n// State-based helpers\n// ---------------------------------------------------------------------------\n\nexport function resolveColumn(\n builder: SchemaQueryBuilder<any, any>,\n ref: any,\n label = 'column'\n): string | Knex.Raw {\n const state = getState(builder);\n return resolveColumnRef(\n ref as ColumnRef<any>,\n state.localSchema,\n label,\n state.knex\n );\n}\n\nexport function invalidateCache(builder: SchemaQueryBuilder<any, any>): void {\n getState(builder).cachedBuiltQuery = null;\n}\n\nexport function getSoftDelete(\n builder: SchemaQueryBuilder<any, any>\n): { column: string } | null {\n const state = getState(builder);\n const ext = (state.localSchema as any).getExtension?.('softDelete');\n return ext ?? null;\n}\n\nexport function getDefaultScope(\n builder: SchemaQueryBuilder<any, any>\n): Function | null {\n const state = getState(builder);\n const fn = (state.localSchema as any).getExtension?.('defaultScope');\n return typeof fn === 'function' ? fn : null;\n}\n\nexport function getTimestamps(\n builder: SchemaQueryBuilder<any, any>\n): { createdAt: string; updatedAt: string } | null {\n const state = getState(builder);\n const ts = (state.localSchema as any).getExtension?.('timestamps');\n return ts ?? null;\n}\n\nconst ALLOWED_OPS = new Set([\n '=',\n '!=',\n '<>',\n '<',\n '>',\n '<=',\n '>=',\n 'like',\n 'not like',\n 'ilike',\n 'not ilike',\n 'in',\n 'not in',\n 'is',\n 'is not'\n]);\n\nexport { ALLOWED_OPS };\n\nexport function getVariantConfig(\n builder: SchemaQueryBuilder<any, any>\n): ResolvedVariantConfig | null {\n const state = getState(builder);\n if (state.variantConfig !== undefined) return state.variantConfig;\n\n const raw = getVariants(state.localSchema);\n if (!raw) {\n state.variantConfig = null;\n return null;\n }\n\n const { propToCol } = buildColumnMap(state.localSchema);\n const discCol = propToCol.get(raw.discriminatorKey) ?? raw.discriminatorKey;\n\n state.variantConfig = {\n ...raw,\n discriminatorColumn: discCol\n };\n return state.variantConfig;\n}\n\nexport function applyVariantJoins(\n builder: SchemaQueryBuilder<any, any>,\n base: Knex.QueryBuilder,\n variantConfig: ResolvedVariantConfig\n): Knex.QueryBuilder {\n const state = getState(builder);\n const knex = state.knex;\n const baseTable = state.tableName;\n const basePkCol = findPrimaryKeyColumn(builder, state.localSchema);\n const discCol = variantConfig.discriminatorColumn;\n\n const qb = base.clone().select(`${baseTable}.*`);\n\n for (const [key, spec] of Object.entries(variantConfig.variants)) {\n if (state.enabledVariants !== null && !state.enabledVariants.has(key))\n continue;\n\n if (spec.storage === 'cti') {\n const variantAlias = `__v_${key}`;\n const variantTable = spec.tableName!;\n const fkCol = spec.foreignKey!;\n\n qb.leftJoin(\n `${variantTable} as ${variantAlias}`,\n knex.raw(`?? = ?? AND ?? = ?`, [\n `${variantAlias}.${fkCol}`,\n `${baseTable}.${basePkCol}`,\n `${baseTable}.${discCol}`,\n key\n ])\n );\n\n const { propToCol } = buildColumnMap(spec.schema);\n const variantIntrospect = spec.schema.introspect() as any;\n const variantProps: Record<string, unknown> =\n variantIntrospect.properties ?? {};\n\n for (const propKey of Object.keys(variantProps)) {\n const colName = propToCol.get(propKey) ?? propKey;\n qb.select(\n knex.raw('?? as ??', [\n `${variantAlias}.${colName}`,\n `${variantAlias}__${colName}`\n ])\n );\n }\n }\n }\n\n for (const vrInc of state.variantRelationIncludes) {\n const variantSpec = variantConfig.variants[vrInc.variantKey];\n if (!variantSpec) continue;\n\n const relSpec = variantSpec.relations.find(\n (r: ResolvedVariantRelationSpec) => r.name === vrInc.relationName\n );\n if (!relSpec) continue;\n\n const foreignSchema = resolveSchema(builder, relSpec.schema);\n const foreignTableName = getTableName(foreignSchema);\n const relAlias = `__v_${vrInc.variantKey}__rel_${vrInc.relationName}`;\n\n if (relSpec.type === 'belongsTo' || relSpec.type === 'hasOne') {\n let localCol: string;\n let foreignCol: string;\n\n if (relSpec.type === 'belongsTo') {\n localCol =\n relSpec.foreignKey ??\n ((): string => {\n throw new Error(\n `includeVariant: relation \"${vrInc.relationName}\" on variant \"${vrInc.variantKey}\" requires foreignKey`\n );\n })();\n foreignCol = findPrimaryKeyColumn(builder, foreignSchema);\n } else {\n localCol = findPrimaryKeyColumn(builder, state.localSchema);\n foreignCol =\n relSpec.foreignKey ??\n ((): string => {\n throw new Error(\n `includeVariant: relation \"${vrInc.relationName}\" on variant \"${vrInc.variantKey}\" requires foreignKey`\n );\n })();\n }\n\n let onExpr: string;\n const variantAlias = `__v_${vrInc.variantKey}`;\n\n if (variantSpec.storage === 'cti') {\n if (relSpec.type === 'belongsTo') {\n onExpr = `${relAlias}.${foreignCol} = ${variantAlias}.${localCol} AND ${baseTable}.${discCol} = '${vrInc.variantKey}'`;\n } else {\n onExpr = `${relAlias}.${foreignCol} = ${baseTable}.${localCol} AND ${baseTable}.${discCol} = '${vrInc.variantKey}'`;\n }\n } else {\n if (relSpec.type === 'belongsTo') {\n onExpr = `${relAlias}.${foreignCol} = ${baseTable}.${localCol} AND ${baseTable}.${discCol} = '${vrInc.variantKey}'`;\n } else {\n onExpr = `${relAlias}.${foreignCol} = ${baseTable}.${localCol} AND ${baseTable}.${discCol} = '${vrInc.variantKey}'`;\n }\n }\n\n const foreignKnex: Knex.QueryBuilder = state.knex(foreignTableName);\n\n const selectionSql = buildVariantRelationSelect(\n builder,\n foreignSchema,\n relAlias,\n foreignTableName,\n vrInc.customize\n );\n\n qb.leftJoin(\n knex.raw(`?? as ??`, [foreignTableName, relAlias]),\n knex.raw(onExpr)\n );\n void foreignKnex;\n\n for (const sel of selectionSql) {\n qb.select(sel);\n }\n }\n }\n\n for (const filter of state.variantWhereFilters) {\n const discColFull = `${baseTable}.${discCol}`;\n qb.where(function (this: Knex.QueryBuilder) {\n this.where(discColFull, filter.key)\n .andWhere(filter.qualifiedColumn, filter.op, filter.value)\n .orWhere(discColFull, '!=', filter.key);\n });\n }\n\n if (state.enabledVariants !== null) {\n qb.whereIn(`${baseTable}.${discCol}`, [...state.enabledVariants]);\n }\n\n return qb;\n}\n\n// Circular-dependency-safe SchemaQueryBuilder constructor reference\n// Set by SchemaQueryBuilder.ts after the class is defined.\nlet SchemaQueryBuilderCtor: new (...args: any[]) => any = null!;\nexport function registerSchemaQueryBuilder(\n ctor: new (...args: any[]) => any\n): void {\n SchemaQueryBuilderCtor = ctor;\n}\nexport function getSchemaQueryBuilderCtor(): new (...args: any[]) => any {\n return SchemaQueryBuilderCtor;\n}\n\nexport function buildVariantRelationSelect(\n builder: SchemaQueryBuilder<any, any>,\n foreignSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n relAlias: string,\n foreignTableName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n): Knex.Raw[] {\n const state = getState(builder);\n const knex = state.knex;\n const { propToCol } = buildColumnMap(foreignSchema);\n const foreignIntrospect = foreignSchema.introspect() as any;\n const foreignProps: Record<string, unknown> =\n foreignIntrospect.properties ?? {};\n\n let columnsToSelect: string[];\n\n if (customize) {\n const probe = new (SchemaQueryBuilderCtor as any)(\n state.knex,\n foreignSchema,\n state.knex(foreignTableName)\n );\n customize(probe);\n const state2 = getState(probe);\n const explicit = state2.explicitSelects;\n if (explicit && explicit.length > 0) {\n columnsToSelect = explicit;\n } else {\n columnsToSelect = Object.keys(foreignProps).map(\n p => propToCol.get(p) ?? p\n );\n }\n } else {\n columnsToSelect = Object.keys(foreignProps).map(\n p => propToCol.get(p) ?? p\n );\n }\n\n return columnsToSelect.map(colName =>\n knex.raw('?? as ??', [\n `${relAlias}.${colName}`,\n `${relAlias}__${colName}`\n ])\n );\n}\n\nexport function mapPolymorphicRow(\n builder: SchemaQueryBuilder<any, any>,\n row: Record<string, any>,\n variantConfig: ResolvedVariantConfig\n): Record<string, any> {\n const state = getState(builder);\n const { colToProp: baseColToProp } = buildColumnMap(state.localSchema);\n const result: Record<string, any> = {};\n\n for (const [colName, value] of Object.entries(row)) {\n if (colName.startsWith('__v_')) continue;\n const propName = baseColToProp.get(colName);\n if (propName) {\n result[propName] = value;\n } else {\n result[colName] = value;\n }\n }\n\n const discPropKey = variantConfig.discriminatorKey;\n const discValue: string | undefined = result[discPropKey];\n\n if (discValue != null) {\n const variantSpec = variantConfig.variants[discValue];\n if (variantSpec) {\n if (variantSpec.storage === 'cti') {\n const { colToProp: varColToProp } = buildColumnMap(\n variantSpec.schema\n );\n const variantAlias = `__v_${discValue}`;\n const prefix = `${variantAlias}__`;\n const fkCol = variantSpec.foreignKey;\n\n if (fkCol) {\n const fkAlias = `${prefix}${fkCol}`;\n if (!variantSpec.allowOrphan && row[fkAlias] == null) {\n throw new Error(\n `Polymorphic orphan: \"${discPropKey}\" = \"${discValue}\" ` +\n `but no matching row found in variant table ` +\n `\"${variantSpec.tableName}\". ` +\n `Set allowOrphan: true on this variant to suppress.`\n );\n }\n }\n\n for (const [colName, value] of Object.entries(row)) {\n if (!colName.startsWith(prefix)) continue;\n const origCol = colName.slice(prefix.length);\n if (origCol === fkCol) continue;\n const propName = varColToProp.get(origCol) ?? origCol;\n result[propName] = value;\n }\n } else {\n const { colToProp: varColToProp } = buildColumnMap(\n variantSpec.schema\n );\n for (const [colName, value] of Object.entries(row)) {\n if (colName.startsWith('__v_')) continue;\n if (baseColToProp.has(colName)) continue;\n const propName = varColToProp.get(colName);\n if (propName) {\n result[propName] = value;\n }\n }\n }\n }\n }\n\n if (state.variantRelationIncludes.length > 0 && discValue != null) {\n const variantSpec3 = variantConfig.variants[discValue];\n if (variantSpec3) {\n for (const vrInc of state.variantRelationIncludes) {\n if (vrInc.variantKey !== discValue) continue;\n\n const relSpec = variantSpec3.relations.find(\n (r: ResolvedVariantRelationSpec) =>\n r.name === vrInc.relationName\n );\n if (!relSpec) continue;\n\n if (relSpec.type === 'belongsTo' || relSpec.type === 'hasOne') {\n const relAlias = `__v_${discValue}__rel_${vrInc.relationName}`;\n const prefix = `${relAlias}__`;\n const foreignSchema = resolveSchema(\n builder,\n relSpec.schema\n );\n const { colToProp: relColToProp } =\n buildColumnMap(foreignSchema);\n const nested: Record<string, unknown> = {};\n let anyNonNull = false;\n\n for (const [colName, value] of Object.entries(row)) {\n if (!colName.startsWith(prefix)) continue;\n const origCol = colName.slice(prefix.length);\n const propName = relColToProp.get(origCol) ?? origCol;\n nested[propName] = value;\n if (value !== null && value !== undefined) {\n anyNonNull = true;\n }\n }\n result[vrInc.relationName] = anyNonNull ? nested : null;\n }\n }\n }\n }\n\n return result;\n}\n\nexport function resolveSchema(\n _builder: SchemaQueryBuilder<any, any>,\n schema: any\n): ObjectSchemaBuilder<any, any, any, any, any, any, any> {\n return typeof schema === 'function' ? schema() : schema;\n}\n\nexport function findPrimaryKeyColumn(\n _builder: SchemaQueryBuilder<any, any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): string {\n const pk = getPrimaryKeyColumns(schema);\n if (pk.columnNames.length > 0) return pk.columnNames[0];\n return 'id';\n}\n\nexport function resolvePkColumns(builder: SchemaQueryBuilder<any, any>): {\n propertyKeys: readonly string[];\n columnNames: readonly string[];\n} {\n const state = getState(builder);\n const pk = getPrimaryKeyColumns(state.localSchema as any);\n if (pk.columnNames.length === 0) {\n throw new Error(\n 'No primary key declared on this schema. Use `.primaryKey()` on a column or `.hasPrimaryKey([...])` on the schema.'\n );\n }\n return pk;\n}\n\nexport function getEffectiveBaseQuery(\n builder: SchemaQueryBuilder<any, any>\n): Knex.QueryBuilder {\n const state = getState(builder);\n let effectiveBase = state.baseQuery;\n let cloned = false;\n\n const softDelete = getSoftDelete(builder);\n if (softDelete && state.onlyDeleted) {\n if (!cloned) {\n effectiveBase = effectiveBase.clone();\n cloned = true;\n }\n effectiveBase.whereNotNull(softDelete.column);\n } else if (softDelete && !state.includeDeleted) {\n if (!cloned) {\n effectiveBase = effectiveBase.clone();\n cloned = true;\n }\n effectiveBase.whereNull(softDelete.column);\n }\n\n if (!state.skipDefaultScope) {\n const defaultScopeFn = getDefaultScope(builder);\n if (defaultScopeFn) {\n if (!cloned) {\n effectiveBase = effectiveBase.clone();\n cloned = true;\n }\n const proxy = new (SchemaQueryBuilderCtor as any)(\n state.knex,\n state.localSchema,\n effectiveBase\n );\n const proxyState = getState(proxy);\n proxyState.skipDefaultScope = true;\n defaultScopeFn(proxy);\n }\n }\n\n return effectiveBase;\n}\n\nexport function buildJoinOne(\n builder: SchemaQueryBuilder<any, any>,\n resultQuery: Knex.QueryBuilder,\n spec: ValidatedSpec & { type: 'one' },\n relationAlias: string\n): void {\n const state = getState(builder);\n const knex = state.knex;\n const foreignTable = spec.foreignQuery;\n const foreignTableName = (foreignTable as any)._single?.table;\n\n if (!foreignTableName) {\n throw new Error(\n `Could not determine table name from foreignQuery for \"${spec.as}\". ` +\n 'Make sure foreignQuery is created via knex(\"tableName\").'\n );\n }\n\n resultQuery.select(\n knex.raw(':relationAlias:.:as:->0 as :as:', {\n relationAlias,\n as: spec.as\n })\n );\n\n const subquery = knex\n .from(foreignTable.as(foreignTableName))\n .select(\n knex.raw(':foreignTable:.:foreignColumn:', {\n foreignTable: foreignTableName,\n foreignColumn: spec.foreignColumn\n })\n )\n .select(\n knex.raw('jsonb_agg(:foreignTable:) as :as:', {\n foreignTable: foreignTableName,\n as: spec.as\n })\n )\n .groupByRaw(':foreignTable:.:foreignColumn:', {\n foreignTable: foreignTableName,\n foreignColumn: spec.foreignColumn\n })\n .as(relationAlias);\n\n const joinMethod = spec.required ? 'join' : 'leftJoin';\n resultQuery[joinMethod](subquery, function () {\n this.on(\n knex.raw(\n ':relationAlias:.:foreignColumn: = :originalQuery:.:localColumn:',\n {\n originalQuery: 'originalQuery',\n relationAlias,\n foreignColumn: spec.foreignColumn,\n localColumn: spec.localColumn\n }\n )\n );\n });\n}\n\nexport function buildJoinMany(\n builder: SchemaQueryBuilder<any, any>,\n resultQuery: Knex.QueryBuilder,\n spec: ValidatedSpec & { type: 'many' },\n relationAlias: string,\n i: number\n): void {\n const state = getState(builder);\n const knex = state.knex;\n const filterName = `withFilter${i}`;\n\n const hasLimitOffset =\n (spec.limit !== null && spec.limit > 0) ||\n (spec.offset !== null && spec.offset > 0);\n\n const orderByColumn = spec.orderBy\n ? spec.orderBy.column\n : spec.foreignColumn;\n const orderByDirection = spec.orderBy ? spec.orderBy.direction : 'asc';\n\n if (hasLimitOffset) {\n resultQuery.with(\n filterName,\n knex\n .from(\n spec.foreignQuery\n .clone()\n .whereIn(\n spec.foreignColumn,\n knex\n .from(\n knex.raw(':originalQuery:', {\n originalQuery: 'originalQuery'\n })\n )\n .distinct(spec.localColumn)\n .as(`__wf_inner_${i}`)\n )\n .as(`__wf_inner_${i}`)\n )\n .select(`__wf_inner_${i}.*`)\n .select(\n knex.raw(\n `row_number() over(partition by :foreignColumn: order by :orderByColumn: ${orderByDirection}) as \"__rn__\"`,\n {\n foreignColumn: spec.foreignColumn,\n orderByColumn\n }\n )\n )\n );\n } else {\n resultQuery.with(\n filterName,\n spec.foreignQuery.clone().whereIn(\n spec.foreignColumn,\n knex\n .from(\n knex.raw(':originalQuery:', {\n originalQuery: 'originalQuery'\n })\n )\n .distinct(spec.localColumn)\n )\n );\n }\n\n const aggSubquery = knex.from(filterName);\n\n if (hasLimitOffset) {\n const hasLimit = spec.limit !== null && spec.limit > 0;\n const hasOffset = spec.offset !== null && spec.offset > 0;\n const effectiveOffset = spec.offset ?? 0;\n const effectiveLimit = effectiveOffset + (spec.limit ?? 0);\n\n const condition =\n hasLimit && hasOffset\n ? '\"__rn__\" > :offset and \"__rn__\" <= :limit'\n : hasLimit\n ? '\"__rn__\" <= :limit'\n : '\"__rn__\" > :offset';\n\n aggSubquery.whereRaw(condition, {\n limit: effectiveLimit,\n offset: effectiveOffset\n });\n\n aggSubquery.select(\n knex.raw(':foreignColumn:', {\n foreignColumn: spec.foreignColumn\n })\n );\n aggSubquery.select(\n knex.raw(\n \"coalesce(jsonb_agg(to_jsonb(:filterName:) - '__rn__' order by \\\"__rn__\\\"), '[]'::jsonb) as :as:\",\n { filterName, as: spec.as }\n )\n );\n } else {\n aggSubquery.select(\n knex.raw(':foreignColumn:', {\n foreignColumn: spec.foreignColumn\n })\n );\n\n const orderClause = spec.orderBy\n ? `jsonb_agg(:filterName: order by :filterName:.:orderByColumn: ${orderByDirection})`\n : 'jsonb_agg(:filterName:)';\n\n aggSubquery.select(\n knex.raw(\n `coalesce(${orderClause}, '[]'::jsonb) as :as:`,\n spec.orderBy\n ? { filterName, orderByColumn, as: spec.as }\n : { filterName, as: spec.as }\n )\n );\n }\n\n aggSubquery.groupByRaw(':foreignColumn:', {\n foreignColumn: spec.foreignColumn\n });\n\n const subquery = aggSubquery.as(relationAlias);\n\n resultQuery.select(\n knex.raw(\"coalesce(:relationAlias:.:as:, '[]'::jsonb) as :as:\", {\n relationAlias,\n as: spec.as\n })\n );\n\n resultQuery.leftJoin(subquery, function () {\n this.on(\n knex.raw(\n ':relationAlias:.:foreignColumn: = :originalQuery:.:localColumn:',\n {\n relationAlias,\n foreignColumn: spec.foreignColumn,\n originalQuery: 'originalQuery',\n localColumn: spec.localColumn\n }\n )\n );\n });\n}\n\nexport function buildQuery(\n builder: SchemaQueryBuilder<any, any>\n): Knex.QueryBuilder {\n const state = getState(builder);\n const effectiveBase = getEffectiveBaseQuery(builder);\n\n const variantConfig = getVariantConfig(builder);\n const queryBase = variantConfig\n ? applyVariantJoins(builder, effectiveBase, variantConfig)\n : effectiveBase;\n\n if (state.specs.length === 0) {\n return queryBase;\n }\n\n const knex = state.knex;\n const specs = state.specs;\n\n const requiredLocalColumns = [...new Set(specs.map(s => s.localColumn))];\n\n let cteQuery = queryBase;\n let extraColumns: string[] = [];\n\n if (state.explicitSelects !== null) {\n const selectedSet = new Set(state.explicitSelects);\n extraColumns = requiredLocalColumns.filter(\n col => !selectedSet.has(col)\n );\n if (extraColumns.length > 0) {\n cteQuery = queryBase.clone();\n for (const col of extraColumns) {\n cteQuery.column(col);\n }\n }\n }\n\n const resultQuery = knex.queryBuilder().with('originalQuery', cteQuery);\n\n if (extraColumns.length > 0 && state.explicitSelects !== null) {\n for (const col of state.explicitSelects) {\n resultQuery.select(\n knex.raw(':originalQuery:.:col: as :col:', {\n originalQuery: 'originalQuery',\n col\n })\n );\n }\n } else {\n resultQuery.select('originalQuery.*');\n }\n\n resultQuery.from(\n knex.raw(':originalQuery:', {\n originalQuery: 'originalQuery'\n })\n );\n\n for (let i = 0; i < specs.length; i++) {\n const spec = specs[i];\n const relationAlias = `eagerRelation${i}`;\n\n if (spec.type === 'one') {\n buildJoinOne(builder, resultQuery, spec, relationAlias);\n } else {\n buildJoinMany(builder, resultQuery, spec, relationAlias, i);\n }\n }\n\n return resultQuery;\n}\n\nexport function getQuery(\n builder: SchemaQueryBuilder<any, any>\n): Knex.QueryBuilder {\n const state = getState(builder);\n if (!state.cachedBuiltQuery) {\n state.cachedBuiltQuery = buildQuery(builder);\n }\n return state.cachedBuiltQuery;\n}\n\nexport function mapRow(\n builder: SchemaQueryBuilder<any, any>,\n row: Record<string, any>\n): Record<string, any> {\n if (!row) return row;\n\n const variantConfig = getVariantConfig(builder);\n if (variantConfig) {\n return mapPolymorphicRow(builder, row, variantConfig);\n }\n\n const state = getState(builder);\n const { colToProp } = buildColumnMap(state.localSchema);\n const result: Record<string, any> = {};\n\n for (const [colName, value] of Object.entries(row)) {\n const propName = colToProp.get(colName);\n if (propName) {\n result[propName] = value;\n } else {\n result[colName] = value;\n }\n }\n\n return result;\n}\n\nexport function cleanAndMapRow(\n builder: SchemaQueryBuilder<any, any>,\n row: Record<string, any>\n): Record<string, any> {\n const state = getState(builder);\n const oneSpecs = state.specs.filter(\n (s): s is ValidatedSpec & { type: 'one' } => s.type === 'one'\n );\n const manySpecs = state.specs.filter(\n (s): s is ValidatedSpec & { type: 'many' } => s.type === 'many'\n );\n const cleaned = clearRow(row, oneSpecs, manySpecs);\n return mapRow(builder, cleaned);\n}\n\nexport function mapObjectToColumns(\n builder: SchemaQueryBuilder<any, any>,\n obj: Record<string, any>\n): Record<string, any> {\n const state = getState(builder);\n const { propToCol } = buildColumnMap(state.localSchema);\n const result: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const colName = propToCol.get(key);\n if (colName) {\n result[colName] = value;\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nexport function mapRecordToColumns(\n builder: SchemaQueryBuilder<any, any>,\n record: Record<string, any>\n): Record<string, any> {\n return mapObjectToColumns(builder, record);\n}\n\nexport function resolveColumnArg(\n builder: SchemaQueryBuilder<any, any>,\n col: any\n): string | Knex.Raw {\n if (typeof col === 'string') {\n return resolveColumn(builder, col, 'column');\n }\n if (typeof col === 'function') {\n return resolveColumn(builder, col, 'column');\n }\n return col;\n}\n\nexport function isColumnAccessor(\n builder: SchemaQueryBuilder<any, any>,\n fn: Function\n): boolean {\n const state = getState(builder);\n try {\n const tree = ObjectSchemaBuilder.getPropertiesFor(\n state.localSchema as any\n );\n const result = fn(tree);\n if (\n result &&\n typeof result === 'object' &&\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in result\n ) {\n return true;\n }\n } catch {}\n return false;\n}\n\nexport function assertNotProjection(\n builder: SchemaQueryBuilder<any, any>,\n method: string\n): void {\n const state = getState(builder);\n if (state.selectionMode === 'projection') {\n throw new Error(\n `Cannot call .${method}() after .projected('${\n state.appliedProjection\n }'). Choose one column-selection mode per query.`\n );\n }\n}\n\nexport function assertNotExplicitSelect(\n builder: SchemaQueryBuilder<any, any>,\n method: string\n): void {\n const state = getState(builder);\n if (state.selectionMode === 'select') {\n throw new Error(\n `Cannot call .${method}() after .select(). Choose one column-selection mode per query.`\n );\n }\n if (state.selectionMode === 'aggregate') {\n throw new Error(\n `Cannot call .${method}() after an aggregate method. Choose one column-selection mode per query.`\n );\n }\n if (state.selectionMode === 'projection') {\n throw new Error(\n `Cannot call .${method}() after .projected('${\n state.appliedProjection\n }'). Choose one column-selection mode per query.`\n );\n }\n}\n","// @cleverbrush/knex-schema — Shared mutable state store for SchemaQueryBuilder\n\nimport type { ObjectSchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type {\n ResolvedVariantConfig,\n ValidatedSpec,\n VariantWhereFilter\n} from '../types.js';\n\nexport interface QueryBuilderState {\n knex: Knex;\n baseQuery: Knex.QueryBuilder;\n localSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n specs: ValidatedSpec[];\n tableName: string;\n\n /** SQL column names explicitly passed to `.select()`. null = SELECT *. */\n explicitSelects: string[] | null;\n\n /** Column-selection mode: null, 'select', 'aggregate', or 'projection'. */\n selectionMode: 'select' | 'aggregate' | 'projection' | null;\n\n /** Name of the projection currently applied, for error messages. */\n appliedProjection: string | null;\n\n /** When true, soft-delete filter is NOT applied. */\n includeDeleted: boolean;\n\n /** When true, only soft-deleted rows are returned. */\n onlyDeleted: boolean;\n\n /** When true, default scope is not applied. */\n skipDefaultScope: boolean;\n\n /** Resolved variant config, lazily populated. undefined = not yet read; null = not polymorphic. */\n variantConfig: ResolvedVariantConfig | null | undefined;\n\n /** When set, only these discriminator values are returned. null = all variants. */\n enabledVariants: Set<string> | null;\n\n /** Pending per-variant WHERE filters registered via .whereVariant(). */\n variantWhereFilters: VariantWhereFilter[];\n\n /** Variant-relation eager-load requests registered via .includeVariant(). */\n variantRelationIncludes: Array<{\n variantKey: string;\n relationName: string;\n customize?: (q: SchemaQueryBuilder<any, any>) => void;\n }>;\n\n /** Memoized result of buildQuery(). null = needs rebuild. */\n cachedBuiltQuery: Knex.QueryBuilder | null;\n}\n\nconst STATE = new WeakMap<SchemaQueryBuilder<any, any>, QueryBuilderState>();\n\nexport function getState(\n builder: SchemaQueryBuilder<any, any>\n): QueryBuilderState {\n const s = STATE.get(builder);\n if (!s) {\n throw new Error(\n 'SchemaQueryBuilder state not found — builder was not properly initialized'\n );\n }\n return s;\n}\n\nexport function setState(\n builder: SchemaQueryBuilder<any, any>,\n state: QueryBuilderState\n): void {\n STATE.set(builder, state);\n}\n","// @cleverbrush/knex-schema — INSERT / upsert / bulk operations\n\nimport type { InferType } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from '../columns.js';\nimport { getTableName } from '../extension.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type { ColumnRef, InsertType } from '../types.js';\nimport {\n getTimestamps,\n mapObjectToColumns,\n mapRow,\n resolveColumn\n} from './helpers.js';\nimport { getState } from './state.js';\n\n// ---------------------------------------------------------------------------\n// OnConflictBuilder\n// ---------------------------------------------------------------------------\n\nexport class OnConflictBuilder<\n TLocalSchema extends import('@cleverbrush/schema').ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n TResult\n> {\n readonly #knex: Knex;\n readonly #localSchema: TLocalSchema;\n readonly #conflictColumns: string[];\n\n constructor(\n knex: Knex,\n localSchema: TLocalSchema,\n _parent: SchemaQueryBuilder<TLocalSchema, TResult>,\n conflictColumns: string[]\n ) {\n this.#knex = knex;\n this.#localSchema = localSchema;\n this.#conflictColumns = conflictColumns;\n }\n\n async merge(\n data: InsertType<TLocalSchema>,\n updateData?: Partial<InferType<TLocalSchema>>\n ): Promise<TResult> {\n return this.#execute(data, 'merge', updateData) as Promise<TResult>;\n }\n\n async ignore(data: InsertType<TLocalSchema>): Promise<TResult | undefined> {\n return this.#execute(data, 'ignore');\n }\n\n async #execute(\n data: InsertType<TLocalSchema>,\n mode: 'merge' | 'ignore',\n updateData?: Partial<InferType<TLocalSchema>>\n ): Promise<TResult | undefined> {\n const tableName = getTableName(this.#localSchema);\n const timestamps: { createdAt: string; updatedAt: string } | null =\n (this.#localSchema as any).getExtension?.('timestamps') ?? null;\n\n const beforeHooks: Function[] =\n (this.#localSchema as any).getExtension?.('beforeInsert') ?? [];\n\n let processed = { ...(data as Record<string, any>) };\n for (const hook of beforeHooks) {\n processed = (await hook(processed)) ?? processed;\n }\n\n const { propToCol } = buildColumnMap(this.#localSchema as any);\n const mapped: Record<string, any> = {};\n for (const [key, val] of Object.entries(processed)) {\n mapped[propToCol.get(key) ?? key] = val;\n }\n if (timestamps) {\n mapped[timestamps.createdAt] = this.#knex.fn.now();\n mapped[timestamps.updatedAt] = this.#knex.fn.now();\n }\n\n let qb = this.#knex(tableName)\n .insert(mapped)\n .onConflict(this.#conflictColumns);\n\n if (mode === 'ignore') {\n qb = (qb as any).ignore();\n } else {\n let mergeObj: Record<string, any>;\n if (updateData) {\n mergeObj = {};\n for (const [key, val] of Object.entries(\n updateData as Record<string, any>\n )) {\n mergeObj[propToCol.get(key) ?? key] = val;\n }\n } else {\n mergeObj = { ...mapped };\n if (timestamps) {\n delete mergeObj[timestamps.createdAt];\n mergeObj[timestamps.updatedAt] = this.#knex.fn.now();\n }\n }\n qb = (qb as any).merge(mergeObj);\n }\n\n const rows = await (qb as any).returning('*');\n if (!rows || rows.length === 0) return undefined;\n\n const { colToProp } = buildColumnMap(this.#localSchema as any);\n const result: Record<string, any> = {};\n for (const [col, val] of Object.entries(rows[0])) {\n result[colToProp.get(col) ?? col] = val;\n }\n return result as TResult;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Insert operation functions\n// ---------------------------------------------------------------------------\n\nexport async function insertImpl(\n builder: SchemaQueryBuilder<any, any>,\n data: InsertType<any>\n): Promise<any> {\n const state = getState(builder);\n\n let processedData = { ...(data as Record<string, any>) };\n\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeInsert') as\n | Function[]\n | undefined) ?? [];\n for (const hook of beforeHooks) {\n processedData = (await hook(processedData)) ?? processedData;\n }\n\n const mapped = mapObjectToColumns(builder, processedData);\n\n const timestamps = getTimestamps(builder);\n if (timestamps) {\n mapped[timestamps.createdAt] = state.knex.fn.now();\n mapped[timestamps.updatedAt] = state.knex.fn.now();\n }\n\n const [row] = await state\n .knex(state.tableName)\n .insert(mapped)\n .returning('*');\n const result = mapRow(builder, row);\n\n const afterHooks =\n ((state.localSchema as any).getExtension?.('afterInsert') as\n | Function[]\n | undefined) ?? [];\n for (const hook of afterHooks) {\n await hook(result);\n }\n\n return result;\n}\n\nexport async function insertManyImpl(\n builder: SchemaQueryBuilder<any, any>,\n data: InsertType<any>[]\n): Promise<any[]> {\n const state = getState(builder);\n const timestamps = getTimestamps(builder);\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeInsert') as\n | Function[]\n | undefined) ?? [];\n\n const mapped = [];\n for (const d of data) {\n let processedData = { ...(d as Record<string, any>) };\n for (const hook of beforeHooks) {\n processedData = (await hook(processedData)) ?? processedData;\n }\n const m = mapObjectToColumns(builder, processedData);\n if (timestamps) {\n m[timestamps.createdAt] = state.knex.fn.now();\n m[timestamps.updatedAt] = state.knex.fn.now();\n }\n mapped.push(m);\n }\n\n const rows = await state\n .knex(state.tableName)\n .insert(mapped)\n .returning('*');\n const results = rows.map((row: any) => mapRow(builder, row));\n\n const afterHooks =\n ((state.localSchema as any).getExtension?.('afterInsert') as\n | Function[]\n | undefined) ?? [];\n for (const result of results) {\n for (const hook of afterHooks) {\n await hook(result);\n }\n }\n\n return results;\n}\n\nexport function onConflictImpl(\n builder: SchemaQueryBuilder<any, any>,\n ...conflictColumns: ColumnRef<any>[]\n): OnConflictBuilder<any, any> {\n const state = getState(builder);\n const cols = conflictColumns.map(\n c => resolveColumn(builder, c, 'onConflict') as string\n );\n return new OnConflictBuilder(state.knex, state.localSchema, builder, cols);\n}\n\nexport async function upsertImpl(\n builder: SchemaQueryBuilder<any, any>,\n data: InsertType<any>,\n opts: {\n conflictColumns: ColumnRef<any>[];\n updateColumns?: ColumnRef<any>[];\n }\n): Promise<any> {\n const state = getState(builder);\n const cols = opts.conflictColumns.map(\n c => resolveColumn(builder, c, 'upsert') as string\n );\n\n const qb = state\n .knex(state.tableName)\n .insert(mapObjectToColumns(builder, data as Record<string, any>))\n .onConflict(cols);\n\n if (opts.updateColumns && opts.updateColumns.length > 0) {\n const updateCols = opts.updateColumns.map(\n c => resolveColumn(builder, c, 'upsert') as string\n );\n (qb as any).merge(updateCols);\n } else {\n (qb as any).merge();\n }\n\n const [row] = await (qb as any).returning('*');\n return mapRow(builder, row);\n}\n\nexport async function bulkInsertImpl(\n builder: SchemaQueryBuilder<any, any>,\n rows: InsertType<any>[],\n opts?: {\n chunkSize?: number;\n onConflict?: 'ignore' | 'merge';\n conflictColumns?: ColumnRef<any>[];\n }\n): Promise<any[]> {\n if (rows.length === 0) return [];\n\n const state = getState(builder);\n\n const requestedChunkSize = opts?.chunkSize ?? 500;\n const bindingsPerRow = Object.keys(rows[0] as object).length || 1;\n const safeChunkCap = Math.max(\n 1,\n Math.floor(60000 / Math.max(1, bindingsPerRow))\n );\n const chunkSize = Math.max(1, Math.min(requestedChunkSize, safeChunkCap));\n\n const timestamps = getTimestamps(builder);\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeInsert') as\n | Function[]\n | undefined) ?? [];\n const afterHooks =\n ((state.localSchema as any).getExtension?.('afterInsert') as\n | Function[]\n | undefined) ?? [];\n\n const conflictCols =\n opts?.onConflict && opts.conflictColumns\n ? opts.conflictColumns.map(\n c =>\n resolveColumn(\n builder,\n c,\n 'bulkInsert.onConflict'\n ) as string\n )\n : null;\n if (opts?.onConflict && (!conflictCols || conflictCols.length === 0)) {\n throw new Error(\n 'bulkInsert: `conflictColumns` is required when `onConflict` is set.'\n );\n }\n\n const results: any[] = [];\n\n for (let i = 0; i < rows.length; i += chunkSize) {\n const chunk = rows.slice(i, i + chunkSize);\n const mapped: Record<string, any>[] = [];\n for (const row of chunk) {\n let processed = { ...(row as Record<string, any>) };\n for (const hook of beforeHooks) {\n processed = (await hook(processed)) ?? processed;\n }\n const m = mapObjectToColumns(builder, processed);\n if (timestamps) {\n m[timestamps.createdAt] = state.knex.fn.now();\n m[timestamps.updatedAt] = state.knex.fn.now();\n }\n mapped.push(m);\n }\n\n let qb: any = state.knex(state.tableName).insert(mapped);\n\n if (conflictCols) {\n qb = qb.onConflict(conflictCols);\n if (opts!.onConflict === 'ignore') {\n qb = qb.ignore();\n } else {\n const updateCols = new Set<string>();\n for (const m of mapped) {\n for (const k of Object.keys(m)) updateCols.add(k);\n }\n for (const c of conflictCols) updateCols.delete(c);\n if (timestamps) {\n updateCols.delete(timestamps.createdAt);\n updateCols.add(timestamps.updatedAt);\n }\n qb = qb.merge(Array.from(updateCols));\n }\n }\n\n const inserted: any[] = await qb.returning('*');\n for (const row of inserted) {\n const mappedRow = mapRow(builder, row);\n for (const hook of afterHooks) {\n await hook(mappedRow);\n }\n results.push(mappedRow);\n }\n }\n\n return results;\n}\n\nexport async function bulkUpsertImpl(\n builder: SchemaQueryBuilder<any, any>,\n rows: InsertType<any>[],\n opts: {\n conflictColumns: ColumnRef<any>[];\n chunkSize?: number;\n }\n): Promise<any[]> {\n return bulkInsertImpl(builder, rows, {\n chunkSize: opts.chunkSize,\n onConflict: 'merge',\n conflictColumns: opts.conflictColumns\n });\n}\n","// @cleverbrush/knex-schema — DELETE / soft-delete / restore operations\n\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport { getSoftDelete, invalidateCache, mapRow } from './helpers.js';\nimport { getState } from './state.js';\n\nexport async function deleteImpl(\n builder: SchemaQueryBuilder<any, any>\n): Promise<number> {\n const state = getState(builder);\n\n const hooks =\n ((state.localSchema as any).getExtension?.('beforeDelete') as\n | Function[]\n | undefined) ?? [];\n for (const hook of hooks) {\n await hook(builder);\n }\n\n const softDelete = getSoftDelete(builder);\n if (softDelete) {\n return state.baseQuery.update({\n [softDelete.column]: state.knex.fn.now()\n });\n }\n return state.baseQuery.delete();\n}\n\nexport function withDeletedImpl(builder: SchemaQueryBuilder<any, any>): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.includeDeleted = true;\n return builder;\n}\n\nexport function onlyDeletedImpl(builder: SchemaQueryBuilder<any, any>): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.onlyDeleted = true;\n state.includeDeleted = true;\n return builder;\n}\n\nexport async function hardDeleteImpl(\n builder: SchemaQueryBuilder<any, any>\n): Promise<number> {\n const state = getState(builder);\n const hooks =\n ((state.localSchema as any).getExtension?.('beforeDelete') as\n | Function[]\n | undefined) ?? [];\n for (const hook of hooks) {\n await hook(builder);\n }\n return state.baseQuery.delete();\n}\n\nexport async function restoreImpl(\n builder: SchemaQueryBuilder<any, any>\n): Promise<any[]> {\n const state = getState(builder);\n const softDelete = getSoftDelete(builder);\n if (!softDelete) {\n throw new Error(\n 'Schema does not have soft delete enabled. Use .softDelete() on the schema.'\n );\n }\n const rows = await state.baseQuery\n .update({ [softDelete.column]: null })\n .returning('*');\n return rows.map((row: any) => mapRow(builder, row));\n}\n","// @cleverbrush/knex-schema — Validation of join specs\n\nimport type { ObjectSchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { resolveColumnRef } from './columns.js';\nimport { getTableName } from './extension.js';\nimport { MAPPERS } from './mappers.js';\nimport type {\n JoinManySpec,\n JoinOneSpec,\n ValidatedJoinManySpec,\n ValidatedJoinOneSpec\n} from './types.js';\n\n/**\n * Resolve foreignQuery: use the provided one, or auto-derive from\n * the foreign schema's tableName extension.\n * Also normalizes SchemaQueryBuilder instances to raw Knex.QueryBuilder\n * by calling `.toKnexQuery()` if available.\n */\nfunction resolveForeignQuery(\n spec: {\n foreignQuery?: Knex.QueryBuilder | { toKnexQuery(): Knex.QueryBuilder };\n foreignSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n },\n knex: Knex\n): Knex.QueryBuilder {\n if (spec.foreignQuery) {\n if ('toKnexQuery' in spec.foreignQuery) {\n return spec.foreignQuery.toKnexQuery();\n }\n return spec.foreignQuery as Knex.QueryBuilder;\n }\n\n const tableName = getTableName(spec.foreignSchema);\n return knex(tableName);\n}\n\nexport function validateJoinOne(\n spec: JoinOneSpec<any, any, any, any>,\n localSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n knex: Knex\n): ValidatedJoinOneSpec {\n const localColumn = resolveColumnRef(\n spec.localColumn,\n localSchema,\n 'localColumn'\n );\n const foreignColumn = resolveColumnRef(\n spec.foreignColumn,\n spec.foreignSchema,\n 'foreignColumn'\n );\n if (typeof spec.as !== 'string' || !spec.as) {\n throw new Error('as must be a non-empty string');\n }\n\n const foreignQuery = resolveForeignQuery(spec, knex);\n const required = spec.required !== false;\n\n if (spec.mappers !== undefined) {\n validateMappers(spec.mappers);\n }\n\n return {\n localColumn,\n foreignColumn,\n as: spec.as,\n required,\n foreignQuery,\n mappers: spec.mappers as\n | Record<string, ((value: any) => any) | string>\n | undefined\n };\n}\n\nexport function validateJoinMany(\n spec: JoinManySpec<any, any, any>,\n localSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n knex: Knex\n): ValidatedJoinManySpec {\n const localColumn = resolveColumnRef(\n spec.localColumn,\n localSchema,\n 'localColumn'\n );\n const foreignColumn = resolveColumnRef(\n spec.foreignColumn,\n spec.foreignSchema,\n 'foreignColumn'\n );\n if (typeof spec.as !== 'string' || !spec.as) {\n throw new Error('as must be a non-empty string');\n }\n\n const foreignQuery = resolveForeignQuery(spec, knex);\n\n if (spec.mappers !== undefined) {\n validateMappers(spec.mappers);\n }\n\n const limit =\n Number.isFinite(spec.limit) && (spec.limit as number) > 0\n ? (spec.limit as number)\n : null;\n const offset =\n Number.isFinite(spec.offset) && (spec.offset as number) > 0\n ? (spec.offset as number)\n : null;\n const orderBy = spec.orderBy\n ? {\n column: resolveColumnRef(\n spec.orderBy.column,\n spec.foreignSchema,\n 'orderBy.column'\n ),\n direction: spec.orderBy.direction ?? ('asc' as const)\n }\n : null;\n\n return {\n localColumn,\n foreignColumn,\n as: spec.as,\n foreignQuery,\n limit,\n offset,\n orderBy,\n mappers: spec.mappers as\n | Record<string, ((value: any) => any) | string>\n | undefined\n };\n}\n\nfunction validateMappers(mappers: Record<string, unknown>): void {\n if (typeof mappers !== 'object' || mappers === null) {\n throw new Error('mappers must be an object');\n }\n for (const key of Object.keys(mappers)) {\n const m = mappers[key];\n if (typeof m === 'string') {\n if (typeof MAPPERS[m] !== 'function') {\n throw new Error(\n `mapper for \"${key}\": unknown built-in mapper name \"${m}\"`\n );\n }\n } else if (typeof m !== 'function') {\n throw new Error(\n `mapper for \"${key}\" must be a function or a built-in mapper name`\n );\n }\n }\n}\n\nexport function validateUniqueFieldNames(specs: Array<{ as: string }>): void {\n const seen = new Set<string>();\n for (const spec of specs) {\n if (seen.has(spec.as)) {\n throw new Error(`duplicate field name: ${spec.as}`);\n }\n seen.add(spec.as);\n }\n}\n","// @cleverbrush/knex-schema — Eager-loading JOIN operations (joinOne, joinMany, include, includeVariant)\n\nimport type { Knex } from 'knex';\nimport { resolveColumnRef } from '../columns.js';\nimport { getTableName } from '../extension.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type {\n JoinManySpec,\n JoinOneSpec,\n RelationSpec,\n ResolvedVariantRelationSpec\n} from '../types.js';\nimport {\n validateJoinMany,\n validateJoinOne,\n validateUniqueFieldNames\n} from '../validate.js';\nimport {\n findPrimaryKeyColumn,\n getSchemaQueryBuilderCtor,\n getVariantConfig,\n invalidateCache,\n resolveSchema\n} from './helpers.js';\nimport { getState } from './state.js';\n\nexport function joinOneImpl(\n builder: SchemaQueryBuilder<any, any>,\n spec: JoinOneSpec<any, any, any, any>\n): any {\n const state = getState(builder);\n const validated = validateJoinOne(spec, state.localSchema, state.knex);\n state.specs.push({ type: 'one' as const, ...validated });\n validateUniqueFieldNames(state.specs);\n invalidateCache(builder);\n return builder;\n}\n\nexport function joinManyImpl(\n builder: SchemaQueryBuilder<any, any>,\n spec: JoinManySpec<any, any, any>\n): any {\n const state = getState(builder);\n const validated = validateJoinMany(spec, state.localSchema, state.knex);\n state.specs.push({ type: 'many' as const, ...validated });\n validateUniqueFieldNames(state.specs);\n invalidateCache(builder);\n return builder;\n}\n\nexport function includeImpl(\n builder: SchemaQueryBuilder<any, any>,\n relationName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const relations: RelationSpec[] =\n (state.localSchema as any).getExtension?.('relations') ?? [];\n const relation = relations.find(\n (r: RelationSpec) => r.name === relationName\n );\n if (!relation) {\n const variantConfig = getVariantConfig(builder);\n if (variantConfig) {\n const matches: Array<{ variantKey: string }> = [];\n for (const [vKey, vSpec] of Object.entries(\n variantConfig.variants\n )) {\n if (\n vSpec.relations.some(\n (r: ResolvedVariantRelationSpec) =>\n r.name === relationName\n )\n ) {\n matches.push({ variantKey: vKey });\n }\n }\n if (matches.length === 1) {\n return includeVariantImpl(\n builder,\n matches[0].variantKey,\n relationName,\n customize\n );\n }\n if (matches.length > 1) {\n throw new Error(\n `Ambiguous relation \"${relationName}\" — found on variants: ${matches.map(m => m.variantKey).join(', ')}. Use .includeVariant(key, name) to be explicit.`\n );\n }\n }\n throw new Error(\n `Unknown relation \"${relationName}\" on schema for table \"${state.tableName}\"`\n );\n }\n\n const foreignSchema = resolveSchema(builder, relation.schema);\n const foreignTableName = getTableName(foreignSchema);\n\n switch (relation.type) {\n case 'belongsTo': {\n const localColumn = resolveColumnRef(\n relation.foreignKey,\n state.localSchema,\n 'foreignKey'\n );\n const foreignColumn = findPrimaryKeyColumn(builder, foreignSchema);\n\n const foreignQuery1: Knex.QueryBuilder =\n state.knex(foreignTableName);\n if (customize) {\n const SQB = getSchemaQueryBuilderCtor();\n const proxy = new SQB(state.knex, foreignSchema, foreignQuery1);\n customize(proxy);\n }\n\n joinOneImpl(builder, {\n foreignSchema,\n localColumn,\n foreignColumn,\n as: relationName,\n foreignQuery: foreignQuery1\n } as any);\n break;\n }\n case 'hasOne': {\n const localColumn = findPrimaryKeyColumn(\n builder,\n state.localSchema\n );\n const foreignColumn = resolveColumnRef(\n relation.foreignKey,\n foreignSchema,\n 'foreignKey'\n );\n\n const foreignQuery2: Knex.QueryBuilder =\n state.knex(foreignTableName);\n if (customize) {\n const SQB = getSchemaQueryBuilderCtor();\n const proxy = new SQB(state.knex, foreignSchema, foreignQuery2);\n customize(proxy);\n }\n\n joinOneImpl(builder, {\n foreignSchema,\n localColumn,\n foreignColumn,\n as: relationName,\n required: false,\n foreignQuery: foreignQuery2\n } as any);\n break;\n }\n case 'hasMany': {\n const localColumn = findPrimaryKeyColumn(\n builder,\n state.localSchema\n );\n const foreignColumn = resolveColumnRef(\n relation.foreignKey,\n foreignSchema,\n 'foreignKey'\n );\n\n const foreignQuery3: Knex.QueryBuilder =\n state.knex(foreignTableName);\n if (customize) {\n const SQB = getSchemaQueryBuilderCtor();\n const proxy = new SQB(state.knex, foreignSchema, foreignQuery3);\n customize(proxy);\n }\n\n joinManyImpl(builder, {\n foreignSchema,\n localColumn,\n foreignColumn,\n as: relationName,\n foreignQuery: foreignQuery3\n } as any);\n break;\n }\n case 'belongsToMany': {\n const through = relation.through!;\n const localColumn = findPrimaryKeyColumn(\n builder,\n state.localSchema\n );\n\n const foreignQuery = state\n .knex(foreignTableName)\n .join(\n through.table,\n `${through.table}.${through.foreignKey}`,\n `${foreignTableName}.${findPrimaryKeyColumn(builder, foreignSchema)}`\n )\n .select(\n `${foreignTableName}.*`,\n `${through.table}.${through.localKey}`\n );\n\n if (customize) {\n const SQB = getSchemaQueryBuilderCtor();\n const proxy = new SQB(state.knex, foreignSchema, foreignQuery);\n customize(proxy);\n }\n\n joinManyImpl(builder, {\n foreignSchema,\n localColumn,\n foreignColumn: through.localKey,\n as: relationName,\n foreignQuery\n } as any);\n break;\n }\n }\n\n return builder;\n}\n\nexport function includeVariantImpl(\n builder: SchemaQueryBuilder<any, any>,\n variantKey: string,\n relationName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const variantConfig = getVariantConfig(builder);\n if (!variantConfig) {\n throw new Error(\n `includeVariant: schema for table \"${state.tableName}\" is not polymorphic (no .withVariants() config found)`\n );\n }\n const variantSpec = variantConfig.variants[variantKey];\n if (!variantSpec) {\n throw new Error(\n `includeVariant: unknown variant key \"${variantKey}\" on schema for table \"${state.tableName}\"`\n );\n }\n const relSpec = variantSpec.relations.find(\n (r: ResolvedVariantRelationSpec) => r.name === relationName\n );\n if (!relSpec) {\n throw new Error(\n `includeVariant: unknown relation \"${relationName}\" on variant \"${variantKey}\" of table \"${state.tableName}\"`\n );\n }\n state.variantRelationIncludes.push({\n variantKey,\n relationName,\n customize\n });\n return builder;\n}\n","// @cleverbrush/knex-schema — WHERE / ORDER BY / GROUP BY / HAVING operations\n\nimport type { Knex } from 'knex';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type { ColumnRef } from '../types.js';\nimport {\n invalidateCache,\n isColumnAccessor,\n mapRecordToColumns,\n resolveColumn,\n resolveColumnArg\n} from './helpers.js';\nimport { getState } from './state.js';\n\nexport function whereImpl(\n builder: SchemaQueryBuilder<any, any>,\n columnOrRaw: any,\n ...args: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (\n typeof columnOrRaw === 'function' &&\n !isColumnAccessor(builder, columnOrRaw)\n ) {\n (state.baseQuery.where as any)(columnOrRaw, ...args);\n } else if (\n typeof columnOrRaw === 'object' &&\n columnOrRaw !== null &&\n !('toSQL' in columnOrRaw)\n ) {\n const mapped = mapRecordToColumns(\n builder,\n columnOrRaw as Record<string, any>\n );\n (state.baseQuery.where as any)(mapped, ...args);\n } else {\n const col = resolveColumnArg(builder, columnOrRaw);\n (state.baseQuery.where as any)(col, ...args);\n }\n return builder;\n}\n\nexport function andWhereImpl(\n builder: SchemaQueryBuilder<any, any>,\n columnOrRaw: any,\n ...args: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (\n typeof columnOrRaw === 'function' &&\n !isColumnAccessor(builder, columnOrRaw)\n ) {\n (state.baseQuery.andWhere as any)(columnOrRaw, ...args);\n } else if (\n typeof columnOrRaw === 'object' &&\n columnOrRaw !== null &&\n !('toSQL' in columnOrRaw)\n ) {\n const mapped = mapRecordToColumns(\n builder,\n columnOrRaw as Record<string, any>\n );\n (state.baseQuery.andWhere as any)(mapped, ...args);\n } else {\n const col = resolveColumnArg(builder, columnOrRaw);\n (state.baseQuery.andWhere as any)(col, ...args);\n }\n return builder;\n}\n\nexport function orWhereImpl(\n builder: SchemaQueryBuilder<any, any>,\n columnOrRaw: any,\n ...args: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (\n typeof columnOrRaw === 'function' &&\n !isColumnAccessor(builder, columnOrRaw)\n ) {\n (state.baseQuery.orWhere as any)(columnOrRaw, ...args);\n } else if (\n typeof columnOrRaw === 'object' &&\n columnOrRaw !== null &&\n !('toSQL' in columnOrRaw)\n ) {\n const mapped = mapRecordToColumns(\n builder,\n columnOrRaw as Record<string, any>\n );\n (state.baseQuery.orWhere as any)(mapped, ...args);\n } else {\n const col = resolveColumnArg(builder, columnOrRaw);\n (state.baseQuery.orWhere as any)(col, ...args);\n }\n return builder;\n}\n\nexport function whereNotImpl(\n builder: SchemaQueryBuilder<any, any>,\n columnOrRaw: any,\n ...args: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (\n typeof columnOrRaw === 'function' &&\n !isColumnAccessor(builder, columnOrRaw)\n ) {\n (state.baseQuery.whereNot as any)(columnOrRaw, ...args);\n } else if (\n typeof columnOrRaw === 'object' &&\n columnOrRaw !== null &&\n !('toSQL' in columnOrRaw)\n ) {\n const mapped = mapRecordToColumns(\n builder,\n columnOrRaw as Record<string, any>\n );\n (state.baseQuery.whereNot as any)(mapped, ...args);\n } else {\n const col = resolveColumnArg(builder, columnOrRaw);\n (state.baseQuery.whereNot as any)(col, ...args);\n }\n return builder;\n}\n\nexport function whereInImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n values: readonly any[] | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereIn(\n resolveColumn(builder, column, 'whereIn') as any,\n values as any\n );\n return builder;\n}\n\nexport function whereNotInImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n values: readonly any[] | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereNotIn(\n resolveColumn(builder, column, 'whereNotIn') as any,\n values as any\n );\n return builder;\n}\n\nexport function orWhereInImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n values: readonly any[] | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).orWhereIn(\n resolveColumn(builder, column, 'orWhereIn'),\n values as any\n );\n return builder;\n}\n\nexport function orWhereNotInImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n values: readonly any[] | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).orWhereNotIn(\n resolveColumn(builder, column, 'orWhereNotIn'),\n values as any\n );\n return builder;\n}\n\nexport function whereNullImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereNull(\n resolveColumn(builder, column, 'whereNull') as any\n );\n return builder;\n}\n\nexport function whereNotNullImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereNotNull(\n resolveColumn(builder, column, 'whereNotNull') as any\n );\n return builder;\n}\n\nexport function orWhereNullImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).orWhereNull(\n resolveColumn(builder, column, 'orWhereNull')\n );\n return builder;\n}\n\nexport function orWhereNotNullImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).orWhereNotNull(\n resolveColumn(builder, column, 'orWhereNotNull')\n );\n return builder;\n}\n\nexport function whereBetweenImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n range: readonly [any, any]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereBetween(\n resolveColumn(builder, column, 'whereBetween') as any,\n range as [any, any]\n );\n return builder;\n}\n\nexport function whereNotBetweenImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n range: readonly [any, any]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereNotBetween(\n resolveColumn(builder, column, 'whereNotBetween') as any,\n range as [any, any]\n );\n return builder;\n}\n\nexport function whereLikeImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n value: string\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).whereLike(\n resolveColumn(builder, column, 'whereLike'),\n value\n );\n return builder;\n}\n\nexport function whereILikeImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n value: string\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).whereILike(\n resolveColumn(builder, column, 'whereILike'),\n value\n );\n return builder;\n}\n\nexport function whereRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n ...bindings: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereRaw(sql, ...bindings);\n return builder;\n}\n\nexport function whereExistsImpl(\n builder: SchemaQueryBuilder<any, any>,\n callback: Knex.QueryCallback | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereExists(callback as any);\n return builder;\n}\n\nexport function whereNotExistsImpl(\n builder: SchemaQueryBuilder<any, any>,\n callback: Knex.QueryCallback | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).whereNotExists(callback as any);\n return builder;\n}\n\nexport function whereJsonPathImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n path: string,\n operator?: string,\n value?: any\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const client = (state.knex as any).client?.config?.client as\n | string\n | undefined;\n if (client !== 'pg' && client !== 'postgresql' && client !== 'postgres') {\n throw new Error(\n `whereJsonPath() is only supported on PostgreSQL (got client: \"${client ?? 'unknown'}\")`\n );\n }\n\n const col = resolveColumn(builder, column, 'whereJsonPath');\n const op = operator ?? '=';\n\n if (op === '@?' || op === '@@') {\n const escapedOp = op === '@?' ? '@\\\\?' : '@@';\n state.baseQuery.whereRaw(`?? ${escapedOp} ?`, [col, path]);\n } else {\n const jsonPath = path.startsWith('$')\n ? path\n : `$.${path.replace(/\\./g, '.')}`;\n state.baseQuery.whereRaw(\n `jsonb_path_query_first(??, ?) ${op} ?::jsonb`,\n [col, jsonPath, JSON.stringify(value)]\n );\n }\n return builder;\n}\n\nexport function orderByImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw,\n direction?: 'asc' | 'desc'\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const col = resolveColumnArg(builder, column);\n state.baseQuery.orderBy(col as string, direction);\n return builder;\n}\n\nexport function orderByRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n ...bindings: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.orderByRaw(sql, ...bindings);\n return builder;\n}\n\nexport function groupByImpl(\n builder: SchemaQueryBuilder<any, any>,\n ...columns: (ColumnRef<any> | Knex.Raw)[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const resolved = columns.map(c => resolveColumnArg(builder, c));\n state.baseQuery.groupBy(...(resolved as string[]));\n return builder;\n}\n\nexport function groupByRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n ...bindings: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.groupByRaw(sql, ...bindings);\n return builder;\n}\n\nexport function havingImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw,\n operator: string,\n value: any\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const col = resolveColumnArg(builder, column);\n state.baseQuery.having(col as string, operator, value);\n return builder;\n}\n\nexport function havingRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n ...bindings: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.havingRaw(sql, ...bindings);\n return builder;\n}\n","// @cleverbrush/knex-schema — Pagination (offset & cursor-based)\n\nimport { resolvePropertyKey } from '../columns.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type {\n ColumnRef,\n CursorPaginationResult,\n PaginationResult\n} from '../types.js';\nimport {\n cleanAndMapRow,\n getEffectiveBaseQuery,\n getQuery,\n invalidateCache\n} from './helpers.js';\nimport { getState } from './state.js';\nimport { orderByImpl, whereImpl } from './where.js';\n\nexport function limitImpl(\n builder: SchemaQueryBuilder<any, any>,\n n: number\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.limit(n);\n return builder;\n}\n\nexport function offsetImpl(\n builder: SchemaQueryBuilder<any, any>,\n n: number\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.offset(n);\n return builder;\n}\n\nexport async function paginateImpl(\n builder: SchemaQueryBuilder<any, any>,\n opts: {\n page: number;\n pageSize: number;\n }\n): Promise<PaginationResult<any>> {\n const { page, pageSize } = opts;\n const _state = getState(builder);\n\n const effectiveBase = getEffectiveBaseQuery(builder);\n\n const countResult = await effectiveBase\n .clone()\n .clearSelect()\n .clearOrder()\n .count('* as count')\n .first();\n const total = Number((countResult as any)?.count ?? 0);\n\n limitImpl(builder, pageSize);\n offsetImpl(builder, (page - 1) * pageSize);\n const data = await executeImpl(builder);\n\n const totalPages = Math.ceil(total / pageSize);\n\n return {\n data,\n total,\n page,\n pageSize,\n totalPages,\n hasNextPage: page < totalPages,\n hasPreviousPage: page > 1\n } as PaginationResult<any>;\n}\n\nexport async function paginateAfterImpl(\n builder: SchemaQueryBuilder<any, any>,\n opts: {\n cursor?: any;\n limit: number;\n column?: ColumnRef<any>;\n direction?: 'asc' | 'desc';\n }\n): Promise<CursorPaginationResult<any>> {\n const direction = opts.direction ?? 'desc';\n const column = opts.column ?? ('id' as any);\n const state = getState(builder);\n\n if (opts.cursor != null) {\n const op = direction === 'desc' ? '<' : '>';\n whereImpl(builder, column, op, opts.cursor);\n }\n\n orderByImpl(builder, column, direction);\n limitImpl(builder, opts.limit + 1);\n const rows = await executeImpl(builder);\n\n const hasMore = rows.length > opts.limit;\n const data = hasMore ? rows.slice(0, opts.limit) : rows;\n\n const propKey =\n typeof column === 'string'\n ? column\n : resolvePropertyKey(column, state.localSchema, 'cursor');\n\n const nextCursor =\n hasMore && data.length > 0\n ? String((data[data.length - 1] as any)[propKey])\n : null;\n\n return { data, nextCursor, hasMore } as CursorPaginationResult<any>;\n}\n\nexport async function executeImpl(\n builder: SchemaQueryBuilder<any, any>\n): Promise<any[]> {\n const query = getQuery(builder);\n const rows = await query;\n\n if (!rows) return [];\n if (!Array.isArray(rows)) return [cleanAndMapRow(builder, rows)];\n\n return rows.map((row: any) => cleanAndMapRow(builder, row));\n}\n","// @cleverbrush/knex-schema — UPDATE / bulk-update operations\n\nimport type { InferType } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from '../columns.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport {\n getTimestamps,\n mapObjectToColumns,\n mapRow,\n resolvePkColumns\n} from './helpers.js';\nimport { getState } from './state.js';\n\nexport async function updateImpl(\n builder: SchemaQueryBuilder<any, any>,\n data: Partial<InferType<any>>\n): Promise<any[]> {\n const state = getState(builder);\n\n let processedData = { ...(data as Record<string, any>) };\n\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeUpdate') as\n | Function[]\n | undefined) ?? [];\n for (const hook of beforeHooks) {\n processedData = (await hook(processedData)) ?? processedData;\n }\n\n const mapped = mapObjectToColumns(builder, processedData);\n\n const timestamps = getTimestamps(builder);\n if (timestamps) {\n mapped[timestamps.updatedAt] = state.knex.fn.now();\n }\n\n const rows = await state.baseQuery.update(mapped).returning('*');\n return rows.map((row: any) => mapRow(builder, row));\n}\n\nexport async function bulkUpdateImpl(\n builder: SchemaQueryBuilder<any, any>,\n updates: ReadonlyArray<{\n where: Partial<InferType<any>>;\n set: Partial<InferType<any>>;\n }>\n): Promise<number> {\n if (updates.length === 0) return 0;\n\n const state = getState(builder);\n const pk = resolvePkColumns(builder);\n const { propToCol } = buildColumnMap(state.localSchema as any);\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeUpdate') as\n | Function[]\n | undefined) ?? [];\n const timestamps = getTimestamps(builder);\n\n const processed: Array<{\n pkValues: unknown[];\n set: Record<string, any>;\n }> = [];\n for (const entry of updates) {\n let setData = { ...(entry.set as Record<string, any>) };\n for (const hook of beforeHooks) {\n setData = (await hook(setData)) ?? setData;\n }\n const setMapped = mapObjectToColumns(builder, setData);\n if (timestamps) {\n setMapped[timestamps.updatedAt] = state.knex.fn.now();\n }\n\n const whereRec = entry.where as Record<string, unknown>;\n const pkValues: unknown[] = [];\n for (const propKey of pk.propertyKeys) {\n const value =\n propKey in whereRec\n ? whereRec[propKey]\n : (whereRec[propToCol.get(propKey) ?? propKey] as\n | unknown\n | undefined);\n if (value === undefined) {\n throw new Error(\n `bulkUpdate: each \\`where\\` clause must include the entity's primary key (missing \"${propKey}\").`\n );\n }\n pkValues.push(value);\n }\n processed.push({ pkValues, set: setMapped });\n }\n\n const allSetCols = new Set<string>();\n for (const p of processed) {\n for (const k of Object.keys(p.set)) allSetCols.add(k);\n }\n if (allSetCols.size === 0) return 0;\n\n const knex = state.knex;\n const updateExpr: Record<string, any> = {};\n for (const col of allSetCols) {\n const fragments: string[] = [];\n const bindings: unknown[] = [];\n for (const p of processed) {\n if (!(col in p.set)) continue;\n if (pk.columnNames.length === 1) {\n fragments.push('WHEN ?? = ? THEN ?');\n bindings.push(pk.columnNames[0], p.pkValues[0], p.set[col]);\n } else {\n const conditions = pk.columnNames\n .map(() => '?? = ?')\n .join(' AND ');\n fragments.push(`WHEN ${conditions} THEN ?`);\n for (let i = 0; i < pk.columnNames.length; i++) {\n bindings.push(pk.columnNames[i], p.pkValues[i]);\n }\n bindings.push(p.set[col]);\n }\n }\n if (fragments.length === 0) continue;\n updateExpr[col] = knex.raw(`CASE ${fragments.join(' ')} ELSE ?? END`, [\n ...bindings,\n col\n ] as any);\n }\n\n let qb: any = knex(state.tableName).update(updateExpr);\n if (pk.columnNames.length === 1) {\n qb = qb.whereIn(\n pk.columnNames[0],\n processed.map(p => p.pkValues[0])\n );\n } else {\n qb = qb.where(function (this: Knex.QueryBuilder) {\n for (const p of processed) {\n this.orWhere(function (this: Knex.QueryBuilder) {\n for (let i = 0; i < pk.columnNames.length; i++) {\n this.andWhere(pk.columnNames[i], p.pkValues[i] as any);\n }\n });\n }\n });\n }\n\n return await qb;\n}\n","// @cleverbrush/knex-schema — SchemaQueryBuilder\n\nimport type { InferType } from '@cleverbrush/schema';\nimport {\n EXTRA_TYPE_BRAND,\n METHOD_LITERAL_BRAND,\n type ObjectSchemaBuilder\n} from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from './columns.js';\nimport { getTableName, POLYMORPHIC_TYPE_BRAND } from './extension.js';\n// Operations\nimport {\n avgImpl,\n countDistinctImpl,\n countImpl,\n distinctImpl,\n maxImpl,\n minImpl,\n projectedImpl,\n scopedImpl,\n selectImpl,\n selectRawImpl,\n sumImpl,\n unscopedImpl\n} from './operations/select.js';\nimport type {\n ColumnRef,\n CursorPaginationResult,\n InsertType,\n JoinManySpec,\n JoinOneSpec,\n PaginationResult,\n SelectProjection,\n SelectSelector\n} from './types.js';\n\nexport { OnConflictBuilder } from './operations/insert.js';\n\nimport {\n deleteImpl,\n hardDeleteImpl,\n onlyDeletedImpl,\n restoreImpl,\n withDeletedImpl\n} from './operations/delete.js';\nimport {\n ALLOWED_OPS,\n buildQuery,\n cleanAndMapRow,\n getQuery,\n getVariantConfig,\n invalidateCache,\n registerSchemaQueryBuilder,\n resolveColumn\n} from './operations/helpers.js';\nimport {\n bulkInsertImpl,\n bulkUpsertImpl,\n insertImpl,\n insertManyImpl,\n onConflictImpl,\n upsertImpl\n} from './operations/insert.js';\nimport {\n includeImpl,\n includeVariantImpl,\n joinManyImpl,\n joinOneImpl\n} from './operations/join.js';\nimport {\n executeImpl,\n limitImpl,\n offsetImpl,\n paginateAfterImpl,\n paginateImpl\n} from './operations/pagination.js';\nimport { getState, setState } from './operations/state.js';\nimport { bulkUpdateImpl, updateImpl } from './operations/update.js';\nimport {\n andWhereImpl,\n groupByImpl,\n groupByRawImpl,\n havingImpl,\n havingRawImpl,\n orderByImpl,\n orderByRawImpl,\n orWhereImpl,\n orWhereInImpl,\n orWhereNotInImpl,\n orWhereNotNullImpl,\n orWhereNullImpl,\n whereBetweenImpl,\n whereExistsImpl,\n whereILikeImpl,\n whereImpl,\n whereInImpl,\n whereJsonPathImpl,\n whereLikeImpl,\n whereNotBetweenImpl,\n whereNotExistsImpl,\n whereNotImpl,\n whereNotInImpl,\n whereNotNullImpl,\n whereNullImpl,\n whereRawImpl\n} from './operations/where.js';\n\n// ---------------------------------------------------------------------------\n// Type-level helpers\n// ---------------------------------------------------------------------------\n\ntype ScopesOf<S> = S extends {\n readonly [METHOD_LITERAL_BRAND]?: infer N;\n}\n ? Extract<N, string>\n : never;\n\ntype ProjectionsOf<S> = S extends {\n readonly [EXTRA_TYPE_BRAND]?: infer P;\n}\n ? P extends Record<string, readonly string[]>\n ? P\n : Record<never, never>\n : Record<never, never>;\n\ntype ProjectionKeysOf<\n S,\n K extends keyof ProjectionsOf<S> & string\n> = ProjectionsOf<S>[K] extends readonly (infer T extends string)[]\n ? T\n : string;\n\ntype QueryResultType<TLocalSchema> = TLocalSchema extends {\n readonly [POLYMORPHIC_TYPE_BRAND]?: infer U;\n}\n ? NonNullable<U>\n : InferType<TLocalSchema>;\n\n// ---------------------------------------------------------------------------\n// SchemaQueryBuilder\n// ---------------------------------------------------------------------------\n\nexport class SchemaQueryBuilder<\n TLocalSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TResult\n> {\n constructor(\n knex: Knex,\n localSchema: TLocalSchema,\n baseQuery?: Knex.QueryBuilder\n ) {\n const tableName = getTableName(localSchema);\n setState(this, {\n knex,\n baseQuery: baseQuery ?? knex(tableName),\n localSchema,\n specs: [],\n tableName,\n explicitSelects: null,\n selectionMode: null,\n appliedProjection: null,\n includeDeleted: false,\n onlyDeleted: false,\n skipDefaultScope: false,\n variantConfig: undefined,\n enabledVariants: null,\n variantWhereFilters: [],\n variantRelationIncludes: [],\n cachedBuiltQuery: null\n });\n }\n\n // =======================================================================\n // SELECT / DISTINCT / AGGREGATES\n // =======================================================================\n\n select(...columns: (ColumnRef<TLocalSchema> | Knex.Raw)[]): this;\n select<TSel extends SelectSelector<TLocalSchema>>(\n selector: TSel\n ): SchemaQueryBuilder<TLocalSchema, SelectProjection<ReturnType<TSel>>>;\n select(...args: unknown[]): any {\n return selectImpl(this as any, ...args);\n }\n\n distinct(...columns: (ColumnRef<TLocalSchema> | Knex.Raw)[]): this {\n return (distinctImpl as any)(this, ...columns);\n }\n\n count(column?: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (countImpl as any)(this, column);\n }\n\n countDistinct(column?: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (countDistinctImpl as any)(this, column);\n }\n\n min(column: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (minImpl as any)(this, column);\n }\n\n max(column: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (maxImpl as any)(this, column);\n }\n\n sum(column: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (sumImpl as any)(this, column);\n }\n\n avg(column: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (avgImpl as any)(this, column);\n }\n\n selectRaw(sql: string, bindings?: any[]): this {\n return selectRawImpl(this as any, sql, bindings);\n }\n\n projected<K extends keyof ProjectionsOf<TLocalSchema> & string>(\n name: K\n ): SchemaQueryBuilder<\n TLocalSchema,\n Pick<TResult, ProjectionKeysOf<TLocalSchema, K> & keyof TResult>\n > {\n return projectedImpl(this as any, name);\n }\n\n scoped<K extends ScopesOf<TLocalSchema>>(name: K): this {\n return scopedImpl(this as any, name as string);\n }\n\n unscoped(): this {\n return unscopedImpl(this as any);\n }\n\n // =======================================================================\n // WHERE\n // =======================================================================\n\n where(column: ColumnRef<TLocalSchema>, operator: string, value: any): this;\n where(column: ColumnRef<TLocalSchema>, value: any): this;\n where(raw: Knex.Raw, operator: string, value: any): this;\n where(callback: (builder: Knex.QueryBuilder) => void): this;\n where(record: Record<string, any>): this;\n where(raw: Knex.Raw): this;\n where(columnOrRaw: any, ...args: any[]): this {\n return whereImpl(this as any, columnOrRaw, ...args);\n }\n\n andWhere(\n column: ColumnRef<TLocalSchema>,\n operator: string,\n value: any\n ): this;\n andWhere(column: ColumnRef<TLocalSchema>, value: any): this;\n andWhere(record: Record<string, any>): this;\n andWhere(callback: (builder: Knex.QueryBuilder) => void): this;\n andWhere(raw: Knex.Raw): this;\n andWhere(columnOrRaw: any, ...args: any[]): this {\n return andWhereImpl(this as any, columnOrRaw, ...args);\n }\n\n orWhere(\n column: ColumnRef<TLocalSchema>,\n operator: string,\n value: any\n ): this;\n orWhere(column: ColumnRef<TLocalSchema>, value: any): this;\n orWhere(record: Record<string, any>): this;\n orWhere(callback: (builder: Knex.QueryBuilder) => void): this;\n orWhere(raw: Knex.Raw): this;\n orWhere(columnOrRaw: any, ...args: any[]): this {\n return orWhereImpl(this as any, columnOrRaw, ...args);\n }\n\n whereNot(\n column: ColumnRef<TLocalSchema>,\n operator: string,\n value: any\n ): this;\n whereNot(column: ColumnRef<TLocalSchema>, value: any): this;\n whereNot(record: Record<string, any>): this;\n whereNot(callback: (builder: Knex.QueryBuilder) => void): this;\n whereNot(raw: Knex.Raw): this;\n whereNot(columnOrRaw: any, ...args: any[]): this {\n return whereNotImpl(this as any, columnOrRaw, ...args);\n }\n\n whereIn(\n column: ColumnRef<TLocalSchema>,\n values: readonly any[] | Knex.QueryBuilder\n ): this {\n return (whereInImpl as any)(this, column, values);\n }\n\n whereNotIn(\n column: ColumnRef<TLocalSchema>,\n values: readonly any[] | Knex.QueryBuilder\n ): this {\n return (whereNotInImpl as any)(this, column, values);\n }\n\n orWhereIn(\n column: ColumnRef<TLocalSchema>,\n values: readonly any[] | Knex.QueryBuilder\n ): this {\n return (orWhereInImpl as any)(this, column, values);\n }\n\n orWhereNotIn(\n column: ColumnRef<TLocalSchema>,\n values: readonly any[] | Knex.QueryBuilder\n ): this {\n return (orWhereNotInImpl as any)(this, column, values);\n }\n\n whereNull(column: ColumnRef<TLocalSchema>): this {\n return (whereNullImpl as any)(this, column);\n }\n\n whereNotNull(column: ColumnRef<TLocalSchema>): this {\n return (whereNotNullImpl as any)(this, column);\n }\n\n orWhereNull(column: ColumnRef<TLocalSchema>): this {\n return (orWhereNullImpl as any)(this, column);\n }\n\n orWhereNotNull(column: ColumnRef<TLocalSchema>): this {\n return (orWhereNotNullImpl as any)(this, column);\n }\n\n whereBetween(\n column: ColumnRef<TLocalSchema>,\n range: readonly [any, any]\n ): this {\n return (whereBetweenImpl as any)(this, column, range);\n }\n\n whereNotBetween(\n column: ColumnRef<TLocalSchema>,\n range: readonly [any, any]\n ): this {\n return (whereNotBetweenImpl as any)(this, column, range);\n }\n\n whereLike(column: ColumnRef<TLocalSchema>, value: string): this {\n return (whereLikeImpl as any)(this, column, value);\n }\n\n whereILike(column: ColumnRef<TLocalSchema>, value: string): this {\n return (whereILikeImpl as any)(this, column, value);\n }\n\n whereRaw(sql: string, ...bindings: any[]): this {\n return (whereRawImpl as any)(this, sql, ...bindings);\n }\n\n whereExists(callback: Knex.QueryCallback | Knex.QueryBuilder): this {\n return (whereExistsImpl as any)(this, callback);\n }\n\n whereNotExists(callback: Knex.QueryCallback | Knex.QueryBuilder): this {\n return (whereNotExistsImpl as any)(this, callback);\n }\n\n whereJsonPath(\n column: ColumnRef<TLocalSchema>,\n path: string,\n operator?: string,\n value?: any\n ): this {\n return (whereJsonPathImpl as any)(this, column, path, operator, value);\n }\n\n // =======================================================================\n // ORDER BY\n // =======================================================================\n\n orderBy(\n column: ColumnRef<TLocalSchema> | Knex.Raw,\n direction?: 'asc' | 'desc'\n ): this {\n return (orderByImpl as any)(this, column, direction);\n }\n\n orderByRaw(sql: string, ...bindings: any[]): this {\n return (orderByRawImpl as any)(this, sql, ...bindings);\n }\n\n // =======================================================================\n // GROUP BY / HAVING\n // =======================================================================\n\n groupBy(...columns: (ColumnRef<TLocalSchema> | Knex.Raw)[]): this {\n return (groupByImpl as any)(this, ...columns);\n }\n\n groupByRaw(sql: string, ...bindings: any[]): this {\n return (groupByRawImpl as any)(this, sql, ...bindings);\n }\n\n having(\n column: ColumnRef<TLocalSchema> | Knex.Raw,\n operator: string,\n value: any\n ): this {\n return (havingImpl as any)(this, column, operator, value);\n }\n\n havingRaw(sql: string, ...bindings: any[]): this {\n return havingRawImpl(this as any, sql, ...bindings);\n }\n\n // =======================================================================\n // PAGINATION\n // =======================================================================\n\n limit(n: number): this {\n return limitImpl(this as any, n);\n }\n\n offset(n: number): this {\n return offsetImpl(this as any, n);\n }\n\n async paginate(opts: {\n page: number;\n pageSize: number;\n }): Promise<PaginationResult<TResult>> {\n return paginateImpl(this as any, opts) as Promise<\n PaginationResult<TResult>\n >;\n }\n\n async paginateAfter(opts: {\n cursor?: any;\n limit: number;\n column?: ColumnRef<TLocalSchema>;\n direction?: 'asc' | 'desc';\n }): Promise<CursorPaginationResult<TResult>> {\n return (paginateAfterImpl as any)(this, opts) as Promise<\n CursorPaginationResult<TResult>\n >;\n }\n\n // =======================================================================\n // WRITE OPERATIONS\n // =======================================================================\n\n async insert(data: InsertType<TLocalSchema>): Promise<TResult> {\n return insertImpl(this as any, data) as Promise<TResult>;\n }\n\n async insertMany(data: InsertType<TLocalSchema>[]): Promise<TResult[]> {\n return insertManyImpl(this as any, data) as Promise<TResult[]>;\n }\n\n onConflict(\n ...conflictColumns: ColumnRef<TLocalSchema>[]\n ): import('./operations/insert.js').OnConflictBuilder<\n TLocalSchema,\n TResult\n > {\n return (onConflictImpl as any)(this, ...conflictColumns);\n }\n\n async upsert(\n data: InsertType<TLocalSchema>,\n opts: {\n conflictColumns: ColumnRef<TLocalSchema>[];\n updateColumns?: ColumnRef<TLocalSchema>[];\n }\n ): Promise<TResult> {\n return (upsertImpl as any)(this, data, opts);\n }\n\n async bulkInsert(\n rows: InsertType<TLocalSchema>[],\n opts?: {\n chunkSize?: number;\n onConflict?: 'ignore' | 'merge';\n conflictColumns?: ColumnRef<TLocalSchema>[];\n }\n ): Promise<TResult[]> {\n return (bulkInsertImpl as any)(this, rows, opts);\n }\n\n async bulkUpsert(\n rows: InsertType<TLocalSchema>[],\n opts: {\n conflictColumns: ColumnRef<TLocalSchema>[];\n chunkSize?: number;\n }\n ): Promise<TResult[]> {\n return (bulkUpsertImpl as any)(this, rows, opts);\n }\n\n // =======================================================================\n // UPDATE\n // =======================================================================\n\n async update(data: Partial<InferType<TLocalSchema>>): Promise<TResult[]> {\n return updateImpl(this as any, data) as Promise<TResult[]>;\n }\n\n async bulkUpdate(\n updates: ReadonlyArray<{\n where: Partial<InferType<TLocalSchema>>;\n set: Partial<InferType<TLocalSchema>>;\n }>\n ): Promise<number> {\n return bulkUpdateImpl(this as any, updates as any);\n }\n\n // =======================================================================\n // DELETE / SOFT DELETE\n // =======================================================================\n\n async delete(): Promise<number> {\n return deleteImpl(this as any);\n }\n\n withDeleted(): this {\n return withDeletedImpl(this as any);\n }\n\n onlyDeleted(): this {\n return onlyDeletedImpl(this as any);\n }\n\n async hardDelete(): Promise<number> {\n return hardDeleteImpl(this as any);\n }\n\n async restore(): Promise<TResult[]> {\n return restoreImpl(this as any) as Promise<TResult[]>;\n }\n\n // =======================================================================\n // EAGER LOADING (JOIN)\n // =======================================================================\n\n joinOne<\n TForeignSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n TFieldName extends string,\n TRequired extends boolean = true\n >(\n spec: JoinOneSpec<TLocalSchema, TForeignSchema, TFieldName, TRequired>\n ): SchemaQueryBuilder<\n TLocalSchema,\n import('./types.js').WithJoinedOne<\n TResult,\n TFieldName,\n TForeignSchema,\n TRequired\n >\n > {\n return joinOneImpl(this as any, spec);\n }\n\n joinMany<\n TForeignSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n TFieldName extends string\n >(\n spec: JoinManySpec<TLocalSchema, TForeignSchema, TFieldName>\n ): SchemaQueryBuilder<\n TLocalSchema,\n import('./types.js').WithJoinedMany<TResult, TFieldName, TForeignSchema>\n > {\n return joinManyImpl(this as any, spec);\n }\n\n include(\n relationName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n ): this {\n return includeImpl(this as any, relationName, customize);\n }\n\n includeVariant(\n variantKey: string,\n relationName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n ): this {\n return includeVariantImpl(\n this as any,\n variantKey,\n relationName,\n customize\n );\n }\n\n // =======================================================================\n // POLYMORPHIC VARIANTS\n // =======================================================================\n\n whereVariant(\n key: string,\n column: string,\n operator: string,\n value: any\n ): this {\n const state = getState(this);\n const variantConfig = getVariantConfig(this);\n if (!variantConfig) {\n throw new Error(\n 'whereVariant() can only be used on a polymorphic schema (created with .withVariants())'\n );\n }\n\n const spec = variantConfig.variants[key];\n if (!spec) {\n throw new Error(\n `whereVariant: unknown variant key \"${key}\". ` +\n `Valid keys: ${Object.keys(variantConfig.variants).join(', ')}`\n );\n }\n\n const op = operator.toLowerCase();\n if (!ALLOWED_OPS.has(op)) {\n throw new Error(\n `whereVariant: operator \"${operator}\" is not allowed. ` +\n `Allowed operators: ${[...ALLOWED_OPS].join(', ')}`\n );\n }\n\n const { propToCol } = buildColumnMap(spec.schema);\n const colName = propToCol.get(column) ?? column;\n\n let qualifiedColumn: string;\n if (spec.storage === 'cti') {\n qualifiedColumn = `__v_${key}.${colName}`;\n } else {\n qualifiedColumn = `${state.tableName}.${colName}`;\n }\n\n state.variantWhereFilters.push({ key, qualifiedColumn, op, value });\n invalidateCache(this);\n return this;\n }\n\n selectVariants(keys: string[]): this {\n const state = getState(this);\n if (!getVariantConfig(this)) {\n throw new Error(\n 'selectVariants() can only be used on a polymorphic schema (created with .withVariants())'\n );\n }\n state.enabledVariants = new Set(keys);\n invalidateCache(this);\n return this;\n }\n\n // =======================================================================\n // ESCAPE HATCH\n // =======================================================================\n\n apply(fn: (builder: Knex.QueryBuilder) => void): this {\n const state = getState(this);\n invalidateCache(this);\n fn(state.baseQuery);\n return this;\n }\n\n // =======================================================================\n // TRANSACTION\n // =======================================================================\n\n transacting(\n trx: Knex.Transaction\n ): SchemaQueryBuilder<TLocalSchema, TResult> {\n const state = getState(this);\n const builder = new SchemaQueryBuilder<TLocalSchema, TResult>(\n trx as unknown as Knex,\n state.localSchema as TLocalSchema,\n state.baseQuery.clone().transacting(trx)\n );\n const builderState = getState(builder);\n for (const spec of state.specs) {\n builderState.specs.push({\n ...spec,\n foreignQuery: spec.foreignQuery.clone().transacting(trx)\n });\n }\n builderState.explicitSelects = state.explicitSelects\n ? [...state.explicitSelects]\n : null;\n builderState.selectionMode = state.selectionMode;\n builderState.appliedProjection = state.appliedProjection;\n builderState.includeDeleted = state.includeDeleted;\n builderState.onlyDeleted = state.onlyDeleted;\n builderState.skipDefaultScope = state.skipDefaultScope;\n builderState.variantConfig = state.variantConfig;\n builderState.enabledVariants =\n state.enabledVariants !== null\n ? new Set(state.enabledVariants)\n : null;\n builderState.variantWhereFilters = [...state.variantWhereFilters];\n builderState.variantRelationIncludes = [\n ...state.variantRelationIncludes\n ];\n return builder;\n }\n\n // =======================================================================\n // EXECUTION\n // =======================================================================\n\n toQuery(): string {\n return getQuery(this).toQuery();\n }\n\n toKnexQuery(): Knex.QueryBuilder {\n return getQuery(this);\n }\n\n toString(): string {\n return getQuery(this).toString();\n }\n\n async execute(): Promise<TResult[]> {\n return executeImpl(this) as Promise<TResult[]>;\n }\n\n async first(): Promise<TResult | undefined> {\n const query = getQuery(this).first();\n const row = await query;\n\n if (!row) return undefined;\n return cleanAndMapRow(this, row) as TResult;\n }\n\n async pluck<K extends keyof TResult & string>(\n column: ColumnRef<TLocalSchema>\n ): Promise<TResult[K][]> {\n const _state = getState(this);\n const col = resolveColumn(this, column, 'pluck') as string;\n const rows = await buildQuery(this).select(col);\n return rows.map(\n (row: any) => row[col] ?? row[column as string]\n ) as TResult[K][];\n }\n\n // biome-ignore lint/suspicious/noThenProperty: intentional thenable\n then<TReturn1 = TResult[], TReturn2 = never>(\n onfulfilled?:\n | ((value: TResult[]) => TReturn1 | PromiseLike<TReturn1>)\n | null,\n onrejected?: ((reason: any) => TReturn2 | PromiseLike<TReturn2>) | null\n ): Promise<TReturn1 | TReturn2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n}\n\n// Register the constructor for circular-dependency-safe access\nregisterSchemaQueryBuilder(SchemaQueryBuilder);\n\n// ---------------------------------------------------------------------------\n// query() — main entry point\n// ---------------------------------------------------------------------------\n\nexport function query<\n TLocalSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(\n knex: Knex,\n schema: TLocalSchema\n): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>;\n\nexport function query<\n TLocalSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(\n knex: Knex,\n schema: TLocalSchema,\n baseQuery: Knex.QueryBuilder\n): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>;\n\nexport function query<\n TLocalSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(\n knex: Knex,\n schema: TLocalSchema,\n baseQuery?: Knex.QueryBuilder\n): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>> {\n return new SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>(\n knex,\n schema,\n baseQuery\n );\n}\n\n// ---------------------------------------------------------------------------\n// createQuery() — knex-bound factory\n// ---------------------------------------------------------------------------\n\nexport interface BoundQuery {\n <\n TLocalSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n schema: TLocalSchema\n ): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>;\n <\n TLocalSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n schema: TLocalSchema,\n baseQuery: Knex.QueryBuilder\n ): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>;\n withTransaction(trx: Knex.Transaction): BoundQuery;\n transaction<T>(callback: (db: BoundQuery) => Promise<T>): Promise<T>;\n}\n\nexport function createQuery(knexInstance: Knex): BoundQuery {\n function boundQuery<\n TLocalSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n schema: TLocalSchema,\n baseQuery?: Knex.QueryBuilder\n ): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>> {\n return baseQuery\n ? query(knexInstance, schema, baseQuery)\n : query(knexInstance, schema);\n }\n\n (boundQuery as BoundQuery).withTransaction = (\n trx: Knex.Transaction\n ): BoundQuery => createQuery(trx as unknown as Knex);\n\n (boundQuery as BoundQuery).transaction = <T>(\n callback: (db: BoundQuery) => Promise<T>\n ): Promise<T> =>\n knexInstance.transaction(trx =>\n callback(createQuery(trx as unknown as Knex))\n );\n\n return boundQuery as BoundQuery;\n}\n","// @cleverbrush/knex-schema — Schema snapshot serialization\n\nimport { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { Entity } from './entity.js';\nimport { getPolymorphicVariantSchemas, getTableName } from './extension.js';\nimport { entitySchemaToTableState } from './migration.js';\nimport type { SchemaSnapshot } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Builders\n// ---------------------------------------------------------------------------\n\n/**\n * Build a {@link SchemaSnapshot} from a set of entities without a live DB.\n *\n * Handles polymorphic (CTI) entities by including each variant table.\n * Deduplicates tables so STI variants sharing a base table are only included\n * once.\n *\n * @param entities - The entities from your `EntityMap`.\n * @returns A snapshot reflecting the current code-first schema state.\n *\n * @example\n * ```ts\n * const snapshot = entitiesToSnapshot(Object.values(entityMap));\n * writeSnapshot('./migrations/snapshot.json', snapshot);\n * ```\n */\nexport function entitiesToSnapshot(\n entities: Entity<any, any>[]\n): SchemaSnapshot {\n const tables: SchemaSnapshot['tables'] = {};\n\n for (const entity of entities) {\n const schema = entity.schema;\n const tableName = getTableName(schema);\n if (!tables[tableName]) {\n tables[tableName] = entitySchemaToTableState(schema);\n }\n\n for (const vs of getPolymorphicVariantSchemas(schema)) {\n const variantTableName = vs.getExtension('tableName') as\n | string\n | undefined;\n if (variantTableName && !tables[variantTableName]) {\n tables[variantTableName] = entitySchemaToTableState(vs);\n }\n }\n }\n\n return { version: 1, tables };\n}\n\n// ---------------------------------------------------------------------------\n// I/O\n// ---------------------------------------------------------------------------\n\n/**\n * Load a {@link SchemaSnapshot} from disk.\n *\n * Returns an empty snapshot (no tables) when the file does not exist — this\n * is the \"first run\" case, which causes `migrate generate` to emit a single\n * migration containing `CREATE TABLE` for every entity.\n *\n * @param snapshotPath - Absolute or cwd-relative path to `snapshot.json`.\n * @returns The parsed snapshot, or `{ version: 1, tables: {} }` if missing or\n * unreadable.\n */\nexport function loadSnapshot(snapshotPath: string): SchemaSnapshot {\n try {\n const raw = readFileSync(resolve(snapshotPath), 'utf-8');\n const parsed = JSON.parse(raw) as SchemaSnapshot;\n if (\n parsed.version !== 1 ||\n parsed.tables == null ||\n typeof parsed.tables !== 'object'\n ) {\n return { version: 1, tables: {} };\n }\n return parsed;\n } catch {\n return { version: 1, tables: {} };\n }\n}\n\n/**\n * Write a {@link SchemaSnapshot} to disk atomically (temp-file + rename) with\n * deterministic key ordering so diffs in version control are minimal.\n *\n * @param snapshotPath - Absolute or cwd-relative path to write `snapshot.json`.\n * @param snapshot - The snapshot to serialize.\n */\nexport function writeSnapshot(\n snapshotPath: string,\n snapshot: SchemaSnapshot\n): void {\n const absPath = resolve(snapshotPath);\n const tmp = absPath + '.tmp';\n writeFileSync(\n tmp,\n JSON.stringify(_sortSnapshot(snapshot), null, 2) + '\\n',\n 'utf-8'\n );\n renameSync(tmp, absPath);\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** @internal Sort all keys in the snapshot for deterministic JSON output. */\nfunction _sortSnapshot(snapshot: SchemaSnapshot): SchemaSnapshot {\n const sortedTables: SchemaSnapshot['tables'] = {};\n for (const tableName of Object.keys(snapshot.tables).sort()) {\n const state = snapshot.tables[tableName];\n sortedTables[tableName] = {\n columns: Object.fromEntries(\n Object.entries(state.columns).sort(([a], [b]) =>\n a.localeCompare(b)\n )\n ),\n indexes: [...state.indexes].sort((a, b) =>\n a.name.localeCompare(b.name)\n ),\n foreignKeys: [...state.foreignKeys].sort((a, b) =>\n a.constraintName.localeCompare(b.constraintName)\n ),\n checks: [...state.checks].sort((a, b) =>\n a.name.localeCompare(b.name)\n )\n };\n }\n return { version: 1, tables: sortedTables };\n}\n"],"mappings":"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","names":["ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","columnMapCache","buildColumnMap","schema","cached","properties","propToCol","colToProp","propKey","propSchema","colName","getColumnName","result","jsonPathRaw","knex","col","jsonPath","pathLiteral","resolveColumnRef","ref","label","topProp","tree","ObjectSchemaBuilder","descriptor","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","pointer","segments","s","resolvePropertyKey","getPrimaryKeyColumns","introspected","extensions","composite","propertyKeys","columnNames","entry","getRowVersionColumn","rv","resolveColumnType","table","col","introspected","ext","maxLen","applyDefault","column","defaultValue","knex","generateCreateTable","schema","tableName","getTableName","tableExt","extensionManagedCols","builder","properties","propKey","propSchema","getColumnName","propIntrospected","fkBuilder","idx","unq","chk","rawCol","rawIndexes","rawIdx","generateCreateTableSource","lines","line","_colTypeCode","_fmtDefault","cols","rawIndexLines","ri","up","down","value","generateCreatePolymorphicTables","result","variantSchemas","getPolymorphicVariantSchemas","variantSchema","ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","Entity","_Entity","schema","spec","existing","next","navSel","_localSel","remoteSel","opts","navName","foreignSchema","remoteKey","localSel","_remoteSel","localKey","through","sel","discKey","key","variant","fkSel","builder","fkColumn","resolveCtiForeignKeyColumn","nextVariants","entityRelationsToVariantRelations","resolveInlineVariantRelations","body","isEntity","varSchema","variants","newSchema","applyVariantsToSchema","existingRelations","selector","tree","ObjectSchemaBuilder","descriptor","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","inner","propSchema","intro","varEntity","rels","propToCol","buildColumnMap","r","fkPropName","fkColName","propKey","getColumnName","relations","result","name","foreignKey","targetSchema","defineEntity","MAPPERS","value","mapValue","mapper","mapObject","obj","mappers","result","key","clearRow","row","oneSpecs","manySpecs","spec","fieldName","k","normalizeDbState","columns","indexes","foreignKeys","checks","colMap","row","idxList","fkList","chkList","introspectDatabase","knex","tableName","schemaTypeToDbType","introspected","ext","entitySchemaToTableState","schema","getTableName","properties","tableExt","propKey","propSchema","col","getColumnName","propIntrospected","ts","createdAtCol","updatedAtCol","delCol","idx","idxName","unq","unqName","diffSchema","dbState","addColumns","dropColumns","alterColumns","addIndexes","dropIndexes","addForeignKeys","dropForeignKeys","extensionOwnedDefaults","schemaColumns","dbCol","changes","expectedNullable","snapshotDefault","schemaDefault","fk","colName","schemaIndexNames","dbIdx","ps","generateMigration","diff","up","down","buildAlterTableFragments","full","tableExistsInDb","isDiffEmpty","applyDiff","constraintName","table","column","buildColumnFromDbType","fkBuilder","key","change","builder","generateMigrationsForContext","entities","prevSnapshot","tableEntries","entity","vs","getPolymorphicVariantSchemas","variantTableName","seen","uniqueEntries","e","sorted","topologicalSort","upParts","downParts","currentTableNames","snapshotState","generateCreateTableSource","state","generateDropTableSource","isEmpty","nextTables","colLines","line","upLines","downLines","mapTypeToKnex","formatDefault","toVal","fromVal","cols","name","dbType","entries","tableSet","deps","depSet","inDegree","graph","dep","queue","t","deg","sortedNames","dependent","newDeg","sortedSet","remaining","byName","type","value","rawQuery","knex","schema","queryOrSql","bindings","rows","result","colToProp","buildColumnMap","row","mapped","key","value","propName","ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","STATE","getState","builder","s","setState","state","resolveColumn","builder","ref","label","state","getState","resolveColumnRef","invalidateCache","getSoftDelete","getDefaultScope","fn","getTimestamps","ALLOWED_OPS","getVariantConfig","builder","state","getState","raw","getVariants","propToCol","buildColumnMap","discCol","applyVariantJoins","base","variantConfig","knex","baseTable","basePkCol","findPrimaryKeyColumn","qb","key","spec","variantAlias","variantTable","fkCol","variantProps","propKey","colName","vrInc","variantSpec","relSpec","r","foreignSchema","resolveSchema","foreignTableName","getTableName","relAlias","localCol","foreignCol","onExpr","foreignKnex","selectionSql","buildVariantRelationSelect","sel","filter","discColFull","SchemaQueryBuilderCtor","registerSchemaQueryBuilder","ctor","getSchemaQueryBuilderCtor","customize","foreignProps","columnsToSelect","probe","explicit","p","mapPolymorphicRow","row","baseColToProp","result","value","propName","discPropKey","discValue","varColToProp","prefix","fkAlias","origCol","variantSpec3","relColToProp","nested","anyNonNull","_builder","schema","pk","getPrimaryKeyColumns","resolvePkColumns","getEffectiveBaseQuery","effectiveBase","cloned","softDelete","getSoftDelete","defaultScopeFn","getDefaultScope","proxy","proxyState","buildJoinOne","resultQuery","relationAlias","foreignTable","subquery","joinMethod","buildJoinMany","i","filterName","hasLimitOffset","orderByColumn","orderByDirection","aggSubquery","hasLimit","hasOffset","effectiveOffset","effectiveLimit","condition","orderClause","buildQuery","queryBase","specs","requiredLocalColumns","s","cteQuery","extraColumns","selectedSet","col","getQuery","mapRow","colToProp","cleanAndMapRow","oneSpecs","manySpecs","cleaned","clearRow","mapObjectToColumns","obj","mapRecordToColumns","record","resolveColumnArg","resolveColumn","isColumnAccessor","fn","tree","ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","assertNotProjection","method","assertNotExplicitSelect","selectImpl","builder","args","state","getState","fn","tree","ObjectSchemaBuilder","result","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","invalidateCache","assertNotProjection","aliasMap","alias","descriptor","col","resolveColumn","resolved","c","resolveColumnArg","r","distinctImpl","columns","countImpl","column","countDistinctImpl","minImpl","maxImpl","sumImpl","avgImpl","selectRawImpl","sql","bindings","projectedImpl","name","assertNotExplicitSelect","projection","getProjections","propToCol","buildColumnMap","sqlCols","key","scopedImpl","scopeFn","unscopedImpl","OnConflictBuilder","#knex","#localSchema","#conflictColumns","knex","localSchema","_parent","conflictColumns","data","updateData","#execute","mode","tableName","getTableName","timestamps","beforeHooks","processed","hook","propToCol","buildColumnMap","mapped","key","val","qb","mergeObj","rows","colToProp","result","col","insertImpl","builder","state","getState","processedData","mapObjectToColumns","getTimestamps","row","mapRow","afterHooks","insertManyImpl","d","m","results","onConflictImpl","cols","c","resolveColumn","upsertImpl","opts","updateCols","bulkInsertImpl","requestedChunkSize","bindingsPerRow","safeChunkCap","chunkSize","conflictCols","i","chunk","k","inserted","mappedRow","bulkUpsertImpl","deleteImpl","builder","state","getState","hooks","hook","softDelete","getSoftDelete","withDeletedImpl","invalidateCache","onlyDeletedImpl","hardDeleteImpl","restoreImpl","row","mapRow","resolveForeignQuery","spec","knex","tableName","getTableName","validateJoinOne","localSchema","localColumn","resolveColumnRef","foreignColumn","foreignQuery","required","validateMappers","validateJoinMany","limit","offset","orderBy","mappers","key","m","MAPPERS","validateUniqueFieldNames","specs","seen","joinOneImpl","builder","spec","state","getState","validated","validateJoinOne","validateUniqueFieldNames","invalidateCache","joinManyImpl","validateJoinMany","includeImpl","relationName","customize","relation","r","variantConfig","getVariantConfig","matches","vKey","vSpec","includeVariantImpl","m","foreignSchema","resolveSchema","foreignTableName","getTableName","localColumn","resolveColumnRef","foreignColumn","findPrimaryKeyColumn","foreignQuery1","SQB","getSchemaQueryBuilderCtor","proxy","foreignQuery2","foreignQuery3","through","foreignQuery","variantKey","variantSpec","whereImpl","builder","columnOrRaw","args","state","getState","invalidateCache","isColumnAccessor","mapped","mapRecordToColumns","col","resolveColumnArg","andWhereImpl","orWhereImpl","whereNotImpl","whereInImpl","column","values","resolveColumn","whereNotInImpl","orWhereInImpl","orWhereNotInImpl","whereNullImpl","whereNotNullImpl","orWhereNullImpl","orWhereNotNullImpl","whereBetweenImpl","range","whereNotBetweenImpl","whereLikeImpl","value","whereILikeImpl","whereRawImpl","sql","bindings","whereExistsImpl","callback","whereNotExistsImpl","whereJsonPathImpl","path","operator","client","op","escapedOp","jsonPath","orderByImpl","direction","orderByRawImpl","groupByImpl","columns","resolved","c","groupByRawImpl","havingImpl","havingRawImpl","limitImpl","builder","state","getState","invalidateCache","offsetImpl","paginateImpl","opts","page","pageSize","_state","countResult","getEffectiveBaseQuery","total","data","executeImpl","totalPages","paginateAfterImpl","direction","column","whereImpl","orderByImpl","rows","hasMore","propKey","resolvePropertyKey","nextCursor","getQuery","row","cleanAndMapRow","updateImpl","builder","data","state","getState","processedData","beforeHooks","hook","mapped","mapObjectToColumns","timestamps","getTimestamps","row","mapRow","bulkUpdateImpl","updates","pk","resolvePkColumns","propToCol","buildColumnMap","processed","entry","setData","setMapped","whereRec","pkValues","propKey","value","allSetCols","p","k","knex","updateExpr","col","fragments","bindings","conditions","i","qb","SchemaQueryBuilder","_SchemaQueryBuilder","knex","localSchema","baseQuery","tableName","getTableName","setState","args","selectImpl","columns","distinctImpl","column","countImpl","countDistinctImpl","minImpl","maxImpl","sumImpl","avgImpl","sql","bindings","selectRawImpl","name","projectedImpl","scopedImpl","unscopedImpl","columnOrRaw","whereImpl","andWhereImpl","orWhereImpl","whereNotImpl","values","whereInImpl","whereNotInImpl","orWhereInImpl","orWhereNotInImpl","whereNullImpl","whereNotNullImpl","orWhereNullImpl","orWhereNotNullImpl","range","whereBetweenImpl","whereNotBetweenImpl","value","whereLikeImpl","whereILikeImpl","whereRawImpl","callback","whereExistsImpl","whereNotExistsImpl","path","operator","whereJsonPathImpl","direction","orderByImpl","orderByRawImpl","groupByImpl","groupByRawImpl","havingImpl","havingRawImpl","limitImpl","offsetImpl","opts","paginateImpl","paginateAfterImpl","data","insertImpl","insertManyImpl","conflictColumns","onConflictImpl","upsertImpl","rows","bulkInsertImpl","bulkUpsertImpl","updateImpl","updates","bulkUpdateImpl","deleteImpl","withDeletedImpl","onlyDeletedImpl","hardDeleteImpl","restoreImpl","spec","joinOneImpl","joinManyImpl","relationName","customize","includeImpl","variantKey","includeVariantImpl","key","state","getState","variantConfig","getVariantConfig","op","ALLOWED_OPS","propToCol","buildColumnMap","colName","qualifiedColumn","invalidateCache","keys","fn","trx","builder","builderState","getQuery","executeImpl","row","cleanAndMapRow","_state","col","resolveColumn","buildQuery","onfulfilled","onrejected","registerSchemaQueryBuilder","query","schema","createQuery","knexInstance","boundQuery","readFileSync","renameSync","writeFileSync","resolve","entitiesToSnapshot","entities","tables","entity","schema","tableName","getTableName","entitySchemaToTableState","vs","getPolymorphicVariantSchemas","variantTableName","loadSnapshot","snapshotPath","raw","readFileSync","resolve","parsed","writeSnapshot","snapshot","absPath","tmp","writeFileSync","_sortSnapshot","renameSync","sortedTables","state","a","b"]}
1
+ {"version":3,"sources":["../src/columns.ts","../src/ddl.ts","../src/entity.ts","../src/mappers.ts","../src/migration.ts","../src/raw.ts","../src/operations/select.ts","../src/operations/helpers.ts","../src/operations/state.ts","../src/operations/insert.ts","../src/operations/delete.ts","../src/validate.ts","../src/operations/join.ts","../src/operations/where.ts","../src/operations/pagination.ts","../src/operations/update.ts","../src/SchemaQueryBuilder.ts","../src/snapshot.ts"],"sourcesContent":["// @cleverbrush/knex-schema — Column resolution and mapping\n\nimport type { SchemaBuilder } from '@cleverbrush/schema';\nimport {\n ObjectSchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR\n} from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { getColumnName } from './extension.js';\nimport type { ColumnRef } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Column map cache (schema → { propToCol, colToProp })\n// ---------------------------------------------------------------------------\n\ninterface ColumnMapResult {\n propToCol: Map<string, string>;\n colToProp: Map<string, string>;\n}\n\nconst columnMapCache = new WeakMap<object, ColumnMapResult>();\n\n/**\n * Build a bidirectional column map from an ObjectSchemaBuilder's properties.\n * Uses `getExtension('columnName')` per property, falling back to the property key.\n * Result is cached per schema instance via WeakMap.\n */\nexport function buildColumnMap(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): ColumnMapResult {\n const cached = columnMapCache.get(schema);\n if (cached) return cached;\n\n const introspected = schema.introspect() as any;\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n\n const propToCol = new Map<string, string>();\n const colToProp = new Map<string, string>();\n\n for (const propKey of Object.keys(properties)) {\n const propSchema = properties[propKey];\n const colName = getColumnName(propSchema, propKey);\n\n propToCol.set(propKey, colName);\n colToProp.set(colName, propKey);\n }\n\n const result: ColumnMapResult = { propToCol, colToProp };\n columnMapCache.set(schema, result);\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Resolve a ColumnRef (string | accessor) to a SQL column name or Knex.Raw\n// ---------------------------------------------------------------------------\n\n/**\n * Build a `Knex.Raw` expression for accessing a nested JSON/JSONB path.\n *\n * - Single-key path: `\"col\"->>'key'` (text output, `->>` operator).\n * - Multi-key path: `\"col\"#>>'{a,b,...}'` (text output, `#>>` operator).\n *\n * Both use positional bindings to prevent SQL injection.\n */\nfunction jsonPathRaw(knex: Knex, col: string, jsonPath: string[]): Knex.Raw {\n if (jsonPath.length === 1) {\n return knex.raw('??->>?', [col, jsonPath[0]]);\n }\n // #>> expects a text array literal, e.g. '{address,city}'\n const pathLiteral = `{${jsonPath.join(',')}}`;\n return knex.raw('??#>>?', [col, pathLiteral]);\n}\n\n/**\n * Resolve a ColumnRef to a plain SQL column name (or a Knex.Raw expression for\n * nested JSON paths when `knex` is supplied).\n *\n * - String refs are treated as **property keys** (or dot-separated nested paths\n * such as `'address.city'`) and translated to column names via the column map.\n * - Function refs (property accessor) are resolved via PropertyDescriptorTree,\n * then translated to column names. Nested accessors (e.g. `t => t.address.city`)\n * produce a `Knex.Raw` JSON-path expression when `knex` is provided.\n *\n * @param ref - Column reference (property key, dotted path, or accessor fn).\n * @param schema - Root ObjectSchemaBuilder.\n * @param label - Human-readable label for error messages.\n * @param knex - Knex instance. Required for nested JSON-path refs; when omitted\n * and a nested path is detected, an error is thrown.\n */\nexport function resolveColumnRef(\n ref: ColumnRef<any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n label: string,\n knex: Knex\n): string | Knex.Raw;\nexport function resolveColumnRef(\n ref: ColumnRef<any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n label: string\n): string;\nexport function resolveColumnRef(\n ref: ColumnRef<any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n label: string,\n knex?: Knex\n): string | Knex.Raw {\n if (typeof ref === 'string') {\n if (!ref) throw new Error(`${label} must be a non-empty string`);\n\n // Dotted paths like 'address.city' — first segment is the top-level prop.\n if (ref.includes('.')) {\n const [topProp, ...jsonPath] = ref.split('.');\n const { propToCol } = buildColumnMap(schema);\n const col = propToCol.get(topProp) ?? topProp;\n if (!knex) {\n throw new Error(\n `${label}: a Knex instance is required to resolve nested JSON path '${ref}'`\n );\n }\n return jsonPathRaw(knex, col, jsonPath);\n }\n\n const { propToCol } = buildColumnMap(schema);\n const col = propToCol.get(ref);\n // If the string is a known property key, return its column name;\n // otherwise assume it's already a raw column name and pass through.\n return col ?? ref;\n }\n\n if (typeof ref === 'function') {\n const tree = ObjectSchemaBuilder.getPropertiesFor(schema as any);\n const descriptor = ref(tree as any);\n\n if (\n !descriptor ||\n typeof descriptor !== 'object' ||\n !(SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in descriptor)\n ) {\n throw new Error(\n `${label} accessor must return a valid property descriptor`\n );\n }\n\n const inner = (descriptor as any)[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n const pointer: string = inner.toJsonPointer();\n\n // pointer is an RFC-6901 JSON Pointer, e.g. '' (root), '/name', '/address/city'\n if (!pointer) {\n throw new Error(`${label} accessor returned the root descriptor`);\n }\n\n // Split '/address/city' → ['address', 'city']\n const segments = pointer\n .slice(1)\n .split('/')\n .map((s: string) => s.replace(/~1/g, '/').replace(/~0/g, '~'));\n\n if (segments.length === 0) {\n throw new Error(`${label} accessor returned the root descriptor`);\n }\n\n const [topProp, ...jsonPath] = segments;\n const { propToCol } = buildColumnMap(schema);\n const col = propToCol.get(topProp) ?? topProp;\n\n if (jsonPath.length === 0) {\n // Top-level property — plain column name\n return col;\n }\n\n // Nested path — need Knex.Raw\n if (!knex) {\n throw new Error(\n `${label}: a Knex instance is required to resolve nested JSON path '${pointer}'`\n );\n }\n return jsonPathRaw(knex, col, jsonPath);\n }\n\n throw new Error(\n `${label} must be a string or a property descriptor accessor function`\n );\n}\n\n/**\n * Resolve a ColumnRef to the **property key** (not the column name).\n * Used for result mapping.\n */\nexport function resolvePropertyKey(\n ref: ColumnRef<any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n label: string\n): string {\n if (typeof ref === 'string') {\n if (!ref) throw new Error(`${label} must be a non-empty string`);\n return ref;\n }\n\n if (typeof ref === 'function') {\n const tree = ObjectSchemaBuilder.getPropertiesFor(schema as any);\n const descriptor = ref(tree as any);\n\n if (\n !descriptor ||\n typeof descriptor !== 'object' ||\n !(SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in descriptor)\n ) {\n throw new Error(\n `${label} accessor must return a valid property descriptor`\n );\n }\n\n const inner = (descriptor as any)[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n const pointer: string = inner.toJsonPointer();\n\n if (!pointer) {\n throw new Error(`${label} accessor returned the root descriptor`);\n }\n\n // Return the first segment (top-level property key) for mapping purposes\n const topProp = pointer.slice(1).split('/')[0];\n return topProp.replace(/~1/g, '/').replace(/~0/g, '~');\n }\n\n throw new Error(\n `${label} must be a string or a property descriptor accessor function`\n );\n}\n\n// ---------------------------------------------------------------------------\n// Primary-key introspection\n// ---------------------------------------------------------------------------\n\n/**\n * Result of {@link getPrimaryKeyColumns}.\n *\n * `propertyKeys` are the schema property names (the keys you'd use in\n * `.where(t => t.id, ...)` style accessors); `columnNames` are the SQL\n * column names after applying any `hasColumnName()` overrides. Order is\n * preserved: composite-PK ordering matches the user's `hasPrimaryKey()`\n * declaration; single-PK arrays have length 1.\n *\n * @public\n */\nexport interface PrimaryKeyColumns {\n readonly propertyKeys: readonly string[];\n readonly columnNames: readonly string[];\n}\n\n/**\n * Resolve the primary-key columns of a schema at runtime.\n *\n * Composite primary keys (declared via `.hasPrimaryKey([...])` on the\n * object schema) take precedence over single-column primary keys. The\n * `columns` argument to `.hasPrimaryKey()` may contain either property keys\n * or SQL column names — both forms are accepted and normalised.\n *\n * Returns `{ propertyKeys: [], columnNames: [] }` when no primary key is\n * declared.\n *\n * @public\n */\nexport function getPrimaryKeyColumns(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): PrimaryKeyColumns {\n const introspected = schema.introspect() as {\n properties?: Record<string, SchemaBuilder<any, any, any>>;\n extensions?: Record<string, unknown>;\n };\n const properties = introspected.properties ?? {};\n const extensions = introspected.extensions ?? {};\n const { propToCol, colToProp } = buildColumnMap(schema);\n\n // Composite PK takes precedence.\n const composite = extensions.compositePrimaryKey as\n | readonly string[]\n | undefined;\n if (composite && composite.length > 0) {\n const propertyKeys: string[] = [];\n const columnNames: string[] = [];\n for (const entry of composite) {\n // Accept either column name or property key.\n if (propToCol.has(entry)) {\n propertyKeys.push(entry);\n columnNames.push(propToCol.get(entry) as string);\n } else if (colToProp.has(entry)) {\n columnNames.push(entry);\n propertyKeys.push(colToProp.get(entry) as string);\n } else {\n // Unknown identifier — pass through as both (best effort).\n propertyKeys.push(entry);\n columnNames.push(entry);\n }\n }\n return { propertyKeys, columnNames };\n }\n\n // Single-column PK — first property whose schema carries the\n // `primaryKey` extension wins.\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const propExt =\n (\n propSchema as {\n introspect?: () => {\n extensions?: Record<string, unknown>;\n };\n }\n ).introspect?.().extensions ?? {};\n if (propExt.primaryKey) {\n return {\n propertyKeys: [propKey],\n columnNames: [propToCol.get(propKey) ?? propKey]\n };\n }\n }\n\n return { propertyKeys: [], columnNames: [] };\n}\n\n// ---------------------------------------------------------------------------\n// Row-version introspection\n// ---------------------------------------------------------------------------\n\n/**\n * Concurrency-token strategy stored by `.rowVersion()`.\n * - `'increment'` — ORM increments an integer counter on each UPDATE.\n * - `'timestamp'` — ORM sets the value to `new Date()` on each UPDATE.\n * - `'manual'` — caller supplies the new value; ORM only enforces the check.\n *\n * @public\n */\nexport type RowVersionStrategy = 'increment' | 'timestamp' | 'manual';\n\n/**\n * Resolved row-version column for a schema, returned by\n * {@link getRowVersionColumn}.\n *\n * @public\n */\nexport interface RowVersionColumn {\n /** Schema property name. */\n propertyKey: string;\n /** SQL column name (after any `hasColumnName()` override). */\n columnName: string;\n /** Concurrency-token update strategy. */\n strategy: RowVersionStrategy;\n}\n\n/**\n * Find the first column marked `.rowVersion()` on the schema and return its\n * metadata. Returns `null` when no row-version column is declared.\n *\n * @public\n */\nexport function getRowVersionColumn(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): RowVersionColumn | null {\n const introspected = schema.introspect() as {\n properties?: Record<\n string,\n { introspect?: () => { extensions?: Record<string, unknown> } }\n >;\n };\n const properties = introspected.properties ?? {};\n const { propToCol } = buildColumnMap(schema);\n\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const ext = propSchema.introspect?.()?.extensions ?? {};\n const rv = ext.rowVersion as { strategy?: string } | undefined;\n if (rv) {\n return {\n propertyKey: propKey,\n columnName: propToCol.get(propKey) ?? propKey,\n strategy: (rv.strategy as RowVersionStrategy) ?? 'increment'\n };\n }\n }\n return null;\n}\n","// @cleverbrush/knex-schema — DDL generation from schema introspection\n\nimport type { ObjectSchemaBuilder, SchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport {\n getColumnName,\n getPolymorphicVariantSchemas,\n getTableName\n} from './extension.js';\n\n// ---------------------------------------------------------------------------\n// Type mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the Knex column type from a schema property's introspection data and\n * DDL extensions.\n *\n * Priority:\n * 1. Explicit `columnType` extension (e.g. `'text'`, `'uuid'`, `'jsonb'`).\n * 2. Schema type (`string`, `number`, `boolean`, `date`).\n *\n * @param table - Knex table builder.\n * @param col - SQL column name.\n * @param introspected - Result of `propSchema.introspect()`.\n * @param ext - The property's `extensions` object.\n * @returns A Knex column builder.\n */\nfunction resolveColumnType(\n table: Knex.CreateTableBuilder,\n col: string,\n introspected: any,\n ext: Record<string, any>\n): Knex.ColumnBuilder {\n if (ext.columnType) {\n return table.specificType(col, ext.columnType);\n }\n switch (introspected.type) {\n case 'string': {\n const maxLen = ext.maxLength ?? introspected.maxLength ?? undefined;\n return maxLen ? table.string(col, maxLen) : table.string(col);\n }\n case 'number':\n return introspected.isInteger !== false\n ? table.integer(col)\n : table.float(col);\n case 'boolean':\n return table.boolean(col);\n case 'date':\n return table.timestamp(col);\n case 'object':\n // Nested objects are stored as jsonb by default; override via .columnType()\n return table.specificType(col, 'jsonb');\n default:\n return table.specificType(col, 'text');\n }\n}\n\n/**\n * Apply a default value to a Knex column builder.\n *\n * Handles special values:\n * - `'now'` → `knex.fn.now()`\n * - `'auto_increment'` → no-op (handled by `table.increments()`)\n * - `{ raw: string }` → `knex.raw(expression)`\n * - Otherwise → literal value.\n *\n * @param column - Knex column builder.\n * @param defaultValue - The default value from the `defaultTo` extension.\n * @param knex - Knex instance (needed for `fn.now()` and `raw()`).\n * @returns The column builder with the default applied.\n */\nfunction applyDefault(\n column: Knex.ColumnBuilder,\n defaultValue: any,\n knex: Knex\n): Knex.ColumnBuilder {\n if (defaultValue === 'now') return column.defaultTo(knex.fn.now());\n if (defaultValue === 'auto_increment') return column;\n if (\n typeof defaultValue === 'object' &&\n defaultValue !== null &&\n defaultValue.raw\n ) {\n return column.defaultTo(knex.raw(defaultValue.raw));\n }\n return column.defaultTo(defaultValue);\n}\n\n// ---------------------------------------------------------------------------\n// generateCreateTable\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a Knex `schema.createTable()` call from an ObjectSchemaBuilder's\n * introspected metadata and DDL extensions.\n *\n * Returns a function that accepts a Knex instance and returns a\n * `SchemaBuilder` (thenable). Call it inside a migration or setup script:\n *\n * @param schema - An `ObjectSchemaBuilder` with `.hasTableName()` and\n * column-level DDL extensions (`.primaryKey()`, `.references()`, etc.).\n * @returns `(knex: Knex) => Knex.SchemaBuilder` — a function that creates the\n * table when executed.\n *\n * @example\n * ```ts\n * const createUsersTable = generateCreateTable(UserSchema);\n * await createUsersTable(knex);\n * ```\n */\nexport function generateCreateTable(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): (knex: Knex) => Knex.SchemaBuilder {\n const tableName = getTableName(schema);\n const introspected = schema.introspect() as any;\n const tableExt: Record<string, any> = introspected.extensions ?? {};\n\n // Column names fully managed by table-level extensions; skip them in the\n // property loop to avoid duplicate DDL.\n const extensionManagedCols = new Set<string>();\n if (tableExt.timestamps) {\n extensionManagedCols.add(tableExt.timestamps.createdAt);\n extensionManagedCols.add(tableExt.timestamps.updatedAt);\n }\n if (tableExt.softDelete) {\n extensionManagedCols.add(tableExt.softDelete.column);\n }\n\n return (knex: Knex) => {\n const builder = knex.schema.createTable(\n tableName,\n (table: Knex.CreateTableBuilder) => {\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n\n for (const [propKey, propSchema] of Object.entries(\n properties\n )) {\n const col = getColumnName(propSchema, propKey);\n const propIntrospected = propSchema.introspect() as any;\n const ext: Record<string, any> =\n propIntrospected.extensions ?? {};\n\n // Skip array navigation properties without an explicit\n // columnType override — these are ORM relations. Nested\n // object properties default to jsonb and are NOT skipped.\n if (propIntrospected.type === 'array' && !ext.columnType) {\n continue;\n }\n // Skip columns owned by table-level extensions.\n if (extensionManagedCols.has(col)) {\n continue;\n }\n\n // Determine column builder\n let column: Knex.ColumnBuilder;\n\n if (ext.primaryKey?.autoIncrement) {\n column = table.increments(col);\n } else {\n column = resolveColumnType(\n table,\n col,\n propIntrospected,\n ext\n );\n }\n\n // Primary key (non-auto-increment)\n if (ext.primaryKey && !ext.primaryKey.autoIncrement) {\n column = column.primary();\n }\n\n // Unique constraint\n if (ext.unique) {\n column = column.unique(\n typeof ext.unique === 'string'\n ? { indexName: ext.unique }\n : undefined\n );\n }\n\n // Index\n if (ext.index) {\n column = column.index(\n typeof ext.index === 'string'\n ? ext.index\n : undefined\n );\n }\n\n // Default value\n if (ext.defaultTo !== undefined) {\n column = applyDefault(column, ext.defaultTo, knex);\n }\n\n // Nullability\n if (\n propIntrospected.isRequired &&\n !ext.primaryKey?.autoIncrement\n ) {\n column = column.notNullable();\n } else if (!propIntrospected.isRequired) {\n column = column.nullable();\n }\n\n // Foreign key references\n if (ext.references) {\n const fkBuilder = column\n .references(ext.references.column)\n .inTable(ext.references.table);\n if (ext.onDelete) fkBuilder.onDelete(ext.onDelete);\n if (ext.onUpdate) fkBuilder.onUpdate(ext.onUpdate);\n }\n\n // Column-level CHECK constraint\n if (ext.check) {\n table.check(ext.check);\n }\n }\n\n // ----- Table-level constraints from object extensions -----\n\n // Composite indexes\n for (const idx of tableExt.indexes ?? []) {\n if (idx.unique) {\n table.unique(idx.columns, {\n indexName: idx.name ?? undefined\n });\n } else {\n table.index(idx.columns, idx.name ?? undefined);\n }\n }\n\n // Composite unique constraints\n for (const unq of tableExt.uniques ?? []) {\n table.unique(unq.columns, {\n indexName: unq.name ?? undefined\n });\n }\n\n // Table-level CHECK constraints\n for (const chk of tableExt.checks ?? []) {\n table.check(chk);\n }\n\n // Composite primary key\n if (tableExt.compositePrimaryKey) {\n table.primary(tableExt.compositePrimaryKey);\n }\n\n // Raw columns (not backed by schema properties)\n for (const rawCol of tableExt.rawColumns ?? []) {\n table.specificType(rawCol.name, rawCol.definition);\n }\n\n // Timestamps (auto-added columns)\n if (tableExt.timestamps) {\n table\n .timestamp(tableExt.timestamps.createdAt)\n .defaultTo(knex.fn.now())\n .notNullable();\n table\n .timestamp(tableExt.timestamps.updatedAt)\n .defaultTo(knex.fn.now())\n .notNullable();\n }\n\n // Soft delete column\n if (tableExt.softDelete) {\n table.timestamp(tableExt.softDelete.column).nullable();\n }\n }\n );\n\n // Raw indexes are executed as separate statements after table creation\n const rawIndexes: string[] = tableExt.rawIndexes ?? [];\n if (rawIndexes.length > 0) {\n return builder.then(async () => {\n for (const rawIdx of rawIndexes) {\n await knex.raw(rawIdx);\n }\n }) as any;\n }\n\n return builder;\n };\n}\n\n// ---------------------------------------------------------------------------\n// generateCreateTableSource\n// ---------------------------------------------------------------------------\n\n/**\n * Generate `up` and `down` TypeScript code *strings* (4-space-indented\\n * fragments) for creating a table from a schema.\n *\n * Unlike {@link generateCreateTable} (which returns a Knex callback), the\n * output is plain source text suitable for writing into a migration file. The\n * fragments are designed to be embedded directly inside `up()` / `down()`\n * functions.\n *\n * @param schema - An `ObjectSchemaBuilder` with `.hasTableName()` and column\n * DDL extensions.\n * @returns `{ up, down }` source fragments.\n *\n * @example\n * ```ts\n * const { up, down } = generateCreateTableSource(UserSchema);\n * // up: \" await knex.schema.createTable('users', (table) => { … });\"\n * // down: \" await knex.schema.dropTableIfExists('users');\"\n * ```\n */\nexport function generateCreateTableSource(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): { up: string; down: string } {\n const tableName = getTableName(schema);\n const introspected = schema.introspect() as any;\n const tableExt: Record<string, any> = introspected.extensions ?? {};\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n\n const lines: string[] = [];\n\n // Column names owned by table-level extensions; skip in property loop.\n const extensionManagedCols = new Set<string>();\n if (tableExt.timestamps) {\n extensionManagedCols.add(tableExt.timestamps.createdAt);\n extensionManagedCols.add(tableExt.timestamps.updatedAt);\n }\n if (tableExt.softDelete) {\n extensionManagedCols.add(tableExt.softDelete.column);\n }\n\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const col = getColumnName(propSchema, propKey);\n const propIntrospected = propSchema.introspect() as any;\n const ext: Record<string, any> = propIntrospected.extensions ?? {};\n\n // Skip navigation properties and extension-managed columns.\n if (\n (propIntrospected.type === 'object' ||\n propIntrospected.type === 'array') &&\n !ext.columnType\n ) {\n continue;\n }\n if (extensionManagedCols.has(col)) {\n continue;\n }\n\n let line: string;\n\n if (ext.primaryKey?.autoIncrement) {\n line = ` table.increments('${col}')`;\n } else {\n line = ` ${_colTypeCode(col, propIntrospected, ext)}`;\n }\n\n // Primary key (non-auto-increment)\n if (ext.primaryKey && !ext.primaryKey.autoIncrement) {\n line += '.primary()';\n }\n\n // Unique\n if (ext.unique) {\n if (typeof ext.unique === 'string') {\n line += `.unique({ indexName: '${ext.unique}' })`;\n } else {\n line += '.unique()';\n }\n }\n\n // Index\n if (ext.index) {\n if (typeof ext.index === 'string') {\n line += `.index('${ext.index}')`;\n } else {\n line += '.index()';\n }\n }\n\n // Default value\n if (ext.defaultTo !== undefined) {\n line += `.defaultTo(${_fmtDefault(ext.defaultTo)})`;\n }\n\n // Nullability\n if (propIntrospected.isRequired && !ext.primaryKey?.autoIncrement) {\n line += '.notNullable()';\n } else if (!propIntrospected.isRequired) {\n line += '.nullable()';\n }\n\n // Foreign key references\n if (ext.references) {\n line += `.references('${ext.references.column}').inTable('${ext.references.table}')`;\n if (ext.onDelete) line += `.onDelete('${ext.onDelete}')`;\n if (ext.onUpdate) line += `.onUpdate('${ext.onUpdate}')`;\n }\n\n lines.push(line + ';');\n\n // Column-level CHECK (separate statement after column line)\n if (ext.check) {\n lines.push(` table.check(${JSON.stringify(ext.check)});`);\n }\n }\n\n // Composite indexes\n for (const idx of tableExt.indexes ?? []) {\n const cols = JSON.stringify(idx.columns);\n if (idx.unique) {\n lines.push(\n ` table.unique(${cols}${idx.name ? `, { indexName: '${idx.name}' }` : ''});`\n );\n } else {\n lines.push(\n ` table.index(${cols}${idx.name ? `, '${idx.name}'` : ''});`\n );\n }\n }\n\n // Composite unique constraints\n for (const unq of tableExt.uniques ?? []) {\n const cols = JSON.stringify(unq.columns);\n lines.push(\n ` table.unique(${cols}${unq.name ? `, { indexName: '${unq.name}' }` : ''});`\n );\n }\n\n // Table-level CHECK constraints\n for (const chk of tableExt.checks ?? []) {\n lines.push(` table.check(${JSON.stringify(chk)});`);\n }\n\n // Composite primary key\n if (tableExt.compositePrimaryKey) {\n lines.push(\n ` table.primary(${JSON.stringify(tableExt.compositePrimaryKey)});`\n );\n }\n\n // Raw columns\n for (const rawCol of tableExt.rawColumns ?? []) {\n lines.push(\n ` table.specificType('${rawCol.name}', '${rawCol.definition}');`\n );\n }\n\n // Timestamps\n if (tableExt.timestamps) {\n lines.push(\n ` table.timestamp('${tableExt.timestamps.createdAt}').notNullable().defaultTo(knex.fn.now());`\n );\n lines.push(\n ` table.timestamp('${tableExt.timestamps.updatedAt}').notNullable().defaultTo(knex.fn.now());`\n );\n }\n\n // Soft-delete column\n if (tableExt.softDelete) {\n lines.push(\n ` table.timestamp('${tableExt.softDelete.column}').nullable();`\n );\n }\n\n const rawIndexes: string[] = tableExt.rawIndexes ?? [];\n const rawIndexLines = rawIndexes.map(\n ri => ` await knex.raw(${JSON.stringify(ri)});`\n );\n\n const up =\n ` await knex.schema.createTable('${tableName}', (table) => {\\n${lines.join('\\n')}\\n });` +\n (rawIndexLines.length > 0 ? '\\n' + rawIndexLines.join('\\n') : '');\n\n const down = ` await knex.schema.dropTableIfExists('${tableName}');`;\n\n return { up, down };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers for generateCreateTableSource\n// ---------------------------------------------------------------------------\n\n/** @internal Render a column type expression for code generation. */\nfunction _colTypeCode(\n col: string,\n introspected: any,\n ext: Record<string, any>\n): string {\n if (ext.columnType)\n return `table.specificType('${col}', '${ext.columnType}')`;\n switch (introspected.type) {\n case 'string': {\n const maxLen = ext.maxLength ?? introspected.maxLength ?? undefined;\n return maxLen\n ? `table.string('${col}', ${maxLen})`\n : `table.string('${col}')`;\n }\n case 'number':\n return introspected.isInteger !== false\n ? `table.integer('${col}')`\n : `table.float('${col}')`;\n case 'boolean':\n return `table.boolean('${col}')`;\n case 'date':\n return `table.timestamp('${col}')`;\n case 'object':\n return `table.specificType('${col}', 'jsonb')`;\n default:\n return `table.specificType('${col}', 'text')`;\n }\n}\n\n/** @internal Format a defaultTo value as a code string for migration source. */\nfunction _fmtDefault(value: any): string {\n if (value === 'now') return 'knex.fn.now()';\n if (typeof value === 'object' && value !== null && value.raw) {\n return `knex.raw('${String(value.raw).replace(/'/g, \"\\\\'\")}')`;\n }\n if (typeof value === 'string') return `'${value.replace(/'/g, \"\\\\'\")}'`;\n return String(value);\n}\n\n// ---------------------------------------------------------------------------\n// generateCreatePolymorphicTables\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a series of Knex `schema.createTable()` calls for a polymorphic\n * schema and all its CTI variant tables.\n *\n * Returns an array of `(knex: Knex) => Knex.SchemaBuilder` functions — one\n * for the base table and one for each CTI variant. STI variants add their\n * columns to the base table itself so no extra table is needed.\n *\n * Execute them sequentially in a migration:\n *\n * @param schema - The base `ObjectSchemaBuilder` with `.withVariants()` applied.\n * @returns An array of table-creation functions to execute in order.\n *\n * @example\n * ```ts\n * const creators = generateCreatePolymorphicTables(FileSchema);\n * for (const create of creators) {\n * await create(knex);\n * }\n * ```\n */\nexport function generateCreatePolymorphicTables(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): Array<(knex: Knex) => Knex.SchemaBuilder> {\n const result: Array<(knex: Knex) => Knex.SchemaBuilder> = [\n generateCreateTable(schema)\n ];\n\n const variantSchemas = getPolymorphicVariantSchemas(schema);\n for (const variantSchema of variantSchemas) {\n // Only CTI variants have their own table\n const tableName = variantSchema.getExtension('tableName') as\n | string\n | undefined;\n if (tableName) {\n result.push(generateCreateTable(variantSchema));\n }\n }\n\n return result;\n}\n","// @cleverbrush/knex-schema — Entity wrapper\n//\n// Provides a typed wrapper around an ObjectSchemaBuilder that tracks\n// declared relations as a real generic parameter (TRels). Unlike the\n// brand-based approach, TRels survives method chaining because we own\n// every method's return type.\n//\n// Relations are still stored at runtime in the schema's `relations`\n// extension (compatible with the existing query/include implementation).\n\nimport {\n type ArraySchemaBuilder,\n type InferType,\n ObjectSchemaBuilder,\n type PropertyDescriptorTree,\n type SchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR\n} from '@cleverbrush/schema';\n\nimport { buildColumnMap } from './columns.js';\nimport {\n applyVariantsToSchema,\n getColumnName,\n type VariantInputForResolver\n} from './extension.js';\nimport type { ResolvedVariantRelationSpec } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Type-level helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Phantom info for a single declared relation, stored on `Entity`'s `TRels`\n * generic. `TForeign` is captured so `.include()` can type the customize\n * callback against the correct foreign schema.\n *\n * @public\n */\nexport interface RelationInfo<\n TKind extends 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany' = any,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> {\n readonly kind: TKind;\n readonly foreign: TForeign;\n}\n\n/**\n * Extract the property record `{ [name]: SchemaBuilder }` from any\n * `ObjectSchemaBuilder` regardless of variance positions.\n *\n * @public\n */\nexport type SchemaProps<T> =\n T extends ObjectSchemaBuilder<infer P, any, any, any, any, any, any>\n ? P\n : never;\n\n/**\n * Strips the `withExtensions()` overlay from a schema type, reducing it to a\n * plain `ObjectSchemaBuilder<TProps, TReq>` so `PropertyDescriptorTree<...>`\n * resolves without hitting TypeScript's recursion depth limit.\n *\n * @internal\n */\ntype EntitySchemaBase<\n T extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> =\n T extends ObjectSchemaBuilder<infer P, infer Req, any, any, any, any, any>\n ? ObjectSchemaBuilder<P, Req>\n : never;\n\n/**\n * `PropertyDescriptorTree` overlay that pins each top-level property's\n * literal `propertyName` into its descriptor. Required because\n * `PropertyDescriptorTree` widens `propertyName` to `string` for sub-trees\n * whose property is itself an `ObjectSchemaBuilder` (since\n * `PropertyDescriptorTree` lacks a `TPropertyKey` generic).\n *\n * @internal\n */\ntype EntityTree<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> = PropertyDescriptorTree<\n EntitySchemaBase<TSchema>,\n EntitySchemaBase<TSchema>\n> & {\n readonly [K in keyof SchemaProps<TSchema> & string]: {\n readonly [SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]: {\n readonly propertyName: K;\n };\n };\n};\n\n/**\n * Selector callback that receives a real {@link PropertyDescriptorTree} so\n * `t => t.someProp` navigates to the property definition and preserves its\n * JSDoc in IDE tooltips. The return shape is matched structurally on the\n * `[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR].propertyName` field, which captures\n * the literal property key as `TKey`.\n *\n * @public\n */\nexport type EntityPropSelector<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TKey extends string = string\n> = (t: EntityTree<TSchema>) => {\n readonly [SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]: {\n readonly propertyName: TKey;\n };\n};\n\n/**\n * Peel `.optional()` / `array(...)` wrappers off a navigation property's\n * schema to recover the underlying foreign `ObjectSchemaBuilder`.\n *\n * @public\n */\nexport type UnwrapNavSchema<TProp> =\n TProp extends ArraySchemaBuilder<infer TEl, any, any, any>\n ? TEl extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n ? TEl\n : never\n : TProp extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n ? TProp\n : TProp extends SchemaBuilder<infer T, any, any, any, any>\n ? T extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n ? T\n : never\n : never;\n\n/**\n * Merge type for a single polymorphic variant branch: variant schema fields\n * overlay base schema fields (narrowing the discriminator from `string` to its\n * specific literal value).\n *\n * @public\n */\nexport type VariantBranch<\n TBaseSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TVarSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> = Omit<InferType<TBaseSchema>, keyof InferType<TVarSchema>> &\n InferType<TVarSchema>;\n\n/**\n * Return type for an Entity method that adds a relation: keeps `TSchema`,\n * extends `TRels` with one more entry, and preserves `TVariantUnion`.\n *\n * @public\n */\nexport type WithRelation<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TRels extends Record<string, RelationInfo>,\n TKey extends string,\n TKind extends 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany',\n TForeign extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TVariantUnion = never\n> = Entity<\n TSchema,\n TRels & Record<TKey, RelationInfo<TKind, TForeign>>,\n TVariantUnion\n>;\n\n// ---------------------------------------------------------------------------\n// Entity\n// ---------------------------------------------------------------------------\n\n/**\n * A typed wrapper around an `ObjectSchemaBuilder` that tracks declared\n * relations in its `TRels` generic. Use {@link defineEntity} to create one.\n *\n * Relations are declared via `.hasOne()` / `.hasMany()` / `.belongsTo()` /\n * `.belongsToMany()` on the entity (NOT on the underlying schema). Each\n * call returns a new `Entity` whose `TRels` includes the new relation, so\n * `query(db, entity).include(t => t.assignee)` is fully typed.\n *\n * @public\n */\nexport class Entity<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TRels extends Record<string, RelationInfo> = {},\n TVariantUnion = never\n> {\n /** The underlying schema (relations registered via `withExtension('relations', ...)`). */\n readonly schema: TSchema;\n\n /** @internal Phantom slot to retain `TRels` in inferred types. */\n private declare readonly __relations__: TRels;\n\n /** @internal Phantom slot to retain `TVariantUnion` in inferred types. */\n private declare readonly __variantUnion__: TVariantUnion;\n\n constructor(schema: TSchema) {\n this.schema = schema;\n }\n\n private _addRelation(spec: {\n type: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany';\n name: string;\n schema: any;\n foreignKey?: any;\n through?: { table: string; localKey: string; foreignKey: string };\n optional?: boolean;\n }): Entity<TSchema, any> {\n const existing =\n ((this.schema as any).getExtension?.('relations') as any[]) ?? [];\n const next = (this.schema as any).withExtension('relations', [\n ...existing,\n spec\n ]);\n return new Entity(next);\n }\n\n /**\n * Declare a one-to-one relation where the FK lives on the FOREIGN table.\n * `navSel` selects the navigation property on THIS schema (must hold the\n * foreign schema, typically `.optional()`). The foreign schema is\n * auto-resolved at runtime from that property; provided explicitly here\n * via `opts.foreign` only when peeling fails.\n *\n * @param navSel Selector of nav property: `t => t.author`\n * @param localSel Selector of local-side join key: `l => l.id`\n * @param remoteSel Selector of remote-side FK on foreign schema: `r => r.userId`\n * @param opts Optional `{ optional?: boolean }` (default false).\n */\n hasOne<\n TKey extends keyof SchemaProps<TSchema> & string,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = UnwrapNavSchema<SchemaProps<TSchema>[TKey]>\n >(\n navSel: EntityPropSelector<TSchema, TKey>,\n _localSel: EntityPropSelector<TSchema>,\n remoteSel: EntityPropSelector<TForeign>,\n opts?: { optional?: boolean }\n ): WithRelation<TSchema, TRels, TKey, 'hasOne', TForeign, TVariantUnion> {\n const navName = this._resolvePropName(\n navSel as EntityPropSelector<TSchema>,\n this.schema\n );\n const foreignSchema = this._resolveForeignSchema(navName);\n const remoteKey = this._resolvePropName(\n remoteSel as EntityPropSelector<any>,\n foreignSchema\n );\n // For hasOne the FK is on the FOREIGN table → store remoteKey.\n return this._addRelation({\n type: 'hasOne',\n name: navName,\n schema: foreignSchema,\n foreignKey: remoteKey,\n optional: opts?.optional\n }) as any;\n }\n\n /**\n * Declare a one-to-many relation where the FK lives on the FOREIGN table.\n *\n * @param navSel Selector of nav array property: `t => t.posts`\n * @param localSel Selector of local-side join key: `l => l.id`\n * @param remoteSel Selector of remote-side FK on foreign schema: `r => r.userId`\n */\n hasMany<\n TKey extends keyof SchemaProps<TSchema> & string,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = UnwrapNavSchema<SchemaProps<TSchema>[TKey]>\n >(\n navSel: EntityPropSelector<TSchema, TKey>,\n _localSel: EntityPropSelector<TSchema>,\n remoteSel: EntityPropSelector<TForeign>\n ): WithRelation<TSchema, TRels, TKey, 'hasMany', TForeign, TVariantUnion> {\n const navName = this._resolvePropName(\n navSel as EntityPropSelector<TSchema>,\n this.schema\n );\n const foreignSchema = this._resolveForeignSchema(navName);\n const remoteKey = this._resolvePropName(\n remoteSel as EntityPropSelector<any>,\n foreignSchema\n );\n return this._addRelation({\n type: 'hasMany',\n name: navName,\n schema: foreignSchema,\n foreignKey: remoteKey\n }) as any;\n }\n\n /**\n * Declare a many-to-one relation where the FK lives on THIS table.\n *\n * @param navSel Selector of nav property (foreign schema, usually `.optional()`).\n * @param localSel Selector of local-side FK property: `l => l.userId`\n * @param remoteSel Selector of foreign-side PK property: `r => r.id`\n */\n belongsTo<\n TKey extends keyof SchemaProps<TSchema> & string,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = UnwrapNavSchema<SchemaProps<TSchema>[TKey]>\n >(\n navSel: EntityPropSelector<TSchema, TKey>,\n localSel: EntityPropSelector<TSchema>,\n _remoteSel: EntityPropSelector<TForeign>,\n opts?: { optional?: boolean }\n ): WithRelation<\n TSchema,\n TRels,\n TKey,\n 'belongsTo',\n TForeign,\n TVariantUnion\n > {\n const navName = this._resolvePropName(\n navSel as EntityPropSelector<TSchema>,\n this.schema\n );\n const foreignSchema = this._resolveForeignSchema(navName);\n const localKey = this._resolvePropName(localSel, this.schema);\n // For belongsTo the FK is on THIS table → store localKey.\n return this._addRelation({\n type: 'belongsTo',\n name: navName,\n schema: foreignSchema,\n foreignKey: localKey,\n optional: opts?.optional\n }) as any;\n }\n\n /**\n * Declare a many-to-many relation through a pivot table.\n *\n * @param navSel Selector of nav array property: `t => t.tags`\n * @param through Pivot table config `{ table, localKey, foreignKey }`.\n */\n belongsToMany<\n TKey extends keyof SchemaProps<TSchema> & string,\n TForeign extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = UnwrapNavSchema<SchemaProps<TSchema>[TKey]>\n >(\n navSel: EntityPropSelector<TSchema, TKey>,\n through: { table: string; localKey: string; foreignKey: string }\n ): WithRelation<\n TSchema,\n TRels,\n TKey,\n 'belongsToMany',\n TForeign,\n TVariantUnion\n > {\n const navName = this._resolvePropName(\n navSel as EntityPropSelector<TSchema>,\n this.schema\n );\n const foreignSchema = this._resolveForeignSchema(navName);\n return this._addRelation({\n type: 'belongsToMany',\n name: navName,\n schema: foreignSchema,\n through\n }) as any;\n }\n\n /**\n * Mark this entity as polymorphic by selecting the discriminator\n * property. Returns a new `Entity` whose `.ctiVariant()` /\n * `.stiVariant()` methods declare each variant.\n *\n * Declare ordinary relations (`.belongsTo()` etc.) on this entity BEFORE\n * `.discriminator()`. After `.discriminator()` you are in the\n * polymorphic-builder phase: `.hasOne/.hasMany/.belongsTo/.belongsToMany`\n * still work, but the per-variant relations live on the `.ctiVariant()`\n * / `.stiVariant()` calls.\n *\n * @example\n * ```ts\n * const FileEntity = defineEntity(FileSchema)\n * .discriminator(t => t.type)\n * .ctiVariant('image', ImageEntity, t => t.fileId)\n * .ctiVariant('document', DocumentEntity, t => t.fileId);\n * ```\n */\n discriminator<TKey extends keyof SchemaProps<TSchema> & string>(\n sel: TKey | EntityPropSelector<TSchema, TKey>\n ): Entity<TSchema, TRels, never> {\n const discKey =\n typeof sel === 'string'\n ? (sel as string)\n : this._resolvePropName(\n sel as EntityPropSelector<TSchema>,\n this.schema\n );\n const next = new Entity(this.schema) as Entity<TSchema, TRels>;\n // Carry the variant-builder state on the new Entity so subsequent\n // `.ctiVariant()`/`.stiVariant()` calls can extend it. Stored on\n // the instance (not in the schema) so the original schema is\n // unchanged until the first variant is added.\n (next as any)._variantBuilder = {\n discKey,\n variants: {} as Record<string, VariantInputForResolver>\n };\n return next;\n }\n\n /**\n * Declare a CTI (Class Table Inheritance) variant. Only valid after\n * `.discriminator()`. Returns a new `Entity` whose schema carries the\n * updated `'variants'` extension.\n *\n * @param key Discriminator literal (e.g. `'image'`).\n * @param variant Entity wrapping the variant table schema.\n * @param fkSel Accessor returning the FK property on the variant\n * schema that joins back to the base PK.\n * @param opts `{ allowOrphan?: boolean; relations?: ... }` — see CTI docs.\n */\n ctiVariant<\n TVarSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n key: string,\n variant: Entity<TVarSchema, any>,\n fkSel: (t: EntityTree<TVarSchema>) => any,\n opts?: {\n allowOrphan?: boolean;\n relations?: Record<string, VariantRelationInput<TVarSchema>>;\n }\n ): Entity<\n TSchema,\n TRels,\n TVariantUnion | VariantBranch<TSchema, TVarSchema>\n > {\n const builder = (this as any)._variantBuilder as\n | VariantBuilderState\n | undefined;\n if (!builder) {\n throw new Error(\n 'ctiVariant: call `.discriminator(...)` first to begin a polymorphic builder chain'\n );\n }\n const fkColumn = resolveCtiForeignKeyColumn(\n variant.schema,\n fkSel as (t: any) => any\n );\n const nextVariants: Record<string, VariantInputForResolver> = {\n ...builder.variants,\n [key]: {\n schema: variant.schema,\n storage: 'cti',\n foreignKeyColumn: fkColumn,\n allowOrphan: opts?.allowOrphan,\n relations: [\n ...entityRelationsToVariantRelations(variant),\n ...resolveInlineVariantRelations(\n variant.schema,\n opts?.relations\n )\n ]\n }\n };\n return this._withVariantBuilder<\n TVariantUnion | VariantBranch<TSchema, TVarSchema>\n >(builder.discKey, nextVariants);\n }\n\n /**\n * Declare an STI (Single Table Inheritance) variant. Only valid after\n * `.discriminator()`. Accepts either an {@link Entity} or a bare\n * {@link ObjectSchemaBuilder}.\n */\n stiVariant<\n TVarSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n key: string,\n body: Entity<TVarSchema, any> | TVarSchema,\n opts?: {\n enforceCheck?: boolean;\n relations?: Record<string, VariantRelationInput<TVarSchema>>;\n }\n ): Entity<\n TSchema,\n TRels,\n TVariantUnion | VariantBranch<TSchema, TVarSchema>\n > {\n const builder = (this as any)._variantBuilder as\n | VariantBuilderState\n | undefined;\n if (!builder) {\n throw new Error(\n 'stiVariant: call `.discriminator(...)` first to begin a polymorphic builder chain'\n );\n }\n const isEntity = body instanceof Entity;\n const varSchema = (\n isEntity ? (body as Entity<any, any>).schema : body\n ) as ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n const nextVariants: Record<string, VariantInputForResolver> = {\n ...builder.variants,\n [key]: {\n schema: varSchema,\n storage: 'sti',\n enforceCheck: opts?.enforceCheck,\n relations: [\n ...(isEntity\n ? entityRelationsToVariantRelations(\n body as Entity<any, any>\n )\n : []),\n ...resolveInlineVariantRelations(varSchema, opts?.relations)\n ]\n }\n };\n return this._withVariantBuilder<\n TVariantUnion | VariantBranch<TSchema, TVarSchema>\n >(builder.discKey, nextVariants);\n }\n\n /** @internal Apply the variant extension to the schema and return a new Entity. */\n private _withVariantBuilder<TNewUnion>(\n discKey: string,\n variants: Record<string, VariantInputForResolver>\n ): Entity<TSchema, TRels, TNewUnion> {\n let newSchema = applyVariantsToSchema(\n this.schema,\n discKey,\n variants\n ) as any;\n // Preserve any existing `relations` extension across the rebuild.\n const existingRelations =\n (this.schema as any).getExtension?.('relations') ?? [];\n if (existingRelations.length) {\n newSchema = newSchema.withExtension('relations', existingRelations);\n }\n const next = new Entity(newSchema as TSchema) as Entity<\n TSchema,\n TRels,\n TNewUnion\n >;\n (next as any)._variantBuilder = { discKey, variants };\n return next;\n }\n\n /**\n * @internal\n * Resolve a selector callback against the real `PropertyDescriptorTree`\n * of the given schema, returning the top-level property name. Throws if\n * the accessor does not yield a valid descriptor.\n */\n private _resolvePropName(\n selector: (t: any) => any,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n ): string {\n const tree = ObjectSchemaBuilder.getPropertiesFor(schema as any);\n const descriptor = selector(tree as any);\n if (\n !descriptor ||\n typeof descriptor !== 'object' ||\n !(SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in descriptor)\n ) {\n throw new Error(\n 'Entity relation selector must return a property descriptor, e.g. `t => t.author`.'\n );\n }\n const inner = (descriptor as any)[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n if (typeof inner.propertyName !== 'string') {\n throw new Error(\n 'Entity relation selector must return a top-level property descriptor.'\n );\n }\n return inner.propertyName as string;\n }\n\n /** @internal Resolve the foreign schema from a nav property. */\n private _resolveForeignSchema(navName: string): any {\n const props = (this.schema as any).introspect?.()?.properties ?? {};\n const propSchema = props[navName];\n if (!propSchema) {\n throw new Error(\n `Entity.relation: navigation property \"${navName}\" not found on schema`\n );\n }\n const intro = propSchema.introspect?.() ?? propSchema;\n // Array → use elementSchema\n if (intro.type === 'array' && intro.elementSchema) {\n return intro.elementSchema;\n }\n // Object schema directly (with or without optional)\n if (\n intro.type === 'object' ||\n propSchema.constructor?.name === 'ObjectSchemaBuilder'\n ) {\n return propSchema;\n }\n // Fall back: assume it's already the schema\n return propSchema;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Polymorphic variant helpers (used by Entity.discriminator/ctiVariant/stiVariant)\n// ---------------------------------------------------------------------------\n\n/** @internal Variant-builder state carried on an Entity instance during a\n * `.discriminator().ctiVariant()/.stiVariant()` chain. */\ninterface VariantBuilderState {\n discKey: string;\n variants: Record<string, VariantInputForResolver>;\n}\n\n/**\n * @internal Convert an Entity's stored relations (which use property-name\n * foreign keys) into the column-name form required by\n * {@link ResolvedVariantRelationSpec}.\n */\nfunction entityRelationsToVariantRelations(\n varEntity: Entity<any, any>\n): ResolvedVariantRelationSpec[] {\n const rels: any[] =\n (varEntity.schema as any).getExtension?.('relations') ?? [];\n if (rels.length === 0) return [];\n\n const { propToCol } = buildColumnMap(varEntity.schema as any);\n\n return rels.map(r => {\n // belongsToMany has no `foreignKey` on the spec itself (uses through.*).\n const fkPropName: string | undefined =\n typeof r.foreignKey === 'string' ? r.foreignKey : undefined;\n const fkColName = fkPropName\n ? (propToCol.get(fkPropName) ?? fkPropName)\n : undefined;\n return {\n name: r.name,\n type: r.type,\n schema: r.schema,\n foreignKey: fkColName,\n through: r.through\n } satisfies ResolvedVariantRelationSpec;\n });\n}\n\n/**\n * @internal Resolve a foreign-key accessor (`t => t.fileId`) against a\n * variant schema to a SQL column name.\n */\nfunction resolveCtiForeignKeyColumn(\n varSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n fkSel: (t: any) => any\n): string {\n const tree = ObjectSchemaBuilder.getPropertiesFor(varSchema as any);\n const desc = fkSel(tree as any);\n const inner = (desc as any)?.[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n if (!inner?.propertyName) {\n throw new Error(\n 'ctiVariant: foreignKey accessor must return a top-level property descriptor on the variant schema'\n );\n }\n const propKey: string = inner.propertyName;\n const props = (varSchema as any).introspect?.()?.properties ?? {};\n const propSchema = props[propKey];\n if (!propSchema) {\n throw new Error(\n `ctiVariant: foreignKey property \"${propKey}\" not found on variant schema`\n );\n }\n return getColumnName(propSchema, propKey);\n}\n\n/**\n * Inline relation spec accepted by {@link Entity.ctiVariant} /\n * {@link Entity.stiVariant} via `opts.relations`. The `foreignKey`\n * accessor (when given) is typed against the variant's own schema and\n * resolved to a SQL column name.\n *\n * @public\n */\nexport interface VariantRelationInput<\n TVarSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = ObjectSchemaBuilder<any, any, any, any, any, any, any>\n> {\n type: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany';\n /**\n * Foreign side — accept either a bare schema, an Entity wrapper, or a\n * lazy thunk for forward references.\n */\n schema?:\n | ObjectSchemaBuilder<any, any, any, any, any, any, any>\n | (() => ObjectSchemaBuilder<any, any, any, any, any, any, any>);\n entity?: Entity<any, any>;\n foreignKey?: (t: EntityTree<TVarSchema>) => any;\n through?: { table: string; localKey: string; foreignKey: string };\n}\n\n/**\n * @internal Resolve a map of {@link VariantRelationInput} into the\n * column-resolved {@link ResolvedVariantRelationSpec[]} shape stored on a\n * resolved variant spec.\n */\nfunction resolveInlineVariantRelations(\n varSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n relations: Record<string, VariantRelationInput<any>> | undefined\n): ResolvedVariantRelationSpec[] {\n if (!relations) return [];\n const { propToCol } = buildColumnMap(varSchema);\n const result: ResolvedVariantRelationSpec[] = [];\n const tree = ObjectSchemaBuilder.getPropertiesFor(varSchema as any);\n\n for (const [name, spec] of Object.entries(relations)) {\n let foreignKey: string | undefined;\n if (spec.foreignKey) {\n const desc = spec.foreignKey(tree as any);\n const inner = (desc as any)?.[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR];\n if (!inner?.propertyName) {\n throw new Error(\n `variant relation \"${name}\": foreignKey accessor must return a top-level property descriptor on the variant schema`\n );\n }\n const propKey: string = inner.propertyName;\n foreignKey = propToCol.get(propKey) ?? propKey;\n }\n const targetSchema = spec.entity ? spec.entity.schema : spec.schema;\n result.push({\n name,\n type: spec.type,\n schema: targetSchema,\n foreignKey,\n through: spec.through\n });\n }\n return result;\n}\n\n/**\n * Wrap an `ObjectSchemaBuilder` in an {@link Entity}, enabling typed relation\n * declaration via `.hasOne()` / `.hasMany()` / `.belongsTo()` / `.belongsToMany()`.\n *\n * @public\n *\n * @example\n * ```ts\n * const UserEntity = defineEntity(\n * object({\n * id: number().primaryKey(),\n * name: string(),\n * posts: array(PostEntity.schema)\n * }).hasTableName('users')\n * ).hasMany(t => t.posts, l => l.id, r => r.userId);\n * ```\n */\nexport function defineEntity<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(schema: TSchema): Entity<TSchema, {}> {\n return new Entity(schema);\n}\n\n/**\n * Type-level helper: extract `TRels` from any `Entity` type.\n * @public\n */\nexport type EntityRelations<E> =\n E extends Entity<any, infer R, any> ? R : never;\n\n/**\n * Type-level helper: extract the underlying schema type from any `Entity`.\n * @public\n */\nexport type EntitySchema<E> = E extends Entity<infer S, any, any> ? S : never;\n\n/**\n * Type-level helper: extract the accumulated variant union from any `Entity`.\n * Resolves to `never` for non-polymorphic entities.\n * @public\n */\nexport type EntityVariantUnion<E> =\n E extends Entity<any, any, infer U> ? U : never;\n\n/**\n * Type-level helper: union of relation key names declared on an entity.\n * Used by `SchemaQueryBuilder.insert()/update()/upsert()` to omit relation\n * navigation properties from accepted input.\n * @public\n */\nexport type EntityRelationKeys<E> =\n E extends Entity<any, infer R, any> ? keyof R & string : never;\n","// @cleverbrush/knex-schema — Post-load value transformers (from knex-eager)\n\nimport type { ValidatedSpec } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Built-in named mappers\n// ---------------------------------------------------------------------------\n\n/**\n * Built-in named value mapper functions.\n *\n * Each entry maps a string key to a transformation function. Pass the key as\n * the `mapper` argument to {@link mapValue} instead of a custom function.\n *\n * Currently available:\n * - `date_from_json` — converts a JSON date string (`string | null`) to a\n * JavaScript `Date` object (or passes through falsy values unchanged).\n */\nexport const MAPPERS: Record<string, (value: any) => any> = {\n date_from_json: (value: any) => {\n if (!value) return value;\n return new Date(Date.parse(value));\n }\n};\n\n// ---------------------------------------------------------------------------\n// mapValue — apply a mapper (function or built-in name) to a value\n// ---------------------------------------------------------------------------\n\n/**\n * Apply a single mapper to a value.\n *\n * @param mapper - Either a transformation function `(v: any) => any`, or a\n * string key referencing one of the {@link MAPPERS} built-ins (e.g.\n * `'date_from_json'`).\n * @param value - The raw value to transform.\n * @returns The transformed value.\n *\n * @throws If `mapper` is a string that does not exist in {@link MAPPERS}.\n */\nexport function mapValue(mapper: ((v: any) => any) | string, value: any): any {\n if (typeof mapper === 'string') {\n if (typeof MAPPERS[mapper] !== 'function') {\n throw new Error(`unknown mapper \"${mapper}\"`);\n }\n return MAPPERS[mapper](value);\n }\n if (typeof mapper === 'function') {\n return mapper(value);\n }\n throw new Error(\"couldn't map value\");\n}\n\n// ---------------------------------------------------------------------------\n// mapObject — apply mappers to all matching keys of an object\n// ---------------------------------------------------------------------------\n\n/**\n * Apply a map of per-key transformations to an object, returning a new object\n * with the transformed values.\n *\n * Keys not present in `mappers` are copied through unchanged. Keys present in\n * `mappers` are passed through {@link mapValue}.\n *\n * @param obj - The source object (e.g. a raw database row).\n * @param mappers - A `Record` mapping property keys to mapper functions or\n * {@link MAPPERS} built-in names.\n * @returns A shallow copy of `obj` with the specified values transformed.\n *\n * @throws If `obj` is `null` or a non-object, it is returned as-is.\n */\nexport function mapObject<T extends Record<string, any>>(\n obj: T,\n mappers: Record<string, ((v: any) => any) | string>\n): T {\n if (!mappers) throw new Error('mappers should be an object');\n if (!obj || typeof obj !== 'object' || obj === null) return obj;\n\n const result = {} as Record<string, any>;\n for (const key of Object.keys(obj)) {\n result[key] = mappers[key]\n ? mapValue(mappers[key], obj[key])\n : obj[key];\n }\n return result as T;\n}\n\n// ---------------------------------------------------------------------------\n// clearRow — apply mappers to joined data in a result row\n// ---------------------------------------------------------------------------\n\n/**\n * Apply value mappers to the joined fields of a result row in place.\n *\n * After an eager-loaded query resolves, joined objects and arrays may contain\n * raw database values that need transformation (e.g. date strings → `Date`).\n * This function iterates over the one-to-one and one-to-many specs, applies\n * the `mappers` defined on each spec to the nested data, and returns the\n * mutated row.\n *\n * This is an internal helper used by {@link SchemaQueryBuilder}'s result\n * mapping pipeline. Exported to allow custom post-processing if needed.\n *\n * @param row - The raw result row (mutated in place).\n * @param oneSpecs - Validated one-to-one join specs with optional `mappers`.\n * @param manySpecs - Validated one-to-many join specs with optional `mappers`.\n * @returns The mutated `row` object.\n */\nexport function clearRow(\n row: Record<string, any>,\n oneSpecs: Array<ValidatedSpec & { type: 'one' }>,\n manySpecs: Array<ValidatedSpec & { type: 'many' }>\n): Record<string, any> {\n for (const spec of oneSpecs) {\n const fieldName = spec.as;\n if (\n spec.mappers &&\n typeof row[fieldName] !== 'undefined' &&\n row[fieldName] !== null\n ) {\n row[fieldName] = mapObject(row[fieldName], spec.mappers);\n }\n }\n\n for (const spec of manySpecs) {\n const fieldName = spec.as;\n if (Array.isArray(row[fieldName])) {\n for (let k = 0; k < row[fieldName].length; k++) {\n if (row[fieldName][k]) {\n if (spec.mappers) {\n row[fieldName][k] = mapObject(\n row[fieldName][k],\n spec.mappers\n );\n }\n }\n }\n }\n }\n\n return row;\n}\n","// @cleverbrush/knex-schema — Schema diff & migration generation\n\nimport type { ObjectSchemaBuilder, SchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { generateCreateTableSource } from './ddl.js';\nimport type { Entity } from './entity.js';\nimport {\n getColumnName,\n getPolymorphicVariantSchemas,\n getTableName\n} from './extension.js';\nimport type {\n AddColumnDiff,\n AddForeignKeyDiff,\n AddIndexDiff,\n AlterColumnDiff,\n DatabaseCheckInfo,\n DatabaseColumnInfo,\n DatabaseForeignKeyInfo,\n DatabaseIndexInfo,\n DatabaseTableState,\n MigrationDiff,\n SchemaSnapshot\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Database introspection\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize raw database query results into a {@link DatabaseTableState}.\n * @internal\n */\nfunction normalizeDbState(\n columns: any[],\n indexes: any[],\n foreignKeys: any[],\n checks: any[]\n): DatabaseTableState {\n const colMap: Record<string, DatabaseColumnInfo> = {};\n for (const row of columns) {\n colMap[row.column_name] = {\n name: row.column_name,\n type: row.data_type,\n nullable: row.is_nullable === 'YES',\n defaultValue: row.column_default ?? null,\n maxLength: row.character_maximum_length ?? null,\n numericPrecision: row.numeric_precision ?? null\n };\n }\n\n const idxList: DatabaseIndexInfo[] = indexes.map((row: any) => ({\n name: row.indexname,\n columns: Array.isArray(row.columns) ? row.columns : [],\n unique: (row.indexdef ?? '').toUpperCase().includes('UNIQUE'),\n definition: row.indexdef ?? ''\n }));\n\n const fkList: DatabaseForeignKeyInfo[] = foreignKeys.map((row: any) => ({\n constraintName: row.constraint_name,\n columnName: row.column_name,\n foreignTable: row.foreign_table,\n foreignColumn: row.foreign_column,\n deleteRule: row.delete_rule,\n updateRule: row.update_rule\n }));\n\n const chkList: DatabaseCheckInfo[] = checks.map((row: any) => ({\n name: row.conname,\n definition: row.definition\n }));\n\n return {\n columns: colMap,\n indexes: idxList,\n foreignKeys: fkList,\n checks: chkList\n };\n}\n\n/**\n * Introspect a PostgreSQL table and return its current state.\n *\n * Queries `information_schema.columns`, `pg_indexes`, `pg_constraint`, and\n * referential constraint metadata to build a complete picture of the table's\n * columns, indexes, foreign keys, and check constraints.\n *\n * @param knex - A configured Knex instance connected to a PostgreSQL database.\n * @param tableName - The table name to introspect.\n * @returns The current database state for the table.\n *\n * @example\n * ```ts\n * const dbState = await introspectDatabase(knex, 'users');\n * console.log(dbState.columns); // { id: { type: 'integer', ... }, ... }\n * ```\n */\nexport async function introspectDatabase(\n knex: Knex,\n tableName: string\n): Promise<DatabaseTableState> {\n const [columns, indexes, foreignKeys, checks] = await Promise.all([\n knex.raw(\n `SELECT column_name, data_type, is_nullable, column_default,\n character_maximum_length, numeric_precision\n FROM information_schema.columns\n WHERE table_name = ? AND table_schema = 'public'\n ORDER BY ordinal_position`,\n [tableName]\n ),\n knex.raw(\n `SELECT indexname, indexdef,\n array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns\n FROM pg_indexes\n JOIN pg_class t ON t.relname = ?\n JOIN pg_index ix ON ix.indrelid = t.oid\n JOIN pg_class i ON i.oid = ix.indexrelid AND i.relname = pg_indexes.indexname\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)\n WHERE pg_indexes.tablename = ?\n GROUP BY indexname, indexdef`,\n [tableName, tableName]\n ),\n knex.raw(\n `SELECT tc.constraint_name, kcu.column_name,\n ccu.table_name AS foreign_table, ccu.column_name AS foreign_column,\n rc.delete_rule, rc.update_rule\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu USING (constraint_name, table_schema)\n JOIN information_schema.constraint_column_usage ccu USING (constraint_name, table_schema)\n JOIN information_schema.referential_constraints rc USING (constraint_name, constraint_schema)\n WHERE tc.table_name = ? AND tc.constraint_type = 'FOREIGN KEY'`,\n [tableName]\n ),\n knex.raw(\n `SELECT conname, pg_get_constraintdef(oid) as definition\n FROM pg_constraint\n WHERE conrelid = ?::regclass AND contype = 'c'`,\n [tableName]\n )\n ]);\n\n return normalizeDbState(\n columns.rows,\n indexes.rows,\n foreignKeys.rows,\n checks.rows\n );\n}\n\n// ---------------------------------------------------------------------------\n// Schema → column info extraction\n// ---------------------------------------------------------------------------\n\n/** @internal Map a schema type to a PostgreSQL data_type string for comparison. */\nfunction schemaTypeToDbType(\n introspected: any,\n ext: Record<string, any>\n): string {\n if (ext.columnType) return ext.columnType;\n if (ext.primaryKey?.autoIncrement) return 'integer';\n switch (introspected.type) {\n case 'string':\n return 'character varying';\n case 'number':\n return introspected.isInteger !== false\n ? 'integer'\n : 'double precision';\n case 'boolean':\n return 'boolean';\n case 'date':\n return 'timestamp without time zone';\n default:\n return 'text';\n }\n}\n\n// ---------------------------------------------------------------------------\n// entitySchemaToTableState\n// ---------------------------------------------------------------------------\n\n/**\n * Derive a {@link DatabaseTableState} from a code-first `ObjectSchemaBuilder`\n * without connecting to the database.\n *\n * The result mirrors what {@link introspectDatabase} would return after the\n * schema has been fully applied, so it can be fed directly into\n * {@link diffSchema} as the `dbState` argument. This is the foundation of\n * snapshot-based migration generation.\n *\n * @param schema - An `ObjectSchemaBuilder` with DDL extensions.\n * @returns A {@link DatabaseTableState} representing the schema's ideal DB shape.\n *\n * @example\n * ```ts\n * const state = entitySchemaToTableState(UserSchema);\n * // state.columns, state.foreignKeys, state.indexes …\n * ```\n */\nexport function entitySchemaToTableState(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): DatabaseTableState {\n const tableName = getTableName(schema);\n const introspected = schema.introspect() as any;\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n const tableExt: Record<string, any> = introspected.extensions ?? {};\n\n const columns: Record<string, DatabaseColumnInfo> = {};\n const indexes: DatabaseIndexInfo[] = [];\n const foreignKeys: DatabaseForeignKeyInfo[] = [];\n const checks: DatabaseCheckInfo[] = [];\n\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const col = getColumnName(propSchema, propKey);\n const propIntrospected = propSchema.introspect() as any;\n const ext: Record<string, any> = propIntrospected.extensions ?? {};\n\n // Skip navigation properties (object/array without an explicit columnType).\n if (\n (propIntrospected.type === 'object' ||\n propIntrospected.type === 'array') &&\n !ext.columnType\n ) {\n continue;\n }\n\n columns[col] = {\n name: col,\n type: schemaTypeToDbType(propIntrospected, ext),\n nullable: !propIntrospected.isRequired,\n defaultValue: ext.defaultTo ?? null,\n maxLength: ext.maxLength ?? propIntrospected.maxLength ?? null,\n numericPrecision: null\n };\n\n if (ext.references) {\n foreignKeys.push({\n // Use Knex's default FK constraint naming convention\n constraintName: `${tableName}_${col}_foreign`,\n columnName: col,\n foreignTable: ext.references.table,\n foreignColumn: ext.references.column,\n deleteRule: (ext.onDelete ?? 'NO ACTION').toUpperCase(),\n updateRule: (ext.onUpdate ?? 'NO ACTION').toUpperCase()\n });\n }\n }\n\n // Timestamp columns (created_at / updated_at)\n if (tableExt.timestamps) {\n const ts = tableExt.timestamps;\n const createdAtCol: string = ts.createdAt ?? 'created_at';\n const updatedAtCol: string = ts.updatedAt ?? 'updated_at';\n columns[createdAtCol] = {\n name: createdAtCol,\n type: 'timestamp without time zone',\n nullable: false,\n defaultValue: 'now',\n maxLength: null,\n numericPrecision: null\n };\n columns[updatedAtCol] = {\n name: updatedAtCol,\n type: 'timestamp without time zone',\n nullable: false,\n defaultValue: 'now',\n maxLength: null,\n numericPrecision: null\n };\n }\n\n // Soft-delete column\n if (tableExt.softDelete) {\n const delCol: string = tableExt.softDelete.column ?? 'deleted_at';\n columns[delCol] = {\n name: delCol,\n type: 'timestamp without time zone',\n nullable: true,\n defaultValue: null,\n maxLength: null,\n numericPrecision: null\n };\n }\n\n // Non-unique indexes\n for (const idx of tableExt.indexes ?? []) {\n const idxName: string =\n idx.name ?? `idx_${(idx.columns as string[]).join('_')}`;\n indexes.push({\n name: idxName,\n columns: idx.columns,\n unique: idx.unique ?? false,\n definition: ''\n });\n }\n\n // Unique constraints\n for (const unq of tableExt.uniques ?? []) {\n const unqName: string =\n unq.name ?? `unq_${(unq.columns as string[]).join('_')}`;\n indexes.push({\n name: unqName,\n columns: unq.columns,\n unique: true,\n definition: ''\n });\n }\n\n return { columns, indexes, foreignKeys, checks };\n}\n\n// ---------------------------------------------------------------------------\n// diffSchema\n// ---------------------------------------------------------------------------\n\n/**\n * Compare a code-first schema model against a live database table state and\n * produce a diff describing the changes needed to bring the database in sync.\n *\n * @param schema - The code-first `ObjectSchemaBuilder`.\n * @param dbState - The current database state from {@link introspectDatabase}.\n * @returns A {@link MigrationDiff} describing columns, indexes, and foreign\n * keys to add, drop, or alter.\n *\n * @example\n * ```ts\n * const dbState = await introspectDatabase(knex, 'users');\n * const diff = diffSchema(UserSchema, dbState);\n * if (diff.addColumns.length > 0) {\n * const migration = generateMigration(diff, 'users');\n * console.log(migration.up);\n * }\n * ```\n */\nexport function diffSchema(\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n dbState: DatabaseTableState\n): MigrationDiff {\n const introspected = schema.introspect() as any;\n const properties: Record<\n string,\n SchemaBuilder<any, any, any>\n > = introspected.properties ?? {};\n const tableExt: Record<string, any> = introspected.extensions ?? {};\n\n const addColumns: AddColumnDiff[] = [];\n const dropColumns: string[] = [];\n const alterColumns: AlterColumnDiff[] = [];\n const addIndexes: AddIndexDiff[] = [];\n const dropIndexes: string[] = [];\n const addForeignKeys: AddForeignKeyDiff[] = [];\n const dropForeignKeys: string[] = [];\n\n // Columns whose default values are owned by table-level extensions\n // (hasTimestamps, softDelete). Don't compare defaultValue for these —\n // the extension is authoritative.\n const extensionOwnedDefaults = new Set<string>();\n if (tableExt.timestamps) {\n extensionOwnedDefaults.add(tableExt.timestamps.createdAt);\n extensionOwnedDefaults.add(tableExt.timestamps.updatedAt);\n }\n\n // Set of schema-defined column names\n const schemaColumns = new Set<string>();\n\n // --- Column diff ---\n for (const [propKey, propSchema] of Object.entries(properties)) {\n const col = getColumnName(propSchema, propKey);\n const propIntrospected = propSchema.introspect() as any;\n const ext: Record<string, any> = propIntrospected.extensions ?? {};\n\n // Skip navigation properties (object/array without explicit columnType).\n if (\n (propIntrospected.type === 'object' ||\n propIntrospected.type === 'array') &&\n !ext.columnType\n ) {\n continue;\n }\n\n schemaColumns.add(col);\n\n const dbCol = dbState.columns[col];\n if (!dbCol) {\n // Column exists in schema but not in DB → add\n addColumns.push({\n name: col,\n type: schemaTypeToDbType(propIntrospected, ext),\n nullable: !propIntrospected.isRequired,\n defaultValue: ext.defaultTo,\n references: ext.references,\n onDelete: ext.onDelete,\n onUpdate: ext.onUpdate\n });\n } else {\n // Column exists in both → check for alterations\n const changes: Record<string, { from: any; to: any }> = {};\n\n const expectedNullable = !propIntrospected.isRequired;\n if (dbCol.nullable !== expectedNullable) {\n changes.nullable = {\n from: dbCol.nullable,\n to: expectedNullable\n };\n }\n\n // Compare defaultValue (null / undefined both mean \"no default\")\n // Skip columns whose default is controlled by a table-level extension,\n // or auto-increment PKs whose nextval(...) default is DB-managed.\n if (\n !extensionOwnedDefaults.has(col) &&\n !ext.primaryKey?.autoIncrement\n ) {\n const snapshotDefault = dbCol.defaultValue ?? null;\n const schemaDefault = ext.defaultTo ?? null;\n if (snapshotDefault !== schemaDefault) {\n changes.defaultValue = {\n from: snapshotDefault,\n to: schemaDefault\n };\n }\n }\n\n if (Object.keys(changes).length > 0) {\n alterColumns.push({ name: col, changes });\n }\n }\n\n // Foreign key diff\n if (ext.references) {\n const existingFK = dbState.foreignKeys.find(\n fk => fk.columnName === col\n );\n if (!existingFK) {\n addForeignKeys.push({\n column: col,\n foreignTable: ext.references.table,\n foreignColumn: ext.references.column,\n onDelete: ext.onDelete,\n onUpdate: ext.onUpdate\n });\n }\n }\n }\n\n // Include timestamp columns in schema column set\n if (tableExt.timestamps) {\n schemaColumns.add(tableExt.timestamps.createdAt);\n schemaColumns.add(tableExt.timestamps.updatedAt);\n }\n if (tableExt.softDelete) {\n schemaColumns.add(tableExt.softDelete.column);\n }\n\n // Columns in DB but not in schema → drop\n for (const colName of Object.keys(dbState.columns)) {\n if (!schemaColumns.has(colName)) {\n dropColumns.push(colName);\n }\n }\n\n // --- Index diff ---\n const schemaIndexNames = new Set<string>();\n\n for (const idx of tableExt.indexes ?? []) {\n const idxName = idx.name ?? `idx_${idx.columns.join('_')}`;\n schemaIndexNames.add(idxName);\n const existingIdx = dbState.indexes.find(\n dbIdx => dbIdx.name === idxName\n );\n if (!existingIdx) {\n addIndexes.push({\n columns: idx.columns,\n name: idx.name,\n unique: idx.unique\n });\n }\n }\n\n for (const unq of tableExt.uniques ?? []) {\n const unqName = unq.name ?? `unq_${unq.columns.join('_')}`;\n schemaIndexNames.add(unqName);\n const existingIdx = dbState.indexes.find(\n dbIdx => dbIdx.name === unqName\n );\n if (!existingIdx) {\n addIndexes.push({\n columns: unq.columns,\n name: unq.name,\n unique: true\n });\n }\n }\n\n // FK constraints that exist in DB but not in schema → drop\n for (const fk of dbState.foreignKeys) {\n const propSchema = Object.entries(properties).find(([propKey, ps]) => {\n return getColumnName(ps, propKey) === fk.columnName;\n });\n if (propSchema) {\n const ext = (propSchema[1].introspect() as any).extensions ?? {};\n if (!ext.references) {\n dropForeignKeys.push(fk.constraintName);\n }\n } else {\n dropForeignKeys.push(fk.constraintName);\n }\n }\n\n return {\n addColumns,\n dropColumns,\n alterColumns,\n addIndexes,\n dropIndexes,\n addForeignKeys,\n dropForeignKeys\n };\n}\n\n// ---------------------------------------------------------------------------\n// generateMigration\n// ---------------------------------------------------------------------------\n\n/**\n * Generate migration `up` and `down` code strings from a {@link MigrationDiff}.\n *\n * The generated code is valid TypeScript that uses Knex's schema builder API.\n * Write it to a migration file and run via Knex's migration system.\n *\n * @param diff - The schema diff from {@link diffSchema}.\n * @param tableName - The table name to alter.\n * @returns An object with `up` and `down` migration code strings.\n *\n * @example\n * ```ts\n * const diff = diffSchema(UserSchema, dbState);\n * const migration = generateMigration(diff, 'users');\n * fs.writeFileSync('migration.ts', migration.full);\n * ```\n */\nexport function generateMigration(\n diff: MigrationDiff,\n tableName: string\n): { up: string; down: string; full: string } {\n const { up, down } = buildAlterTableFragments(diff, tableName);\n\n const full = `import type { Knex } from 'knex';\n\nexport async function up(knex: Knex): Promise<void> {\n${up}\n}\n\nexport async function down(knex: Knex): Promise<void> {\n${down}\n}\n`;\n\n return { up, down, full };\n}\n\n// ---------------------------------------------------------------------------\n// tableExistsInDb\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether a table exists in the connected PostgreSQL database.\n *\n * @param knex - A configured Knex instance (or transaction).\n * @param tableName - The table name to check.\n * @returns `true` when the table exists.\n *\n * @example\n * ```ts\n * const exists = await tableExistsInDb(knex, 'users');\n * if (!exists) await generateCreateTable(UserSchema)(knex);\n * ```\n */\nexport async function tableExistsInDb(\n knex: Knex,\n tableName: string\n): Promise<boolean> {\n return knex.schema.hasTable(tableName);\n}\n\n// ---------------------------------------------------------------------------\n// validateEntitiesAgainstDatabase\n// ---------------------------------------------------------------------------\n\n/**\n * A schema validation issue detected against the live database.\n */\nexport type EntitySchemaValidationIssue =\n | {\n type: 'missing-table';\n tableName: string;\n }\n | {\n type: 'schema-drift';\n tableName: string;\n diff: MigrationDiff;\n };\n\n/**\n * Result returned by {@link validateEntitiesAgainstDatabase}.\n */\nexport interface EntitySchemaValidationResult {\n /** `true` when every entity table exists and has an empty schema diff. */\n valid: boolean;\n /** Table names inspected during validation. */\n checkedTables: string[];\n /** Missing tables or non-empty schema diffs. */\n issues: EntitySchemaValidationIssue[];\n}\n\n/**\n * Validate entity schemas against a live database without changing anything.\n *\n * This is the read-only counterpart to `db push`: it checks every registered\n * entity table, including class-table-inheritance variant tables, and reports\n * missing tables or schema drift.\n *\n * @param knex - A configured Knex instance or transaction.\n * @param entities - The entity definitions to validate.\n * @returns A validation result with all detected issues.\n */\nexport async function validateEntitiesAgainstDatabase(\n knex: Knex,\n entities: Entity<any, any>[]\n): Promise<EntitySchemaValidationResult> {\n const unique = collectUniqueEntityTables(entities);\n const issues: EntitySchemaValidationIssue[] = [];\n\n for (const { schema, tableName } of unique) {\n const exists = await tableExistsInDb(knex, tableName);\n if (!exists) {\n issues.push({ type: 'missing-table', tableName });\n continue;\n }\n\n const dbState = await introspectDatabase(knex, tableName);\n const diff = diffSchema(schema, dbState);\n if (!isDiffEmpty(diff)) {\n issues.push({ type: 'schema-drift', tableName, diff });\n }\n }\n\n return {\n valid: issues.length === 0,\n checkedTables: unique.map(entry => entry.tableName),\n issues\n };\n}\n\n// ---------------------------------------------------------------------------\n// isDiffEmpty\n// ---------------------------------------------------------------------------\n\n/**\n * Return `true` when a {@link MigrationDiff} has no operations — i.e. the\n * database table is already in sync with the schema.\n */\nexport function isDiffEmpty(diff: MigrationDiff): boolean {\n return (\n diff.addColumns.length === 0 &&\n diff.dropColumns.length === 0 &&\n diff.alterColumns.length === 0 &&\n diff.addIndexes.length === 0 &&\n diff.dropIndexes.length === 0 &&\n diff.addForeignKeys.length === 0 &&\n diff.dropForeignKeys.length === 0\n );\n}\n\n// ---------------------------------------------------------------------------\n// applyDiff\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a {@link MigrationDiff} directly against a live database without\n * writing a migration file. Intended for `db push` (dev-only schema sync).\n *\n * Foreign-key constraint drops are executed as raw `ALTER TABLE … DROP\n * CONSTRAINT` statements before the main `alterTable` call.\n *\n * @param knex - A configured Knex instance or transaction.\n * @param diff - The diff from {@link diffSchema}.\n * @param tableName - The table to alter.\n *\n * @example\n * ```ts\n * const dbState = await introspectDatabase(knex, 'users');\n * const diff = diffSchema(UserSchema, dbState);\n * if (!isDiffEmpty(diff)) await applyDiff(knex, diff, 'users');\n * ```\n */\nexport async function applyDiff(\n knex: Knex,\n diff: MigrationDiff,\n tableName: string\n): Promise<void> {\n if (isDiffEmpty(diff)) return;\n\n // FK constraint drops require raw SQL (we only have constraint names, not\n // column names, in the diff so Knex's dropForeign helper cannot be used).\n for (const constraintName of diff.dropForeignKeys) {\n await knex.raw('ALTER TABLE ?? DROP CONSTRAINT ??', [\n tableName,\n constraintName\n ]);\n }\n\n const hasTableChanges =\n diff.addColumns.length > 0 ||\n diff.dropColumns.length > 0 ||\n diff.alterColumns.length > 0 ||\n diff.addIndexes.length > 0 ||\n diff.dropIndexes.length > 0 ||\n diff.addForeignKeys.length > 0;\n\n if (!hasTableChanges) return;\n\n await knex.schema.alterTable(tableName, table => {\n // Add columns\n for (const col of diff.addColumns) {\n let column = buildColumnFromDbType(\n table as unknown as Knex.CreateTableBuilder,\n col.name,\n col.type\n );\n if (col.nullable) column = column.nullable();\n else column = column.notNullable();\n if (col.defaultValue !== undefined) {\n if (col.defaultValue === 'now') {\n column = column.defaultTo(knex.fn.now());\n } else if (\n typeof col.defaultValue === 'object' &&\n col.defaultValue !== null &&\n col.defaultValue.raw\n ) {\n column = column.defaultTo(knex.raw(col.defaultValue.raw));\n } else {\n column = column.defaultTo(col.defaultValue);\n }\n }\n if (col.references) {\n const fkBuilder = column\n .references(col.references.column)\n .inTable(col.references.table);\n if (col.onDelete) fkBuilder.onDelete(col.onDelete);\n if (col.onUpdate) fkBuilder.onUpdate(col.onUpdate);\n }\n }\n\n // Drop columns\n for (const colName of diff.dropColumns) {\n table.dropColumn(colName);\n }\n\n // Alter nullable / default\n for (const col of diff.alterColumns) {\n for (const [key, change] of Object.entries(col.changes)) {\n if (key === 'nullable') {\n if (change.to) {\n (table as any).setNullable(col.name);\n } else {\n (table as any).dropNullable(col.name);\n }\n } else if (key === 'defaultValue') {\n if (change.to === null) {\n table.dropColumn(col.name); // fallback — handled in source gen\n } else {\n // ALTER COLUMN SET DEFAULT is not directly in Knex builder;\n // handled via raw in source generation\n }\n }\n }\n }\n\n // Add indexes\n for (const idx of diff.addIndexes) {\n if (idx.unique) {\n table.unique(\n idx.columns,\n idx.name ? { indexName: idx.name } : undefined\n );\n } else {\n table.index(idx.columns, idx.name);\n }\n }\n\n // Drop indexes\n for (const idx of diff.dropIndexes) {\n table.dropIndex([], idx);\n }\n\n // Add foreign keys\n for (const fk of diff.addForeignKeys) {\n let builder = table\n .foreign(fk.column)\n .references(fk.foreignColumn)\n .inTable(fk.foreignTable);\n if (fk.onDelete) builder = builder.onDelete(fk.onDelete);\n if (fk.onUpdate) builder = builder.onUpdate(fk.onUpdate);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// generateMigrationsForContext\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a single combined migration (up + down) for a set of entities by\n * diffing the current code-first schemas against a **serialized snapshot**\n * stored in the repository — no live database connection required.\n *\n * For each entity's table the function:\n * - **New tables** (in entities but not in `prevSnapshot`): emits `CREATE TABLE`.\n * - **Existing tables** (in both): diffs entity schema against the snapshot\n * state via {@link diffSchema} and emits `ALTER TABLE` when changes exist.\n * - **Dropped tables** (in `prevSnapshot` but not in entities): emits\n * `DROP TABLE` with a best-effort `CREATE TABLE` in the `down` direction.\n * - Orders tables topologically by FK dependencies so parent tables are\n * created before child tables in `up` (and dropped after in `down`).\n *\n * @param entities - The entities from your {@link EntityMap}.\n * @param prevSnapshot - The last committed {@link SchemaSnapshot} (empty on first run).\n * @returns `{ up, down, full, isEmpty, nextSnapshot }` where `nextSnapshot`\n * should be written to disk after the migration file is created.\n *\n * @example\n * ```ts\n * const prev = loadSnapshot('./migrations/snapshot.json');\n * const result = generateMigrationsForContext(\n * Object.values({ todos: TodoEntity, users: UserEntity }),\n * prev\n * );\n * if (!result.isEmpty) {\n * fs.writeFileSync('migrations/20260423000000_init.ts', result.full);\n * writeSnapshot('./migrations/snapshot.json', result.nextSnapshot);\n * }\n * ```\n */\nexport function generateMigrationsForContext(\n entities: Entity<any, any>[],\n prevSnapshot: SchemaSnapshot\n): {\n up: string;\n down: string;\n full: string;\n isEmpty: boolean;\n nextSnapshot: SchemaSnapshot;\n} {\n // 1. Collect all (schema, tableName) pairs including CTI variant tables\n const uniqueEntries = collectUniqueEntityTables(entities);\n\n // 3. Topological sort by FK dependencies\n const sorted = topologicalSort(uniqueEntries);\n\n // 4. Generate CREATE or ALTER fragment for each current table\n const upParts: string[] = [];\n const downParts: string[] = [];\n\n const currentTableNames = new Set(sorted.map(e => e.tableName));\n\n for (const { schema, tableName } of sorted) {\n const snapshotState = prevSnapshot.tables[tableName];\n if (!snapshotState) {\n // New table — emit CREATE TABLE\n const { up, down } = generateCreateTableSource(schema);\n upParts.push(up);\n downParts.push(down);\n } else {\n // Existing table — diff schema against snapshot (pure, no DB)\n const diff = diffSchema(schema, snapshotState);\n if (!isDiffEmpty(diff)) {\n const { up, down } = buildAlterTableFragments(diff, tableName);\n upParts.push(up);\n downParts.push(down);\n }\n }\n }\n\n // 5. Tables in snapshot but absent from current entities → DROP TABLE\n for (const tableName of Object.keys(prevSnapshot.tables)) {\n if (!currentTableNames.has(tableName)) {\n const state = prevSnapshot.tables[tableName];\n const { up, down } = generateDropTableSource(tableName, state);\n upParts.push(up);\n // Recreate before other downs so FK deps are satisfied\n downParts.unshift(down);\n }\n }\n\n const isEmpty = upParts.length === 0;\n\n // Down reverses creation order so child tables are dropped before parents\n const up = upParts.join('\\n\\n');\n const down = [...downParts].reverse().join('\\n\\n');\n\n const full = `import type { Knex } from 'knex';\n\nexport async function up(knex: Knex): Promise<void> {\n${isEmpty ? ' // No changes needed' : up}\n}\n\nexport async function down(knex: Knex): Promise<void> {\n${isEmpty ? ' // No changes needed' : down}\n}\n`;\n\n // Build the next snapshot from current entity schemas\n const nextTables: Record<string, DatabaseTableState> = {};\n for (const { schema, tableName } of sorted) {\n nextTables[tableName] = entitySchemaToTableState(schema);\n }\n const nextSnapshot: SchemaSnapshot = { version: 1, tables: nextTables };\n\n return { up, down, full, isEmpty, nextSnapshot };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * @internal\n * Emit `DROP TABLE` (up) and a best-effort `CREATE TABLE` reconstruction\n * (down) from a {@link DatabaseTableState} stored in the snapshot.\n * Called for tables that exist in the previous snapshot but are absent from\n * the current entity set.\n */\nfunction generateDropTableSource(\n tableName: string,\n state: DatabaseTableState\n): { up: string; down: string } {\n const up =\n ` // TODO: review destructive change — dropped table '${tableName}'\\n` +\n ` await knex.schema.dropTableIfExists(${JSON.stringify(tableName)});`;\n\n // Reconstruct CREATE TABLE from snapshot state using specificType for\n // all columns so the raw DB types are preserved faithfully.\n const colLines: string[] = [];\n for (const [colName, col] of Object.entries(state.columns)) {\n let line = ` table.specificType(${JSON.stringify(colName)}, ${JSON.stringify(col.type)})`;\n if (col.nullable) line += '.nullable()';\n else line += '.notNullable()';\n if (col.defaultValue !== null && col.defaultValue !== undefined) {\n line += `.defaultTo(${JSON.stringify(col.defaultValue)})`;\n }\n colLines.push(line + ';');\n }\n for (const fk of state.foreignKeys) {\n colLines.push(\n ` table.foreign(${JSON.stringify(fk.columnName)}).references(${JSON.stringify(fk.foreignColumn)}).inTable(${JSON.stringify(fk.foreignTable)}).onDelete(${JSON.stringify(fk.deleteRule)}).onUpdate(${JSON.stringify(fk.updateRule)});`\n );\n }\n for (const idx of state.indexes) {\n if (idx.unique) {\n colLines.push(\n ` table.unique(${JSON.stringify(idx.columns)}, { indexName: ${JSON.stringify(idx.name)} });`\n );\n } else {\n colLines.push(\n ` table.index(${JSON.stringify(idx.columns)}, ${JSON.stringify(idx.name)});`\n );\n }\n }\n\n const down =\n ` await knex.schema.createTable(${JSON.stringify(tableName)}, (table) => {\\n` +\n colLines.join('\\n') +\n '\\n });';\n\n return { up, down };\n}\n\n/**\n * @internal\n * Extract the body of a MigrationDiff into up/down Knex schema code strings\n * (indented 4 spaces, wrapped in `alterTable` when non-empty).\n * Used by both {@link generateMigration} and {@link generateMigrationsForContext}.\n */\nfunction buildAlterTableFragments(\n diff: MigrationDiff,\n tableName: string\n): { up: string; down: string } {\n const upLines: string[] = [];\n const downLines: string[] = [];\n\n // --- ADD COLUMNS ---\n for (const col of diff.addColumns) {\n const typeCall = col.type.includes(' ')\n ? `table.specificType('${col.name}', '${col.type}')`\n : `table.${mapTypeToKnex(col.type)}('${col.name}')`;\n\n let line = ` ${typeCall}`;\n if (col.nullable) line += '.nullable()';\n else line += '.notNullable()';\n if (col.defaultValue !== undefined) {\n line += `.defaultTo(${formatDefault(col.defaultValue)})`;\n }\n line += ';';\n\n upLines.push(line);\n downLines.push(` table.dropColumn('${col.name}');`);\n }\n\n // --- DROP COLUMNS ---\n for (const col of diff.dropColumns) {\n upLines.push(` table.dropColumn('${col}');`);\n downLines.push(\n ` // TODO: recreate column '${col}' with original definition`\n );\n }\n\n // --- ALTER COLUMNS ---\n for (const col of diff.alterColumns) {\n for (const [key, change] of Object.entries(col.changes)) {\n if (key === 'nullable') {\n if (change.to) {\n upLines.push(` table.setNullable('${col.name}');`);\n downLines.push(\n ` table.dropNullable('${col.name}');`\n );\n } else {\n upLines.push(` table.dropNullable('${col.name}');`);\n downLines.push(` table.setNullable('${col.name}');`);\n }\n } else if (key === 'defaultValue') {\n const toVal = change.to;\n const fromVal = change.from;\n if (toVal === null) {\n upLines.push(\n ` table.timestamp('${col.name}').alter(); // DROP DEFAULT`\n );\n downLines.push(\n ` table.timestamp('${col.name}').defaultTo(knex.fn.now()).alter();`\n );\n } else {\n upLines.push(\n ` table.timestamp('${col.name}').notNullable().defaultTo(knex.fn.now()).alter();`\n );\n downLines.push(\n fromVal === null\n ? ` table.timestamp('${col.name}').notNullable().alter();`\n : ` table.timestamp('${col.name}').notNullable().defaultTo(knex.fn.now()).alter();`\n );\n }\n }\n }\n }\n\n // --- ADD INDEXES ---\n for (const idx of diff.addIndexes) {\n const cols = JSON.stringify(idx.columns);\n if (idx.unique) {\n upLines.push(\n ` table.unique(${cols}${idx.name ? `, { indexName: '${idx.name}' }` : ''});`\n );\n downLines.push(\n ` table.dropUnique(${cols}${idx.name ? `, '${idx.name}'` : ''});`\n );\n } else {\n upLines.push(\n ` table.index(${cols}${idx.name ? `, '${idx.name}'` : ''});`\n );\n downLines.push(\n ` table.dropIndex([]${idx.name ? `, '${idx.name}'` : ''});`\n );\n }\n }\n\n // --- DROP INDEXES ---\n for (const idx of diff.dropIndexes) {\n upLines.push(` table.dropIndex([], '${idx}');`);\n downLines.push(\n ` // TODO: recreate index '${idx}' with original definition`\n );\n }\n\n // --- ADD FOREIGN KEYS ---\n for (const fk of diff.addForeignKeys) {\n let line = ` table.foreign('${fk.column}').references('${fk.foreignColumn}').inTable('${fk.foreignTable}')`;\n if (fk.onDelete) line += `.onDelete('${fk.onDelete}')`;\n if (fk.onUpdate) line += `.onUpdate('${fk.onUpdate}')`;\n line += ';';\n upLines.push(line);\n downLines.push(` table.dropForeign('${fk.column}');`);\n }\n\n // --- DROP FOREIGN KEYS ---\n for (const fk of diff.dropForeignKeys) {\n upLines.push(` // TODO: drop foreign key constraint '${fk}'`);\n }\n\n const isEmpty = upLines.length === 0;\n\n const up = isEmpty\n ? ` // No changes needed`\n : ` await knex.schema.alterTable('${tableName}', (table) => {\\n${upLines.join('\\n')}\\n });`;\n\n const down = isEmpty\n ? ` // No changes needed`\n : ` await knex.schema.alterTable('${tableName}', (table) => {\\n${downLines.join('\\n')}\\n });`;\n\n return { up, down };\n}\n\n/** @internal Build a Knex ColumnBuilder from a PostgreSQL data type string (runtime use). */\nfunction buildColumnFromDbType(\n table: Knex.CreateTableBuilder,\n name: string,\n dbType: string\n): Knex.ColumnBuilder {\n switch (dbType) {\n case 'integer':\n return table.integer(name);\n case 'character varying':\n return table.string(name);\n case 'text':\n return table.text(name);\n case 'boolean':\n return table.boolean(name);\n case 'timestamp without time zone':\n case 'timestamp':\n return table.timestamp(name);\n case 'double precision':\n case 'float':\n return table.float(name);\n case 'jsonb':\n case 'json':\n return table.specificType(name, 'jsonb');\n case 'uuid':\n return table.uuid(name);\n default:\n return table.specificType(name, dbType);\n }\n}\n\nfunction collectUniqueEntityTables(entities: Entity<any, any>[]): {\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n tableName: string;\n}[] {\n const tableEntries: {\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n tableName: string;\n }[] = [];\n\n for (const entity of entities) {\n const schema = entity.schema;\n const tableName = getTableName(schema);\n tableEntries.push({ schema, tableName });\n\n for (const variantSchema of getPolymorphicVariantSchemas(schema)) {\n const variantTableName = variantSchema.getExtension('tableName') as\n | string\n | undefined;\n if (variantTableName) {\n tableEntries.push({\n schema: variantSchema,\n tableName: variantTableName\n });\n }\n }\n }\n\n const seen = new Set<string>();\n return tableEntries.filter(entry => {\n if (seen.has(entry.tableName)) return false;\n seen.add(entry.tableName);\n return true;\n });\n}\n\n/**\n * @internal\n * Topologically sort table entries by FK dependency so parent tables\n * come first in `up` (and last in `down`). Falls back to original order\n * for cycles or external references.\n */\nfunction topologicalSort(\n entries: {\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n tableName: string;\n }[]\n): typeof entries {\n const tableSet = new Set(entries.map(e => e.tableName));\n const deps = new Map<string, Set<string>>();\n\n for (const { schema, tableName } of entries) {\n const depSet = new Set<string>();\n const properties: Record<string, any> =\n (schema.introspect() as any).properties ?? {};\n for (const [, propSchema] of Object.entries(properties)) {\n const ext =\n ((propSchema as any).introspect?.() as any)?.extensions ?? {};\n if (ext.references?.table && tableSet.has(ext.references.table)) {\n depSet.add(ext.references.table);\n }\n }\n deps.set(tableName, depSet);\n }\n\n // Kahn's algorithm\n const inDegree = new Map<string, number>();\n const graph = new Map<string, string[]>(); // dep -> tables that depend on it\n for (const { tableName } of entries) {\n inDegree.set(tableName, 0);\n graph.set(tableName, []);\n }\n for (const { tableName } of entries) {\n for (const dep of deps.get(tableName) ?? []) {\n graph.get(dep)!.push(tableName);\n inDegree.set(tableName, (inDegree.get(tableName) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const [t, deg] of inDegree) {\n if (deg === 0) queue.push(t);\n }\n\n const sortedNames: string[] = [];\n while (queue.length > 0) {\n const t = queue.shift()!;\n sortedNames.push(t);\n for (const dependent of graph.get(t) ?? []) {\n const newDeg = inDegree.get(dependent)! - 1;\n inDegree.set(dependent, newDeg);\n if (newDeg === 0) queue.push(dependent);\n }\n }\n\n // Append any cycles / unresolved entries in their original relative order\n const sortedSet = new Set(sortedNames);\n const remaining = entries.filter(e => !sortedSet.has(e.tableName));\n const byName = new Map(entries.map(e => [e.tableName, e]));\n return [...sortedNames.map(t => byName.get(t)!), ...remaining];\n}\n\n/** @internal Map a PostgreSQL data type string to a Knex column method name. */\nfunction mapTypeToKnex(type: string): string {\n switch (type) {\n case 'integer':\n return 'integer';\n case 'character varying':\n return 'string';\n case 'text':\n return 'text';\n case 'boolean':\n return 'boolean';\n case 'timestamp without time zone':\n case 'timestamp':\n return 'timestamp';\n case 'double precision':\n case 'float':\n return 'float';\n case 'jsonb':\n case 'json':\n return 'jsonb';\n case 'uuid':\n return 'uuid';\n default:\n return `specificType('${type}')` as any;\n }\n}\n\n/** @internal Format a default value for migration code generation. */\nfunction formatDefault(value: any): string {\n if (value === 'now') return 'knex.fn.now()';\n if (typeof value === 'object' && value !== null && value.raw) {\n return `knex.raw('${value.raw.replace(/'/g, \"\\\\'\")}')`;\n }\n if (typeof value === 'string') return `'${value.replace(/'/g, \"\\\\'\")}'`;\n return String(value);\n}\n","// @cleverbrush/knex-schema — Raw query execution with schema result mapping\n\nimport type { InferType, ObjectSchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from './columns.js';\n\n/**\n * Execute a raw SQL query or Knex query builder and map the result rows\n * through the schema's column→property name mapping.\n *\n * This is the escape hatch for complex queries that can't be expressed with\n * the typed `SchemaQueryBuilder` API. The schema is used only for result\n * mapping — column names in the result are converted back to property names.\n * Extra columns (not in the schema) are passed through unchanged.\n *\n * @param knex - A configured Knex instance.\n * @param schema - The `ObjectSchemaBuilder` for result mapping.\n * @param queryOrSql - A raw SQL string or a `Knex.QueryBuilder`.\n * @param bindings - Optional bindings for parameterised SQL queries.\n * @returns Mapped result rows.\n *\n * @example\n * ```ts\n * // Raw SQL with schema result mapping\n * const results = await rawQuery(knex, PostSchema, `\n * SELECT p.*, COUNT(c.id) AS comment_count\n * FROM posts p\n * LEFT JOIN comments c ON c.post_id = p.id\n * GROUP BY p.id\n * ORDER BY comment_count DESC\n * LIMIT ?\n * `, [10]);\n *\n * // Knex query builder as the source\n * const subQuery = knex('posts').select('author_id', knex.raw('COUNT(*) as post_count')).groupBy('author_id');\n * const results = await rawQuery(knex, UserSchema, subQuery);\n * ```\n */\nexport async function rawQuery<\n TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(\n knex: Knex,\n schema: TSchema,\n queryOrSql: string | Knex.QueryBuilder,\n bindings?: any[]\n): Promise<(InferType<TSchema> & Record<string, any>)[]> {\n let rows: any[];\n\n if (typeof queryOrSql === 'string') {\n const result = await knex.raw(queryOrSql, bindings ?? []);\n rows = result.rows ?? result;\n } else {\n rows = await queryOrSql;\n }\n\n if (!rows || !Array.isArray(rows)) return [];\n\n const { colToProp } = buildColumnMap(schema);\n\n return rows.map(row => {\n const mapped: Record<string, any> = {};\n for (const [key, value] of Object.entries(row)) {\n const propName = colToProp.get(key);\n mapped[propName ?? key] = value;\n }\n return mapped;\n }) as any;\n}\n","// @cleverbrush/knex-schema — SELECT / DISTINCT / aggregates / projections / scopes\n\nimport {\n ObjectSchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR\n} from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from '../columns.js';\nimport { getProjections } from '../extension.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type { ColumnRef } from '../types.js';\nimport {\n assertNotExplicitSelect,\n assertNotProjection,\n invalidateCache,\n resolveColumn,\n resolveColumnArg\n} from './helpers.js';\nimport { getState } from './state.js';\n\nexport function selectImpl(\n builder: SchemaQueryBuilder<any, any>,\n ...args: unknown[]\n): any {\n const state = getState(builder);\n\n if (args.length === 1 && typeof args[0] === 'function') {\n const fn = args[0] as (t: any) => unknown;\n const tree = ObjectSchemaBuilder.getPropertiesFor(\n state.localSchema as any\n );\n const result = fn(tree);\n if (\n result &&\n typeof result === 'object' &&\n !(SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in (result as object))\n ) {\n invalidateCache(builder);\n assertNotProjection(builder, 'select');\n state.selectionMode = 'projection';\n state.appliedProjection = '<inline>';\n\n const aliasMap: Record<string, string> = {};\n state.explicitSelects ??= [];\n for (const [alias, descriptor] of Object.entries(\n result as Record<string, unknown>\n )) {\n if (\n !descriptor ||\n typeof descriptor !== 'object' ||\n !(\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in\n (descriptor as object)\n )\n ) {\n throw new Error(\n `select(selector): value for alias \"${alias}\" must be a property descriptor (e.g. \\`t.someProp\\`).`\n );\n }\n const col = resolveColumn(\n builder,\n (() => descriptor) as ColumnRef<any>,\n `select(selector).${alias}`\n );\n aliasMap[alias] = col as string;\n state.explicitSelects.push(col as string);\n }\n state.baseQuery.select(aliasMap);\n return builder;\n }\n }\n\n invalidateCache(builder);\n assertNotProjection(builder, 'select');\n state.selectionMode = 'select';\n const resolved = (args as (ColumnRef<any> | Knex.Raw)[]).map(c =>\n resolveColumnArg(builder, c)\n );\n state.baseQuery.select(...(resolved as string[]));\n state.explicitSelects ??= [];\n for (const r of resolved) {\n if (typeof r === 'string') {\n state.explicitSelects.push(r);\n }\n }\n return builder;\n}\n\nexport function distinctImpl(\n builder: SchemaQueryBuilder<any, any>,\n ...columns: (ColumnRef<any> | Knex.Raw)[]\n): any {\n invalidateCache(builder);\n const resolved = columns.map(c => resolveColumnArg(builder, c));\n getState(builder).baseQuery.distinct(...(resolved as string[]));\n return builder;\n}\n\nexport function countImpl(\n builder: SchemaQueryBuilder<any, any>,\n column?: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'count');\n state.selectionMode = 'aggregate';\n if (column) {\n state.baseQuery.count(resolveColumnArg(builder, column) as string);\n } else {\n state.baseQuery.count();\n }\n return builder;\n}\n\nexport function countDistinctImpl(\n builder: SchemaQueryBuilder<any, any>,\n column?: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'countDistinct');\n state.selectionMode = 'aggregate';\n if (column) {\n state.baseQuery.countDistinct(\n resolveColumnArg(builder, column) as string\n );\n } else {\n state.baseQuery.countDistinct();\n }\n return builder;\n}\n\nexport function minImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'min');\n state.selectionMode = 'aggregate';\n state.baseQuery.min(resolveColumnArg(builder, column) as string);\n return builder;\n}\n\nexport function maxImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'max');\n state.selectionMode = 'aggregate';\n state.baseQuery.max(resolveColumnArg(builder, column) as string);\n return builder;\n}\n\nexport function sumImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'sum');\n state.selectionMode = 'aggregate';\n state.baseQuery.sum(resolveColumnArg(builder, column) as string);\n return builder;\n}\n\nexport function avgImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n assertNotProjection(builder, 'avg');\n state.selectionMode = 'aggregate';\n state.baseQuery.avg(resolveColumnArg(builder, column) as string);\n return builder;\n}\n\nexport function selectRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n bindings?: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (bindings) {\n state.baseQuery.select(state.knex.raw(sql, bindings));\n } else {\n state.baseQuery.select(state.knex.raw(sql));\n }\n return builder;\n}\n\nexport function projectedImpl(\n builder: SchemaQueryBuilder<any, any>,\n name: string\n): any {\n const state = getState(builder);\n assertNotExplicitSelect(builder, 'projected');\n if (state.selectionMode === 'projection') {\n throw new Error(\n `Cannot call .projected('${name}') — .projected('${\n state.appliedProjection\n }') was already applied. Only one projection per query.`\n );\n }\n const projections = getProjections(state.localSchema as any);\n const projection = projections[name];\n if (!projection) {\n throw new Error(\n `Unknown projection \"${name}\" on schema for table \"${\n state.tableName\n }\"`\n );\n }\n const { propToCol } = buildColumnMap(state.localSchema as any);\n const sqlCols = projection.keys.map(key => propToCol.get(key) ?? key);\n state.baseQuery.select(...sqlCols);\n state.explicitSelects ??= [];\n for (const col of sqlCols) {\n state.explicitSelects.push(col);\n }\n state.selectionMode = 'projection';\n state.appliedProjection = name;\n invalidateCache(builder);\n return builder;\n}\n\nexport function scopedImpl(\n builder: SchemaQueryBuilder<any, any>,\n name: string\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const scopes = (state.localSchema as any).getExtension?.('scopes') as\n | Record<string, Function>\n | undefined;\n const scopeFn = scopes?.[name];\n if (!scopeFn) {\n throw new Error(\n `Unknown scope \"${name}\" on schema for table \"${state.tableName}\"`\n );\n }\n scopeFn(builder);\n return builder;\n}\n\nexport function unscopedImpl(builder: SchemaQueryBuilder<any, any>): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.skipDefaultScope = true;\n state.includeDeleted = true;\n return builder;\n}\n","// @cleverbrush/knex-schema — Extracted helper functions from SchemaQueryBuilder\n\nimport type { InferType } from '@cleverbrush/schema';\nimport {\n EXTRA_TYPE_BRAND,\n METHOD_LITERAL_BRAND,\n ObjectSchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR\n} from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport {\n buildColumnMap,\n getPrimaryKeyColumns,\n resolveColumnRef\n} from '../columns.js';\nimport {\n getTableName,\n getVariants,\n POLYMORPHIC_TYPE_BRAND\n} from '../extension.js';\nimport { clearRow } from '../mappers.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type {\n ColumnRef,\n ResolvedVariantConfig,\n ResolvedVariantRelationSpec,\n ValidatedSpec\n} from '../types.js';\nimport { getState } from './state.js';\n\n// ---------------------------------------------------------------------------\n// Type-level helpers\n// ---------------------------------------------------------------------------\n\nexport type ScopesOf<S> = S extends {\n readonly [METHOD_LITERAL_BRAND]?: infer N;\n}\n ? Extract<N, string>\n : never;\n\nexport type ProjectionsOf<S> = S extends {\n readonly [EXTRA_TYPE_BRAND]?: infer P;\n}\n ? P extends Record<string, readonly string[]>\n ? P\n : Record<never, never>\n : Record<never, never>;\n\nexport type ProjectionKeysOf<\n S,\n K extends keyof ProjectionsOf<S> & string\n> = ProjectionsOf<S>[K] extends readonly (infer T extends string)[]\n ? T\n : string;\n\nexport type QueryResultType<TLocalSchema> = TLocalSchema extends {\n readonly [POLYMORPHIC_TYPE_BRAND]?: infer U;\n}\n ? NonNullable<U>\n : InferType<TLocalSchema>;\n\n// ---------------------------------------------------------------------------\n// State-based helpers\n// ---------------------------------------------------------------------------\n\nexport function resolveColumn(\n builder: SchemaQueryBuilder<any, any>,\n ref: any,\n label = 'column'\n): string | Knex.Raw {\n const state = getState(builder);\n return resolveColumnRef(\n ref as ColumnRef<any>,\n state.localSchema,\n label,\n state.knex\n );\n}\n\nexport function invalidateCache(builder: SchemaQueryBuilder<any, any>): void {\n getState(builder).cachedBuiltQuery = null;\n}\n\nexport function getSoftDelete(\n builder: SchemaQueryBuilder<any, any>\n): { column: string } | null {\n const state = getState(builder);\n const ext = (state.localSchema as any).getExtension?.('softDelete');\n return ext ?? null;\n}\n\nexport function getDefaultScope(\n builder: SchemaQueryBuilder<any, any>\n): Function | null {\n const state = getState(builder);\n const fn = (state.localSchema as any).getExtension?.('defaultScope');\n return typeof fn === 'function' ? fn : null;\n}\n\nexport function getTimestamps(\n builder: SchemaQueryBuilder<any, any>\n): { createdAt: string; updatedAt: string } | null {\n const state = getState(builder);\n const ts = (state.localSchema as any).getExtension?.('timestamps');\n return ts ?? null;\n}\n\nconst ALLOWED_OPS = new Set([\n '=',\n '!=',\n '<>',\n '<',\n '>',\n '<=',\n '>=',\n 'like',\n 'not like',\n 'ilike',\n 'not ilike',\n 'in',\n 'not in',\n 'is',\n 'is not'\n]);\n\nexport { ALLOWED_OPS };\n\nexport function getVariantConfig(\n builder: SchemaQueryBuilder<any, any>\n): ResolvedVariantConfig | null {\n const state = getState(builder);\n if (state.variantConfig !== undefined) return state.variantConfig;\n\n const raw = getVariants(state.localSchema);\n if (!raw) {\n state.variantConfig = null;\n return null;\n }\n\n const { propToCol } = buildColumnMap(state.localSchema);\n const discCol = propToCol.get(raw.discriminatorKey) ?? raw.discriminatorKey;\n\n state.variantConfig = {\n ...raw,\n discriminatorColumn: discCol\n };\n return state.variantConfig;\n}\n\nexport function applyVariantJoins(\n builder: SchemaQueryBuilder<any, any>,\n base: Knex.QueryBuilder,\n variantConfig: ResolvedVariantConfig\n): Knex.QueryBuilder {\n const state = getState(builder);\n const knex = state.knex;\n const baseTable = state.tableName;\n const basePkCol = findPrimaryKeyColumn(builder, state.localSchema);\n const discCol = variantConfig.discriminatorColumn;\n\n const qb = base.clone().select(`${baseTable}.*`);\n\n for (const [key, spec] of Object.entries(variantConfig.variants)) {\n if (state.enabledVariants !== null && !state.enabledVariants.has(key))\n continue;\n\n if (spec.storage === 'cti') {\n const variantAlias = `__v_${key}`;\n const variantTable = spec.tableName!;\n const fkCol = spec.foreignKey!;\n\n qb.leftJoin(\n `${variantTable} as ${variantAlias}`,\n knex.raw(`?? = ?? AND ?? = ?`, [\n `${variantAlias}.${fkCol}`,\n `${baseTable}.${basePkCol}`,\n `${baseTable}.${discCol}`,\n key\n ])\n );\n\n const { propToCol } = buildColumnMap(spec.schema);\n const variantIntrospect = spec.schema.introspect() as any;\n const variantProps: Record<string, unknown> =\n variantIntrospect.properties ?? {};\n\n for (const propKey of Object.keys(variantProps)) {\n const colName = propToCol.get(propKey) ?? propKey;\n qb.select(\n knex.raw('?? as ??', [\n `${variantAlias}.${colName}`,\n `${variantAlias}__${colName}`\n ])\n );\n }\n }\n }\n\n for (const vrInc of state.variantRelationIncludes) {\n const variantSpec = variantConfig.variants[vrInc.variantKey];\n if (!variantSpec) continue;\n\n const relSpec = variantSpec.relations.find(\n (r: ResolvedVariantRelationSpec) => r.name === vrInc.relationName\n );\n if (!relSpec) continue;\n\n const foreignSchema = resolveSchema(builder, relSpec.schema);\n const foreignTableName = getTableName(foreignSchema);\n const relAlias = `__v_${vrInc.variantKey}__rel_${vrInc.relationName}`;\n\n if (relSpec.type === 'belongsTo' || relSpec.type === 'hasOne') {\n let localCol: string;\n let foreignCol: string;\n\n if (relSpec.type === 'belongsTo') {\n localCol =\n relSpec.foreignKey ??\n ((): string => {\n throw new Error(\n `includeVariant: relation \"${vrInc.relationName}\" on variant \"${vrInc.variantKey}\" requires foreignKey`\n );\n })();\n foreignCol = findPrimaryKeyColumn(builder, foreignSchema);\n } else {\n localCol = findPrimaryKeyColumn(builder, state.localSchema);\n foreignCol =\n relSpec.foreignKey ??\n ((): string => {\n throw new Error(\n `includeVariant: relation \"${vrInc.relationName}\" on variant \"${vrInc.variantKey}\" requires foreignKey`\n );\n })();\n }\n\n let onExpr: string;\n const variantAlias = `__v_${vrInc.variantKey}`;\n\n if (variantSpec.storage === 'cti') {\n if (relSpec.type === 'belongsTo') {\n onExpr = `${relAlias}.${foreignCol} = ${variantAlias}.${localCol} AND ${baseTable}.${discCol} = '${vrInc.variantKey}'`;\n } else {\n onExpr = `${relAlias}.${foreignCol} = ${baseTable}.${localCol} AND ${baseTable}.${discCol} = '${vrInc.variantKey}'`;\n }\n } else {\n if (relSpec.type === 'belongsTo') {\n onExpr = `${relAlias}.${foreignCol} = ${baseTable}.${localCol} AND ${baseTable}.${discCol} = '${vrInc.variantKey}'`;\n } else {\n onExpr = `${relAlias}.${foreignCol} = ${baseTable}.${localCol} AND ${baseTable}.${discCol} = '${vrInc.variantKey}'`;\n }\n }\n\n const foreignKnex: Knex.QueryBuilder = state.knex(foreignTableName);\n\n const selectionSql = buildVariantRelationSelect(\n builder,\n foreignSchema,\n relAlias,\n foreignTableName,\n vrInc.customize\n );\n\n qb.leftJoin(\n knex.raw(`?? as ??`, [foreignTableName, relAlias]),\n knex.raw(onExpr)\n );\n void foreignKnex;\n\n for (const sel of selectionSql) {\n qb.select(sel);\n }\n }\n }\n\n for (const filter of state.variantWhereFilters) {\n const discColFull = `${baseTable}.${discCol}`;\n qb.where(function (this: Knex.QueryBuilder) {\n this.where(discColFull, filter.key)\n .andWhere(filter.qualifiedColumn, filter.op, filter.value)\n .orWhere(discColFull, '!=', filter.key);\n });\n }\n\n if (state.enabledVariants !== null) {\n qb.whereIn(`${baseTable}.${discCol}`, [...state.enabledVariants]);\n }\n\n return qb;\n}\n\n// Circular-dependency-safe SchemaQueryBuilder constructor reference\n// Set by SchemaQueryBuilder.ts after the class is defined.\nlet SchemaQueryBuilderCtor: new (...args: any[]) => any = null!;\nexport function registerSchemaQueryBuilder(\n ctor: new (...args: any[]) => any\n): void {\n SchemaQueryBuilderCtor = ctor;\n}\nexport function getSchemaQueryBuilderCtor(): new (...args: any[]) => any {\n return SchemaQueryBuilderCtor;\n}\n\nexport function buildVariantRelationSelect(\n builder: SchemaQueryBuilder<any, any>,\n foreignSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n relAlias: string,\n foreignTableName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n): Knex.Raw[] {\n const state = getState(builder);\n const knex = state.knex;\n const { propToCol } = buildColumnMap(foreignSchema);\n const foreignIntrospect = foreignSchema.introspect() as any;\n const foreignProps: Record<string, unknown> =\n foreignIntrospect.properties ?? {};\n\n let columnsToSelect: string[];\n\n if (customize) {\n const probe = new (SchemaQueryBuilderCtor as any)(\n state.knex,\n foreignSchema,\n state.knex(foreignTableName)\n );\n customize(probe);\n const state2 = getState(probe);\n const explicit = state2.explicitSelects;\n if (explicit && explicit.length > 0) {\n columnsToSelect = explicit;\n } else {\n columnsToSelect = Object.keys(foreignProps).map(\n p => propToCol.get(p) ?? p\n );\n }\n } else {\n columnsToSelect = Object.keys(foreignProps).map(\n p => propToCol.get(p) ?? p\n );\n }\n\n return columnsToSelect.map(colName =>\n knex.raw('?? as ??', [\n `${relAlias}.${colName}`,\n `${relAlias}__${colName}`\n ])\n );\n}\n\nexport function mapPolymorphicRow(\n builder: SchemaQueryBuilder<any, any>,\n row: Record<string, any>,\n variantConfig: ResolvedVariantConfig\n): Record<string, any> {\n const state = getState(builder);\n const { colToProp: baseColToProp } = buildColumnMap(state.localSchema);\n const result: Record<string, any> = {};\n\n for (const [colName, value] of Object.entries(row)) {\n if (colName.startsWith('__v_')) continue;\n const propName = baseColToProp.get(colName);\n if (propName) {\n result[propName] = value;\n } else {\n result[colName] = value;\n }\n }\n\n const discPropKey = variantConfig.discriminatorKey;\n const discValue: string | undefined = result[discPropKey];\n\n if (discValue != null) {\n const variantSpec = variantConfig.variants[discValue];\n if (variantSpec) {\n if (variantSpec.storage === 'cti') {\n const { colToProp: varColToProp } = buildColumnMap(\n variantSpec.schema\n );\n const variantAlias = `__v_${discValue}`;\n const prefix = `${variantAlias}__`;\n const fkCol = variantSpec.foreignKey;\n\n if (fkCol) {\n const fkAlias = `${prefix}${fkCol}`;\n if (!variantSpec.allowOrphan && row[fkAlias] == null) {\n throw new Error(\n `Polymorphic orphan: \"${discPropKey}\" = \"${discValue}\" ` +\n `but no matching row found in variant table ` +\n `\"${variantSpec.tableName}\". ` +\n `Set allowOrphan: true on this variant to suppress.`\n );\n }\n }\n\n for (const [colName, value] of Object.entries(row)) {\n if (!colName.startsWith(prefix)) continue;\n const origCol = colName.slice(prefix.length);\n if (origCol === fkCol) continue;\n const propName = varColToProp.get(origCol) ?? origCol;\n result[propName] = value;\n }\n } else {\n const { colToProp: varColToProp } = buildColumnMap(\n variantSpec.schema\n );\n for (const [colName, value] of Object.entries(row)) {\n if (colName.startsWith('__v_')) continue;\n if (baseColToProp.has(colName)) continue;\n const propName = varColToProp.get(colName);\n if (propName) {\n result[propName] = value;\n }\n }\n }\n }\n }\n\n if (state.variantRelationIncludes.length > 0 && discValue != null) {\n const variantSpec3 = variantConfig.variants[discValue];\n if (variantSpec3) {\n for (const vrInc of state.variantRelationIncludes) {\n if (vrInc.variantKey !== discValue) continue;\n\n const relSpec = variantSpec3.relations.find(\n (r: ResolvedVariantRelationSpec) =>\n r.name === vrInc.relationName\n );\n if (!relSpec) continue;\n\n if (relSpec.type === 'belongsTo' || relSpec.type === 'hasOne') {\n const relAlias = `__v_${discValue}__rel_${vrInc.relationName}`;\n const prefix = `${relAlias}__`;\n const foreignSchema = resolveSchema(\n builder,\n relSpec.schema\n );\n const { colToProp: relColToProp } =\n buildColumnMap(foreignSchema);\n const nested: Record<string, unknown> = {};\n let anyNonNull = false;\n\n for (const [colName, value] of Object.entries(row)) {\n if (!colName.startsWith(prefix)) continue;\n const origCol = colName.slice(prefix.length);\n const propName = relColToProp.get(origCol) ?? origCol;\n nested[propName] = value;\n if (value !== null && value !== undefined) {\n anyNonNull = true;\n }\n }\n result[vrInc.relationName] = anyNonNull ? nested : null;\n }\n }\n }\n }\n\n return result;\n}\n\nexport function resolveSchema(\n _builder: SchemaQueryBuilder<any, any>,\n schema: any\n): ObjectSchemaBuilder<any, any, any, any, any, any, any> {\n return typeof schema === 'function' ? schema() : schema;\n}\n\nexport function findPrimaryKeyColumn(\n _builder: SchemaQueryBuilder<any, any>,\n schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>\n): string {\n const pk = getPrimaryKeyColumns(schema);\n if (pk.columnNames.length > 0) return pk.columnNames[0];\n return 'id';\n}\n\nexport function resolvePkColumns(builder: SchemaQueryBuilder<any, any>): {\n propertyKeys: readonly string[];\n columnNames: readonly string[];\n} {\n const state = getState(builder);\n const pk = getPrimaryKeyColumns(state.localSchema as any);\n if (pk.columnNames.length === 0) {\n throw new Error(\n 'No primary key declared on this schema. Use `.primaryKey()` on a column or `.hasPrimaryKey([...])` on the schema.'\n );\n }\n return pk;\n}\n\nexport function getEffectiveBaseQuery(\n builder: SchemaQueryBuilder<any, any>\n): Knex.QueryBuilder {\n const state = getState(builder);\n let effectiveBase = state.baseQuery;\n let cloned = false;\n\n const softDelete = getSoftDelete(builder);\n if (softDelete && state.onlyDeleted) {\n if (!cloned) {\n effectiveBase = effectiveBase.clone();\n cloned = true;\n }\n effectiveBase.whereNotNull(softDelete.column);\n } else if (softDelete && !state.includeDeleted) {\n if (!cloned) {\n effectiveBase = effectiveBase.clone();\n cloned = true;\n }\n effectiveBase.whereNull(softDelete.column);\n }\n\n if (!state.skipDefaultScope) {\n const defaultScopeFn = getDefaultScope(builder);\n if (defaultScopeFn) {\n if (!cloned) {\n effectiveBase = effectiveBase.clone();\n cloned = true;\n }\n const proxy = new (SchemaQueryBuilderCtor as any)(\n state.knex,\n state.localSchema,\n effectiveBase\n );\n const proxyState = getState(proxy);\n proxyState.skipDefaultScope = true;\n defaultScopeFn(proxy);\n }\n }\n\n return effectiveBase;\n}\n\nexport function buildJoinOne(\n builder: SchemaQueryBuilder<any, any>,\n resultQuery: Knex.QueryBuilder,\n spec: ValidatedSpec & { type: 'one' },\n relationAlias: string\n): void {\n const state = getState(builder);\n const knex = state.knex;\n const foreignTable = spec.foreignQuery;\n const foreignTableName = (foreignTable as any)._single?.table;\n\n if (!foreignTableName) {\n throw new Error(\n `Could not determine table name from foreignQuery for \"${spec.as}\". ` +\n 'Make sure foreignQuery is created via knex(\"tableName\").'\n );\n }\n\n resultQuery.select(\n knex.raw(':relationAlias:.:as:->0 as :as:', {\n relationAlias,\n as: spec.as\n })\n );\n\n const subquery = knex\n .from(foreignTable.as(foreignTableName))\n .select(\n knex.raw(':foreignTable:.:foreignColumn:', {\n foreignTable: foreignTableName,\n foreignColumn: spec.foreignColumn\n })\n )\n .select(\n knex.raw('jsonb_agg(:foreignTable:) as :as:', {\n foreignTable: foreignTableName,\n as: spec.as\n })\n )\n .groupByRaw(':foreignTable:.:foreignColumn:', {\n foreignTable: foreignTableName,\n foreignColumn: spec.foreignColumn\n })\n .as(relationAlias);\n\n const joinMethod = spec.required ? 'join' : 'leftJoin';\n resultQuery[joinMethod](subquery, function () {\n this.on(\n knex.raw(\n ':relationAlias:.:foreignColumn: = :originalQuery:.:localColumn:',\n {\n originalQuery: 'originalQuery',\n relationAlias,\n foreignColumn: spec.foreignColumn,\n localColumn: spec.localColumn\n }\n )\n );\n });\n}\n\nexport function buildJoinMany(\n builder: SchemaQueryBuilder<any, any>,\n resultQuery: Knex.QueryBuilder,\n spec: ValidatedSpec & { type: 'many' },\n relationAlias: string,\n i: number\n): void {\n const state = getState(builder);\n const knex = state.knex;\n const filterName = `withFilter${i}`;\n\n const hasLimitOffset =\n (spec.limit !== null && spec.limit > 0) ||\n (spec.offset !== null && spec.offset > 0);\n\n const orderByColumn = spec.orderBy\n ? spec.orderBy.column\n : spec.foreignColumn;\n const orderByDirection = spec.orderBy ? spec.orderBy.direction : 'asc';\n\n if (hasLimitOffset) {\n resultQuery.with(\n filterName,\n knex\n .from(\n spec.foreignQuery\n .clone()\n .whereIn(\n spec.foreignColumn,\n knex\n .from(\n knex.raw(':originalQuery:', {\n originalQuery: 'originalQuery'\n })\n )\n .distinct(spec.localColumn)\n .as(`__wf_inner_${i}`)\n )\n .as(`__wf_inner_${i}`)\n )\n .select(`__wf_inner_${i}.*`)\n .select(\n knex.raw(\n `row_number() over(partition by :foreignColumn: order by :orderByColumn: ${orderByDirection}) as \"__rn__\"`,\n {\n foreignColumn: spec.foreignColumn,\n orderByColumn\n }\n )\n )\n );\n } else {\n resultQuery.with(\n filterName,\n spec.foreignQuery.clone().whereIn(\n spec.foreignColumn,\n knex\n .from(\n knex.raw(':originalQuery:', {\n originalQuery: 'originalQuery'\n })\n )\n .distinct(spec.localColumn)\n )\n );\n }\n\n const aggSubquery = knex.from(filterName);\n\n if (hasLimitOffset) {\n const hasLimit = spec.limit !== null && spec.limit > 0;\n const hasOffset = spec.offset !== null && spec.offset > 0;\n const effectiveOffset = spec.offset ?? 0;\n const effectiveLimit = effectiveOffset + (spec.limit ?? 0);\n\n const condition =\n hasLimit && hasOffset\n ? '\"__rn__\" > :offset and \"__rn__\" <= :limit'\n : hasLimit\n ? '\"__rn__\" <= :limit'\n : '\"__rn__\" > :offset';\n\n aggSubquery.whereRaw(condition, {\n limit: effectiveLimit,\n offset: effectiveOffset\n });\n\n aggSubquery.select(\n knex.raw(':foreignColumn:', {\n foreignColumn: spec.foreignColumn\n })\n );\n aggSubquery.select(\n knex.raw(\n \"coalesce(jsonb_agg(to_jsonb(:filterName:) - '__rn__' order by \\\"__rn__\\\"), '[]'::jsonb) as :as:\",\n { filterName, as: spec.as }\n )\n );\n } else {\n aggSubquery.select(\n knex.raw(':foreignColumn:', {\n foreignColumn: spec.foreignColumn\n })\n );\n\n const orderClause = spec.orderBy\n ? `jsonb_agg(:filterName: order by :filterName:.:orderByColumn: ${orderByDirection})`\n : 'jsonb_agg(:filterName:)';\n\n aggSubquery.select(\n knex.raw(\n `coalesce(${orderClause}, '[]'::jsonb) as :as:`,\n spec.orderBy\n ? { filterName, orderByColumn, as: spec.as }\n : { filterName, as: spec.as }\n )\n );\n }\n\n aggSubquery.groupByRaw(':foreignColumn:', {\n foreignColumn: spec.foreignColumn\n });\n\n const subquery = aggSubquery.as(relationAlias);\n\n resultQuery.select(\n knex.raw(\"coalesce(:relationAlias:.:as:, '[]'::jsonb) as :as:\", {\n relationAlias,\n as: spec.as\n })\n );\n\n resultQuery.leftJoin(subquery, function () {\n this.on(\n knex.raw(\n ':relationAlias:.:foreignColumn: = :originalQuery:.:localColumn:',\n {\n relationAlias,\n foreignColumn: spec.foreignColumn,\n originalQuery: 'originalQuery',\n localColumn: spec.localColumn\n }\n )\n );\n });\n}\n\nexport function buildQuery(\n builder: SchemaQueryBuilder<any, any>\n): Knex.QueryBuilder {\n const state = getState(builder);\n const effectiveBase = getEffectiveBaseQuery(builder);\n\n const variantConfig = getVariantConfig(builder);\n const queryBase = variantConfig\n ? applyVariantJoins(builder, effectiveBase, variantConfig)\n : effectiveBase;\n\n if (state.specs.length === 0) {\n return queryBase;\n }\n\n const knex = state.knex;\n const specs = state.specs;\n\n const requiredLocalColumns = [...new Set(specs.map(s => s.localColumn))];\n\n let cteQuery = queryBase;\n let extraColumns: string[] = [];\n\n if (state.explicitSelects !== null) {\n const selectedSet = new Set(state.explicitSelects);\n extraColumns = requiredLocalColumns.filter(\n col => !selectedSet.has(col)\n );\n if (extraColumns.length > 0) {\n cteQuery = queryBase.clone();\n for (const col of extraColumns) {\n cteQuery.column(col);\n }\n }\n }\n\n const resultQuery = knex.queryBuilder().with('originalQuery', cteQuery);\n\n if (extraColumns.length > 0 && state.explicitSelects !== null) {\n for (const col of state.explicitSelects) {\n resultQuery.select(\n knex.raw(':originalQuery:.:col: as :col:', {\n originalQuery: 'originalQuery',\n col\n })\n );\n }\n } else {\n resultQuery.select('originalQuery.*');\n }\n\n resultQuery.from(\n knex.raw(':originalQuery:', {\n originalQuery: 'originalQuery'\n })\n );\n\n for (let i = 0; i < specs.length; i++) {\n const spec = specs[i];\n const relationAlias = `eagerRelation${i}`;\n\n if (spec.type === 'one') {\n buildJoinOne(builder, resultQuery, spec, relationAlias);\n } else {\n buildJoinMany(builder, resultQuery, spec, relationAlias, i);\n }\n }\n\n return resultQuery;\n}\n\nexport function getQuery(\n builder: SchemaQueryBuilder<any, any>\n): Knex.QueryBuilder {\n const state = getState(builder);\n if (!state.cachedBuiltQuery) {\n state.cachedBuiltQuery = buildQuery(builder);\n }\n return state.cachedBuiltQuery;\n}\n\nexport function mapRow(\n builder: SchemaQueryBuilder<any, any>,\n row: Record<string, any>\n): Record<string, any> {\n if (!row) return row;\n\n const variantConfig = getVariantConfig(builder);\n if (variantConfig) {\n return mapPolymorphicRow(builder, row, variantConfig);\n }\n\n const state = getState(builder);\n const { colToProp } = buildColumnMap(state.localSchema);\n const result: Record<string, any> = {};\n\n for (const [colName, value] of Object.entries(row)) {\n const propName = colToProp.get(colName);\n if (propName) {\n result[propName] = value;\n } else {\n result[colName] = value;\n }\n }\n\n return result;\n}\n\nexport function cleanAndMapRow(\n builder: SchemaQueryBuilder<any, any>,\n row: Record<string, any>\n): Record<string, any> {\n const state = getState(builder);\n const oneSpecs = state.specs.filter(\n (s): s is ValidatedSpec & { type: 'one' } => s.type === 'one'\n );\n const manySpecs = state.specs.filter(\n (s): s is ValidatedSpec & { type: 'many' } => s.type === 'many'\n );\n const cleaned = clearRow(row, oneSpecs, manySpecs);\n return mapRow(builder, cleaned);\n}\n\nexport function mapObjectToColumns(\n builder: SchemaQueryBuilder<any, any>,\n obj: Record<string, any>\n): Record<string, any> {\n const state = getState(builder);\n const { propToCol } = buildColumnMap(state.localSchema);\n const result: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const colName = propToCol.get(key);\n if (colName) {\n result[colName] = value;\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nexport function mapRecordToColumns(\n builder: SchemaQueryBuilder<any, any>,\n record: Record<string, any>\n): Record<string, any> {\n return mapObjectToColumns(builder, record);\n}\n\nexport function resolveColumnArg(\n builder: SchemaQueryBuilder<any, any>,\n col: any\n): string | Knex.Raw {\n if (typeof col === 'string') {\n return resolveColumn(builder, col, 'column');\n }\n if (typeof col === 'function') {\n return resolveColumn(builder, col, 'column');\n }\n return col;\n}\n\nexport function isColumnAccessor(\n builder: SchemaQueryBuilder<any, any>,\n fn: Function\n): boolean {\n const state = getState(builder);\n try {\n const tree = ObjectSchemaBuilder.getPropertiesFor(\n state.localSchema as any\n );\n const result = fn(tree);\n if (\n result &&\n typeof result === 'object' &&\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR in result\n ) {\n return true;\n }\n } catch {}\n return false;\n}\n\nexport function assertNotProjection(\n builder: SchemaQueryBuilder<any, any>,\n method: string\n): void {\n const state = getState(builder);\n if (state.selectionMode === 'projection') {\n throw new Error(\n `Cannot call .${method}() after .projected('${\n state.appliedProjection\n }'). Choose one column-selection mode per query.`\n );\n }\n}\n\nexport function assertNotExplicitSelect(\n builder: SchemaQueryBuilder<any, any>,\n method: string\n): void {\n const state = getState(builder);\n if (state.selectionMode === 'select') {\n throw new Error(\n `Cannot call .${method}() after .select(). Choose one column-selection mode per query.`\n );\n }\n if (state.selectionMode === 'aggregate') {\n throw new Error(\n `Cannot call .${method}() after an aggregate method. Choose one column-selection mode per query.`\n );\n }\n if (state.selectionMode === 'projection') {\n throw new Error(\n `Cannot call .${method}() after .projected('${\n state.appliedProjection\n }'). Choose one column-selection mode per query.`\n );\n }\n}\n","// @cleverbrush/knex-schema — Shared mutable state store for SchemaQueryBuilder\n\nimport type { ObjectSchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type {\n ResolvedVariantConfig,\n ValidatedSpec,\n VariantWhereFilter\n} from '../types.js';\n\nexport interface QueryBuilderState {\n knex: Knex;\n baseQuery: Knex.QueryBuilder;\n localSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n specs: ValidatedSpec[];\n tableName: string;\n\n /** SQL column names explicitly passed to `.select()`. null = SELECT *. */\n explicitSelects: string[] | null;\n\n /** Column-selection mode: null, 'select', 'aggregate', or 'projection'. */\n selectionMode: 'select' | 'aggregate' | 'projection' | null;\n\n /** Name of the projection currently applied, for error messages. */\n appliedProjection: string | null;\n\n /** When true, soft-delete filter is NOT applied. */\n includeDeleted: boolean;\n\n /** When true, only soft-deleted rows are returned. */\n onlyDeleted: boolean;\n\n /** When true, default scope is not applied. */\n skipDefaultScope: boolean;\n\n /** Resolved variant config, lazily populated. undefined = not yet read; null = not polymorphic. */\n variantConfig: ResolvedVariantConfig | null | undefined;\n\n /** When set, only these discriminator values are returned. null = all variants. */\n enabledVariants: Set<string> | null;\n\n /** Pending per-variant WHERE filters registered via .whereVariant(). */\n variantWhereFilters: VariantWhereFilter[];\n\n /** Variant-relation eager-load requests registered via .includeVariant(). */\n variantRelationIncludes: Array<{\n variantKey: string;\n relationName: string;\n customize?: (q: SchemaQueryBuilder<any, any>) => void;\n }>;\n\n /** Memoized result of buildQuery(). null = needs rebuild. */\n cachedBuiltQuery: Knex.QueryBuilder | null;\n}\n\nconst STATE = new WeakMap<SchemaQueryBuilder<any, any>, QueryBuilderState>();\n\nexport function getState(\n builder: SchemaQueryBuilder<any, any>\n): QueryBuilderState {\n const s = STATE.get(builder);\n if (!s) {\n throw new Error(\n 'SchemaQueryBuilder state not found — builder was not properly initialized'\n );\n }\n return s;\n}\n\nexport function setState(\n builder: SchemaQueryBuilder<any, any>,\n state: QueryBuilderState\n): void {\n STATE.set(builder, state);\n}\n","// @cleverbrush/knex-schema — INSERT / upsert / bulk operations\n\nimport type { InferType, ObjectSchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap, resolveColumnRef } from '../columns.js';\nimport { getTableName } from '../extension.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type { ColumnRef, InsertType } from '../types.js';\nimport {\n getTimestamps,\n mapObjectToColumns,\n mapRow,\n resolveColumn\n} from './helpers.js';\nimport { getState } from './state.js';\n\n// ---------------------------------------------------------------------------\n// OnConflictBuilder\n// ---------------------------------------------------------------------------\n\ntype AnyObjectSchema = ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n\n/**\n * Helpers available to `onConflict().merge()` update expressions and\n * conditional `where` callbacks.\n */\nexport interface OnConflictMergeHelpers<TLocalSchema extends AnyObjectSchema> {\n /** The Knex instance used by the query builder. */\n readonly knex: Knex;\n\n /**\n * Resolve a schema property reference to its mapped database column name.\n */\n column(ref: ColumnRef<TLocalSchema>): string;\n\n /**\n * Create a raw SQL expression with Knex bindings.\n */\n raw(sql: string, bindings?: readonly unknown[]): Knex.Raw;\n\n /**\n * Reference the `excluded.<column>` value in an upsert merge expression.\n */\n excluded(ref: ColumnRef<TLocalSchema>): Knex.Raw;\n}\n\n/**\n * Value accepted in explicit `onConflict().merge(data, updateData)` payloads.\n */\nexport type OnConflictUpdateValue<\n TLocalSchema extends AnyObjectSchema,\n TValue\n> =\n | TValue\n | Knex.Raw\n | ((helpers: OnConflictMergeHelpers<TLocalSchema>) => TValue | Knex.Raw);\n\n/**\n * Explicit update payload accepted by `onConflict().merge()`.\n */\nexport type OnConflictUpdateData<TLocalSchema extends AnyObjectSchema> =\n Partial<{\n [K in keyof InferType<TLocalSchema>]: OnConflictUpdateValue<\n TLocalSchema,\n InferType<TLocalSchema>[K]\n >;\n }>;\n\n/**\n * Options for `onConflict().merge()`.\n */\nexport interface OnConflictMergeOptions<TLocalSchema extends AnyObjectSchema> {\n /**\n * Attach a conditional `WHERE` clause to the generated merge.\n *\n * This is useful for row-version or timestamp guarded upserts.\n */\n where?: (\n query: Knex.QueryBuilder,\n helpers: OnConflictMergeHelpers<TLocalSchema>\n ) => void;\n}\n\nexport class OnConflictBuilder<TLocalSchema extends AnyObjectSchema, TResult> {\n readonly #knex: Knex;\n readonly #localSchema: TLocalSchema;\n readonly #conflictColumns: string[];\n\n constructor(\n knex: Knex,\n localSchema: TLocalSchema,\n _parent: SchemaQueryBuilder<TLocalSchema, TResult>,\n conflictColumns: string[]\n ) {\n this.#knex = knex;\n this.#localSchema = localSchema;\n this.#conflictColumns = conflictColumns;\n }\n\n async merge(\n data: InsertType<TLocalSchema>,\n options?: OnConflictMergeOptions<TLocalSchema>\n ): Promise<TResult>;\n async merge(\n data: InsertType<TLocalSchema>,\n updateData?: OnConflictUpdateData<TLocalSchema>,\n options?: OnConflictMergeOptions<TLocalSchema>\n ): Promise<TResult>;\n async merge(\n data: InsertType<TLocalSchema>,\n updateData?:\n | OnConflictUpdateData<TLocalSchema>\n | OnConflictMergeOptions<TLocalSchema>,\n options?: OnConflictMergeOptions<TLocalSchema>\n ): Promise<TResult> {\n let resolvedUpdateData: OnConflictUpdateData<TLocalSchema> | undefined;\n let resolvedOptions = options;\n\n if (options === undefined && isMergeOptions(updateData)) {\n resolvedOptions = updateData;\n } else {\n resolvedUpdateData = updateData as\n | OnConflictUpdateData<TLocalSchema>\n | undefined;\n }\n\n return this.#execute(\n data,\n 'merge',\n resolvedUpdateData,\n resolvedOptions\n ) as Promise<TResult>;\n }\n\n async ignore(data: InsertType<TLocalSchema>): Promise<TResult | undefined> {\n return this.#execute(data, 'ignore');\n }\n\n async #execute(\n data: InsertType<TLocalSchema>,\n mode: 'merge' | 'ignore',\n updateData?: OnConflictUpdateData<TLocalSchema>,\n options?: OnConflictMergeOptions<TLocalSchema>\n ): Promise<TResult | undefined> {\n const tableName = getTableName(this.#localSchema);\n const timestamps: { createdAt: string; updatedAt: string } | null =\n (this.#localSchema as any).getExtension?.('timestamps') ?? null;\n\n const beforeHooks: Function[] =\n (this.#localSchema as any).getExtension?.('beforeInsert') ?? [];\n\n let processed = { ...(data as Record<string, any>) };\n for (const hook of beforeHooks) {\n processed = (await hook(processed)) ?? processed;\n }\n\n const { propToCol } = buildColumnMap(this.#localSchema as any);\n const mapped: Record<string, any> = {};\n for (const [key, val] of Object.entries(processed)) {\n mapped[propToCol.get(key) ?? key] = val;\n }\n if (timestamps) {\n mapped[timestamps.createdAt] = this.#knex.fn.now();\n mapped[timestamps.updatedAt] = this.#knex.fn.now();\n }\n\n let qb = this.#knex(tableName)\n .insert(mapped)\n .onConflict(this.#conflictColumns);\n\n if (mode === 'ignore') {\n qb = (qb as any).ignore();\n } else {\n const helpers = this.#createMergeHelpers();\n let mergeObj: Record<string, any>;\n if (updateData) {\n mergeObj = {};\n for (const [key, val] of Object.entries(\n updateData as Record<string, any>\n )) {\n mergeObj[propToCol.get(key) ?? key] =\n typeof val === 'function' ? val(helpers) : val;\n }\n } else {\n mergeObj = { ...mapped };\n if (timestamps) {\n delete mergeObj[timestamps.createdAt];\n mergeObj[timestamps.updatedAt] = this.#knex.fn.now();\n }\n }\n qb = (qb as any).merge(mergeObj);\n options?.where?.(qb as unknown as Knex.QueryBuilder, helpers);\n }\n\n const rows = await (qb as any).returning('*');\n if (!rows || rows.length === 0) return undefined;\n\n const { colToProp } = buildColumnMap(this.#localSchema as any);\n const result: Record<string, any> = {};\n for (const [col, val] of Object.entries(rows[0])) {\n result[colToProp.get(col) ?? col] = val;\n }\n return result as TResult;\n }\n\n #createMergeHelpers(): OnConflictMergeHelpers<TLocalSchema> {\n return {\n knex: this.#knex,\n column: ref => this.#resolveTopLevelColumn(ref),\n raw: (sql, bindings = []) => this.#knex.raw(sql, bindings as any),\n excluded: ref =>\n this.#knex.raw('excluded.??', [\n this.#resolveTopLevelColumn(ref)\n ])\n };\n }\n\n #resolveTopLevelColumn(ref: ColumnRef<TLocalSchema>): string {\n const column = resolveColumnRef(\n ref as ColumnRef<any>,\n this.#localSchema as any,\n 'onConflict.merge',\n this.#knex\n );\n if (typeof column !== 'string') {\n throw new Error(\n 'onConflict.merge only accepts top-level column references'\n );\n }\n return column;\n }\n}\n\nfunction isMergeOptions<TLocalSchema extends AnyObjectSchema>(\n value: unknown\n): value is OnConflictMergeOptions<TLocalSchema> {\n if (!value || typeof value !== 'object') return false;\n const keys = Object.keys(value);\n return keys.length > 0 && keys.every(key => key === 'where');\n}\n\n// ---------------------------------------------------------------------------\n// Insert operation functions\n// ---------------------------------------------------------------------------\n\nexport async function insertImpl(\n builder: SchemaQueryBuilder<any, any>,\n data: InsertType<any>\n): Promise<any> {\n const state = getState(builder);\n\n let processedData = { ...(data as Record<string, any>) };\n\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeInsert') as\n | Function[]\n | undefined) ?? [];\n for (const hook of beforeHooks) {\n processedData = (await hook(processedData)) ?? processedData;\n }\n\n const mapped = mapObjectToColumns(builder, processedData);\n\n const timestamps = getTimestamps(builder);\n if (timestamps) {\n mapped[timestamps.createdAt] = state.knex.fn.now();\n mapped[timestamps.updatedAt] = state.knex.fn.now();\n }\n\n const [row] = await state\n .knex(state.tableName)\n .insert(mapped)\n .returning('*');\n const result = mapRow(builder, row);\n\n const afterHooks =\n ((state.localSchema as any).getExtension?.('afterInsert') as\n | Function[]\n | undefined) ?? [];\n for (const hook of afterHooks) {\n await hook(result);\n }\n\n return result;\n}\n\nexport async function insertManyImpl(\n builder: SchemaQueryBuilder<any, any>,\n data: InsertType<any>[]\n): Promise<any[]> {\n const state = getState(builder);\n const timestamps = getTimestamps(builder);\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeInsert') as\n | Function[]\n | undefined) ?? [];\n\n const mapped = [];\n for (const d of data) {\n let processedData = { ...(d as Record<string, any>) };\n for (const hook of beforeHooks) {\n processedData = (await hook(processedData)) ?? processedData;\n }\n const m = mapObjectToColumns(builder, processedData);\n if (timestamps) {\n m[timestamps.createdAt] = state.knex.fn.now();\n m[timestamps.updatedAt] = state.knex.fn.now();\n }\n mapped.push(m);\n }\n\n const rows = await state\n .knex(state.tableName)\n .insert(mapped)\n .returning('*');\n const results = rows.map((row: any) => mapRow(builder, row));\n\n const afterHooks =\n ((state.localSchema as any).getExtension?.('afterInsert') as\n | Function[]\n | undefined) ?? [];\n for (const result of results) {\n for (const hook of afterHooks) {\n await hook(result);\n }\n }\n\n return results;\n}\n\nexport function onConflictImpl(\n builder: SchemaQueryBuilder<any, any>,\n ...conflictColumns: ColumnRef<any>[]\n): OnConflictBuilder<any, any> {\n const state = getState(builder);\n const cols = conflictColumns.map(\n c => resolveColumn(builder, c, 'onConflict') as string\n );\n return new OnConflictBuilder(state.knex, state.localSchema, builder, cols);\n}\n\nexport async function upsertImpl(\n builder: SchemaQueryBuilder<any, any>,\n data: InsertType<any>,\n opts: {\n conflictColumns: ColumnRef<any>[];\n updateColumns?: ColumnRef<any>[];\n }\n): Promise<any> {\n const state = getState(builder);\n const cols = opts.conflictColumns.map(\n c => resolveColumn(builder, c, 'upsert') as string\n );\n\n const qb = state\n .knex(state.tableName)\n .insert(mapObjectToColumns(builder, data as Record<string, any>))\n .onConflict(cols);\n\n if (opts.updateColumns && opts.updateColumns.length > 0) {\n const updateCols = opts.updateColumns.map(\n c => resolveColumn(builder, c, 'upsert') as string\n );\n (qb as any).merge(updateCols);\n } else {\n (qb as any).merge();\n }\n\n const [row] = await (qb as any).returning('*');\n return mapRow(builder, row);\n}\n\nexport async function bulkInsertImpl(\n builder: SchemaQueryBuilder<any, any>,\n rows: InsertType<any>[],\n opts?: {\n chunkSize?: number;\n onConflict?: 'ignore' | 'merge';\n conflictColumns?: ColumnRef<any>[];\n }\n): Promise<any[]> {\n if (rows.length === 0) return [];\n\n const state = getState(builder);\n\n const requestedChunkSize = opts?.chunkSize ?? 500;\n const bindingsPerRow = Object.keys(rows[0] as object).length || 1;\n const safeChunkCap = Math.max(\n 1,\n Math.floor(60000 / Math.max(1, bindingsPerRow))\n );\n const chunkSize = Math.max(1, Math.min(requestedChunkSize, safeChunkCap));\n\n const timestamps = getTimestamps(builder);\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeInsert') as\n | Function[]\n | undefined) ?? [];\n const afterHooks =\n ((state.localSchema as any).getExtension?.('afterInsert') as\n | Function[]\n | undefined) ?? [];\n\n const conflictCols =\n opts?.onConflict && opts.conflictColumns\n ? opts.conflictColumns.map(\n c =>\n resolveColumn(\n builder,\n c,\n 'bulkInsert.onConflict'\n ) as string\n )\n : null;\n if (opts?.onConflict && (!conflictCols || conflictCols.length === 0)) {\n throw new Error(\n 'bulkInsert: `conflictColumns` is required when `onConflict` is set.'\n );\n }\n\n const results: any[] = [];\n\n for (let i = 0; i < rows.length; i += chunkSize) {\n const chunk = rows.slice(i, i + chunkSize);\n const mapped: Record<string, any>[] = [];\n for (const row of chunk) {\n let processed = { ...(row as Record<string, any>) };\n for (const hook of beforeHooks) {\n processed = (await hook(processed)) ?? processed;\n }\n const m = mapObjectToColumns(builder, processed);\n if (timestamps) {\n m[timestamps.createdAt] = state.knex.fn.now();\n m[timestamps.updatedAt] = state.knex.fn.now();\n }\n mapped.push(m);\n }\n\n let qb: any = state.knex(state.tableName).insert(mapped);\n\n if (conflictCols) {\n qb = qb.onConflict(conflictCols);\n if (opts!.onConflict === 'ignore') {\n qb = qb.ignore();\n } else {\n const updateCols = new Set<string>();\n for (const m of mapped) {\n for (const k of Object.keys(m)) updateCols.add(k);\n }\n for (const c of conflictCols) updateCols.delete(c);\n if (timestamps) {\n updateCols.delete(timestamps.createdAt);\n updateCols.add(timestamps.updatedAt);\n }\n qb = qb.merge(Array.from(updateCols));\n }\n }\n\n const inserted: any[] = await qb.returning('*');\n for (const row of inserted) {\n const mappedRow = mapRow(builder, row);\n for (const hook of afterHooks) {\n await hook(mappedRow);\n }\n results.push(mappedRow);\n }\n }\n\n return results;\n}\n\nexport async function bulkUpsertImpl(\n builder: SchemaQueryBuilder<any, any>,\n rows: InsertType<any>[],\n opts: {\n conflictColumns: ColumnRef<any>[];\n chunkSize?: number;\n }\n): Promise<any[]> {\n return bulkInsertImpl(builder, rows, {\n chunkSize: opts.chunkSize,\n onConflict: 'merge',\n conflictColumns: opts.conflictColumns\n });\n}\n","// @cleverbrush/knex-schema — DELETE / soft-delete / restore operations\n\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport { getSoftDelete, invalidateCache, mapRow } from './helpers.js';\nimport { getState } from './state.js';\n\nexport async function deleteImpl(\n builder: SchemaQueryBuilder<any, any>\n): Promise<number> {\n const state = getState(builder);\n\n const hooks =\n ((state.localSchema as any).getExtension?.('beforeDelete') as\n | Function[]\n | undefined) ?? [];\n for (const hook of hooks) {\n await hook(builder);\n }\n\n const softDelete = getSoftDelete(builder);\n if (softDelete) {\n return state.baseQuery.update({\n [softDelete.column]: state.knex.fn.now()\n });\n }\n return state.baseQuery.delete();\n}\n\nexport function withDeletedImpl(builder: SchemaQueryBuilder<any, any>): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.includeDeleted = true;\n return builder;\n}\n\nexport function onlyDeletedImpl(builder: SchemaQueryBuilder<any, any>): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.onlyDeleted = true;\n state.includeDeleted = true;\n return builder;\n}\n\nexport async function hardDeleteImpl(\n builder: SchemaQueryBuilder<any, any>\n): Promise<number> {\n const state = getState(builder);\n const hooks =\n ((state.localSchema as any).getExtension?.('beforeDelete') as\n | Function[]\n | undefined) ?? [];\n for (const hook of hooks) {\n await hook(builder);\n }\n return state.baseQuery.delete();\n}\n\nexport async function restoreImpl(\n builder: SchemaQueryBuilder<any, any>\n): Promise<any[]> {\n const state = getState(builder);\n const softDelete = getSoftDelete(builder);\n if (!softDelete) {\n throw new Error(\n 'Schema does not have soft delete enabled. Use .softDelete() on the schema.'\n );\n }\n const rows = await state.baseQuery\n .update({ [softDelete.column]: null })\n .returning('*');\n return rows.map((row: any) => mapRow(builder, row));\n}\n","// @cleverbrush/knex-schema — Validation of join specs\n\nimport type { ObjectSchemaBuilder } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { resolveColumnRef } from './columns.js';\nimport { getTableName } from './extension.js';\nimport { MAPPERS } from './mappers.js';\nimport type {\n JoinManySpec,\n JoinOneSpec,\n ValidatedJoinManySpec,\n ValidatedJoinOneSpec\n} from './types.js';\n\n/**\n * Resolve foreignQuery: use the provided one, or auto-derive from\n * the foreign schema's tableName extension.\n * Also normalizes SchemaQueryBuilder instances to raw Knex.QueryBuilder\n * by calling `.toKnexQuery()` if available.\n */\nfunction resolveForeignQuery(\n spec: {\n foreignQuery?: Knex.QueryBuilder | { toKnexQuery(): Knex.QueryBuilder };\n foreignSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;\n },\n knex: Knex\n): Knex.QueryBuilder {\n if (spec.foreignQuery) {\n if ('toKnexQuery' in spec.foreignQuery) {\n return spec.foreignQuery.toKnexQuery();\n }\n return spec.foreignQuery as Knex.QueryBuilder;\n }\n\n const tableName = getTableName(spec.foreignSchema);\n return knex(tableName);\n}\n\nexport function validateJoinOne(\n spec: JoinOneSpec<any, any, any, any>,\n localSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n knex: Knex\n): ValidatedJoinOneSpec {\n const localColumn = resolveColumnRef(\n spec.localColumn,\n localSchema,\n 'localColumn'\n );\n const foreignColumn = resolveColumnRef(\n spec.foreignColumn,\n spec.foreignSchema,\n 'foreignColumn'\n );\n if (typeof spec.as !== 'string' || !spec.as) {\n throw new Error('as must be a non-empty string');\n }\n\n const foreignQuery = resolveForeignQuery(spec, knex);\n const required = spec.required !== false;\n\n if (spec.mappers !== undefined) {\n validateMappers(spec.mappers);\n }\n\n return {\n localColumn,\n foreignColumn,\n as: spec.as,\n required,\n foreignQuery,\n mappers: spec.mappers as\n | Record<string, ((value: any) => any) | string>\n | undefined\n };\n}\n\nexport function validateJoinMany(\n spec: JoinManySpec<any, any, any>,\n localSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n knex: Knex\n): ValidatedJoinManySpec {\n const localColumn = resolveColumnRef(\n spec.localColumn,\n localSchema,\n 'localColumn'\n );\n const foreignColumn = resolveColumnRef(\n spec.foreignColumn,\n spec.foreignSchema,\n 'foreignColumn'\n );\n if (typeof spec.as !== 'string' || !spec.as) {\n throw new Error('as must be a non-empty string');\n }\n\n const foreignQuery = resolveForeignQuery(spec, knex);\n\n if (spec.mappers !== undefined) {\n validateMappers(spec.mappers);\n }\n\n const limit =\n Number.isFinite(spec.limit) && (spec.limit as number) > 0\n ? (spec.limit as number)\n : null;\n const offset =\n Number.isFinite(spec.offset) && (spec.offset as number) > 0\n ? (spec.offset as number)\n : null;\n const orderBy = spec.orderBy\n ? {\n column: resolveColumnRef(\n spec.orderBy.column,\n spec.foreignSchema,\n 'orderBy.column'\n ),\n direction: spec.orderBy.direction ?? ('asc' as const)\n }\n : null;\n\n return {\n localColumn,\n foreignColumn,\n as: spec.as,\n foreignQuery,\n limit,\n offset,\n orderBy,\n mappers: spec.mappers as\n | Record<string, ((value: any) => any) | string>\n | undefined\n };\n}\n\nfunction validateMappers(mappers: Record<string, unknown>): void {\n if (typeof mappers !== 'object' || mappers === null) {\n throw new Error('mappers must be an object');\n }\n for (const key of Object.keys(mappers)) {\n const m = mappers[key];\n if (typeof m === 'string') {\n if (typeof MAPPERS[m] !== 'function') {\n throw new Error(\n `mapper for \"${key}\": unknown built-in mapper name \"${m}\"`\n );\n }\n } else if (typeof m !== 'function') {\n throw new Error(\n `mapper for \"${key}\" must be a function or a built-in mapper name`\n );\n }\n }\n}\n\nexport function validateUniqueFieldNames(specs: Array<{ as: string }>): void {\n const seen = new Set<string>();\n for (const spec of specs) {\n if (seen.has(spec.as)) {\n throw new Error(`duplicate field name: ${spec.as}`);\n }\n seen.add(spec.as);\n }\n}\n","// @cleverbrush/knex-schema — Eager-loading JOIN operations (joinOne, joinMany, include, includeVariant)\n\nimport type { Knex } from 'knex';\nimport { resolveColumnRef } from '../columns.js';\nimport { getTableName } from '../extension.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type {\n JoinManySpec,\n JoinOneSpec,\n RelationSpec,\n ResolvedVariantRelationSpec\n} from '../types.js';\nimport {\n validateJoinMany,\n validateJoinOne,\n validateUniqueFieldNames\n} from '../validate.js';\nimport {\n findPrimaryKeyColumn,\n getSchemaQueryBuilderCtor,\n getVariantConfig,\n invalidateCache,\n resolveSchema\n} from './helpers.js';\nimport { getState } from './state.js';\n\nexport function joinOneImpl(\n builder: SchemaQueryBuilder<any, any>,\n spec: JoinOneSpec<any, any, any, any>\n): any {\n const state = getState(builder);\n const validated = validateJoinOne(spec, state.localSchema, state.knex);\n state.specs.push({ type: 'one' as const, ...validated });\n validateUniqueFieldNames(state.specs);\n invalidateCache(builder);\n return builder;\n}\n\nexport function joinManyImpl(\n builder: SchemaQueryBuilder<any, any>,\n spec: JoinManySpec<any, any, any>\n): any {\n const state = getState(builder);\n const validated = validateJoinMany(spec, state.localSchema, state.knex);\n state.specs.push({ type: 'many' as const, ...validated });\n validateUniqueFieldNames(state.specs);\n invalidateCache(builder);\n return builder;\n}\n\nexport function includeImpl(\n builder: SchemaQueryBuilder<any, any>,\n relationName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const relations: RelationSpec[] =\n (state.localSchema as any).getExtension?.('relations') ?? [];\n const relation = relations.find(\n (r: RelationSpec) => r.name === relationName\n );\n if (!relation) {\n const variantConfig = getVariantConfig(builder);\n if (variantConfig) {\n const matches: Array<{ variantKey: string }> = [];\n for (const [vKey, vSpec] of Object.entries(\n variantConfig.variants\n )) {\n if (\n vSpec.relations.some(\n (r: ResolvedVariantRelationSpec) =>\n r.name === relationName\n )\n ) {\n matches.push({ variantKey: vKey });\n }\n }\n if (matches.length === 1) {\n return includeVariantImpl(\n builder,\n matches[0].variantKey,\n relationName,\n customize\n );\n }\n if (matches.length > 1) {\n throw new Error(\n `Ambiguous relation \"${relationName}\" — found on variants: ${matches.map(m => m.variantKey).join(', ')}. Use .includeVariant(key, name) to be explicit.`\n );\n }\n }\n throw new Error(\n `Unknown relation \"${relationName}\" on schema for table \"${state.tableName}\"`\n );\n }\n\n const foreignSchema = resolveSchema(builder, relation.schema);\n const foreignTableName = getTableName(foreignSchema);\n\n switch (relation.type) {\n case 'belongsTo': {\n const localColumn = resolveColumnRef(\n relation.foreignKey,\n state.localSchema,\n 'foreignKey'\n );\n const foreignColumn = findPrimaryKeyColumn(builder, foreignSchema);\n\n const foreignQuery1: Knex.QueryBuilder =\n state.knex(foreignTableName);\n if (customize) {\n const SQB = getSchemaQueryBuilderCtor();\n const proxy = new SQB(state.knex, foreignSchema, foreignQuery1);\n customize(proxy);\n }\n\n joinOneImpl(builder, {\n foreignSchema,\n localColumn,\n foreignColumn,\n as: relationName,\n foreignQuery: foreignQuery1\n } as any);\n break;\n }\n case 'hasOne': {\n const localColumn = findPrimaryKeyColumn(\n builder,\n state.localSchema\n );\n const foreignColumn = resolveColumnRef(\n relation.foreignKey,\n foreignSchema,\n 'foreignKey'\n );\n\n const foreignQuery2: Knex.QueryBuilder =\n state.knex(foreignTableName);\n if (customize) {\n const SQB = getSchemaQueryBuilderCtor();\n const proxy = new SQB(state.knex, foreignSchema, foreignQuery2);\n customize(proxy);\n }\n\n joinOneImpl(builder, {\n foreignSchema,\n localColumn,\n foreignColumn,\n as: relationName,\n required: false,\n foreignQuery: foreignQuery2\n } as any);\n break;\n }\n case 'hasMany': {\n const localColumn = findPrimaryKeyColumn(\n builder,\n state.localSchema\n );\n const foreignColumn = resolveColumnRef(\n relation.foreignKey,\n foreignSchema,\n 'foreignKey'\n );\n\n const foreignQuery3: Knex.QueryBuilder =\n state.knex(foreignTableName);\n if (customize) {\n const SQB = getSchemaQueryBuilderCtor();\n const proxy = new SQB(state.knex, foreignSchema, foreignQuery3);\n customize(proxy);\n }\n\n joinManyImpl(builder, {\n foreignSchema,\n localColumn,\n foreignColumn,\n as: relationName,\n foreignQuery: foreignQuery3\n } as any);\n break;\n }\n case 'belongsToMany': {\n const through = relation.through!;\n const localColumn = findPrimaryKeyColumn(\n builder,\n state.localSchema\n );\n\n const foreignQuery = state\n .knex(foreignTableName)\n .join(\n through.table,\n `${through.table}.${through.foreignKey}`,\n `${foreignTableName}.${findPrimaryKeyColumn(builder, foreignSchema)}`\n )\n .select(\n `${foreignTableName}.*`,\n `${through.table}.${through.localKey}`\n );\n\n if (customize) {\n const SQB = getSchemaQueryBuilderCtor();\n const proxy = new SQB(state.knex, foreignSchema, foreignQuery);\n customize(proxy);\n }\n\n joinManyImpl(builder, {\n foreignSchema,\n localColumn,\n foreignColumn: through.localKey,\n as: relationName,\n foreignQuery\n } as any);\n break;\n }\n }\n\n return builder;\n}\n\nexport function includeVariantImpl(\n builder: SchemaQueryBuilder<any, any>,\n variantKey: string,\n relationName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const variantConfig = getVariantConfig(builder);\n if (!variantConfig) {\n throw new Error(\n `includeVariant: schema for table \"${state.tableName}\" is not polymorphic (no .withVariants() config found)`\n );\n }\n const variantSpec = variantConfig.variants[variantKey];\n if (!variantSpec) {\n throw new Error(\n `includeVariant: unknown variant key \"${variantKey}\" on schema for table \"${state.tableName}\"`\n );\n }\n const relSpec = variantSpec.relations.find(\n (r: ResolvedVariantRelationSpec) => r.name === relationName\n );\n if (!relSpec) {\n throw new Error(\n `includeVariant: unknown relation \"${relationName}\" on variant \"${variantKey}\" of table \"${state.tableName}\"`\n );\n }\n state.variantRelationIncludes.push({\n variantKey,\n relationName,\n customize\n });\n return builder;\n}\n","// @cleverbrush/knex-schema — WHERE / ORDER BY / GROUP BY / HAVING operations\n\nimport type { Knex } from 'knex';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type { ColumnRef } from '../types.js';\nimport {\n invalidateCache,\n isColumnAccessor,\n mapRecordToColumns,\n resolveColumn,\n resolveColumnArg\n} from './helpers.js';\nimport { getState } from './state.js';\n\nexport function whereImpl(\n builder: SchemaQueryBuilder<any, any>,\n columnOrRaw: any,\n ...args: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (\n typeof columnOrRaw === 'function' &&\n !isColumnAccessor(builder, columnOrRaw)\n ) {\n (state.baseQuery.where as any)(columnOrRaw, ...args);\n } else if (\n typeof columnOrRaw === 'object' &&\n columnOrRaw !== null &&\n !('toSQL' in columnOrRaw)\n ) {\n const mapped = mapRecordToColumns(\n builder,\n columnOrRaw as Record<string, any>\n );\n (state.baseQuery.where as any)(mapped, ...args);\n } else {\n const col = resolveColumnArg(builder, columnOrRaw);\n (state.baseQuery.where as any)(col, ...args);\n }\n return builder;\n}\n\nexport function andWhereImpl(\n builder: SchemaQueryBuilder<any, any>,\n columnOrRaw: any,\n ...args: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (\n typeof columnOrRaw === 'function' &&\n !isColumnAccessor(builder, columnOrRaw)\n ) {\n (state.baseQuery.andWhere as any)(columnOrRaw, ...args);\n } else if (\n typeof columnOrRaw === 'object' &&\n columnOrRaw !== null &&\n !('toSQL' in columnOrRaw)\n ) {\n const mapped = mapRecordToColumns(\n builder,\n columnOrRaw as Record<string, any>\n );\n (state.baseQuery.andWhere as any)(mapped, ...args);\n } else {\n const col = resolveColumnArg(builder, columnOrRaw);\n (state.baseQuery.andWhere as any)(col, ...args);\n }\n return builder;\n}\n\nexport function orWhereImpl(\n builder: SchemaQueryBuilder<any, any>,\n columnOrRaw: any,\n ...args: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (\n typeof columnOrRaw === 'function' &&\n !isColumnAccessor(builder, columnOrRaw)\n ) {\n (state.baseQuery.orWhere as any)(columnOrRaw, ...args);\n } else if (\n typeof columnOrRaw === 'object' &&\n columnOrRaw !== null &&\n !('toSQL' in columnOrRaw)\n ) {\n const mapped = mapRecordToColumns(\n builder,\n columnOrRaw as Record<string, any>\n );\n (state.baseQuery.orWhere as any)(mapped, ...args);\n } else {\n const col = resolveColumnArg(builder, columnOrRaw);\n (state.baseQuery.orWhere as any)(col, ...args);\n }\n return builder;\n}\n\nexport function whereNotImpl(\n builder: SchemaQueryBuilder<any, any>,\n columnOrRaw: any,\n ...args: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n if (\n typeof columnOrRaw === 'function' &&\n !isColumnAccessor(builder, columnOrRaw)\n ) {\n (state.baseQuery.whereNot as any)(columnOrRaw, ...args);\n } else if (\n typeof columnOrRaw === 'object' &&\n columnOrRaw !== null &&\n !('toSQL' in columnOrRaw)\n ) {\n const mapped = mapRecordToColumns(\n builder,\n columnOrRaw as Record<string, any>\n );\n (state.baseQuery.whereNot as any)(mapped, ...args);\n } else {\n const col = resolveColumnArg(builder, columnOrRaw);\n (state.baseQuery.whereNot as any)(col, ...args);\n }\n return builder;\n}\n\nexport function whereInImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n values: readonly any[] | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereIn(\n resolveColumn(builder, column, 'whereIn') as any,\n values as any\n );\n return builder;\n}\n\nexport function whereNotInImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n values: readonly any[] | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereNotIn(\n resolveColumn(builder, column, 'whereNotIn') as any,\n values as any\n );\n return builder;\n}\n\nexport function orWhereInImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n values: readonly any[] | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).orWhereIn(\n resolveColumn(builder, column, 'orWhereIn'),\n values as any\n );\n return builder;\n}\n\nexport function orWhereNotInImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n values: readonly any[] | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).orWhereNotIn(\n resolveColumn(builder, column, 'orWhereNotIn'),\n values as any\n );\n return builder;\n}\n\nexport function whereNullImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereNull(\n resolveColumn(builder, column, 'whereNull') as any\n );\n return builder;\n}\n\nexport function whereNotNullImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereNotNull(\n resolveColumn(builder, column, 'whereNotNull') as any\n );\n return builder;\n}\n\nexport function orWhereNullImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).orWhereNull(\n resolveColumn(builder, column, 'orWhereNull')\n );\n return builder;\n}\n\nexport function orWhereNotNullImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).orWhereNotNull(\n resolveColumn(builder, column, 'orWhereNotNull')\n );\n return builder;\n}\n\nexport function whereBetweenImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n range: readonly [any, any]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereBetween(\n resolveColumn(builder, column, 'whereBetween') as any,\n range as [any, any]\n );\n return builder;\n}\n\nexport function whereNotBetweenImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n range: readonly [any, any]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereNotBetween(\n resolveColumn(builder, column, 'whereNotBetween') as any,\n range as [any, any]\n );\n return builder;\n}\n\nexport function whereLikeImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n value: string\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).whereLike(\n resolveColumn(builder, column, 'whereLike'),\n value\n );\n return builder;\n}\n\nexport function whereILikeImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n value: string\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).whereILike(\n resolveColumn(builder, column, 'whereILike'),\n value\n );\n return builder;\n}\n\nexport function whereRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n ...bindings: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereRaw(sql, ...bindings);\n return builder;\n}\n\nexport function whereExistsImpl(\n builder: SchemaQueryBuilder<any, any>,\n callback: Knex.QueryCallback | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.whereExists(callback as any);\n return builder;\n}\n\nexport function whereNotExistsImpl(\n builder: SchemaQueryBuilder<any, any>,\n callback: Knex.QueryCallback | Knex.QueryBuilder\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n (state.baseQuery as any).whereNotExists(callback as any);\n return builder;\n}\n\nexport function whereJsonPathImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any>,\n path: string,\n operator?: string,\n value?: any\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const client = (state.knex as any).client?.config?.client as\n | string\n | undefined;\n if (client !== 'pg' && client !== 'postgresql' && client !== 'postgres') {\n throw new Error(\n `whereJsonPath() is only supported on PostgreSQL (got client: \"${client ?? 'unknown'}\")`\n );\n }\n\n const col = resolveColumn(builder, column, 'whereJsonPath');\n const op = operator ?? '=';\n\n if (op === '@?' || op === '@@') {\n const escapedOp = op === '@?' ? '@\\\\?' : '@@';\n state.baseQuery.whereRaw(`?? ${escapedOp} ?`, [col, path]);\n } else {\n const jsonPath = path.startsWith('$')\n ? path\n : `$.${path.replace(/\\./g, '.')}`;\n state.baseQuery.whereRaw(\n `jsonb_path_query_first(??, ?) ${op} ?::jsonb`,\n [col, jsonPath, JSON.stringify(value)]\n );\n }\n return builder;\n}\n\nexport function orderByImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw,\n direction?: 'asc' | 'desc'\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const col = resolveColumnArg(builder, column);\n state.baseQuery.orderBy(col as string, direction);\n return builder;\n}\n\nexport function orderByRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n ...bindings: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.orderByRaw(sql, ...bindings);\n return builder;\n}\n\nexport function groupByImpl(\n builder: SchemaQueryBuilder<any, any>,\n ...columns: (ColumnRef<any> | Knex.Raw)[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const resolved = columns.map(c => resolveColumnArg(builder, c));\n state.baseQuery.groupBy(...(resolved as string[]));\n return builder;\n}\n\nexport function groupByRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n ...bindings: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.groupByRaw(sql, ...bindings);\n return builder;\n}\n\nexport function havingImpl(\n builder: SchemaQueryBuilder<any, any>,\n column: ColumnRef<any> | Knex.Raw,\n operator: string,\n value: any\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n const col = resolveColumnArg(builder, column);\n state.baseQuery.having(col as string, operator, value);\n return builder;\n}\n\nexport function havingRawImpl(\n builder: SchemaQueryBuilder<any, any>,\n sql: string,\n ...bindings: any[]\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.havingRaw(sql, ...bindings);\n return builder;\n}\n","// @cleverbrush/knex-schema — Pagination (offset & cursor-based)\n\nimport { resolvePropertyKey } from '../columns.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport type {\n ColumnRef,\n CursorPaginationResult,\n PaginationResult\n} from '../types.js';\nimport {\n cleanAndMapRow,\n getEffectiveBaseQuery,\n getQuery,\n invalidateCache\n} from './helpers.js';\nimport { getState } from './state.js';\nimport { orderByImpl, whereImpl } from './where.js';\n\nexport function limitImpl(\n builder: SchemaQueryBuilder<any, any>,\n n: number\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.limit(n);\n return builder;\n}\n\nexport function offsetImpl(\n builder: SchemaQueryBuilder<any, any>,\n n: number\n): any {\n const state = getState(builder);\n invalidateCache(builder);\n state.baseQuery.offset(n);\n return builder;\n}\n\nexport async function paginateImpl(\n builder: SchemaQueryBuilder<any, any>,\n opts: {\n page: number;\n pageSize: number;\n }\n): Promise<PaginationResult<any>> {\n const { page, pageSize } = opts;\n const _state = getState(builder);\n\n const effectiveBase = getEffectiveBaseQuery(builder);\n\n const countResult = await effectiveBase\n .clone()\n .clearSelect()\n .clearOrder()\n .count('* as count')\n .first();\n const total = Number((countResult as any)?.count ?? 0);\n\n limitImpl(builder, pageSize);\n offsetImpl(builder, (page - 1) * pageSize);\n const data = await executeImpl(builder);\n\n const totalPages = Math.ceil(total / pageSize);\n\n return {\n data,\n total,\n page,\n pageSize,\n totalPages,\n hasNextPage: page < totalPages,\n hasPreviousPage: page > 1\n } as PaginationResult<any>;\n}\n\nexport async function paginateAfterImpl(\n builder: SchemaQueryBuilder<any, any>,\n opts: {\n cursor?: any;\n limit: number;\n column?: ColumnRef<any>;\n direction?: 'asc' | 'desc';\n }\n): Promise<CursorPaginationResult<any>> {\n const direction = opts.direction ?? 'desc';\n const column = opts.column ?? ('id' as any);\n const state = getState(builder);\n\n if (opts.cursor != null) {\n const op = direction === 'desc' ? '<' : '>';\n whereImpl(builder, column, op, opts.cursor);\n }\n\n orderByImpl(builder, column, direction);\n limitImpl(builder, opts.limit + 1);\n const rows = await executeImpl(builder);\n\n const hasMore = rows.length > opts.limit;\n const data = hasMore ? rows.slice(0, opts.limit) : rows;\n\n const propKey =\n typeof column === 'string'\n ? column\n : resolvePropertyKey(column, state.localSchema, 'cursor');\n\n const nextCursor =\n hasMore && data.length > 0\n ? String((data[data.length - 1] as any)[propKey])\n : null;\n\n return { data, nextCursor, hasMore } as CursorPaginationResult<any>;\n}\n\nexport async function executeImpl(\n builder: SchemaQueryBuilder<any, any>\n): Promise<any[]> {\n const query = getQuery(builder);\n const rows = await query;\n\n if (!rows) return [];\n if (!Array.isArray(rows)) return [cleanAndMapRow(builder, rows)];\n\n return rows.map((row: any) => cleanAndMapRow(builder, row));\n}\n","// @cleverbrush/knex-schema — UPDATE / bulk-update operations\n\nimport type { InferType } from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from '../columns.js';\nimport type { SchemaQueryBuilder } from '../SchemaQueryBuilder.js';\nimport {\n getTimestamps,\n mapObjectToColumns,\n mapRow,\n resolvePkColumns\n} from './helpers.js';\nimport { getState } from './state.js';\n\nexport async function updateImpl(\n builder: SchemaQueryBuilder<any, any>,\n data: Partial<InferType<any>>\n): Promise<any[]> {\n const state = getState(builder);\n\n let processedData = { ...(data as Record<string, any>) };\n\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeUpdate') as\n | Function[]\n | undefined) ?? [];\n for (const hook of beforeHooks) {\n processedData = (await hook(processedData)) ?? processedData;\n }\n\n const mapped = mapObjectToColumns(builder, processedData);\n\n const timestamps = getTimestamps(builder);\n if (timestamps) {\n mapped[timestamps.updatedAt] = state.knex.fn.now();\n }\n\n const rows = await state.baseQuery.update(mapped).returning('*');\n return rows.map((row: any) => mapRow(builder, row));\n}\n\nexport async function bulkUpdateImpl(\n builder: SchemaQueryBuilder<any, any>,\n updates: ReadonlyArray<{\n where: Partial<InferType<any>>;\n set: Partial<InferType<any>>;\n }>\n): Promise<number> {\n if (updates.length === 0) return 0;\n\n const state = getState(builder);\n const pk = resolvePkColumns(builder);\n const { propToCol } = buildColumnMap(state.localSchema as any);\n const beforeHooks =\n ((state.localSchema as any).getExtension?.('beforeUpdate') as\n | Function[]\n | undefined) ?? [];\n const timestamps = getTimestamps(builder);\n\n const processed: Array<{\n pkValues: unknown[];\n set: Record<string, any>;\n }> = [];\n for (const entry of updates) {\n let setData = { ...(entry.set as Record<string, any>) };\n for (const hook of beforeHooks) {\n setData = (await hook(setData)) ?? setData;\n }\n const setMapped = mapObjectToColumns(builder, setData);\n if (timestamps) {\n setMapped[timestamps.updatedAt] = state.knex.fn.now();\n }\n\n const whereRec = entry.where as Record<string, unknown>;\n const pkValues: unknown[] = [];\n for (const propKey of pk.propertyKeys) {\n const value =\n propKey in whereRec\n ? whereRec[propKey]\n : (whereRec[propToCol.get(propKey) ?? propKey] as\n | unknown\n | undefined);\n if (value === undefined) {\n throw new Error(\n `bulkUpdate: each \\`where\\` clause must include the entity's primary key (missing \"${propKey}\").`\n );\n }\n pkValues.push(value);\n }\n processed.push({ pkValues, set: setMapped });\n }\n\n const allSetCols = new Set<string>();\n for (const p of processed) {\n for (const k of Object.keys(p.set)) allSetCols.add(k);\n }\n if (allSetCols.size === 0) return 0;\n\n const knex = state.knex;\n const updateExpr: Record<string, any> = {};\n for (const col of allSetCols) {\n const fragments: string[] = [];\n const bindings: unknown[] = [];\n for (const p of processed) {\n if (!(col in p.set)) continue;\n if (pk.columnNames.length === 1) {\n fragments.push('WHEN ?? = ? THEN ?');\n bindings.push(pk.columnNames[0], p.pkValues[0], p.set[col]);\n } else {\n const conditions = pk.columnNames\n .map(() => '?? = ?')\n .join(' AND ');\n fragments.push(`WHEN ${conditions} THEN ?`);\n for (let i = 0; i < pk.columnNames.length; i++) {\n bindings.push(pk.columnNames[i], p.pkValues[i]);\n }\n bindings.push(p.set[col]);\n }\n }\n if (fragments.length === 0) continue;\n updateExpr[col] = knex.raw(`CASE ${fragments.join(' ')} ELSE ?? END`, [\n ...bindings,\n col\n ] as any);\n }\n\n let qb: any = knex(state.tableName).update(updateExpr);\n if (pk.columnNames.length === 1) {\n qb = qb.whereIn(\n pk.columnNames[0],\n processed.map(p => p.pkValues[0])\n );\n } else {\n qb = qb.where(function (this: Knex.QueryBuilder) {\n for (const p of processed) {\n this.orWhere(function (this: Knex.QueryBuilder) {\n for (let i = 0; i < pk.columnNames.length; i++) {\n this.andWhere(pk.columnNames[i], p.pkValues[i] as any);\n }\n });\n }\n });\n }\n\n return await qb;\n}\n","// @cleverbrush/knex-schema — SchemaQueryBuilder\n\nimport type { InferType } from '@cleverbrush/schema';\nimport {\n EXTRA_TYPE_BRAND,\n METHOD_LITERAL_BRAND,\n type ObjectSchemaBuilder\n} from '@cleverbrush/schema';\nimport type { Knex } from 'knex';\nimport { buildColumnMap } from './columns.js';\nimport { getTableName, POLYMORPHIC_TYPE_BRAND } from './extension.js';\n// Operations\nimport {\n avgImpl,\n countDistinctImpl,\n countImpl,\n distinctImpl,\n maxImpl,\n minImpl,\n projectedImpl,\n scopedImpl,\n selectImpl,\n selectRawImpl,\n sumImpl,\n unscopedImpl\n} from './operations/select.js';\nimport type {\n ColumnRef,\n CursorPaginationResult,\n InsertType,\n JoinManySpec,\n JoinOneSpec,\n PaginationResult,\n SelectProjection,\n SelectSelector\n} from './types.js';\n\nexport {\n OnConflictBuilder,\n type OnConflictMergeHelpers,\n type OnConflictMergeOptions,\n type OnConflictUpdateData,\n type OnConflictUpdateValue\n} from './operations/insert.js';\n\nimport {\n deleteImpl,\n hardDeleteImpl,\n onlyDeletedImpl,\n restoreImpl,\n withDeletedImpl\n} from './operations/delete.js';\nimport {\n ALLOWED_OPS,\n buildQuery,\n cleanAndMapRow,\n getQuery,\n getVariantConfig,\n invalidateCache,\n registerSchemaQueryBuilder,\n resolveColumn\n} from './operations/helpers.js';\nimport {\n bulkInsertImpl,\n bulkUpsertImpl,\n insertImpl,\n insertManyImpl,\n onConflictImpl,\n upsertImpl\n} from './operations/insert.js';\nimport {\n includeImpl,\n includeVariantImpl,\n joinManyImpl,\n joinOneImpl\n} from './operations/join.js';\nimport {\n executeImpl,\n limitImpl,\n offsetImpl,\n paginateAfterImpl,\n paginateImpl\n} from './operations/pagination.js';\nimport { getState, setState } from './operations/state.js';\nimport { bulkUpdateImpl, updateImpl } from './operations/update.js';\nimport {\n andWhereImpl,\n groupByImpl,\n groupByRawImpl,\n havingImpl,\n havingRawImpl,\n orderByImpl,\n orderByRawImpl,\n orWhereImpl,\n orWhereInImpl,\n orWhereNotInImpl,\n orWhereNotNullImpl,\n orWhereNullImpl,\n whereBetweenImpl,\n whereExistsImpl,\n whereILikeImpl,\n whereImpl,\n whereInImpl,\n whereJsonPathImpl,\n whereLikeImpl,\n whereNotBetweenImpl,\n whereNotExistsImpl,\n whereNotImpl,\n whereNotInImpl,\n whereNotNullImpl,\n whereNullImpl,\n whereRawImpl\n} from './operations/where.js';\n\n// ---------------------------------------------------------------------------\n// Type-level helpers\n// ---------------------------------------------------------------------------\n\ntype ScopesOf<S> = S extends {\n readonly [METHOD_LITERAL_BRAND]?: infer N;\n}\n ? Extract<N, string>\n : never;\n\ntype ProjectionsOf<S> = S extends {\n readonly [EXTRA_TYPE_BRAND]?: infer P;\n}\n ? P extends Record<string, readonly string[]>\n ? P\n : Record<never, never>\n : Record<never, never>;\n\ntype ProjectionKeysOf<\n S,\n K extends keyof ProjectionsOf<S> & string\n> = ProjectionsOf<S>[K] extends readonly (infer T extends string)[]\n ? T\n : string;\n\ntype QueryResultType<TLocalSchema> = TLocalSchema extends {\n readonly [POLYMORPHIC_TYPE_BRAND]?: infer U;\n}\n ? NonNullable<U>\n : InferType<TLocalSchema>;\n\n// ---------------------------------------------------------------------------\n// SchemaQueryBuilder\n// ---------------------------------------------------------------------------\n\nexport class SchemaQueryBuilder<\n TLocalSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>,\n TResult\n> {\n constructor(\n knex: Knex,\n localSchema: TLocalSchema,\n baseQuery?: Knex.QueryBuilder\n ) {\n const tableName = getTableName(localSchema);\n setState(this, {\n knex,\n baseQuery: baseQuery ?? knex(tableName),\n localSchema,\n specs: [],\n tableName,\n explicitSelects: null,\n selectionMode: null,\n appliedProjection: null,\n includeDeleted: false,\n onlyDeleted: false,\n skipDefaultScope: false,\n variantConfig: undefined,\n enabledVariants: null,\n variantWhereFilters: [],\n variantRelationIncludes: [],\n cachedBuiltQuery: null\n });\n }\n\n // =======================================================================\n // SELECT / DISTINCT / AGGREGATES\n // =======================================================================\n\n select(...columns: (ColumnRef<TLocalSchema> | Knex.Raw)[]): this;\n select<TSel extends SelectSelector<TLocalSchema>>(\n selector: TSel\n ): SchemaQueryBuilder<TLocalSchema, SelectProjection<ReturnType<TSel>>>;\n select(...args: unknown[]): any {\n return selectImpl(this as any, ...args);\n }\n\n distinct(...columns: (ColumnRef<TLocalSchema> | Knex.Raw)[]): this {\n return (distinctImpl as any)(this, ...columns);\n }\n\n count(column?: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (countImpl as any)(this, column);\n }\n\n countDistinct(column?: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (countDistinctImpl as any)(this, column);\n }\n\n min(column: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (minImpl as any)(this, column);\n }\n\n max(column: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (maxImpl as any)(this, column);\n }\n\n sum(column: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (sumImpl as any)(this, column);\n }\n\n avg(column: ColumnRef<TLocalSchema> | Knex.Raw): this {\n return (avgImpl as any)(this, column);\n }\n\n selectRaw(sql: string, bindings?: any[]): this {\n return selectRawImpl(this as any, sql, bindings);\n }\n\n projected<K extends keyof ProjectionsOf<TLocalSchema> & string>(\n name: K\n ): SchemaQueryBuilder<\n TLocalSchema,\n Pick<TResult, ProjectionKeysOf<TLocalSchema, K> & keyof TResult>\n > {\n return projectedImpl(this as any, name);\n }\n\n scoped<K extends ScopesOf<TLocalSchema>>(name: K): this {\n return scopedImpl(this as any, name as string);\n }\n\n unscoped(): this {\n return unscopedImpl(this as any);\n }\n\n // =======================================================================\n // WHERE\n // =======================================================================\n\n where(column: ColumnRef<TLocalSchema>, operator: string, value: any): this;\n where(column: ColumnRef<TLocalSchema>, value: any): this;\n where(raw: Knex.Raw, operator: string, value: any): this;\n where(callback: (builder: Knex.QueryBuilder) => void): this;\n where(record: Record<string, any>): this;\n where(raw: Knex.Raw): this;\n where(columnOrRaw: any, ...args: any[]): this {\n return whereImpl(this as any, columnOrRaw, ...args);\n }\n\n andWhere(\n column: ColumnRef<TLocalSchema>,\n operator: string,\n value: any\n ): this;\n andWhere(column: ColumnRef<TLocalSchema>, value: any): this;\n andWhere(record: Record<string, any>): this;\n andWhere(callback: (builder: Knex.QueryBuilder) => void): this;\n andWhere(raw: Knex.Raw): this;\n andWhere(columnOrRaw: any, ...args: any[]): this {\n return andWhereImpl(this as any, columnOrRaw, ...args);\n }\n\n orWhere(\n column: ColumnRef<TLocalSchema>,\n operator: string,\n value: any\n ): this;\n orWhere(column: ColumnRef<TLocalSchema>, value: any): this;\n orWhere(record: Record<string, any>): this;\n orWhere(callback: (builder: Knex.QueryBuilder) => void): this;\n orWhere(raw: Knex.Raw): this;\n orWhere(columnOrRaw: any, ...args: any[]): this {\n return orWhereImpl(this as any, columnOrRaw, ...args);\n }\n\n whereNot(\n column: ColumnRef<TLocalSchema>,\n operator: string,\n value: any\n ): this;\n whereNot(column: ColumnRef<TLocalSchema>, value: any): this;\n whereNot(record: Record<string, any>): this;\n whereNot(callback: (builder: Knex.QueryBuilder) => void): this;\n whereNot(raw: Knex.Raw): this;\n whereNot(columnOrRaw: any, ...args: any[]): this {\n return whereNotImpl(this as any, columnOrRaw, ...args);\n }\n\n whereIn(\n column: ColumnRef<TLocalSchema>,\n values: readonly any[] | Knex.QueryBuilder\n ): this {\n return (whereInImpl as any)(this, column, values);\n }\n\n whereNotIn(\n column: ColumnRef<TLocalSchema>,\n values: readonly any[] | Knex.QueryBuilder\n ): this {\n return (whereNotInImpl as any)(this, column, values);\n }\n\n orWhereIn(\n column: ColumnRef<TLocalSchema>,\n values: readonly any[] | Knex.QueryBuilder\n ): this {\n return (orWhereInImpl as any)(this, column, values);\n }\n\n orWhereNotIn(\n column: ColumnRef<TLocalSchema>,\n values: readonly any[] | Knex.QueryBuilder\n ): this {\n return (orWhereNotInImpl as any)(this, column, values);\n }\n\n whereNull(column: ColumnRef<TLocalSchema>): this {\n return (whereNullImpl as any)(this, column);\n }\n\n whereNotNull(column: ColumnRef<TLocalSchema>): this {\n return (whereNotNullImpl as any)(this, column);\n }\n\n orWhereNull(column: ColumnRef<TLocalSchema>): this {\n return (orWhereNullImpl as any)(this, column);\n }\n\n orWhereNotNull(column: ColumnRef<TLocalSchema>): this {\n return (orWhereNotNullImpl as any)(this, column);\n }\n\n whereBetween(\n column: ColumnRef<TLocalSchema>,\n range: readonly [any, any]\n ): this {\n return (whereBetweenImpl as any)(this, column, range);\n }\n\n whereNotBetween(\n column: ColumnRef<TLocalSchema>,\n range: readonly [any, any]\n ): this {\n return (whereNotBetweenImpl as any)(this, column, range);\n }\n\n whereLike(column: ColumnRef<TLocalSchema>, value: string): this {\n return (whereLikeImpl as any)(this, column, value);\n }\n\n whereILike(column: ColumnRef<TLocalSchema>, value: string): this {\n return (whereILikeImpl as any)(this, column, value);\n }\n\n whereRaw(sql: string, ...bindings: any[]): this {\n return (whereRawImpl as any)(this, sql, ...bindings);\n }\n\n whereExists(callback: Knex.QueryCallback | Knex.QueryBuilder): this {\n return (whereExistsImpl as any)(this, callback);\n }\n\n whereNotExists(callback: Knex.QueryCallback | Knex.QueryBuilder): this {\n return (whereNotExistsImpl as any)(this, callback);\n }\n\n whereJsonPath(\n column: ColumnRef<TLocalSchema>,\n path: string,\n operator?: string,\n value?: any\n ): this {\n return (whereJsonPathImpl as any)(this, column, path, operator, value);\n }\n\n // =======================================================================\n // ORDER BY\n // =======================================================================\n\n orderBy(\n column: ColumnRef<TLocalSchema> | Knex.Raw,\n direction?: 'asc' | 'desc'\n ): this {\n return (orderByImpl as any)(this, column, direction);\n }\n\n orderByRaw(sql: string, ...bindings: any[]): this {\n return (orderByRawImpl as any)(this, sql, ...bindings);\n }\n\n // =======================================================================\n // GROUP BY / HAVING\n // =======================================================================\n\n groupBy(...columns: (ColumnRef<TLocalSchema> | Knex.Raw)[]): this {\n return (groupByImpl as any)(this, ...columns);\n }\n\n groupByRaw(sql: string, ...bindings: any[]): this {\n return (groupByRawImpl as any)(this, sql, ...bindings);\n }\n\n having(\n column: ColumnRef<TLocalSchema> | Knex.Raw,\n operator: string,\n value: any\n ): this {\n return (havingImpl as any)(this, column, operator, value);\n }\n\n havingRaw(sql: string, ...bindings: any[]): this {\n return havingRawImpl(this as any, sql, ...bindings);\n }\n\n // =======================================================================\n // PAGINATION\n // =======================================================================\n\n limit(n: number): this {\n return limitImpl(this as any, n);\n }\n\n offset(n: number): this {\n return offsetImpl(this as any, n);\n }\n\n async paginate(opts: {\n page: number;\n pageSize: number;\n }): Promise<PaginationResult<TResult>> {\n return paginateImpl(this as any, opts) as Promise<\n PaginationResult<TResult>\n >;\n }\n\n async paginateAfter(opts: {\n cursor?: any;\n limit: number;\n column?: ColumnRef<TLocalSchema>;\n direction?: 'asc' | 'desc';\n }): Promise<CursorPaginationResult<TResult>> {\n return (paginateAfterImpl as any)(this, opts) as Promise<\n CursorPaginationResult<TResult>\n >;\n }\n\n // =======================================================================\n // WRITE OPERATIONS\n // =======================================================================\n\n async insert(data: InsertType<TLocalSchema>): Promise<TResult> {\n return insertImpl(this as any, data) as Promise<TResult>;\n }\n\n async insertMany(data: InsertType<TLocalSchema>[]): Promise<TResult[]> {\n return insertManyImpl(this as any, data) as Promise<TResult[]>;\n }\n\n onConflict(\n ...conflictColumns: ColumnRef<TLocalSchema>[]\n ): import('./operations/insert.js').OnConflictBuilder<\n TLocalSchema,\n TResult\n > {\n return (onConflictImpl as any)(this, ...conflictColumns);\n }\n\n async upsert(\n data: InsertType<TLocalSchema>,\n opts: {\n conflictColumns: ColumnRef<TLocalSchema>[];\n updateColumns?: ColumnRef<TLocalSchema>[];\n }\n ): Promise<TResult> {\n return (upsertImpl as any)(this, data, opts);\n }\n\n async bulkInsert(\n rows: InsertType<TLocalSchema>[],\n opts?: {\n chunkSize?: number;\n onConflict?: 'ignore' | 'merge';\n conflictColumns?: ColumnRef<TLocalSchema>[];\n }\n ): Promise<TResult[]> {\n return (bulkInsertImpl as any)(this, rows, opts);\n }\n\n async bulkUpsert(\n rows: InsertType<TLocalSchema>[],\n opts: {\n conflictColumns: ColumnRef<TLocalSchema>[];\n chunkSize?: number;\n }\n ): Promise<TResult[]> {\n return (bulkUpsertImpl as any)(this, rows, opts);\n }\n\n // =======================================================================\n // UPDATE\n // =======================================================================\n\n async update(data: Partial<InferType<TLocalSchema>>): Promise<TResult[]> {\n return updateImpl(this as any, data) as Promise<TResult[]>;\n }\n\n async bulkUpdate(\n updates: ReadonlyArray<{\n where: Partial<InferType<TLocalSchema>>;\n set: Partial<InferType<TLocalSchema>>;\n }>\n ): Promise<number> {\n return bulkUpdateImpl(this as any, updates as any);\n }\n\n // =======================================================================\n // DELETE / SOFT DELETE\n // =======================================================================\n\n async delete(): Promise<number> {\n return deleteImpl(this as any);\n }\n\n withDeleted(): this {\n return withDeletedImpl(this as any);\n }\n\n onlyDeleted(): this {\n return onlyDeletedImpl(this as any);\n }\n\n async hardDelete(): Promise<number> {\n return hardDeleteImpl(this as any);\n }\n\n async restore(): Promise<TResult[]> {\n return restoreImpl(this as any) as Promise<TResult[]>;\n }\n\n // =======================================================================\n // EAGER LOADING (JOIN)\n // =======================================================================\n\n joinOne<\n TForeignSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n TFieldName extends string,\n TRequired extends boolean = true\n >(\n spec: JoinOneSpec<TLocalSchema, TForeignSchema, TFieldName, TRequired>\n ): SchemaQueryBuilder<\n TLocalSchema,\n import('./types.js').WithJoinedOne<\n TResult,\n TFieldName,\n TForeignSchema,\n TRequired\n >\n > {\n return joinOneImpl(this as any, spec);\n }\n\n joinMany<\n TForeignSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n TFieldName extends string\n >(\n spec: JoinManySpec<TLocalSchema, TForeignSchema, TFieldName>\n ): SchemaQueryBuilder<\n TLocalSchema,\n import('./types.js').WithJoinedMany<TResult, TFieldName, TForeignSchema>\n > {\n return joinManyImpl(this as any, spec);\n }\n\n include(\n relationName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n ): this {\n return includeImpl(this as any, relationName, customize);\n }\n\n includeVariant(\n variantKey: string,\n relationName: string,\n customize?: (q: SchemaQueryBuilder<any, any>) => void\n ): this {\n return includeVariantImpl(\n this as any,\n variantKey,\n relationName,\n customize\n );\n }\n\n // =======================================================================\n // POLYMORPHIC VARIANTS\n // =======================================================================\n\n whereVariant(\n key: string,\n column: string,\n operator: string,\n value: any\n ): this {\n const state = getState(this);\n const variantConfig = getVariantConfig(this);\n if (!variantConfig) {\n throw new Error(\n 'whereVariant() can only be used on a polymorphic schema (created with .withVariants())'\n );\n }\n\n const spec = variantConfig.variants[key];\n if (!spec) {\n throw new Error(\n `whereVariant: unknown variant key \"${key}\". ` +\n `Valid keys: ${Object.keys(variantConfig.variants).join(', ')}`\n );\n }\n\n const op = operator.toLowerCase();\n if (!ALLOWED_OPS.has(op)) {\n throw new Error(\n `whereVariant: operator \"${operator}\" is not allowed. ` +\n `Allowed operators: ${[...ALLOWED_OPS].join(', ')}`\n );\n }\n\n const { propToCol } = buildColumnMap(spec.schema);\n const colName = propToCol.get(column) ?? column;\n\n let qualifiedColumn: string;\n if (spec.storage === 'cti') {\n qualifiedColumn = `__v_${key}.${colName}`;\n } else {\n qualifiedColumn = `${state.tableName}.${colName}`;\n }\n\n state.variantWhereFilters.push({ key, qualifiedColumn, op, value });\n invalidateCache(this);\n return this;\n }\n\n selectVariants(keys: string[]): this {\n const state = getState(this);\n if (!getVariantConfig(this)) {\n throw new Error(\n 'selectVariants() can only be used on a polymorphic schema (created with .withVariants())'\n );\n }\n state.enabledVariants = new Set(keys);\n invalidateCache(this);\n return this;\n }\n\n // =======================================================================\n // ESCAPE HATCH\n // =======================================================================\n\n apply(fn: (builder: Knex.QueryBuilder) => void): this {\n const state = getState(this);\n invalidateCache(this);\n fn(state.baseQuery);\n return this;\n }\n\n // =======================================================================\n // TRANSACTION\n // =======================================================================\n\n transacting(\n trx: Knex.Transaction\n ): SchemaQueryBuilder<TLocalSchema, TResult> {\n const state = getState(this);\n const builder = new SchemaQueryBuilder<TLocalSchema, TResult>(\n trx as unknown as Knex,\n state.localSchema as TLocalSchema,\n state.baseQuery.clone().transacting(trx)\n );\n const builderState = getState(builder);\n for (const spec of state.specs) {\n builderState.specs.push({\n ...spec,\n foreignQuery: spec.foreignQuery.clone().transacting(trx)\n });\n }\n builderState.explicitSelects = state.explicitSelects\n ? [...state.explicitSelects]\n : null;\n builderState.selectionMode = state.selectionMode;\n builderState.appliedProjection = state.appliedProjection;\n builderState.includeDeleted = state.includeDeleted;\n builderState.onlyDeleted = state.onlyDeleted;\n builderState.skipDefaultScope = state.skipDefaultScope;\n builderState.variantConfig = state.variantConfig;\n builderState.enabledVariants =\n state.enabledVariants !== null\n ? new Set(state.enabledVariants)\n : null;\n builderState.variantWhereFilters = [...state.variantWhereFilters];\n builderState.variantRelationIncludes = [\n ...state.variantRelationIncludes\n ];\n return builder;\n }\n\n // =======================================================================\n // EXECUTION\n // =======================================================================\n\n toQuery(): string {\n return getQuery(this).toQuery();\n }\n\n toKnexQuery(): Knex.QueryBuilder {\n return getQuery(this);\n }\n\n toString(): string {\n return getQuery(this).toString();\n }\n\n async execute(): Promise<TResult[]> {\n return executeImpl(this) as Promise<TResult[]>;\n }\n\n async first(): Promise<TResult | undefined> {\n const query = getQuery(this).first();\n const row = await query;\n\n if (!row) return undefined;\n return cleanAndMapRow(this, row) as TResult;\n }\n\n async pluck<K extends keyof TResult & string>(\n column: ColumnRef<TLocalSchema>\n ): Promise<TResult[K][]> {\n const _state = getState(this);\n const col = resolveColumn(this, column, 'pluck') as string;\n const rows = await buildQuery(this).select(col);\n return rows.map(\n (row: any) => row[col] ?? row[column as string]\n ) as TResult[K][];\n }\n\n // biome-ignore lint/suspicious/noThenProperty: intentional thenable\n then<TReturn1 = TResult[], TReturn2 = never>(\n onfulfilled?:\n | ((value: TResult[]) => TReturn1 | PromiseLike<TReturn1>)\n | null,\n onrejected?: ((reason: any) => TReturn2 | PromiseLike<TReturn2>) | null\n ): Promise<TReturn1 | TReturn2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n}\n\n// Register the constructor for circular-dependency-safe access\nregisterSchemaQueryBuilder(SchemaQueryBuilder);\n\n// ---------------------------------------------------------------------------\n// query() — main entry point\n// ---------------------------------------------------------------------------\n\nexport function query<\n TLocalSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(\n knex: Knex,\n schema: TLocalSchema\n): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>;\n\nexport function query<\n TLocalSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(\n knex: Knex,\n schema: TLocalSchema,\n baseQuery: Knex.QueryBuilder\n): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>;\n\nexport function query<\n TLocalSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>\n>(\n knex: Knex,\n schema: TLocalSchema,\n baseQuery?: Knex.QueryBuilder\n): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>> {\n return new SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>(\n knex,\n schema,\n baseQuery\n );\n}\n\n// ---------------------------------------------------------------------------\n// createQuery() — knex-bound factory\n// ---------------------------------------------------------------------------\n\nexport interface BoundQuery {\n <\n TLocalSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n schema: TLocalSchema\n ): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>;\n <\n TLocalSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n schema: TLocalSchema,\n baseQuery: Knex.QueryBuilder\n ): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>>;\n withTransaction(trx: Knex.Transaction): BoundQuery;\n transaction<T>(callback: (db: BoundQuery) => Promise<T>): Promise<T>;\n}\n\nexport function createQuery(knexInstance: Knex): BoundQuery {\n function boundQuery<\n TLocalSchema extends ObjectSchemaBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n >(\n schema: TLocalSchema,\n baseQuery?: Knex.QueryBuilder\n ): SchemaQueryBuilder<TLocalSchema, QueryResultType<TLocalSchema>> {\n return baseQuery\n ? query(knexInstance, schema, baseQuery)\n : query(knexInstance, schema);\n }\n\n (boundQuery as BoundQuery).withTransaction = (\n trx: Knex.Transaction\n ): BoundQuery => createQuery(trx as unknown as Knex);\n\n (boundQuery as BoundQuery).transaction = <T>(\n callback: (db: BoundQuery) => Promise<T>\n ): Promise<T> =>\n knexInstance.transaction(trx =>\n callback(createQuery(trx as unknown as Knex))\n );\n\n return boundQuery as BoundQuery;\n}\n","// @cleverbrush/knex-schema — Schema snapshot serialization\n\nimport { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { Entity } from './entity.js';\nimport { getPolymorphicVariantSchemas, getTableName } from './extension.js';\nimport { entitySchemaToTableState } from './migration.js';\nimport type { SchemaSnapshot } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Builders\n// ---------------------------------------------------------------------------\n\n/**\n * Build a {@link SchemaSnapshot} from a set of entities without a live DB.\n *\n * Handles polymorphic (CTI) entities by including each variant table.\n * Deduplicates tables so STI variants sharing a base table are only included\n * once.\n *\n * @param entities - The entities from your `EntityMap`.\n * @returns A snapshot reflecting the current code-first schema state.\n *\n * @example\n * ```ts\n * const snapshot = entitiesToSnapshot(Object.values(entityMap));\n * writeSnapshot('./migrations/snapshot.json', snapshot);\n * ```\n */\nexport function entitiesToSnapshot(\n entities: Entity<any, any>[]\n): SchemaSnapshot {\n const tables: SchemaSnapshot['tables'] = {};\n\n for (const entity of entities) {\n const schema = entity.schema;\n const tableName = getTableName(schema);\n if (!tables[tableName]) {\n tables[tableName] = entitySchemaToTableState(schema);\n }\n\n for (const vs of getPolymorphicVariantSchemas(schema)) {\n const variantTableName = vs.getExtension('tableName') as\n | string\n | undefined;\n if (variantTableName && !tables[variantTableName]) {\n tables[variantTableName] = entitySchemaToTableState(vs);\n }\n }\n }\n\n return { version: 1, tables };\n}\n\n// ---------------------------------------------------------------------------\n// I/O\n// ---------------------------------------------------------------------------\n\n/**\n * Load a {@link SchemaSnapshot} from disk.\n *\n * Returns an empty snapshot (no tables) when the file does not exist — this\n * is the \"first run\" case, which causes `migrate generate` to emit a single\n * migration containing `CREATE TABLE` for every entity.\n *\n * @param snapshotPath - Absolute or cwd-relative path to `snapshot.json`.\n * @returns The parsed snapshot, or `{ version: 1, tables: {} }` if missing or\n * unreadable.\n */\nexport function loadSnapshot(snapshotPath: string): SchemaSnapshot {\n try {\n const raw = readFileSync(resolve(snapshotPath), 'utf-8');\n const parsed = JSON.parse(raw) as SchemaSnapshot;\n if (\n parsed.version !== 1 ||\n parsed.tables == null ||\n typeof parsed.tables !== 'object'\n ) {\n return { version: 1, tables: {} };\n }\n return parsed;\n } catch {\n return { version: 1, tables: {} };\n }\n}\n\n/**\n * Write a {@link SchemaSnapshot} to disk atomically (temp-file + rename) with\n * deterministic key ordering so diffs in version control are minimal.\n *\n * @param snapshotPath - Absolute or cwd-relative path to write `snapshot.json`.\n * @param snapshot - The snapshot to serialize.\n */\nexport function writeSnapshot(\n snapshotPath: string,\n snapshot: SchemaSnapshot\n): void {\n const absPath = resolve(snapshotPath);\n const tmp = absPath + '.tmp';\n writeFileSync(\n tmp,\n JSON.stringify(_sortSnapshot(snapshot), null, 2) + '\\n',\n 'utf-8'\n );\n renameSync(tmp, absPath);\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** @internal Sort all keys in the snapshot for deterministic JSON output. */\nfunction _sortSnapshot(snapshot: SchemaSnapshot): SchemaSnapshot {\n const sortedTables: SchemaSnapshot['tables'] = {};\n for (const tableName of Object.keys(snapshot.tables).sort()) {\n const state = snapshot.tables[tableName];\n sortedTables[tableName] = {\n columns: Object.fromEntries(\n Object.entries(state.columns).sort(([a], [b]) =>\n a.localeCompare(b)\n )\n ),\n indexes: [...state.indexes].sort((a, b) =>\n a.name.localeCompare(b.name)\n ),\n foreignKeys: [...state.foreignKeys].sort((a, b) =>\n a.constraintName.localeCompare(b.constraintName)\n ),\n checks: [...state.checks].sort((a, b) =>\n a.name.localeCompare(b.name)\n )\n };\n }\n return { version: 1, tables: sortedTables };\n}\n"],"mappings":"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","names":["ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","columnMapCache","buildColumnMap","schema","cached","properties","propToCol","colToProp","propKey","propSchema","colName","getColumnName","result","jsonPathRaw","knex","col","jsonPath","pathLiteral","resolveColumnRef","ref","label","topProp","tree","ObjectSchemaBuilder","descriptor","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","pointer","segments","s","resolvePropertyKey","getPrimaryKeyColumns","introspected","extensions","composite","propertyKeys","columnNames","entry","getRowVersionColumn","rv","resolveColumnType","table","col","introspected","ext","maxLen","applyDefault","column","defaultValue","knex","generateCreateTable","schema","tableName","getTableName","tableExt","extensionManagedCols","builder","properties","propKey","propSchema","getColumnName","propIntrospected","fkBuilder","idx","unq","chk","rawCol","rawIndexes","rawIdx","generateCreateTableSource","lines","line","_colTypeCode","_fmtDefault","cols","rawIndexLines","ri","up","down","value","generateCreatePolymorphicTables","result","variantSchemas","getPolymorphicVariantSchemas","variantSchema","ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","Entity","_Entity","schema","spec","existing","next","navSel","_localSel","remoteSel","opts","navName","foreignSchema","remoteKey","localSel","_remoteSel","localKey","through","sel","discKey","key","variant","fkSel","builder","fkColumn","resolveCtiForeignKeyColumn","nextVariants","entityRelationsToVariantRelations","resolveInlineVariantRelations","body","isEntity","varSchema","variants","newSchema","applyVariantsToSchema","existingRelations","selector","tree","ObjectSchemaBuilder","descriptor","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","inner","propSchema","intro","varEntity","rels","propToCol","buildColumnMap","r","fkPropName","fkColName","propKey","getColumnName","relations","result","name","foreignKey","targetSchema","defineEntity","MAPPERS","value","mapValue","mapper","mapObject","obj","mappers","result","key","clearRow","row","oneSpecs","manySpecs","spec","fieldName","k","normalizeDbState","columns","indexes","foreignKeys","checks","colMap","row","idxList","fkList","chkList","introspectDatabase","knex","tableName","schemaTypeToDbType","introspected","ext","entitySchemaToTableState","schema","getTableName","properties","tableExt","propKey","propSchema","col","getColumnName","propIntrospected","ts","createdAtCol","updatedAtCol","delCol","idx","idxName","unq","unqName","diffSchema","dbState","addColumns","dropColumns","alterColumns","addIndexes","dropIndexes","addForeignKeys","dropForeignKeys","extensionOwnedDefaults","schemaColumns","dbCol","changes","expectedNullable","snapshotDefault","schemaDefault","fk","colName","schemaIndexNames","dbIdx","ps","generateMigration","diff","up","down","buildAlterTableFragments","full","tableExistsInDb","validateEntitiesAgainstDatabase","entities","unique","collectUniqueEntityTables","issues","isDiffEmpty","entry","applyDiff","constraintName","table","column","buildColumnFromDbType","fkBuilder","key","change","builder","generateMigrationsForContext","prevSnapshot","uniqueEntries","sorted","topologicalSort","upParts","downParts","currentTableNames","e","snapshotState","generateCreateTableSource","state","generateDropTableSource","isEmpty","nextTables","colLines","line","upLines","downLines","mapTypeToKnex","formatDefault","toVal","fromVal","cols","name","dbType","tableEntries","entity","variantSchema","getPolymorphicVariantSchemas","variantTableName","seen","entries","tableSet","deps","depSet","inDegree","graph","dep","queue","t","deg","sortedNames","dependent","newDeg","sortedSet","remaining","byName","type","value","rawQuery","knex","schema","queryOrSql","bindings","rows","result","colToProp","buildColumnMap","row","mapped","key","value","propName","ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","STATE","getState","builder","s","setState","state","resolveColumn","builder","ref","label","state","getState","resolveColumnRef","invalidateCache","getSoftDelete","getDefaultScope","fn","getTimestamps","ALLOWED_OPS","getVariantConfig","builder","state","getState","raw","getVariants","propToCol","buildColumnMap","discCol","applyVariantJoins","base","variantConfig","knex","baseTable","basePkCol","findPrimaryKeyColumn","qb","key","spec","variantAlias","variantTable","fkCol","variantProps","propKey","colName","vrInc","variantSpec","relSpec","r","foreignSchema","resolveSchema","foreignTableName","getTableName","relAlias","localCol","foreignCol","onExpr","foreignKnex","selectionSql","buildVariantRelationSelect","sel","filter","discColFull","SchemaQueryBuilderCtor","registerSchemaQueryBuilder","ctor","getSchemaQueryBuilderCtor","customize","foreignProps","columnsToSelect","probe","explicit","p","mapPolymorphicRow","row","baseColToProp","result","value","propName","discPropKey","discValue","varColToProp","prefix","fkAlias","origCol","variantSpec3","relColToProp","nested","anyNonNull","_builder","schema","pk","getPrimaryKeyColumns","resolvePkColumns","getEffectiveBaseQuery","effectiveBase","cloned","softDelete","getSoftDelete","defaultScopeFn","getDefaultScope","proxy","proxyState","buildJoinOne","resultQuery","relationAlias","foreignTable","subquery","joinMethod","buildJoinMany","i","filterName","hasLimitOffset","orderByColumn","orderByDirection","aggSubquery","hasLimit","hasOffset","effectiveOffset","effectiveLimit","condition","orderClause","buildQuery","queryBase","specs","requiredLocalColumns","s","cteQuery","extraColumns","selectedSet","col","getQuery","mapRow","colToProp","cleanAndMapRow","oneSpecs","manySpecs","cleaned","clearRow","mapObjectToColumns","obj","mapRecordToColumns","record","resolveColumnArg","resolveColumn","isColumnAccessor","fn","tree","ObjectSchemaBuilder","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","assertNotProjection","method","assertNotExplicitSelect","selectImpl","builder","args","state","getState","fn","tree","ObjectSchemaBuilder","result","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","invalidateCache","assertNotProjection","aliasMap","alias","descriptor","col","resolveColumn","resolved","c","resolveColumnArg","r","distinctImpl","columns","countImpl","column","countDistinctImpl","minImpl","maxImpl","sumImpl","avgImpl","selectRawImpl","sql","bindings","projectedImpl","name","assertNotExplicitSelect","projection","getProjections","propToCol","buildColumnMap","sqlCols","key","scopedImpl","scopeFn","unscopedImpl","OnConflictBuilder","#knex","#localSchema","#conflictColumns","knex","localSchema","_parent","conflictColumns","data","updateData","options","resolvedUpdateData","resolvedOptions","isMergeOptions","#execute","mode","tableName","getTableName","timestamps","beforeHooks","processed","hook","propToCol","buildColumnMap","mapped","key","val","qb","helpers","#createMergeHelpers","mergeObj","rows","colToProp","result","col","ref","#resolveTopLevelColumn","sql","bindings","column","resolveColumnRef","value","keys","insertImpl","builder","state","getState","processedData","mapObjectToColumns","getTimestamps","row","mapRow","afterHooks","insertManyImpl","d","m","results","onConflictImpl","cols","c","resolveColumn","upsertImpl","opts","updateCols","bulkInsertImpl","requestedChunkSize","bindingsPerRow","safeChunkCap","chunkSize","conflictCols","i","chunk","k","inserted","mappedRow","bulkUpsertImpl","deleteImpl","builder","state","getState","hooks","hook","softDelete","getSoftDelete","withDeletedImpl","invalidateCache","onlyDeletedImpl","hardDeleteImpl","restoreImpl","row","mapRow","resolveForeignQuery","spec","knex","tableName","getTableName","validateJoinOne","localSchema","localColumn","resolveColumnRef","foreignColumn","foreignQuery","required","validateMappers","validateJoinMany","limit","offset","orderBy","mappers","key","m","MAPPERS","validateUniqueFieldNames","specs","seen","joinOneImpl","builder","spec","state","getState","validated","validateJoinOne","validateUniqueFieldNames","invalidateCache","joinManyImpl","validateJoinMany","includeImpl","relationName","customize","relation","r","variantConfig","getVariantConfig","matches","vKey","vSpec","includeVariantImpl","m","foreignSchema","resolveSchema","foreignTableName","getTableName","localColumn","resolveColumnRef","foreignColumn","findPrimaryKeyColumn","foreignQuery1","SQB","getSchemaQueryBuilderCtor","proxy","foreignQuery2","foreignQuery3","through","foreignQuery","variantKey","variantSpec","whereImpl","builder","columnOrRaw","args","state","getState","invalidateCache","isColumnAccessor","mapped","mapRecordToColumns","col","resolveColumnArg","andWhereImpl","orWhereImpl","whereNotImpl","whereInImpl","column","values","resolveColumn","whereNotInImpl","orWhereInImpl","orWhereNotInImpl","whereNullImpl","whereNotNullImpl","orWhereNullImpl","orWhereNotNullImpl","whereBetweenImpl","range","whereNotBetweenImpl","whereLikeImpl","value","whereILikeImpl","whereRawImpl","sql","bindings","whereExistsImpl","callback","whereNotExistsImpl","whereJsonPathImpl","path","operator","client","op","escapedOp","jsonPath","orderByImpl","direction","orderByRawImpl","groupByImpl","columns","resolved","c","groupByRawImpl","havingImpl","havingRawImpl","limitImpl","builder","state","getState","invalidateCache","offsetImpl","paginateImpl","opts","page","pageSize","_state","countResult","getEffectiveBaseQuery","total","data","executeImpl","totalPages","paginateAfterImpl","direction","column","whereImpl","orderByImpl","rows","hasMore","propKey","resolvePropertyKey","nextCursor","getQuery","row","cleanAndMapRow","updateImpl","builder","data","state","getState","processedData","beforeHooks","hook","mapped","mapObjectToColumns","timestamps","getTimestamps","row","mapRow","bulkUpdateImpl","updates","pk","resolvePkColumns","propToCol","buildColumnMap","processed","entry","setData","setMapped","whereRec","pkValues","propKey","value","allSetCols","p","k","knex","updateExpr","col","fragments","bindings","conditions","i","qb","SchemaQueryBuilder","_SchemaQueryBuilder","knex","localSchema","baseQuery","tableName","getTableName","setState","args","selectImpl","columns","distinctImpl","column","countImpl","countDistinctImpl","minImpl","maxImpl","sumImpl","avgImpl","sql","bindings","selectRawImpl","name","projectedImpl","scopedImpl","unscopedImpl","columnOrRaw","whereImpl","andWhereImpl","orWhereImpl","whereNotImpl","values","whereInImpl","whereNotInImpl","orWhereInImpl","orWhereNotInImpl","whereNullImpl","whereNotNullImpl","orWhereNullImpl","orWhereNotNullImpl","range","whereBetweenImpl","whereNotBetweenImpl","value","whereLikeImpl","whereILikeImpl","whereRawImpl","callback","whereExistsImpl","whereNotExistsImpl","path","operator","whereJsonPathImpl","direction","orderByImpl","orderByRawImpl","groupByImpl","groupByRawImpl","havingImpl","havingRawImpl","limitImpl","offsetImpl","opts","paginateImpl","paginateAfterImpl","data","insertImpl","insertManyImpl","conflictColumns","onConflictImpl","upsertImpl","rows","bulkInsertImpl","bulkUpsertImpl","updateImpl","updates","bulkUpdateImpl","deleteImpl","withDeletedImpl","onlyDeletedImpl","hardDeleteImpl","restoreImpl","spec","joinOneImpl","joinManyImpl","relationName","customize","includeImpl","variantKey","includeVariantImpl","key","state","getState","variantConfig","getVariantConfig","op","ALLOWED_OPS","propToCol","buildColumnMap","colName","qualifiedColumn","invalidateCache","keys","fn","trx","builder","builderState","getQuery","executeImpl","row","cleanAndMapRow","_state","col","resolveColumn","buildQuery","onfulfilled","onrejected","registerSchemaQueryBuilder","query","schema","createQuery","knexInstance","boundQuery","readFileSync","renameSync","writeFileSync","resolve","entitiesToSnapshot","entities","tables","entity","schema","tableName","getTableName","entitySchemaToTableState","vs","getPolymorphicVariantSchemas","variantTableName","loadSnapshot","snapshotPath","raw","readFileSync","resolve","parsed","writeSnapshot","snapshot","absPath","tmp","writeFileSync","_sortSnapshot","renameSync","sortedTables","state","a","b"]}