@nextlyhq/adapter-drizzle 0.0.2-alpha.62 → 0.0.2-alpha.65
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/README.md +25 -1
- package/dist/{adapter-BeMxQXZs.d.cts → adapter-C6ENLDau.d.cts} +63 -1
- package/dist/{adapter-BRvxUZrS.d.ts → adapter-D4GM1VAZ.d.ts} +63 -1
- package/dist/index.cjs +107 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +108 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{migration-DhMuYiIm.d.cts → migration-B6AmjCQ1.d.cts} +25 -1
- package/dist/{migration-BnT96HFp.d.ts → migration-R06fsTrz.d.ts} +25 -1
- package/dist/migrations.d.cts +3 -3
- package/dist/migrations.d.ts +3 -3
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +3 -3
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/drizzle-order.ts","../src/drizzle-where.ts","../src/transaction-forwarders.ts","../src/types/error.ts","../src/adapter.ts","../src/index.ts"],"names":["isNull","sql","db","getColumns","result"],"mappings":"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","file":"index.mjs","sourcesContent":["import { asc, desc, sql } from \"drizzle-orm\";\nimport type { AnyColumn, SQL } from \"drizzle-orm\";\n\nimport type { OrderBySpec } from \"./types\";\n\n/**\n * Turn order specifications into drizzle order clauses.\n *\n * Extracted from `DrizzleAdapter.select` so the rendered SQL can be asserted\n * directly. That matters more than it looks: `OrderBySpec.nulls` was declared,\n * documented as \"can be explicitly controlled\", and read NOWHERE — every caller\n * that set it silently got the dialect default instead, and no test could have\n * caught that while the mapping lived inline in a method that needs a database.\n *\n * ## Why null placement is a leading sort key, not `NULLS FIRST/LAST`\n *\n * That clause is not portable: PostgreSQL and SQLite accept it, MySQL does not.\n * `col IS NULL` is a boolean expression all three evaluate, and sorting on it\n * ascending puts non-null rows first — which is `NULLS LAST` by another name,\n * spelled in something every supported engine understands.\n *\n * The defaults genuinely disagree, which is why the control exists at all:\n * PostgreSQL treats NULL as largest and puts it FIRST on a descending order,\n * while MySQL and SQLite treat it as smallest and put it last. A \"newest\n * scheduled first\" list containing undated drafts therefore returns different\n * rows per engine, and under a limit it can return only drafts.\n */\nexport function buildDrizzleOrderBy(\n columns: Record<string, AnyColumn>,\n orderBy: OrderBySpec[] | undefined\n): SQL[] {\n if (!orderBy?.length) return [];\n\n return orderBy.flatMap((spec): SQL[] => {\n const col = columns[spec.column];\n // An unknown column is skipped rather than thrown on: ordering is a\n // refinement, and a caller naming a column that is not there should get an\n // unordered answer rather than a failed query.\n if (!col) return [];\n\n const direction = spec.direction === \"desc\" ? desc(col) : asc(col);\n if (spec.nulls === undefined) return [direction];\n\n const isNull = sql`${col} is null`;\n return [spec.nulls === \"last\" ? asc(isNull) : desc(isNull), direction];\n });\n}\n","// Translates WhereClause objects into Drizzle SQL conditions.\n// Used internally by the adapter's CRUD methods when a TableResolver is available.\n\nimport {\n eq,\n ne,\n gt,\n lt,\n gte,\n lte,\n like,\n ilike,\n inArray,\n notInArray,\n isNull,\n isNotNull,\n between,\n notBetween,\n and,\n or,\n not,\n sql,\n type SQL,\n} from \"drizzle-orm\";\nimport { getColumns } from \"drizzle-orm\";\n\nimport type { WhereClause, WhereCondition } from \"./types\";\n\n// Build a Drizzle SQL condition from a WhereClause and a Drizzle table object.\n// Returns undefined if the where clause is empty.\nexport function buildDrizzleWhere(\n table: Record<string, unknown>,\n where: WhereClause\n): SQL | undefined {\n const columns = getColumns(table as never);\n return processWhereClause(columns, where);\n}\n\nfunction processWhereClause(\n columns: Record<string, unknown>,\n where: WhereClause\n): SQL | undefined {\n const parts: SQL[] = [];\n\n if (where.and?.length) {\n const andParts = where.and\n .map(item => {\n if (isWhereCondition(item)) {\n return buildCondition(columns, item);\n }\n return processWhereClause(columns, item);\n })\n .filter((p): p is SQL => p !== undefined);\n\n if (andParts.length) {\n parts.push(and(...andParts)!);\n }\n }\n\n if (where.or?.length) {\n const orParts = where.or\n .map(item => {\n if (isWhereCondition(item)) {\n return buildCondition(columns, item);\n }\n return processWhereClause(columns, item);\n })\n .filter((p): p is SQL => p !== undefined);\n\n if (orParts.length) {\n parts.push(or(...orParts)!);\n }\n }\n\n if (where.not) {\n const notItem = where.not;\n const notCondition = isWhereCondition(notItem)\n ? buildCondition(columns, notItem)\n : processWhereClause(columns, notItem);\n\n if (notCondition) {\n parts.push(not(notCondition));\n }\n }\n\n if (parts.length === 0) {\n // A clause that named no branch at all is the caller saying \"no filter\", and `undefined` is\n // how that reaches the adapter. A clause that named one and produced nothing is a different\n // thing entirely: every branch it asked for evaporated — an `and`/`or` whose every member\n // resolved to nothing, or a `not` over such a member. Returning `undefined` for that is what\n // makes it dangerous rather than merely wrong, because `update` and `delete` take the where\n // clause as a REQUIRED argument and simply omit the WHERE when none comes back. A caller\n // that asked to delete a subset would delete the table. Refusing is consistent with the two\n // refusals below: this builder already rejects input it cannot express rather than\n // approximating it.\n if (namesABranch(where)) {\n throw new Error(\n `Where clause produced no condition: ${JSON.stringify(where)}. ` +\n `Every branch resolved to nothing, which would match every row. ` +\n `Pass {} to mean \"no filter\".`\n );\n }\n return undefined;\n }\n if (parts.length === 1) return parts[0];\n return and(...parts);\n}\n\nfunction isWhereCondition(\n item: WhereCondition | WhereClause\n): item is WhereCondition {\n return \"column\" in item && \"op\" in item;\n}\n\n/**\n * Whether the clause asked for a constraint at all — as opposed to being the empty clause a\n * caller passes to mean \"no filter\".\n *\n * An empty `and`/`or` array does NOT count: nothing was named, so nothing could be dropped.\n * What counts is a branch with members in it, or a `not`, because those are the shapes that can\n * resolve to nothing and leave the caller believing a filter was applied.\n */\nfunction namesABranch(where: WhereClause): boolean {\n // `||` and not `??`: an empty array's `length` is 0, which is defined, so `??` would stop at\n // the first branch that exists and never look at the others — `{ and: [], or: [{}] }` would\n // read as \"named nothing\" on the strength of the empty `and`.\n return Boolean(where.and?.length || where.or?.length || where.not);\n}\n\n/**\n * Wraps a value in `%…%` for a substring match, escaping the LIKE metacharacters inside it so\n * the value matches literally.\n *\n * `!` is the escape character rather than the more usual backslash, and it has to be, because\n * this builder emits one statement for every dialect. SQLite gives LIKE no default escape\n * character at all, so a backslash there is just a backslash; declaring `ESCAPE '\\'` instead\n * runs into MySQL, where the backslash also escapes inside the string literal and the clause\n * would have to be spelled differently per dialect. `ESCAPE '!'` parses identically on\n * PostgreSQL, MySQL and SQLite, and needs no per-dialect branch to stay correct.\n *\n * The escape character is escaped FIRST by including it in the character class, so a literal\n * `!` in the value cannot be produced by escaping something else afterwards.\n */\nfunction containsPattern(value: string): string {\n return `%${value.replace(/[!%_]/g, character => `!${character}`)}%`;\n}\n\nfunction buildCondition(\n columns: Record<string, unknown>,\n cond: WhereCondition\n): SQL {\n const column = columns[cond.column];\n if (!column) {\n throw new Error(\n `Column \"${cond.column}\" not found in table. Available: ${Object.keys(columns).join(\", \")}`\n );\n }\n\n const col = column as never;\n\n switch (cond.op) {\n case \"=\":\n return eq(col, cond.value);\n case \"!=\":\n return ne(col, cond.value);\n case \">\":\n return gt(col, cond.value);\n case \"<\":\n return lt(col, cond.value);\n case \">=\":\n return gte(col, cond.value);\n case \"<=\":\n return lte(col, cond.value);\n case \"LIKE\":\n return like(col, cond.value as string);\n case \"ILIKE\":\n return ilike(col, cond.value as string);\n case \"IN\":\n return inArray(col, cond.value as unknown[]);\n case \"NOT IN\":\n return notInArray(col, cond.value as unknown[]);\n case \"IS NULL\":\n return isNull(col);\n case \"IS NOT NULL\":\n return isNotNull(col);\n case \"BETWEEN\":\n return between(col, cond.value, cond.valueTo);\n case \"NOT BETWEEN\":\n return notBetween(col, cond.value, cond.valueTo);\n case \"CONTAINS\":\n // A substring match on a TEXT column, NOT JSON containment despite the operator's name.\n // The column is used uncast, so this is text-columns-only: PostgreSQL has no `LIKE` for\n // `json`/`jsonb` and the statement errors there, while MySQL and SQLite coerce and search\n // the serialized text. Casting per dialect would make it work on all three and is a\n // change to what the operator DOES, so it is not made here.\n //\n // The value is matched LITERALLY: a `%` or `_` the caller passed is a character to find,\n // not a wildcard, so both are escaped and the escape character is declared. Without that,\n // `CONTAINS \"a%b\"` silently widens to \"a, anything, b\" — and through `delete`, which takes\n // its where clause as a required argument, a widened match is a widened deletion.\n return sql`${col} like ${containsPattern(String(cond.value))} escape '!'`;\n default:\n throw new Error(`Unsupported operator: ${cond.op}`);\n }\n}\n","/**\n * Transaction CRUD forwarder helper for database adapters.\n *\n * @remarks\n * Encapsulates the delegation pattern where a transaction context forwards its\n * CRUD methods to the adapter's implementation while passing the transaction-bound\n * Drizzle executor.\n *\n * @packageDocumentation\n */\n\nimport type {\n DeleteOptions,\n SelectOptions,\n TransactionContext,\n UpdateOptions,\n UpsertOptions,\n WhereClause,\n} from \"./types\";\n\n/**\n * Interface representing an adapter that can execute CRUD operations with an optional executor.\n */\nexport interface TransactionCrudDelegator {\n select<T = unknown>(\n table: string,\n options?: SelectOptions,\n executor?: unknown\n ): Promise<T[]>;\n selectOne<T = unknown>(\n table: string,\n options?: SelectOptions,\n executor?: unknown\n ): Promise<T | null>;\n update<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n options?: UpdateOptions,\n executor?: unknown\n ): Promise<T[]>;\n updateCount(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n executor?: unknown\n ): Promise<number>;\n delete(\n table: string,\n where: WhereClause,\n options?: DeleteOptions,\n executor?: unknown\n ): Promise<number>;\n upsert<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options: UpsertOptions,\n executor?: unknown\n ): Promise<T>;\n}\n\n/**\n * Transaction context CRUD methods provided by the forwarder.\n */\nexport type TransactionCrudForwarders = Pick<\n TransactionContext,\n | \"select\"\n | \"selectOne\"\n | \"update\"\n // The fenced compare-and-set. Listed explicitly like every other key here:\n // the type is DERIVED from `TransactionContext` in the sense that its\n // signatures come from there, but the key set is enumerated, so a method\n // added to the context is not forwarded until it is named here too.\n | \"updateCount\"\n | \"delete\"\n | \"upsert\"\n | \"getDrizzle\"\n>;\n\n/**\n * Create CRUD and Drizzle instance forwarding methods for a TransactionContext.\n *\n * @remarks\n * TransactionContext delegates its CRUD methods to the adapter's Drizzle CRUD\n * implementation while binding the transaction executor so queries run inside\n * the transaction rather than on the connection pool.\n *\n * @param delegator - Object providing the underlying adapter CRUD methods\n * @param txDb - Thunk returning the transaction-bound Drizzle instance\n * @returns Object with forwarded TransactionContext methods\n */\nexport function createTransactionForwarders(\n delegator: TransactionCrudDelegator,\n txDb: () => unknown\n): TransactionCrudForwarders {\n return {\n select: async <T = unknown>(\n table: string,\n options?: SelectOptions\n ): Promise<T[]> => {\n return delegator.select<T>(table, options, txDb());\n },\n\n selectOne: async <T = unknown>(\n table: string,\n options?: SelectOptions\n ): Promise<T | null> => {\n return delegator.selectOne<T>(table, options, txDb());\n },\n\n update: async <T = unknown>(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n options?: UpdateOptions\n ): Promise<T[]> => {\n return delegator.update<T>(table, data, where, options, txDb());\n },\n\n updateCount: async (\n table: string,\n data: Record<string, unknown>,\n where: WhereClause\n ): Promise<number> => {\n return delegator.updateCount(table, data, where, txDb());\n },\n\n delete: async (\n table: string,\n where: WhereClause,\n options?: DeleteOptions\n ): Promise<number> => {\n return delegator.delete(table, where, options, txDb());\n },\n\n upsert: async <T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options: UpsertOptions\n ): Promise<T> => {\n return delegator.upsert<T>(table, data, options, txDb());\n },\n\n getDrizzle: <T = unknown>(): T => txDb() as T,\n };\n}\n","/**\n * Database error type definitions.\n *\n * @packageDocumentation\n */\n\n/**\n * Database error classification.\n *\n * @remarks\n * Categorizes database errors for consistent error handling across adapters.\n * Each adapter translates database-specific error codes to these kinds.\n *\n * @public\n */\nexport type DatabaseErrorKind =\n | \"connection\" // Connection/network errors\n | \"query\" // Syntax or execution errors\n | \"constraint\" // Generic constraint violation\n | \"unique_violation\" // Unique constraint violation\n | \"foreign_key_violation\" // Foreign key constraint violation\n | \"check_violation\" // Check constraint violation\n | \"not_null_violation\" // NOT NULL constraint violation\n | \"deadlock\" // Transaction deadlock\n | \"timeout\" // Query or connection timeout\n | \"serialization_failure\" // Serializable transaction conflict\n | \"unsupported_version\" // F17: DB version below minimum or unparseable at connect\n | \"unknown\"; // Unclassified error\n\n/**\n * Enhanced database error interface.\n *\n * @remarks\n * Extends the standard Error interface with database-specific context.\n * Adapters should throw errors implementing this interface for consistent\n * error handling.\n *\n * @example\n * ```typescript\n * try {\n * await adapter.insert('users', { email: 'duplicate@example.com' });\n * } catch (error) {\n * if (isDatabaseError(error) && error.kind === 'unique_violation') {\n * console.log(`Duplicate ${error.column} in ${error.table}`);\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface DatabaseError extends Error {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Database-specific error code (e.g., \"23505\" for PostgreSQL unique violation) */\n code?: string;\n\n /** Constraint name that was violated (if applicable) */\n constraint?: string;\n\n /** Table name involved in the error */\n table?: string;\n\n /** Column name involved in the error */\n column?: string;\n\n /** Detailed error description from the database */\n detail?: string;\n\n /** Hint for resolving the error */\n hint?: string;\n\n /** Original error from the database driver */\n cause?: Error;\n}\n\n/**\n * Type guard for DatabaseError.\n *\n * @remarks\n * Checks if an error is a DatabaseError with proper typing.\n *\n * @param error - Error to check\n * @returns True if error is a DatabaseError\n *\n * @public\n */\nexport function isDatabaseError(error: unknown): error is DatabaseError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"kind\" in error &&\n typeof (error as DatabaseError).kind === \"string\"\n );\n}\n\n/**\n * The brand every Nextly application error carries.\n *\n * Read through the global symbol registry rather than imported, because the\n * adapters must not depend on the package that defines the error: `Symbol.for`\n * resolves to the same symbol in every module instance, which is why the brand\n * exists in that form to begin with.\n *\n * @internal\n */\nconst APPLICATION_ERROR_BRAND: unique symbol = Symbol.for(\"nextly/NextlyError\");\n\n/**\n * Whether an error is the application's verdict rather than the database's\n * failure.\n *\n * Work running inside a transaction may throw to roll the write back — a\n * refused value, a permission denial — and such an error is not something the\n * driver produced. Classifying it as a database error replaces its code and its\n * payload with a generic one, so a caller that asked for a refusal is handed an\n * unexplained failure instead, and per-field validation detail is lost on the\n * way out.\n *\n * @param error - Error to check\n * @returns True if the error was raised by application code\n *\n * @public\n */\nexport function isApplicationError(error: unknown): boolean {\n if (\n error === null ||\n (typeof error !== \"object\" && typeof error !== \"function\")\n ) {\n return false;\n }\n return (error as Record<symbol, unknown>)[APPLICATION_ERROR_BRAND] === true;\n}\n\n/**\n * Database error constructor options.\n *\n * @public\n */\nexport interface DatabaseErrorOptions {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Error message */\n message: string;\n\n /** Database-specific error code */\n code?: string;\n\n /** Constraint name */\n constraint?: string;\n\n /** Table name */\n table?: string;\n\n /** Column name */\n column?: string;\n\n /** Detailed description */\n detail?: string;\n\n /** Resolution hint */\n hint?: string;\n\n /** Original error */\n cause?: Error;\n}\n\n/**\n * Create a DatabaseError instance.\n *\n * @remarks\n * Helper function to create properly structured DatabaseError objects.\n *\n * @param options - Error options\n * @returns DatabaseError instance\n *\n * @public\n */\nexport function createDatabaseError(\n options: DatabaseErrorOptions\n): DatabaseError {\n const error = new Error(options.message) as DatabaseError;\n error.name = \"DatabaseError\";\n error.kind = options.kind;\n\n if (options.code !== undefined) error.code = options.code;\n if (options.constraint !== undefined) error.constraint = options.constraint;\n if (options.table !== undefined) error.table = options.table;\n if (options.column !== undefined) error.column = options.column;\n if (options.detail !== undefined) error.detail = options.detail;\n if (options.hint !== undefined) error.hint = options.hint;\n if (options.cause !== undefined) error.cause = options.cause;\n\n return error;\n}\n","/**\n * Base database adapter abstract class.\n *\n * @remarks\n * This abstract class provides the foundation for all dialect-specific database adapters\n * (PostgreSQL, MySQL, SQLite). It defines required abstract methods that must be implemented\n * by subclasses, while providing default implementations for CRUD operations and query building.\n *\n * Dialect adapters can override any default method to provide optimized implementations.\n *\n * @packageDocumentation\n */\n\nimport { getColumns } from \"drizzle-orm\";\nimport type { AnyRelations, SQL } from \"drizzle-orm\";\n\nimport { buildDrizzleOrderBy } from \"./drizzle-order\";\nimport { buildDrizzleWhere } from \"./drizzle-where\";\nimport {\n createTransactionForwarders,\n type TransactionCrudForwarders,\n} from \"./transaction-forwarders\";\nimport type {\n SupportedDialect,\n SqlParam,\n WhereClause,\n SelectOptions,\n InsertOptions,\n UpdateOptions,\n DeleteOptions,\n UpsertOptions,\n TransactionContext,\n TransactionOptions,\n DatabaseCapabilities,\n PoolStats,\n DatabaseError,\n DatabaseErrorKind,\n Migration,\n MigrationResult,\n TableDefinition,\n CreateTableOptions,\n DropTableOptions,\n AlterTableOptions,\n AlterTableOperation,\n TableResolver,\n} from \"./types\";\nimport { createDatabaseError, isDatabaseError } from \"./types\";\n\n/**\n * A Drizzle column that decodes its own driver representation.\n *\n * `dataType` is the dialect-independent kind (\"string\", \"boolean\", \"date\");\n * `mapFromDriverValue` turns what the driver handed back into the JS value a\n * Drizzle query would have produced.\n */\ninterface DecodableColumn {\n dataType: unknown;\n mapFromDriverValue(value: unknown): unknown;\n mapToDriverValue(value: unknown): unknown;\n}\n\n/**\n * Matches the `dataType` a Drizzle timestamp/datetime column reports, in both\n * the bare form and the object-qualified form some column classes carry.\n */\nconst DATE_DATA_TYPE = /(?:^|\\s)date$/;\n\n/**\n * How far an echoed timestamp may sit from the one that was bound and still\n * count as the same value.\n *\n * A column with no fractional precision keeps whole seconds, so a stored value\n * can differ from the bound one by up to a second without anything being wrong.\n * Every real UTC offset is at least fifteen minutes, so a shift is never\n * mistaken for rounding.\n */\n/**\n * Stem for the alias a statement spells a timestamp's wall clock out under.\n *\n * Short on purpose. PostgreSQL truncates an identifier at 63 bytes, and a\n * truncated alias is worse than a rejected one: the statement still succeeds,\n * the lookup misses the name it asked for, and the row keeps both the driver's\n * value and a stray property. A stem plus an index stays far inside the limit\n * whatever the column is called.\n */\nconst WALL_CLOCK_ALIAS_STEM = \"__nx_wc\";\n\n/**\n * A timestamp as the database itself spells it, in a fixed field order.\n *\n * Matched rather than handed to `new Date`, so nothing depends on the host's\n * parsing of a partial date. The fraction is optional and of any length, which\n * covers PostgreSQL's milliseconds and MySQL's microseconds alike.\n */\nconst WALL_CLOCK_PATTERN =\n /^(\\d{4})-(\\d{2})-(\\d{2})[T ](\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?$/;\n\n/**\n * Read a database's own rendering of a timestamp as UTC.\n *\n * The statement wrote a UTC wall clock, so reading one back as UTC is what\n * makes a write agree with a later read. The rendering is one the statement\n * asked for by name, so its shape does not depend on a session setting.\n *\n * Anything that does not match answers nothing, leaving the driver's value in\n * place rather than replacing it with an `Invalid Date`.\n */\nfunction parseWallClockAsUtc(text: string): Date | undefined {\n const match = WALL_CLOCK_PATTERN.exec(text.trim());\n if (!match) return undefined;\n const [, year, month, day, hour, minute, second, fraction = \"\"] = match;\n // Milliseconds, whatever precision the dialect rendered: a shorter fraction\n // is padded and a longer one truncated, which is what a `Date` can hold.\n const millis = Number(`${fraction}000`.slice(0, 3));\n const parsed = new Date(\n Date.UTC(\n Number(year),\n Number(month) - 1,\n Number(day),\n Number(hour),\n Number(minute),\n Number(second),\n millis\n )\n );\n // `Date.UTC` reads a year under 100 as shorthand for the 1900s, so year 50\n // would land in 1950. The database said 0050 and meant it.\n if (Number(year) < 100) parsed.setUTCFullYear(Number(year));\n return parsed;\n}\n\n/** Whether a table property is a date column that can convert its own values. */\nfunction isDateColumn(colDef: unknown): colDef is DecodableColumn {\n if (!colDef || typeof colDef !== \"object\") return false;\n const candidate = colDef as Partial<DecodableColumn>;\n return (\n typeof candidate.mapFromDriverValue === \"function\" &&\n typeof candidate.mapToDriverValue === \"function\" &&\n DATE_DATA_TYPE.test(String(candidate.dataType))\n );\n}\n\n/**\n * Whether a date column records the zone its value belongs to.\n *\n * A column declared WITH a time zone stores an instant, so a driver reading it\n * back gets the same moment whatever zone either end is in -- there is nothing\n * ambiguous to resolve and nothing to correct. Rendering one as text would\n * spell it in the session's zone, and reading that as UTC would move it.\n */\nfunction carriesTimeZone(colDef: unknown): boolean {\n return (colDef as { withTimezone?: unknown }).withTimezone === true;\n}\n\n/**\n * Abstract base class for database adapters.\n *\n * @remarks\n * All dialect-specific adapters must extend this class and implement the abstract methods.\n * Default implementations are provided for CRUD operations, which can be overridden for\n * optimization or dialect-specific behavior.\n *\n * ## Required Implementations\n *\n * Subclasses must implement:\n * - `dialect` - Database dialect identifier\n * - `connect()` - Establish database connection\n * - `disconnect()` - Close database connection\n * - `executeQuery()` - Execute raw SQL query\n * - `transaction()` - Execute operations within a transaction\n * - `getCapabilities()` - Report database feature support\n *\n * ## Optional Overrides\n *\n * Subclasses can override default CRUD methods for optimization:\n * - `select()`, `selectOne()` - Custom query optimization\n * - `insert()`, `insertMany()` - Bulk insert optimization\n * - `update()`, `delete()` - Custom update/delete logic\n * - `upsert()` - Dialect-specific upsert syntax\n *\n * @example\n * ```typescript\n * export class PostgresAdapter extends DrizzleAdapter {\n * readonly dialect = 'postgresql' as const;\n *\n * async connect() {\n * this.pool = new Pool({ connectionString: this.config.url });\n * // ... connection logic\n * }\n *\n * async executeQuery<T>(sql: string, params?: SqlParam[]) {\n * const result = await this.pool.query(sql, params);\n * return result.rows as T[];\n * }\n *\n * // ... other required methods\n * }\n * ```\n *\n * @public\n */\n/**\n * Rows affected by a write, normalised across the driver shapes Drizzle returns.\n *\n * mysql2 resolves to `[ResultSetHeader, FieldPacket[]]`, so treating any array\n * as a row list reports the tuple length — a constant 2 whether the statement\n * matched nothing, one row, or many. Callers that branch on the count (a\n * conditional claim, a retention loop) silently get the wrong answer on MySQL,\n * so the header is read first. node-postgres reports `rowCount` and\n * better-sqlite3 reports `changes`; a plain array is a RETURNING row list, whose\n * length is the count.\n */\nfunction affectedRowCount(result: unknown): number {\n if (Array.isArray(result)) {\n const header = result[0] as { affectedRows?: unknown } | undefined;\n if (header && typeof header.affectedRows === \"number\") {\n return header.affectedRows;\n }\n return result.length;\n }\n const record = result as Record<string, unknown> | null | undefined;\n const rowCount = record?.rowCount;\n if (typeof rowCount === \"number\") return rowCount;\n const changes = record?.changes;\n if (typeof changes === \"number\") return changes;\n return 0;\n}\n\n/**\n * The fragment of Drizzle's update builder `updateCount` uses, spelled dialect-neutrally.\n *\n * Declared rather than reached for through a permissive generic: the three dialects' builders carry\n * different type parameters but agree on this chain, so naming just the chain keeps the compiler\n * checking the call while leaving the parts that genuinely differ outside the contract. `set` is\n * awaitable on its own, which is what makes an update with no WHERE a complete statement rather\n * than a builder waiting for one.\n */\ninterface UpdateCapableDb {\n update(table: unknown): {\n set(values: Record<string, unknown>): PromiseLike<unknown> & {\n where(condition: unknown): PromiseLike<unknown>;\n };\n };\n}\n\nexport abstract class DrizzleAdapter {\n // ============================================================\n // Abstract Methods (MUST be implemented by subclasses)\n // ============================================================\n\n /**\n * Database dialect identifier.\n *\n * @remarks\n * Must be set by subclass to identify the database type.\n */\n abstract readonly dialect: SupportedDialect;\n\n /**\n * Establish connection to the database.\n *\n * @remarks\n * This method should be idempotent - calling it multiple times\n * should not create multiple connections.\n *\n * @throws {DatabaseError} If connection fails\n */\n abstract connect(): Promise<void>;\n\n /**\n * Close database connection and release resources.\n *\n * @remarks\n * This method should be idempotent - calling it multiple times\n * should be safe.\n */\n abstract disconnect(): Promise<void>;\n\n /**\n * Execute a raw SQL query.\n *\n * @param sql - SQL query to execute\n * @param params - Query parameters\n * @returns Array of result rows\n *\n * @throws {DatabaseError} If query execution fails\n */\n abstract executeQuery<T = unknown>(\n sql: string,\n params?: SqlParam[]\n ): Promise<T[]>;\n\n /**\n * Execute operations within a database transaction.\n *\n * @remarks\n * The transaction is automatically committed on success or rolled back on error.\n * Supports nested transactions via savepoints on databases that support them.\n *\n * Two kinds of error leave this method, and a caller has to be able to tell\n * them apart. An error carrying the Nextly application brand — see\n * `isApplicationError` — arrives exactly as it was thrown, because that is\n * the application refusing the write rather than the database failing to\n * perform it, and rewriting it would discard the code and payload the caller\n * is meant to act on.\n *\n * Everything else arrives as a `DatabaseError` with its kind classified, and\n * that deliberately includes an unbranded error the callback itself threw:\n * the brand is the only thing distinguishing a deliberate refusal from a\n * driver failure that surfaced through callback code, and guessing from the\n * throw site would put raw driver text on the wire under a caller's own\n * error shape.\n *\n * The rollback is the same either way.\n *\n * @param callback - Function to execute within transaction\n * @param options - Transaction options\n * @returns Result from the callback\n *\n * @throws {DatabaseError} If the transaction itself fails, or if the callback\n * threw an error that does not carry the application brand\n * @throws The callback's own error, unchanged, when it carries that brand\n */\n abstract transaction<T>(\n callback: (ctx: TransactionContext) => Promise<T>,\n options?: TransactionOptions\n ): Promise<T>;\n\n /**\n * Get database capabilities.\n *\n * @remarks\n * Returns static capability flags for this adapter's dialect.\n * Used by services to conditionally enable features or implement fallbacks.\n *\n * @returns Database capability flags\n */\n abstract getCapabilities(): DatabaseCapabilities;\n\n /**\n * Get the raw Drizzle ORM instance for direct queries.\n *\n * @remarks\n * This method provides escape hatch access to the raw Drizzle instance.\n * Use this when you need to run complex queries that the adapter API\n * doesn't support, or for legacy code migration.\n *\n * **Note:** Prefer using adapter methods when possible as they provide:\n * - Database-agnostic API\n * - Consistent error handling\n * - Proper connection pooling\n *\n * @param relations - Optional drizzle v1 relations config (defineRelations\n * output) that enables the typed relational query API on the instance\n * @returns Raw Drizzle ORM database instance\n *\n * @example\n * ```typescript\n * // For legacy code that needs direct Drizzle access\n * const db = adapter.getDrizzle(myRelations); // defineRelations output\n * const result = await db.insert(users).values({ ... }).returning();\n * ```\n */\n abstract getDrizzle<T = unknown>(relations?: AnyRelations): T;\n\n // ============================================================\n // Drizzle Query API Support\n // ============================================================\n\n /**\n * Table resolver for looking up Drizzle table objects by name.\n * When set, CRUD methods use Drizzle's query API instead of raw SQL.\n * Set via setTableResolver() after boot-time schema loading.\n */\n protected tableResolver: TableResolver | null = null;\n\n /**\n * Set the table resolver for Drizzle query API support.\n * When a resolver is set, CRUD methods (select, insert, update, delete, upsert)\n * will use Drizzle's query API (db.select().from(), etc.) instead of raw SQL\n * string building. Falls back to raw SQL if the resolver doesn't have the table.\n *\n * @param resolver - TableResolver implementation (e.g. SchemaRegistry)\n */\n setTableResolver(resolver: TableResolver): void {\n this.tableResolver = resolver;\n }\n\n /**\n * Get a Drizzle table object by name from the resolver.\n * Returns null if no resolver is set or table is not found.\n */\n protected getTableObject(tableName: string): unknown {\n return this.tableResolver?.getTable(tableName) ?? null;\n }\n\n /**\n * Run a Drizzle-built statement and return its rows.\n *\n * @remarks\n * The CRUD methods resolve their table through the schema registry and reject\n * any name it does not declare, which leaves no way to read from a table the\n * ORM does not know — one mid-rename, above all — except by assembling SQL and\n * quoting identifiers by hand. This takes Drizzle's `sql` template instead, so\n * the dialect in use decides the quoting and the parameter binding.\n *\n * Concrete rather than abstract so existing adapters keep working unchanged.\n * The three drivers disagree about both the call and the result: node-postgres\n * returns `{ rows }`, mysql2 a `[rows, fields]` tuple, and better-sqlite3 has\n * no `execute` at all and answers `all`. Keeping that here rather than at each\n * call site is the point — a caller reasoning about it would be reasoning\n * about a driver it cannot see.\n *\n * @param statement - Drizzle `sql` template to run\n * @returns Rows the statement produced\n */\n async queryStatement<T = Record<string, unknown>>(\n statement: SQL\n ): Promise<T[]> {\n if (this.getCapabilities().dialect === \"sqlite\") {\n const db = this.getDrizzle<{ all(query: SQL): T[] | Promise<T[]> }>();\n return await db.all(statement);\n }\n const db = this.getDrizzle<{ execute(query: SQL): Promise<unknown> }>();\n const result = await db.execute(statement);\n // `{ rows }` is node-postgres. A bare array is mysql2's `[rows, fields]`\n // tuple, told apart by its first element being an array — the only test that\n // does not depend on trusting one driver to keep its shape.\n if (Array.isArray(result)) {\n return (Array.isArray(result[0]) ? result[0] : result) as T[];\n }\n if (\n typeof result === \"object\" &&\n result !== null &&\n Array.isArray((result as { rows?: unknown }).rows)\n ) {\n return (result as { rows: T[] }).rows;\n }\n // Refused rather than reported as no rows. All three drivers answer one of\n // the shapes above, so anything else means the result was not understood —\n // and \"I could not read this\" must not reach a caller as \"there is nothing\n // there\", which is an answer it would act on.\n throw this.createDatabaseError(\n \"query\",\n \"Drizzle statement returned a result shape this adapter does not recognise; refusing to report it as an empty result.\",\n undefined\n );\n }\n\n /**\n * Map data keys from SQL column names (snake_case) to Drizzle JS property names (camelCase).\n * Drizzle schemas define columns as e.g. `createdAt: timestamp(\"created_at\")` — the JS\n * property is `createdAt` but the SQL column is `created_at`. Services pass snake_case keys\n * because they match the DB column names. This method maps them to the JS names Drizzle expects.\n */\n protected mapDataToColumnNames(\n tableObj: unknown,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n if (!tableObj || typeof tableObj !== \"object\") return data;\n\n // Build maps: SQL column name -> JS property name, and JS name -> column metadata\n const sqlToJs = new Map<string, string>();\n const jsonColumns = new Set<string>();\n\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (\n !colDef ||\n typeof colDef !== \"object\" ||\n !(\"name\" in colDef) ||\n typeof colDef.name !== \"string\"\n )\n continue;\n const sqlName = (colDef as { name: string }).name;\n sqlToJs.set(sqlName, jsName);\n\n // Detect JSON/JSONB columns — Drizzle auto-serializes objects for these,\n // so pre-stringified values must be parsed to avoid double-encoding.\n const dataType = (colDef as { dataType?: string }).dataType;\n const columnType = (colDef as { columnType?: string }).columnType;\n // Detect JSON/JSONB columns — Drizzle auto-serializes objects for these,\n // so pre-stringified values must be parsed to avoid double-encoding.\n // IMPORTANT: For SQLite, only match text columns declared with { mode: \"json\" }\n // (columnType \"SQLiteTextJson\", dataType \"json\"). Plain SQLiteText columns\n // (dataType \"string\") store pre-serialized strings and must NOT be re-parsed,\n // otherwise better-sqlite3 receives objects it cannot bind.\n if (\n dataType === \"json\" ||\n columnType === \"PgJsonb\" ||\n columnType === \"PgJson\" ||\n columnType === \"MySqlJson\" ||\n columnType === \"SQLiteTextJson\" // SQLite JSON-mode text columns only\n ) {\n jsonColumns.add(jsName);\n }\n }\n\n // If no mappings found, return data as-is\n if (sqlToJs.size === 0) return data;\n\n const mapped: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n const jsKey = sqlToJs.get(key) ?? key;\n // Parse pre-stringified JSON for JSON/JSONB columns to avoid double-encoding\n if (jsonColumns.has(jsKey) && typeof value === \"string\") {\n try {\n mapped[jsKey] = JSON.parse(value);\n } catch {\n mapped[jsKey] = value;\n }\n } else {\n mapped[jsKey] = value;\n }\n }\n return mapped;\n }\n\n /**\n * Map data keys from Drizzle JS property names to SQL column names for the\n * raw-SQL transaction insert path. The transaction context builds INSERT\n * statements from Object.keys(data) used directly as column identifiers, so a\n * table whose Drizzle property names differ from its SQL column names\n * (camelCase core tables like nextly_versions) needs its keys translated\n * first. For tables whose property names already equal their column names\n * (the dynamic dc_/single_/comp_ tables) every lookup is identity, so\n * existing callers are unaffected.\n */\n protected mapKeysToSqlColumns(\n tableObj: unknown,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n if (!tableObj || typeof tableObj !== \"object\") return data;\n\n const jsToSql = new Map<string, string>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (\n colDef &&\n typeof colDef === \"object\" &&\n \"name\" in colDef &&\n typeof (colDef as { name?: unknown }).name === \"string\"\n ) {\n jsToSql.set(jsName, (colDef as { name: string }).name);\n }\n }\n if (jsToSql.size === 0) return data;\n\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n out[jsToSql.get(key) ?? key] = value;\n }\n return out;\n }\n\n /**\n * Map a list of column identifiers (Drizzle property names) to their SQL\n * column names, for the raw-SQL transaction insert paths that build a\n * RETURNING clause from `options.returning`. Same identity behavior as\n * `mapKeysToSqlColumns`: names that are already SQL columns (the dynamic\n * dc_/single_/comp_ tables) pass through unchanged.\n */\n protected mapColumnNamesToSql(tableObj: unknown, names: string[]): string[] {\n if (!tableObj || typeof tableObj !== \"object\") return names;\n\n const jsToSql = new Map<string, string>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (\n colDef &&\n typeof colDef === \"object\" &&\n \"name\" in colDef &&\n typeof (colDef as { name?: unknown }).name === \"string\"\n ) {\n jsToSql.set(jsName, (colDef as { name: string }).name);\n }\n }\n if (jsToSql.size === 0) return names;\n\n return names.map(n => jsToSql.get(n) ?? n);\n }\n\n /**\n * Remap a raw-SQL result row's KEYS from SQL column names to Drizzle property\n * names, so the raw-SQL transaction insert paths return the same key casing\n * as the non-transactional (Drizzle) insert. Keys only - values are left\n * untouched, so this does not change how JSON/date columns are decoded. For\n * tables whose property names already equal their SQL columns (the dynamic\n * dc_/single_/comp_ tables) every lookup is identity, so existing callers see\n * no change.\n */\n protected mapRowKeysToJs<T = unknown>(tableObj: unknown, row: T): T {\n if (\n !tableObj ||\n typeof tableObj !== \"object\" ||\n !row ||\n typeof row !== \"object\"\n ) {\n return row;\n }\n\n const sqlToJs = new Map<string, string>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (\n colDef &&\n typeof colDef === \"object\" &&\n \"name\" in colDef &&\n typeof (colDef as { name?: unknown }).name === \"string\"\n ) {\n sqlToJs.set((colDef as { name: string }).name, jsName);\n }\n }\n if (sqlToJs.size === 0) return row;\n\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row as Record<string, unknown>)) {\n out[sqlToJs.get(key) ?? key] = value;\n }\n return out as T;\n }\n\n /**\n * Decode a raw-SQL result row's DATE column values the way a Drizzle query\n * would, so a write answers with the same representation a read of the same\n * column gives.\n *\n * A Drizzle query path runs every value through its column definition; a\n * raw-SQL path does not, so a dialect that stores a timestamp as a number\n * answers a write with that number while every read answers a `Date`. Only\n * date columns are touched, and a value that is already a `Date` is left\n * alone, so a driver that decodes on its own is unaffected.\n *\n * Runs after {@link mapRowKeysToJs}: keys are Drizzle property names by then,\n * which is what the table definition is keyed by.\n */\n protected mapDateValuesFromDriver<T = unknown>(tableObj: unknown, row: T): T {\n if (\n !tableObj ||\n typeof tableObj !== \"object\" ||\n !row ||\n typeof row !== \"object\"\n ) {\n return row;\n }\n\n let decoded: Record<string, unknown> | undefined;\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (!isDateColumn(colDef)) continue;\n const value = (row as Record<string, unknown>)[jsName];\n // `undefined` means the column was not projected; `null` is a stored\n // absence. Neither is a driver representation to decode.\n if (value == null || value instanceof Date) continue;\n decoded ??= { ...(row as Record<string, unknown>) };\n decoded[jsName] = colDef.mapFromDriverValue(value);\n }\n return (decoded as T | undefined) ?? row;\n }\n\n /**\n * Encode a row's DATE values the way a Drizzle query would before binding\n * them, so what lands in the column does not depend on the server's timezone.\n *\n * A column declared without a time zone stores a wall clock and records\n * nothing about which zone it belongs to, so both ends have to agree. Drizzle\n * writes UTC and reads UTC. A driver handed a `Date` writes the LOCAL wall\n * clock instead, and the same row then reads back shifted by the offset --\n * on a UTC server the two agree and nothing is visibly wrong, which is why\n * this survives CI.\n *\n * Only date columns are touched. A value that is not a `Date` is left as it\n * is, so a caller that already encoded one is not encoded twice.\n *\n * Keys may be spelled either way at this point, so both the Drizzle property\n * name and the SQL column name resolve.\n */\n protected mapDateValuesToDriver(\n tableObj: unknown,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n if (!tableObj || typeof tableObj !== \"object\" || !data) return data;\n\n const dateColumns = new Map<string, DecodableColumn>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (!isDateColumn(colDef)) continue;\n dateColumns.set(jsName, colDef);\n const sqlName = (colDef as { name?: unknown }).name;\n if (typeof sqlName === \"string\") dateColumns.set(sqlName, colDef);\n }\n if (dateColumns.size === 0) return data;\n\n let encoded: Record<string, unknown> | undefined;\n for (const [key, value] of Object.entries(data)) {\n if (!(value instanceof Date)) continue;\n const column = dateColumns.get(key);\n if (!column) continue;\n encoded ??= { ...data };\n encoded[key] = column.mapToDriverValue(value);\n }\n return encoded ?? data;\n }\n\n /**\n * Bring a row about to be written through a raw-SQL statement into the shape\n * a Drizzle query would have bound: SQL column names for keys, encoded values\n * for date columns.\n *\n * The mirror of {@link mapRowFromRawSql}. The raw-SQL write paths exist\n * because a dialect needs SQL a Drizzle query cannot express, not because\n * their callers want different values in the table.\n */\n protected mapRowToRawSql(\n tableObj: unknown,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n return this.mapDateValuesToDriver(\n tableObj,\n this.mapKeysToSqlColumns(tableObj, data)\n );\n }\n\n /**\n * Bring a raw-SQL result row into the shape a Drizzle query would have\n * produced: Drizzle property names for keys, decoded values for date columns.\n *\n * The raw-SQL write paths exist because a dialect needs SQL a Drizzle query\n * cannot express, not because their callers want a different row shape, so\n * every one of them ends here.\n */\n protected mapRowFromRawSql<T = unknown>(\n tableObj: unknown,\n row: T,\n aliases: ReadonlyArray<{ alias: string; jsName: string }> = []\n ): T {\n const mapped = this.mapDateValuesFromDriver(\n tableObj,\n this.mapRowKeysToJs(tableObj, row)\n );\n return this.applyWallClockAliases(mapped, aliases);\n }\n\n /**\n * The date columns a statement is about to return, and the alias each one's\n * wall clock is spelled out under.\n *\n * A driver turns a timestamp into a `Date` using ITS zone before any of this\n * code runs, and that conversion is lossy: a wall clock inside a\n * daylight-saving gap is a local time that does not exist, so the driver\n * normalizes it and the original is gone. Asking the database for the wall\n * clock as text alongside the row is the only way to read it exactly.\n *\n * `\"*\"` covers every date column; a projection covers only the ones it asked\n * for, so a caller still gets back what it requested and nothing more.\n */\n protected dateWallClockAliases(\n tableObj: unknown,\n returning: string[] | \"*\" | undefined\n ): Array<{ sqlName: string; alias: string; jsName: string }> {\n if (!tableObj || typeof tableObj !== \"object\" || returning === undefined) {\n return [];\n }\n const requested =\n returning === \"*\" ? undefined : new Set(returning.map(String));\n\n // Every name the row can already carry, so an alias cannot land on one and\n // overwrite or delete it. A column really called `__nx_wc0` is far-fetched,\n // but one set makes it impossible rather than unlikely.\n const taken = new Set<string>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n taken.add(jsName);\n const columnName = (colDef as { name?: unknown }).name;\n if (typeof columnName === \"string\") taken.add(columnName);\n }\n\n let next = 0;\n const freeAlias = (): string => {\n let candidate = `${WALL_CLOCK_ALIAS_STEM}${next++}`;\n while (taken.has(candidate)) {\n candidate = `${WALL_CLOCK_ALIAS_STEM}${next++}`;\n }\n taken.add(candidate);\n return candidate;\n };\n\n const aliases: Array<{ sqlName: string; alias: string; jsName: string }> =\n [];\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (!isDateColumn(colDef)) continue;\n // A column carrying its own zone is already unambiguous; spelling it out\n // would render it in the session's zone and reading that as UTC would\n // move an instant that was correct to begin with.\n if (carriesTimeZone(colDef)) continue;\n const sqlName = (colDef as { name?: unknown }).name;\n if (typeof sqlName !== \"string\") continue;\n if (requested && !requested.has(sqlName) && !requested.has(jsName)) {\n continue;\n }\n aliases.push({ sqlName, alias: freeAlias(), jsName });\n }\n return aliases;\n }\n\n /**\n * Replace each date in a row with the wall clock the database spelled out,\n * read as UTC, and drop the aliases that carried it.\n *\n * The statement writes a UTC wall clock, so reading one back as UTC is what\n * makes a write and a later read agree. Whatever the column actually stored\n * is what arrives -- a column keeping only whole seconds reports whole\n * seconds -- because this is the database's own text, not a value\n * reconstructed from the one that was bound.\n */\n protected applyWallClockAliases<T>(\n row: T,\n aliases: ReadonlyArray<{ alias: string; jsName: string }>\n ): T {\n if (!row || typeof row !== \"object\" || aliases.length === 0) return row;\n const record = row as Record<string, unknown>;\n\n let resolved: Record<string, unknown> | undefined;\n for (const { alias, jsName } of aliases) {\n if (!(alias in record)) continue;\n resolved ??= { ...record };\n const text = resolved[alias];\n delete resolved[alias];\n if (typeof text !== \"string\") continue;\n const parsed = parseWallClockAsUtc(text);\n if (parsed !== undefined) resolved[jsName] = parsed;\n }\n return (resolved as T | undefined) ?? row;\n }\n\n /**\n * Build a Drizzle column projection object (`{ propertyName: column }`) from a\n * requested column list, used by `select` (columns) and `insert` (returning).\n * A requested name resolves against either the Drizzle property name\n * (camelCase) or the SQL column name (snake_case); the projection is keyed by\n * the property name so the row shape matches a full select. Returns undefined\n * for `\"*\"` or when nothing resolves, so callers fall back to all columns.\n */\n protected buildColumnProjection(\n tableObj: unknown,\n names: string[] | \"*\" | undefined\n ): Record<string, unknown> | undefined {\n if (\n names == null ||\n names === \"*\" ||\n !tableObj ||\n typeof tableObj !== \"object\"\n ) {\n return undefined;\n }\n const cols = getColumns(tableObj as never);\n const byAnyName: Record<string, { jsName: string; col: unknown }> = {};\n for (const [jsName, col] of Object.entries(cols)) {\n byAnyName[jsName] = { jsName, col };\n const sqlName = (col as { name?: unknown })?.name;\n if (typeof sqlName === \"string\") byAnyName[sqlName] = { jsName, col };\n }\n const projection: Record<string, unknown> = {};\n for (const name of names) {\n const hit = byAnyName[name];\n if (hit) projection[hit.jsName] = hit.col;\n }\n return Object.keys(projection).length ? projection : undefined;\n }\n\n // ============================================================\n // Connection Status (Default implementations, can override)\n // ============================================================\n\n /**\n * Check if the adapter is currently connected.\n *\n * @remarks\n * Default implementation returns false. Subclasses should override\n * to provide accurate connection status.\n *\n * @returns True if connected, false otherwise\n */\n isConnected(): boolean {\n return false;\n }\n\n /**\n * Get connection pool statistics.\n *\n * @remarks\n * Returns null by default. Subclasses with connection pooling\n * should override to provide pool statistics.\n *\n * @returns Pool statistics or null if not applicable\n */\n getPoolStats(): PoolStats | null {\n return null;\n }\n\n // ============================================================\n // Timeout Utilities\n // ============================================================\n\n /**\n * Default query timeout in milliseconds.\n *\n * @remarks\n * This value is used by executeWithTimeout() when no explicit timeout\n * is provided. Subclasses should set this from their config.\n *\n * @default 15000 (15 seconds)\n *\n * @protected\n */\n protected defaultQueryTimeoutMs: number = 15000;\n\n /**\n * Execute an async operation with a timeout.\n *\n * @remarks\n * Wraps an async operation with a timeout that aborts if the operation\n * exceeds the specified duration. Uses Promise.race for clean timeout\n * handling without memory leaks.\n *\n * When the timeout is reached, a DatabaseError with kind 'timeout' is thrown.\n * Note that this does NOT cancel the underlying database query - it only\n * prevents the calling code from waiting indefinitely. For true query\n * cancellation, use database-level statement timeouts (PostgreSQL) or\n * similar mechanisms.\n *\n * @param operation - Async operation to execute\n * @param timeoutMs - Timeout in milliseconds (defaults to defaultQueryTimeoutMs)\n * @returns Result of the operation\n *\n * @throws {DatabaseError} With kind 'timeout' if operation exceeds timeout\n *\n * @example\n * ```typescript\n * // Use default timeout\n * const result = await adapter.executeWithTimeout(\n * () => adapter.select('users', { limit: 1000 })\n * );\n *\n * // Use custom timeout for specific operation\n * const result = await adapter.executeWithTimeout(\n * () => adapter.select('large_table'),\n * 60000 // 60 seconds for large queries\n * );\n * ```\n *\n * @public\n */\n async executeWithTimeout<T>(\n operation: () => Promise<T>,\n timeoutMs?: number\n ): Promise<T> {\n const timeout = timeoutMs ?? this.defaultQueryTimeoutMs;\n\n // If timeout is 0 or negative, execute without timeout\n if (timeout <= 0) {\n return operation();\n }\n\n // Create a timeout promise that rejects after the specified duration\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n this.createDatabaseError(\n \"timeout\",\n `Query execution timed out after ${timeout}ms`\n )\n );\n }, timeout);\n });\n\n try {\n // Race between the operation and the timeout\n const result = await Promise.race([operation(), timeoutPromise]);\n return result;\n } finally {\n // Always clear the timeout to prevent memory leaks\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Set the default query timeout.\n *\n * @remarks\n * This method allows runtime configuration of the default timeout.\n * Subclasses should call this in their constructor or connect() method\n * based on their configuration.\n *\n * @param timeoutMs - Timeout in milliseconds (0 to disable)\n *\n * @protected\n */\n protected setDefaultQueryTimeout(timeoutMs: number): void {\n this.defaultQueryTimeoutMs = timeoutMs;\n }\n\n /**\n * Get the current default query timeout.\n *\n * @returns Current default timeout in milliseconds\n *\n * @public\n */\n getDefaultQueryTimeout(): number {\n return this.defaultQueryTimeoutMs;\n }\n\n // ============================================================\n // CRUD Operations (Default implementations, can override)\n // ============================================================\n\n /**\n * Select multiple records from a table.\n *\n * @remarks\n * Default implementation builds a SELECT query and executes it.\n * Subclasses can override for optimization or dialect-specific features.\n *\n * @param table - Table name\n * @param options - Select options (filtering, sorting, pagination)\n * @returns Array of matching records\n *\n * @throws {DatabaseError} If query fails\n *\n * @example\n * ```typescript\n * const users = await adapter.select('users', {\n * where: { and: [{ column: 'role', op: '=', value: 'admin' }] },\n * orderBy: [{ column: 'created_at', direction: 'desc' }],\n * limit: 10\n * });\n * ```\n */\n async select<T = unknown>(\n table: string,\n options?: SelectOptions,\n executor?: unknown\n ): Promise<T[]> {\n // Drizzle query API path: use when table resolver has a Drizzle table object\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Run on the transaction's executor when one is supplied, otherwise the\n // pooled instance. Without this, a read inside a transaction would use\n // the pool and miss rows written earlier in the same uncommitted tx.\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = executor ?? this.getDrizzle<any>();\n // Honor the columns projection when provided: select only the requested\n // columns instead of every column, so callers can avoid transferring\n // large columns (e.g. JSON snapshots) they do not need. Falls back to a\n // full select when no columns are requested or none resolve.\n const projection = options?.columns?.length\n ? this.buildColumnProjection(tableObj, options.columns)\n : undefined;\n let query = projection\n ? db.select(projection).from(tableObj)\n : db.select().from(tableObj);\n\n if (options?.where) {\n const whereCondition = buildDrizzleWhere(\n tableObj as never,\n options.where\n );\n if (whereCondition) {\n query = query.where(whereCondition);\n }\n }\n\n // Guarded, so `getColumns` is not reached for a select that does not\n // order. Hoisting it out of this check ran it on every select and broke\n // callers whose table handle cannot answer it.\n if (options?.orderBy?.length) {\n const orderClauses = buildDrizzleOrderBy(\n getColumns(tableObj as never),\n options.orderBy\n );\n if (orderClauses.length) {\n query = query.orderBy(...orderClauses);\n }\n }\n\n if (options?.limit !== undefined) {\n query = query.limit(options.limit);\n }\n\n if (options?.offset !== undefined) {\n query = query.offset(options.offset);\n }\n\n // A lock request is only meaningful inside a transaction, on EVERY\n // dialect. On the row-locking dialects the pooled connection autocommits\n // the SELECT, releasing the lock the instant it returns; on SQLite the\n // lock IS the transaction (BEGIN IMMEDIATE serializes writers), so a\n // pooled call takes no lock at all. Either way a `forUpdate` without a\n // transaction executor is silent false safety and reopens the TOCTOU\n // window it was meant to close, so fail fast regardless of dialect.\n if (options?.forUpdate && !executor) {\n throw this.createDatabaseError(\n \"query\",\n \"forUpdate requires a transaction executor: a lock request on the pooled connection takes no durable lock and cannot prevent a concurrent write.\",\n undefined\n );\n }\n\n // Row-lock the selected rows for the rest of the transaction and read the\n // latest committed values (not the transaction's snapshot). SQLite has no\n // FOR UPDATE and needs none (BEGIN IMMEDIATE serializes its writers), so\n // it is skipped there.\n if (options?.forUpdate && this.dialect !== \"sqlite\") {\n query = query.for(\"update\");\n }\n\n return (await query) as T[];\n } catch (error) {\n throw this.handleQueryError(error, \"select\", table);\n }\n }\n\n // Table not found in schema registry - cannot use Drizzle query API\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Select a single record from a table.\n *\n * @remarks\n * Default implementation uses `select()` with limit 1 and returns first result.\n * Returns null if no matching record is found.\n *\n * @param table - Table name\n * @param options - Select options\n * @returns First matching record or null\n *\n * @throws {DatabaseError} If query fails\n *\n * @example\n * ```typescript\n * const user = await adapter.selectOne('users', {\n * where: { and: [{ column: 'email', op: '=', value: 'user@example.com' }] }\n * });\n * ```\n */\n async selectOne<T = unknown>(\n table: string,\n options?: SelectOptions,\n executor?: unknown\n ): Promise<T | null> {\n const results = await this.select<T>(\n table,\n { ...options, limit: 1 },\n executor\n );\n return results.length > 0 ? results[0] : null;\n }\n\n /**\n * Insert a single record into a table.\n *\n * @remarks\n * Default implementation handles databases with and without RETURNING support.\n * For databases without RETURNING (MySQL), performs INSERT followed by SELECT.\n *\n * @param table - Table name\n * @param data - Record data to insert\n * @param options - Insert options\n * @returns Inserted record (with RETURNING columns if specified)\n *\n * @throws {DatabaseError} If insert fails\n *\n * @example\n * ```typescript\n * const user = await adapter.insert('users', {\n * email: 'user@example.com',\n * name: 'John Doe'\n * }, { returning: ['id', 'email', 'created_at'] });\n * ```\n */\n async insert<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options?: InsertOptions\n ): Promise<T> {\n // Drizzle query API path\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Map snake_case keys to Drizzle JS property names\n const mappedData = this.mapDataToColumnNames(tableObj, data);\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = this.getDrizzle<any>();\n const caps = this.getCapabilities();\n\n const returning = options?.returning;\n // An empty array means \"no columns back\": skip RETURNING entirely and,\n // on MySQL, skip the select-back reread. Useful for callers that ignore\n // the insert result and don't want a large row (e.g. a JSON snapshot)\n // materialized. `\"*\"` returns all; a specific list is projected.\n const wantsReturning =\n returning != null &&\n !(Array.isArray(returning) && returning.length === 0);\n\n if (caps.supportsReturning && wantsReturning) {\n const projection = this.buildColumnProjection(tableObj, returning);\n const insertQuery = db.insert(tableObj).values(mappedData);\n const result = await (projection\n ? insertQuery.returning(projection)\n : insertQuery.returning());\n return (Array.isArray(result) ? result[0] : result) as T;\n }\n\n const result = await db.insert(tableObj).values(mappedData);\n\n // For databases without RETURNING (MySQL): select back the inserted\n // record, projecting only the requested columns so unrequested ones\n // (a large JSON snapshot) are not read and decoded.\n if (\n !caps.supportsReturning &&\n wantsReturning &&\n data.id !== undefined\n ) {\n return (await this.selectOne<T>(table, {\n columns: returning === \"*\" ? undefined : returning,\n where: {\n and: [{ column: \"id\", op: \"=\", value: data.id as SqlParam }],\n },\n })) as T;\n }\n\n return (Array.isArray(result) ? result[0] : result) as T;\n } catch (error) {\n throw this.handleQueryError(error, \"insert\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Insert multiple records into a table.\n *\n * @remarks\n * Default implementation performs individual inserts in sequence.\n * Subclasses can override for bulk insert optimization (e.g., COPY in PostgreSQL).\n *\n * @param table - Table name\n * @param data - Array of records to insert\n * @param options - Insert options\n * @returns Inserted records (with RETURNING columns if specified)\n *\n * @throws {DatabaseError} If insert fails\n *\n * @example\n * ```typescript\n * const users = await adapter.insertMany('users', [\n * { email: 'user1@example.com', name: 'User 1' },\n * { email: 'user2@example.com', name: 'User 2' }\n * ], { returning: ['id'] });\n * ```\n */\n async insertMany<T = unknown>(\n table: string,\n data: Record<string, unknown>[],\n options?: InsertOptions\n ): Promise<T[]> {\n if (data.length === 0) {\n return [];\n }\n\n // Default implementation: insert one by one\n // Subclasses can override for bulk optimization\n const results: T[] = [];\n for (const record of data) {\n const result = await this.insert<T>(table, record, options);\n results.push(result);\n }\n return results;\n }\n\n /**\n * Update records in a table.\n *\n * @remarks\n * Default implementation builds an UPDATE query with WHERE clause.\n * Returns updated records if RETURNING is supported and requested.\n *\n * @param table - Table name\n * @param data - Data to update\n * @param where - Conditions for records to update\n * @param options - Update options\n * @returns Updated records (with RETURNING columns if specified)\n *\n * @throws {DatabaseError} If update fails\n *\n * @example\n * ```typescript\n * const updated = await adapter.update('users',\n * { status: 'active' },\n * { and: [{ column: 'id', op: '=', value: userId }] },\n * { returning: ['id', 'status', 'updated_at'] }\n * );\n * ```\n */\n async update<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n options?: UpdateOptions,\n executor?: unknown\n ): Promise<T[]> {\n // Drizzle query API path\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Transaction executor when supplied, otherwise the pooled instance.\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = executor ?? this.getDrizzle<any>();\n const caps = this.getCapabilities();\n // Map snake_case keys to Drizzle JS property names\n const mappedData = this.mapDataToColumnNames(tableObj, data);\n let query = db.update(tableObj).set(mappedData);\n\n const whereCondition = buildDrizzleWhere(tableObj as never, where);\n if (whereCondition) {\n query = query.where(whereCondition);\n }\n\n if (caps.supportsReturning && options?.returning) {\n return (await query.returning()) as T[];\n }\n\n await query;\n\n // For databases without RETURNING: select back the updated records on\n // the same executor so a transactional update reads its own writes.\n if (!caps.supportsReturning && options?.returning) {\n return await this.select<T>(table, { where }, executor);\n }\n\n return [] as T[];\n } catch (error) {\n throw this.handleQueryError(error, \"update\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Update records in a table and report how many rows the statement affected.\n *\n * The count is the whole return value, mirroring `delete`. `update` cannot answer this: without\n * `returning` it discards the driver's count, and WITH `returning` on a dialect that lacks\n * RETURNING it re-SELECTs using the same WHERE — so a conditional update that just changed a\n * column named in that WHERE reads back zero rows and a write that landed reports as unmatched.\n * Reading the driver's own count has no second query to disagree with the first.\n *\n * 🔴 MySQL reports CHANGED rows, not matched rows: an UPDATE that matches a row but writes values\n * identical to what it holds counts zero. A caller using this as a compare-and-set must therefore\n * include a column the write always moves — a version bump, a timestamp with enough resolution —\n * so that matched implies changed. Postgres (`rowCount`) and SQLite (`changes`) count matched\n * rows and do not need the precaution, which is exactly why it cannot be dropped: the dialect\n * where the distinction exists is the one with no RETURNING to fall back on.\n */\n async updateCount(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n executor?: unknown\n ): Promise<number> {\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Transaction executor when supplied, otherwise the pooled instance — narrowed to the\n // fragment of the update builder this method uses rather than the whole dialect-specific\n // surface, which is the same seam `getDrizzle<{ execute }>()` above takes. `where` returns\n // a thenable rather than a further builder, so awaiting either branch is what the type\n // says: the statement is issued whether or not a condition was added.\n const db = (executor ??\n this.getDrizzle<UpdateCapableDb>()) as UpdateCapableDb;\n const mappedData = this.mapDataToColumnNames(tableObj, data);\n const statement = db.update(tableObj).set(mappedData);\n\n const whereCondition = buildDrizzleWhere(tableObj as never, where);\n const result = await (whereCondition\n ? statement.where(whereCondition)\n : statement);\n return affectedRowCount(result);\n } catch (error) {\n throw this.handleQueryError(error, \"update\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Delete records from a table.\n *\n * @remarks\n * Default implementation builds a DELETE query with WHERE clause.\n * Returns the number of deleted records.\n *\n * @param table - Table name\n * @param where - Conditions for records to delete\n * @param options - Delete options\n * @returns Number of deleted records\n *\n * @throws {DatabaseError} If delete fails\n *\n * @example\n * ```typescript\n * const count = await adapter.delete('users', {\n * and: [{ column: 'status', op: '=', value: 'inactive' }]\n * });\n * console.log(`Deleted ${count} users`);\n * ```\n */\n async delete(\n table: string,\n where: WhereClause,\n _options?: DeleteOptions,\n executor?: unknown\n ): Promise<number> {\n // Drizzle query API path\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Transaction executor when supplied, otherwise the pooled instance.\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = executor ?? this.getDrizzle<any>();\n let query = db.delete(tableObj);\n\n const whereCondition = buildDrizzleWhere(tableObj as never, where);\n if (whereCondition) {\n query = query.where(whereCondition);\n }\n\n const result = await query;\n return affectedRowCount(result);\n } catch (error) {\n throw this.handleQueryError(error, \"delete\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Upsert (INSERT or UPDATE) a record.\n *\n * @remarks\n * Default implementation uses dialect-specific ON CONFLICT syntax.\n * PostgreSQL/SQLite: ON CONFLICT ... DO UPDATE\n * MySQL: ON DUPLICATE KEY UPDATE\n *\n * @param table - Table name\n * @param data - Record data\n * @param options - Upsert options (must specify conflict columns)\n * @returns Upserted record (with RETURNING columns if specified)\n *\n * @throws {DatabaseError} If upsert fails\n *\n * @example\n * ```typescript\n * const user = await adapter.upsert('users', {\n * email: 'user@example.com',\n * name: 'Updated Name'\n * }, {\n * conflictColumns: ['email'],\n * updateColumns: ['name'],\n * returning: ['id', 'email', 'name']\n * });\n * ```\n */\n async upsert<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options: UpsertOptions,\n executor?: unknown\n ): Promise<T> {\n // Drizzle query API path\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Transaction executor when supplied, otherwise the pooled instance.\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = executor ?? this.getDrizzle<any>();\n const caps = this.getCapabilities();\n const columns = getColumns(tableObj as never);\n\n // Build conflict target columns\n const conflictTarget = options.conflictColumns\n .map(col => columns[col])\n .filter(Boolean);\n\n // Build update set (exclude conflict columns from update data)\n const conflictSet = new Set(options.conflictColumns);\n const updateData: Record<string, unknown> = {};\n const updateColumns = options.updateColumns ?? Object.keys(data);\n for (const key of updateColumns) {\n if (!conflictSet.has(key) && key in data) {\n updateData[key] = data[key];\n }\n }\n\n let query;\n if (caps.supportsOnConflict) {\n // PostgreSQL/SQLite: ON CONFLICT DO UPDATE\n query = db.insert(tableObj).values(data).onConflictDoUpdate({\n target: conflictTarget,\n set: updateData,\n });\n } else {\n // MySQL: fallback to insert, catch duplicate key, then update\n // This is handled by the MySQL adapter override\n query = db.insert(tableObj).values(data);\n }\n\n if (caps.supportsReturning) {\n const result = await query.returning();\n return (Array.isArray(result) ? result[0] : result) as T;\n }\n\n await query;\n\n // For databases without RETURNING: select back using conflict columns\n // on the same executor so a transactional upsert reads its own write.\n if (\n options.conflictColumns.length &&\n data[options.conflictColumns[0]] !== undefined\n ) {\n return (await this.selectOne<T>(\n table,\n {\n where: {\n and: [\n {\n column: options.conflictColumns[0],\n op: \"=\",\n value: data[options.conflictColumns[0]] as SqlParam,\n },\n ],\n },\n },\n executor\n )) as T;\n }\n\n return data as T;\n } catch (error) {\n throw this.handleQueryError(error, \"upsert\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n // ============================================================\n // Migration Support (Default implementations, can override)\n // ============================================================\n\n /**\n * Run pending migrations.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * migration tracking and execution logic.\n *\n * @param migrations - Array of migrations to run\n * @returns Migration result with applied and pending migrations\n *\n * @throws {DatabaseError} If migration fails\n */\n // Base implementation throws synchronously; dialect adapters override with async logic.\n // eslint-disable-next-line @typescript-eslint/require-await\n async migrate(_migrations: Migration[]): Promise<MigrationResult> {\n // Base implementation: migrate() requires dialect-specific migrator import.\n // Dialect adapters (PostgresAdapter, MySqlAdapter, SqliteAdapter) should\n // override this with their specific drizzle-orm migrator.\n throw this.createDatabaseError(\n \"query\",\n \"migrate() must be implemented by dialect-specific adapter. \" +\n \"Use PostgresAdapter, MySqlAdapter, or SqliteAdapter.\",\n undefined\n );\n }\n\n /**\n * Rollback the last migration.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * migration rollback logic.\n *\n * @returns Migration result after rollback\n *\n * @throws {DatabaseError} If rollback fails\n */\n // Base implementation throws synchronously; dialect adapters override with async logic.\n // eslint-disable-next-line @typescript-eslint/require-await\n async rollback(): Promise<MigrationResult> {\n // Base implementation: rollback requires dialect-specific handling.\n // Dialect adapters should override this.\n throw this.createDatabaseError(\n \"query\",\n \"rollback() must be implemented by dialect-specific adapter. \" +\n \"Use PostgresAdapter, MySqlAdapter, or SqliteAdapter.\",\n undefined\n );\n }\n\n /**\n * Get migration status.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * migration status checking.\n *\n * @returns Current migration status\n *\n * @throws {DatabaseError} If status check fails\n */\n async getMigrationStatus(): Promise<MigrationResult> {\n // Query the drizzle migrations tracking table for applied migrations\n try {\n const rows = await this.executeQuery<{\n id: number;\n hash: string;\n created_at: number;\n }>(`SELECT * FROM \"__drizzle_migrations\" ORDER BY created_at ASC`);\n\n const applied = rows.map(r => ({\n id: String(r.id),\n name: r.hash,\n appliedAt: new Date(r.created_at),\n checksum: r.hash,\n }));\n return {\n applied,\n pending: [],\n current: applied.length > 0 ? applied[applied.length - 1].id : null,\n };\n } catch {\n // Table may not exist yet if no migrations have been applied\n return { applied: [], pending: [], current: null };\n }\n }\n\n // ============================================================\n // Schema Operations (Default implementations, can override)\n // ============================================================\n\n /**\n * Create a new table.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * table creation logic.\n *\n * @param definition - Table definition\n * @param options - Creation options\n *\n * @throws {DatabaseError} If table creation fails\n */\n async createTable(\n definition: TableDefinition,\n options?: CreateTableOptions\n ): Promise<void> {\n // Build CREATE TABLE SQL from the TableDefinition\n const columnDefs = definition.columns.map(col => {\n let colSql = `${this.escapeIdentifier(col.name)} ${col.type.toUpperCase()}`;\n if (col.primaryKey) colSql += \" PRIMARY KEY\";\n if (col.nullable === false) colSql += \" NOT NULL\";\n if (col.unique) colSql += \" UNIQUE\";\n if (col.default !== undefined) {\n colSql += ` DEFAULT ${renderDefaultValue(col.default, col.name)}`;\n }\n return colSql;\n });\n\n const ifNotExists = options?.ifNotExists !== false ? \"IF NOT EXISTS \" : \"\";\n const query = `CREATE TABLE ${ifNotExists}${this.escapeIdentifier(definition.name)} (\\n ${columnDefs.join(\",\\n \")}\\n)`;\n\n try {\n await this.executeQuery(query);\n } catch (error) {\n throw this.handleQueryError(error, \"createTable\", definition.name);\n }\n }\n\n /**\n * Drop a table.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * table dropping logic.\n *\n * @param tableName - Name of table to drop\n * @param options - Drop options\n *\n * @throws {DatabaseError} If table drop fails\n */\n async dropTable(\n tableName: string,\n options?: DropTableOptions\n ): Promise<void> {\n const ifExists = options?.ifExists !== false ? \"IF EXISTS \" : \"\";\n const cascade = options?.cascade ? \" CASCADE\" : \"\";\n const query = `DROP TABLE ${ifExists}${this.escapeIdentifier(tableName)}${cascade}`;\n\n try {\n await this.executeQuery(query);\n } catch (error) {\n throw this.handleQueryError(error, \"dropTable\", tableName);\n }\n }\n\n /**\n * Alter an existing table.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * table alteration logic.\n *\n * @param tableName - Name of table to alter\n * @param operations - Alteration operations\n * @param options - Alter options\n *\n * @throws {DatabaseError} If table alteration fails\n */\n async alterTable(\n tableName: string,\n operations: AlterTableOperation[],\n _options?: AlterTableOptions\n ): Promise<void> {\n const quotedTable = this.escapeIdentifier(tableName);\n\n for (const op of operations) {\n let query: string;\n\n switch (op.kind) {\n case \"add_column\": {\n let colDef = `${this.escapeIdentifier(op.column.name)} ${op.column.type.toUpperCase()}`;\n if (op.column.nullable === false) colDef += \" NOT NULL\";\n if (op.column.unique) colDef += \" UNIQUE\";\n if (op.column.default !== undefined) {\n const defaultVal =\n typeof op.column.default === \"object\" &&\n op.column.default !== null &&\n \"sql\" in op.column.default\n ? op.column.default.sql\n : typeof op.column.default === \"string\"\n ? `'${op.column.default}'`\n : String(op.column.default);\n colDef += ` DEFAULT ${defaultVal}`;\n }\n query = `ALTER TABLE ${quotedTable} ADD COLUMN ${colDef}`;\n break;\n }\n case \"drop_column\": {\n const cascade = op.cascade ? \" CASCADE\" : \"\";\n query = `ALTER TABLE ${quotedTable} DROP COLUMN ${this.escapeIdentifier(op.columnName)}${cascade}`;\n break;\n }\n case \"rename_column\":\n query = `ALTER TABLE ${quotedTable} RENAME COLUMN ${this.escapeIdentifier(op.from)} TO ${this.escapeIdentifier(op.to)}`;\n break;\n case \"modify_column\": {\n // ALTER COLUMN ... TYPE is PostgreSQL syntax; MySQL uses MODIFY COLUMN\n // Dialect adapters can override for specific syntax\n query = `ALTER TABLE ${quotedTable} ALTER COLUMN ${this.escapeIdentifier(op.column.name)} TYPE ${op.column.type.toUpperCase()}`;\n break;\n }\n case \"add_constraint\":\n {\n // Constraint SQL depends on the constraint type\n const constraintCols = op.constraint.columns ?? [];\n const colList = constraintCols\n .map(c => this.escapeIdentifier(c))\n .join(\", \");\n if (op.constraint.type === \"check\" && op.constraint.expression) {\n query = `ALTER TABLE ${quotedTable} ADD CONSTRAINT ${this.escapeIdentifier(op.constraint.name)} CHECK (${op.constraint.expression})`;\n } else {\n query = `ALTER TABLE ${quotedTable} ADD CONSTRAINT ${this.escapeIdentifier(op.constraint.name)} ${op.constraint.type.toUpperCase()} (${colList})`;\n }\n break;\n }\n break;\n case \"drop_constraint\": {\n const cascadeConstraint = op.cascade ? \" CASCADE\" : \"\";\n query = `ALTER TABLE ${quotedTable} DROP CONSTRAINT ${this.escapeIdentifier(op.constraintName)}${cascadeConstraint}`;\n break;\n }\n default:\n throw this.createDatabaseError(\n \"query\",\n `Unsupported alter table operation: ${(op as { kind: string }).kind}`,\n undefined\n );\n }\n\n try {\n await this.executeQuery(query);\n } catch (error) {\n throw this.handleQueryError(error, \"alterTable\", tableName);\n }\n }\n }\n\n /**\n * Check if a table exists in the database.\n *\n * @remarks\n * Uses dialect-specific information schema queries to check table existence.\n * This is useful for development mode auto-sync to determine whether to\n * CREATE or DROP/CREATE tables.\n *\n * @param tableName - Name of table to check\n * @param schema - Optional schema name (defaults to 'public' for PostgreSQL)\n * @returns True if table exists, false otherwise\n *\n * @throws {DatabaseError} If query fails\n *\n * @example\n * ```typescript\n * const exists = await adapter.tableExists('users');\n * if (exists) {\n * await adapter.dropTable('users');\n * }\n * await adapter.createTable(userTableDef);\n * ```\n */\n async tableExists(tableName: string, schema?: string): Promise<boolean> {\n try {\n let sql: string;\n const params: SqlParam[] = [];\n\n switch (this.dialect) {\n case \"postgresql\":\n sql = `\n SELECT EXISTS (\n SELECT FROM information_schema.tables\n WHERE table_schema = COALESCE($1, (\n SELECT n.nspname FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE c.oid = to_regclass($2)\n ))\n AND table_name = $2\n ) as exists\n `;\n // Unqualified DDL and DML resolve across the whole search path, not against one\n // schema. Naming `public` reported a populated table as absent whenever a deployment\n // used a schema of its own, and naming only the FIRST entry misses a table that lives\n // further along it. `to_regclass` resolves exactly as the statements do, so the\n // lookup and the ALTER cannot disagree about which table is meant. A caller that\n // reads \"absent\" as \"nothing to conflict with\" would otherwise act on the wrong one.\n params.push(schema ?? null, tableName);\n break;\n\n case \"mysql\":\n sql = `\n SELECT COUNT(*) as count\n FROM information_schema.tables\n WHERE table_schema = DATABASE()\n AND table_name = ?\n `;\n params.push(tableName);\n break;\n\n case \"sqlite\":\n sql = `\n SELECT COUNT(*) as count\n FROM sqlite_master\n WHERE type = 'table'\n AND name = ?\n `;\n params.push(tableName);\n break;\n\n default:\n throw this.createDatabaseError(\n \"query\",\n `tableExists not implemented for dialect: ${String(this.dialect)}`,\n undefined\n );\n }\n\n const results = await this.executeQuery<Record<string, unknown>>(\n sql,\n params\n );\n\n if (results.length === 0) {\n return false;\n }\n\n const row = results[0];\n\n // PostgreSQL returns { exists: true/false }\n if (\"exists\" in row) {\n return row.exists === true || row.exists === \"t\" || row.exists === 1;\n }\n\n // MySQL/SQLite return { count: number }\n if (\"count\" in row) {\n return Number(row.count) > 0;\n }\n\n return false;\n } catch (error) {\n throw this.handleQueryError(error, \"tableExists\", tableName);\n }\n }\n\n /**\n * Get list of all tables in the database.\n *\n * @remarks\n * Uses dialect-specific information schema queries to list tables.\n * Useful for detecting orphaned tables or validating schema state.\n *\n * @param schema - Optional schema name (defaults to 'public' for PostgreSQL)\n * @returns Array of table names\n *\n * @throws {DatabaseError} If query fails\n */\n async listTables(schema?: string): Promise<string[]> {\n try {\n let sql: string;\n const params: SqlParam[] = [];\n\n switch (this.dialect) {\n case \"postgresql\":\n sql = `\n SELECT table_name\n FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n ORDER BY table_name\n `;\n params.push(schema ?? \"public\");\n break;\n\n case \"mysql\":\n // The alias matters: MySQL 8's information_schema returns the\n // column key as uppercase TABLE_NAME without it, so `row.table_name`\n // was undefined and every caller mapping the rows crashed.\n sql = `\n SELECT table_name AS table_name\n FROM information_schema.tables\n WHERE table_schema = DATABASE()\n AND table_type = 'BASE TABLE'\n ORDER BY table_name\n `;\n break;\n\n case \"sqlite\":\n sql = `\n SELECT name as table_name\n FROM sqlite_master\n WHERE type = 'table'\n AND name NOT LIKE 'sqlite_%'\n ORDER BY name\n `;\n break;\n\n default:\n throw this.createDatabaseError(\n \"query\",\n `listTables not implemented for dialect: ${String(this.dialect)}`,\n undefined\n );\n }\n\n const results = await this.executeQuery<{ table_name: string }>(\n sql,\n params\n );\n\n return results.map(row => row.table_name);\n } catch (error) {\n throw this.handleQueryError(error, \"listTables\", \"\");\n }\n }\n\n // ============================================================\n // Protected Utilities\n // ============================================================\n\n // Old raw SQL query builders (buildSelectQuery, buildInsertQuery, buildUpdateQuery,\n // buildDeleteQuery, buildUpsertQuery, buildWhereClause, buildPlaceholder,\n // buildPlaceholders) have been removed. CRUD methods now use Drizzle query API\n // via the TableResolver set during boot. See drizzle-where.ts for where clause\n // translation.\n\n // NOTE: The following content up to escapeIdentifier has been removed.\n // If you're looking for the old query builder methods, see git history\n // (commit before \"refactor: remove dead SQL builder code\").\n\n /**\n * Escape a table or column identifier.\n *\n * @remarks\n * Default uses double quotes (SQL standard).\n * MySQL adapter should override to use backticks.\n *\n * @param identifier - Identifier to escape\n * @returns Escaped identifier\n *\n * @protected\n */\n protected escapeIdentifier(identifier: string): string {\n // SQL standard: double quotes\n // MySQL uses backticks, override in MySqlAdapter\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n }\n\n /**\n * Create a DatabaseError with proper error kind classification.\n *\n * @remarks\n * Protected helper for subclasses to create consistent errors.\n * Subclasses can override to add dialect-specific error classification.\n *\n * @param kind - Error kind\n * @param message - Error message\n * @param cause - Original error\n * @returns DatabaseError instance\n *\n * @protected\n */\n protected createDatabaseError(\n kind: DatabaseErrorKind,\n message: string,\n cause?: Error\n ): DatabaseError {\n return createDatabaseError({\n kind,\n message,\n cause,\n });\n }\n\n /**\n * Helper to create transaction context CRUD forwarding methods.\n *\n * @param txDb - Thunk returning the transaction-bound Drizzle executor\n * @returns Object providing forwarded CRUD and getDrizzle methods\n *\n * @protected\n */\n protected createTransactionForwarders(\n txDb: () => unknown\n ): TransactionCrudForwarders {\n return createTransactionForwarders(this, txDb);\n }\n\n /**\n * Classify an error into a DatabaseError.\n *\n * @remarks\n * Subclasses can override this method to add dialect-specific error code classification.\n *\n * @param error - Original error\n * @param sql - SQL statement that caused the error (optional)\n * @returns DatabaseError instance\n *\n * @protected\n */\n protected classifyError(error: unknown, sql?: string): DatabaseError {\n if (isDatabaseError(error)) {\n return error;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n return this.createDatabaseError(\n \"query\",\n sql ? `Query failed: ${errorMessage}` : errorMessage,\n error instanceof Error ? error : undefined\n );\n }\n\n /**\n * Handle query errors and convert to DatabaseError.\n *\n * @remarks\n * Protected helper for consistent error handling across CRUD operations.\n * Delegates to `classifyError` and attaches operation and table context if not present.\n * Subclasses override `classifyError` to provide dialect-specific error code classification.\n *\n * @param error - Original error\n * @param operation - Operation that failed\n * @param table - Table name\n * @returns DatabaseError instance\n *\n * @protected\n */\n protected handleQueryError(\n error: unknown,\n operation: string,\n table: string\n ): DatabaseError {\n const dbError = this.classifyError(error);\n\n // Add operation context if not already present\n if (!dbError.message.includes(operation)) {\n dbError.message = `${operation} operation failed on table '${table}': ${dbError.message}`;\n }\n\n if (!dbError.table) {\n dbError.table = table;\n }\n\n return dbError;\n }\n}\n\n/**\n * Render a `ColumnDefinition.default` as a SQL fragment\n * for embedding in a `DEFAULT` clause. DDL is not protected by Drizzle's\n * prepared statements — these expressions are concatenated into raw SQL —\n * so we treat the default as untrusted input even though it currently\n * flows from server-side schema definitions: an admin-defined dynamic\n * collection would otherwise turn into RCE-on-DB instead of just CMS\n * admin.\n *\n * Rules:\n *\n * - **null / number / boolean** → rendered as a SQL literal.\n * - **string** → quoted; embedded `'` doubled; `;`, `\\`, control\n * characters, and null bytes rejected so they can't break out of\n * the surrounding quote pair into adjacent DDL.\n * - **`{ sql: \"…\" }`** → only the explicit allowlist of named\n * functions below is honored (case-insensitive). Anything else is\n * a hard error: the previous code embedded the raw `sql` string\n * verbatim, which is the SQL injection primitive the audit flagged.\n */\nconst ALLOWED_DEFAULT_SQL_EXPRESSIONS = new Set([\n \"current_timestamp\",\n \"now()\",\n \"gen_random_uuid()\",\n \"uuid_generate_v4()\",\n \"current_date\",\n \"current_time\",\n]);\n\nfunction renderDefaultValue(value: unknown, columnName: string): string {\n if (value === null) return \"NULL\";\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new Error(\n `DEFAULT for column \"${columnName}\" must be a finite number (got ${value}).`\n );\n }\n return String(value);\n }\n if (typeof value === \"boolean\") {\n return value ? \"TRUE\" : \"FALSE\";\n }\n if (typeof value === \"string\") {\n if (/[;\\\\\\n\\r\\0]/.test(value)) {\n throw new Error(\n `DEFAULT string for column \"${columnName}\" contains characters that are not allowed in DDL (no semicolons, backslashes, control chars, or null bytes).`\n );\n }\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n if (typeof value === \"object\" && value !== null && \"sql\" in value) {\n const raw = value.sql;\n if (typeof raw !== \"string\") {\n throw new Error(\n `DEFAULT for column \"${columnName}\" has a { sql } expression that is not a string.`\n );\n }\n const normalized = raw.trim().toLowerCase();\n if (!ALLOWED_DEFAULT_SQL_EXPRESSIONS.has(normalized)) {\n throw new Error(\n `DEFAULT for column \"${columnName}\" uses a SQL expression \"${raw}\" that is not on the allowlist. Allowed: ${[...ALLOWED_DEFAULT_SQL_EXPRESSIONS].join(\", \")}.`\n );\n }\n return raw.trim();\n }\n throw new Error(\n `DEFAULT for column \"${columnName}\" has an unsupported type (${typeof value}).`\n );\n}\n","/**\n * @nextly/adapter-drizzle\n *\n * Shared Drizzle ORM adapter logic for Nextly database adapters.\n * This package provides the base adapter class and utilities used by\n * dialect-specific adapters (PostgreSQL, MySQL, SQLite).\n *\n * @remarks\n * This is the main entry point that exports only the core adapter class.\n * Specialized utilities are available via subpath exports for optimal tree-shaking.\n *\n * ## Subpath Exports\n *\n * **Types:**\n * ```typescript\n * import type {\n * DatabaseCapabilities,\n * TransactionContext,\n * WhereClause,\n * SelectOptions,\n * } from '@nextly/adapter-drizzle/types';\n * ```\n *\n * **Query Builder:**\n * ```typescript\n * import { QueryBuilder } from '@nextly/adapter-drizzle/query-builder';\n * ```\n *\n * **Migrations:**\n * ```typescript\n * import {\n * calculateChecksum,\n * sortMigrations,\n * migrationHelpers,\n * } from '@nextly/adapter-drizzle/migrations';\n * ```\n *\n * **Schema Utilities:**\n * ```typescript\n * import { schemaUtils } from '@nextly/adapter-drizzle/schema';\n * ```\n *\n * @packageDocumentation\n */\n\n/**\n * Package version\n * @public\n */\nexport const version = \"0.1.0\";\n\n// ============================================================\n// Core Adapter Export\n// ============================================================\n\n/**\n * Base database adapter abstract class.\n *\n * @remarks\n * All dialect-specific adapters extend this class. It provides:\n * - Abstract methods that must be implemented (connect, disconnect, executeQuery, transaction)\n * - Default CRUD implementations that can be overridden for optimization\n * - Protected query builders for dialect-specific SQL generation\n * - Error handling and database capability reporting\n *\n * ## Required Abstract Methods\n * - `dialect` - Database dialect identifier\n * - `connect()` - Establish database connection\n * - `disconnect()` - Close database connection\n * - `executeQuery()` - Execute raw SQL query\n * - `transaction()` - Execute work within a transaction\n * - `getCapabilities()` - Report database features\n *\n * ## Default CRUD Methods (Overridable)\n * - `select()`, `selectOne()` - Query records\n * - `insert()`, `insertMany()` - Insert records\n * - `update()` - Update records\n * - `delete()` - Delete records\n * - `upsert()` - Insert or update records\n *\n * @example\n * Basic adapter implementation:\n * ```typescript\n * import { DrizzleAdapter } from '@nextly/adapter-drizzle';\n * import type {\n * DatabaseCapabilities,\n * SqlParam,\n * TransactionContext,\n * } from '@nextly/adapter-drizzle/types';\n *\n * export class PostgresAdapter extends DrizzleAdapter {\n * readonly dialect = 'postgresql' as const;\n *\n * async connect(): Promise<void> {\n * // Connect to PostgreSQL\n * }\n *\n * async disconnect(): Promise<void> {\n * // Close connection\n * }\n *\n * async executeQuery<T>(sql: string, params?: SqlParam[]): Promise<T[]> {\n * // Execute query\n * }\n *\n * async transaction<T>(\n * work: (tx: TransactionContext) => Promise<T>\n * ): Promise<T> {\n * // Transaction logic\n * }\n *\n * getCapabilities(): DatabaseCapabilities {\n * return {\n * dialect: 'postgresql',\n * supportsJsonb: true,\n * supportsReturning: true,\n * // ... other capabilities\n * };\n * }\n * }\n * ```\n *\n * @public\n */\nexport { DrizzleAdapter } from \"./adapter\";\nexport type {\n TransactionCrudDelegator,\n TransactionCrudForwarders,\n} from \"./transaction-forwarders\";\nexport type { TableResolver } from \"./types/core\";\n\n// Why no F17 re-exports here: the main index follows a strict tree-shaking\n// policy (only DrizzleAdapter + version are exported). F17's\n// checkDialectVersion / NEXTLY_MIN_DB_VERSIONS / UnsupportedDialectVersionError\n// live behind the dedicated subpath @nextlyhq/adapter-drizzle/version-check.\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/drizzle-order.ts","../src/drizzle-where.ts","../src/transaction-forwarders.ts","../src/types/error.ts","../src/adapter.ts","../src/index.ts"],"names":["isNull","sql","db","getColumns","result"],"mappings":"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","file":"index.mjs","sourcesContent":["import { asc, desc, sql } from \"drizzle-orm\";\nimport type { AnyColumn, SQL } from \"drizzle-orm\";\n\nimport type { OrderBySpec } from \"./types\";\n\n/**\n * Turn order specifications into drizzle order clauses.\n *\n * Extracted from `DrizzleAdapter.select` so the rendered SQL can be asserted\n * directly. That matters more than it looks: `OrderBySpec.nulls` was declared,\n * documented as \"can be explicitly controlled\", and read NOWHERE — every caller\n * that set it silently got the dialect default instead, and no test could have\n * caught that while the mapping lived inline in a method that needs a database.\n *\n * ## Why null placement is a leading sort key, not `NULLS FIRST/LAST`\n *\n * That clause is not portable: PostgreSQL and SQLite accept it, MySQL does not.\n * `col IS NULL` is a boolean expression all three evaluate, and sorting on it\n * ascending puts non-null rows first — which is `NULLS LAST` by another name,\n * spelled in something every supported engine understands.\n *\n * The defaults genuinely disagree, which is why the control exists at all:\n * PostgreSQL treats NULL as largest and puts it FIRST on a descending order,\n * while MySQL and SQLite treat it as smallest and put it last. A \"newest\n * scheduled first\" list containing undated drafts therefore returns different\n * rows per engine, and under a limit it can return only drafts.\n */\nexport function buildDrizzleOrderBy(\n columns: Record<string, AnyColumn>,\n orderBy: OrderBySpec[] | undefined\n): SQL[] {\n if (!orderBy?.length) return [];\n\n return orderBy.flatMap((spec): SQL[] => {\n const col = columns[spec.column];\n // An unknown column is skipped rather than thrown on: ordering is a\n // refinement, and a caller naming a column that is not there should get an\n // unordered answer rather than a failed query.\n if (!col) return [];\n\n const direction = spec.direction === \"desc\" ? desc(col) : asc(col);\n if (spec.nulls === undefined) return [direction];\n\n const isNull = sql`${col} is null`;\n return [spec.nulls === \"last\" ? asc(isNull) : desc(isNull), direction];\n });\n}\n","// Translates WhereClause objects into Drizzle SQL conditions.\n// Used internally by the adapter's CRUD methods when a TableResolver is available.\n\nimport {\n eq,\n ne,\n gt,\n lt,\n gte,\n lte,\n like,\n ilike,\n inArray,\n notInArray,\n isNull,\n isNotNull,\n between,\n notBetween,\n and,\n or,\n not,\n sql,\n type SQL,\n} from \"drizzle-orm\";\nimport { getColumns } from \"drizzle-orm\";\n\nimport type { WhereClause, WhereCondition } from \"./types\";\n\n// Build a Drizzle SQL condition from a WhereClause and a Drizzle table object.\n// Returns undefined if the where clause is empty.\nexport function buildDrizzleWhere(\n table: Record<string, unknown>,\n where: WhereClause\n): SQL | undefined {\n const columns = getColumns(table as never);\n return processWhereClause(columns, where);\n}\n\nfunction processWhereClause(\n columns: Record<string, unknown>,\n where: WhereClause\n): SQL | undefined {\n const parts: SQL[] = [];\n\n if (where.and?.length) {\n const andParts = where.and\n .map(item => {\n if (isWhereCondition(item)) {\n return buildCondition(columns, item);\n }\n return processWhereClause(columns, item);\n })\n .filter((p): p is SQL => p !== undefined);\n\n if (andParts.length) {\n parts.push(and(...andParts)!);\n }\n }\n\n if (where.or?.length) {\n const orParts = where.or\n .map(item => {\n if (isWhereCondition(item)) {\n return buildCondition(columns, item);\n }\n return processWhereClause(columns, item);\n })\n .filter((p): p is SQL => p !== undefined);\n\n if (orParts.length) {\n parts.push(or(...orParts)!);\n }\n }\n\n if (where.not) {\n const notItem = where.not;\n const notCondition = isWhereCondition(notItem)\n ? buildCondition(columns, notItem)\n : processWhereClause(columns, notItem);\n\n if (notCondition) {\n parts.push(not(notCondition));\n }\n }\n\n if (parts.length === 0) {\n // A clause that named no branch at all is the caller saying \"no filter\", and `undefined` is\n // how that reaches the adapter. A clause that named one and produced nothing is a different\n // thing entirely: every branch it asked for evaporated — an `and`/`or` whose every member\n // resolved to nothing, or a `not` over such a member. Returning `undefined` for that is what\n // makes it dangerous rather than merely wrong, because `update` and `delete` take the where\n // clause as a REQUIRED argument and simply omit the WHERE when none comes back. A caller\n // that asked to delete a subset would delete the table. Refusing is consistent with the two\n // refusals below: this builder already rejects input it cannot express rather than\n // approximating it.\n if (namesABranch(where)) {\n throw new Error(\n `Where clause produced no condition: ${JSON.stringify(where)}. ` +\n `Every branch resolved to nothing, which would match every row. ` +\n `Pass {} to mean \"no filter\".`\n );\n }\n return undefined;\n }\n if (parts.length === 1) return parts[0];\n return and(...parts);\n}\n\nfunction isWhereCondition(\n item: WhereCondition | WhereClause\n): item is WhereCondition {\n return \"column\" in item && \"op\" in item;\n}\n\n/**\n * Whether the clause asked for a constraint at all — as opposed to being the empty clause a\n * caller passes to mean \"no filter\".\n *\n * An empty `and`/`or` array does NOT count: nothing was named, so nothing could be dropped.\n * What counts is a branch with members in it, or a `not`, because those are the shapes that can\n * resolve to nothing and leave the caller believing a filter was applied.\n */\nfunction namesABranch(where: WhereClause): boolean {\n // `||` and not `??`: an empty array's `length` is 0, which is defined, so `??` would stop at\n // the first branch that exists and never look at the others — `{ and: [], or: [{}] }` would\n // read as \"named nothing\" on the strength of the empty `and`.\n return Boolean(where.and?.length || where.or?.length || where.not);\n}\n\n/**\n * Wraps a value in `%…%` for a substring match, escaping the LIKE metacharacters inside it so\n * the value matches literally.\n *\n * `!` is the escape character rather than the more usual backslash, and it has to be, because\n * this builder emits one statement for every dialect. SQLite gives LIKE no default escape\n * character at all, so a backslash there is just a backslash; declaring `ESCAPE '\\'` instead\n * runs into MySQL, where the backslash also escapes inside the string literal and the clause\n * would have to be spelled differently per dialect. `ESCAPE '!'` parses identically on\n * PostgreSQL, MySQL and SQLite, and needs no per-dialect branch to stay correct.\n *\n * The escape character is escaped FIRST by including it in the character class, so a literal\n * `!` in the value cannot be produced by escaping something else afterwards.\n */\nfunction containsPattern(value: string): string {\n return `%${value.replace(/[!%_]/g, character => `!${character}`)}%`;\n}\n\nfunction buildCondition(\n columns: Record<string, unknown>,\n cond: WhereCondition\n): SQL {\n const column = columns[cond.column];\n if (!column) {\n throw new Error(\n `Column \"${cond.column}\" not found in table. Available: ${Object.keys(columns).join(\", \")}`\n );\n }\n\n const col = column as never;\n\n switch (cond.op) {\n case \"=\":\n return eq(col, cond.value);\n case \"!=\":\n return ne(col, cond.value);\n case \">\":\n return gt(col, cond.value);\n case \"<\":\n return lt(col, cond.value);\n case \">=\":\n return gte(col, cond.value);\n case \"<=\":\n return lte(col, cond.value);\n case \"LIKE\":\n return like(col, cond.value as string);\n case \"ILIKE\":\n return ilike(col, cond.value as string);\n case \"IN\":\n return inArray(col, cond.value as unknown[]);\n case \"NOT IN\":\n return notInArray(col, cond.value as unknown[]);\n case \"IS NULL\":\n return isNull(col);\n case \"IS NOT NULL\":\n return isNotNull(col);\n case \"BETWEEN\":\n return between(col, cond.value, cond.valueTo);\n case \"NOT BETWEEN\":\n return notBetween(col, cond.value, cond.valueTo);\n case \"CONTAINS\":\n // A substring match on a TEXT column, NOT JSON containment despite the operator's name.\n // The column is used uncast, so this is text-columns-only: PostgreSQL has no `LIKE` for\n // `json`/`jsonb` and the statement errors there, while MySQL and SQLite coerce and search\n // the serialized text. Casting per dialect would make it work on all three and is a\n // change to what the operator DOES, so it is not made here.\n //\n // The value is matched LITERALLY: a `%` or `_` the caller passed is a character to find,\n // not a wildcard, so both are escaped and the escape character is declared. Without that,\n // `CONTAINS \"a%b\"` silently widens to \"a, anything, b\" — and through `delete`, which takes\n // its where clause as a required argument, a widened match is a widened deletion.\n return sql`${col} like ${containsPattern(String(cond.value))} escape '!'`;\n default:\n throw new Error(`Unsupported operator: ${cond.op}`);\n }\n}\n","/**\n * Transaction CRUD forwarder helper for database adapters.\n *\n * @remarks\n * Encapsulates the delegation pattern where a transaction context forwards its\n * CRUD methods to the adapter's implementation while passing the transaction-bound\n * Drizzle executor.\n *\n * @packageDocumentation\n */\n\nimport type {\n DeleteOptions,\n SelectOptions,\n TransactionContext,\n UpdateOptions,\n UpsertOptions,\n WhereClause,\n} from \"./types\";\n\n/**\n * Interface representing an adapter that can execute CRUD operations with an optional executor.\n */\nexport interface TransactionCrudDelegator {\n select<T = unknown>(\n table: string,\n options?: SelectOptions,\n executor?: unknown\n ): Promise<T[]>;\n selectOne<T = unknown>(\n table: string,\n options?: SelectOptions,\n executor?: unknown\n ): Promise<T | null>;\n update<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n options?: UpdateOptions,\n executor?: unknown\n ): Promise<T[]>;\n updateCount(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n executor?: unknown\n ): Promise<number>;\n delete(\n table: string,\n where: WhereClause,\n options?: DeleteOptions,\n executor?: unknown\n ): Promise<number>;\n upsert<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options: UpsertOptions,\n executor?: unknown\n ): Promise<T>;\n}\n\n/**\n * Transaction context CRUD methods provided by the forwarder.\n */\nexport type TransactionCrudForwarders = Pick<\n TransactionContext,\n | \"select\"\n | \"selectOne\"\n | \"update\"\n // The fenced compare-and-set. Listed explicitly like every other key here:\n // the type is DERIVED from `TransactionContext` in the sense that its\n // signatures come from there, but the key set is enumerated, so a method\n // added to the context is not forwarded until it is named here too.\n | \"updateCount\"\n | \"delete\"\n | \"upsert\"\n | \"getDrizzle\"\n>;\n\n/**\n * Create CRUD and Drizzle instance forwarding methods for a TransactionContext.\n *\n * @remarks\n * TransactionContext delegates its CRUD methods to the adapter's Drizzle CRUD\n * implementation while binding the transaction executor so queries run inside\n * the transaction rather than on the connection pool.\n *\n * @param delegator - Object providing the underlying adapter CRUD methods\n * @param txDb - Thunk returning the transaction-bound Drizzle instance\n * @returns Object with forwarded TransactionContext methods\n */\nexport function createTransactionForwarders(\n delegator: TransactionCrudDelegator,\n txDb: () => unknown\n): TransactionCrudForwarders {\n return {\n select: async <T = unknown>(\n table: string,\n options?: SelectOptions\n ): Promise<T[]> => {\n return delegator.select<T>(table, options, txDb());\n },\n\n selectOne: async <T = unknown>(\n table: string,\n options?: SelectOptions\n ): Promise<T | null> => {\n return delegator.selectOne<T>(table, options, txDb());\n },\n\n update: async <T = unknown>(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n options?: UpdateOptions\n ): Promise<T[]> => {\n return delegator.update<T>(table, data, where, options, txDb());\n },\n\n updateCount: async (\n table: string,\n data: Record<string, unknown>,\n where: WhereClause\n ): Promise<number> => {\n return delegator.updateCount(table, data, where, txDb());\n },\n\n delete: async (\n table: string,\n where: WhereClause,\n options?: DeleteOptions\n ): Promise<number> => {\n return delegator.delete(table, where, options, txDb());\n },\n\n upsert: async <T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options: UpsertOptions\n ): Promise<T> => {\n return delegator.upsert<T>(table, data, options, txDb());\n },\n\n getDrizzle: <T = unknown>(): T => txDb() as T,\n };\n}\n","/**\n * Database error type definitions.\n *\n * @packageDocumentation\n */\n\n/**\n * Database error classification.\n *\n * @remarks\n * Categorizes database errors for consistent error handling across adapters.\n * Each adapter translates database-specific error codes to these kinds.\n *\n * @public\n */\nexport type DatabaseErrorKind =\n | \"connection\" // Connection/network errors\n | \"query\" // Syntax or execution errors\n | \"constraint\" // Generic constraint violation\n | \"unique_violation\" // Unique constraint violation\n | \"foreign_key_violation\" // Foreign key constraint violation\n | \"check_violation\" // Check constraint violation\n | \"not_null_violation\" // NOT NULL constraint violation\n | \"deadlock\" // Transaction deadlock\n | \"timeout\" // Query or connection timeout\n | \"serialization_failure\" // Serializable transaction conflict\n | \"unsupported_version\" // F17: DB version below minimum or unparseable at connect\n | \"unknown\"; // Unclassified error\n\n/**\n * Enhanced database error interface.\n *\n * @remarks\n * Extends the standard Error interface with database-specific context.\n * Adapters should throw errors implementing this interface for consistent\n * error handling.\n *\n * @example\n * ```typescript\n * try {\n * await adapter.insert('users', { email: 'duplicate@example.com' });\n * } catch (error) {\n * if (isDatabaseError(error) && error.kind === 'unique_violation') {\n * console.log(`Duplicate ${error.column} in ${error.table}`);\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface DatabaseError extends Error {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Database-specific error code (e.g., \"23505\" for PostgreSQL unique violation) */\n code?: string;\n\n /** Constraint name that was violated (if applicable) */\n constraint?: string;\n\n /** Table name involved in the error */\n table?: string;\n\n /** Column name involved in the error */\n column?: string;\n\n /** Detailed error description from the database */\n detail?: string;\n\n /** Hint for resolving the error */\n hint?: string;\n\n /** Original error from the database driver */\n cause?: Error;\n}\n\n/**\n * Type guard for DatabaseError.\n *\n * @remarks\n * Checks if an error is a DatabaseError with proper typing.\n *\n * @param error - Error to check\n * @returns True if error is a DatabaseError\n *\n * @public\n */\nexport function isDatabaseError(error: unknown): error is DatabaseError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"kind\" in error &&\n typeof (error as DatabaseError).kind === \"string\"\n );\n}\n\n/**\n * The brand every Nextly application error carries.\n *\n * Read through the global symbol registry rather than imported, because the\n * adapters must not depend on the package that defines the error: `Symbol.for`\n * resolves to the same symbol in every module instance, which is why the brand\n * exists in that form to begin with.\n *\n * @internal\n */\nconst APPLICATION_ERROR_BRAND: unique symbol = Symbol.for(\"nextly/NextlyError\");\n\n/**\n * Whether an error is the application's verdict rather than the database's\n * failure.\n *\n * Work running inside a transaction may throw to roll the write back — a\n * refused value, a permission denial — and such an error is not something the\n * driver produced. Classifying it as a database error replaces its code and its\n * payload with a generic one, so a caller that asked for a refusal is handed an\n * unexplained failure instead, and per-field validation detail is lost on the\n * way out.\n *\n * @param error - Error to check\n * @returns True if the error was raised by application code\n *\n * @public\n */\nexport function isApplicationError(error: unknown): boolean {\n if (\n error === null ||\n (typeof error !== \"object\" && typeof error !== \"function\")\n ) {\n return false;\n }\n return (error as Record<symbol, unknown>)[APPLICATION_ERROR_BRAND] === true;\n}\n\n/**\n * Database error constructor options.\n *\n * @public\n */\nexport interface DatabaseErrorOptions {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Error message */\n message: string;\n\n /** Database-specific error code */\n code?: string;\n\n /** Constraint name */\n constraint?: string;\n\n /** Table name */\n table?: string;\n\n /** Column name */\n column?: string;\n\n /** Detailed description */\n detail?: string;\n\n /** Resolution hint */\n hint?: string;\n\n /** Original error */\n cause?: Error;\n}\n\n/**\n * Create a DatabaseError instance.\n *\n * @remarks\n * Helper function to create properly structured DatabaseError objects.\n *\n * @param options - Error options\n * @returns DatabaseError instance\n *\n * @public\n */\nexport function createDatabaseError(\n options: DatabaseErrorOptions\n): DatabaseError {\n const error = new Error(options.message) as DatabaseError;\n error.name = \"DatabaseError\";\n error.kind = options.kind;\n\n if (options.code !== undefined) error.code = options.code;\n if (options.constraint !== undefined) error.constraint = options.constraint;\n if (options.table !== undefined) error.table = options.table;\n if (options.column !== undefined) error.column = options.column;\n if (options.detail !== undefined) error.detail = options.detail;\n if (options.hint !== undefined) error.hint = options.hint;\n if (options.cause !== undefined) error.cause = options.cause;\n\n return error;\n}\n","/**\n * Base database adapter abstract class.\n *\n * @remarks\n * This abstract class provides the foundation for all dialect-specific database adapters\n * (PostgreSQL, MySQL, SQLite). It defines required abstract methods that must be implemented\n * by subclasses, while providing default implementations for CRUD operations and query building.\n *\n * Dialect adapters can override any default method to provide optimized implementations.\n *\n * @packageDocumentation\n */\n\nimport { count, getColumns } from \"drizzle-orm\";\nimport type { AnyRelations, SQL } from \"drizzle-orm\";\n\nimport { buildDrizzleOrderBy } from \"./drizzle-order\";\nimport { buildDrizzleWhere } from \"./drizzle-where\";\nimport {\n createTransactionForwarders,\n type TransactionCrudForwarders,\n} from \"./transaction-forwarders\";\nimport type {\n SupportedDialect,\n SqlParam,\n WhereClause,\n CountOptions,\n SelectOptions,\n InsertOptions,\n UpdateOptions,\n DeleteOptions,\n UpsertOptions,\n TransactionContext,\n TransactionOptions,\n DatabaseCapabilities,\n PoolStats,\n DatabaseError,\n DatabaseErrorKind,\n Migration,\n MigrationResult,\n TableDefinition,\n CreateTableOptions,\n DropTableOptions,\n AlterTableOptions,\n AlterTableOperation,\n TableResolver,\n} from \"./types\";\nimport { createDatabaseError, isDatabaseError } from \"./types\";\n\n/**\n * A Drizzle column that decodes its own driver representation.\n *\n * `dataType` is the dialect-independent kind (\"string\", \"boolean\", \"date\");\n * `mapFromDriverValue` turns what the driver handed back into the JS value a\n * Drizzle query would have produced.\n */\ninterface DecodableColumn {\n dataType: unknown;\n mapFromDriverValue(value: unknown): unknown;\n mapToDriverValue(value: unknown): unknown;\n}\n\n/**\n * Matches the `dataType` a Drizzle timestamp/datetime column reports, in both\n * the bare form and the object-qualified form some column classes carry.\n */\nconst DATE_DATA_TYPE = /(?:^|\\s)date$/;\n\n/**\n * How far an echoed timestamp may sit from the one that was bound and still\n * count as the same value.\n *\n * A column with no fractional precision keeps whole seconds, so a stored value\n * can differ from the bound one by up to a second without anything being wrong.\n * Every real UTC offset is at least fifteen minutes, so a shift is never\n * mistaken for rounding.\n */\n/**\n * Stem for the alias a statement spells a timestamp's wall clock out under.\n *\n * Short on purpose. PostgreSQL truncates an identifier at 63 bytes, and a\n * truncated alias is worse than a rejected one: the statement still succeeds,\n * the lookup misses the name it asked for, and the row keeps both the driver's\n * value and a stray property. A stem plus an index stays far inside the limit\n * whatever the column is called.\n */\nconst WALL_CLOCK_ALIAS_STEM = \"__nx_wc\";\n\n/**\n * A timestamp as the database itself spells it, in a fixed field order.\n *\n * Matched rather than handed to `new Date`, so nothing depends on the host's\n * parsing of a partial date. The fraction is optional and of any length, which\n * covers PostgreSQL's milliseconds and MySQL's microseconds alike.\n */\nconst WALL_CLOCK_PATTERN =\n /^(\\d{4})-(\\d{2})-(\\d{2})[T ](\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?$/;\n\n/**\n * Read a database's own rendering of a timestamp as UTC.\n *\n * The statement wrote a UTC wall clock, so reading one back as UTC is what\n * makes a write agree with a later read. The rendering is one the statement\n * asked for by name, so its shape does not depend on a session setting.\n *\n * Anything that does not match answers nothing, leaving the driver's value in\n * place rather than replacing it with an `Invalid Date`.\n */\nfunction parseWallClockAsUtc(text: string): Date | undefined {\n const match = WALL_CLOCK_PATTERN.exec(text.trim());\n if (!match) return undefined;\n const [, year, month, day, hour, minute, second, fraction = \"\"] = match;\n // Milliseconds, whatever precision the dialect rendered: a shorter fraction\n // is padded and a longer one truncated, which is what a `Date` can hold.\n const millis = Number(`${fraction}000`.slice(0, 3));\n const parsed = new Date(\n Date.UTC(\n Number(year),\n Number(month) - 1,\n Number(day),\n Number(hour),\n Number(minute),\n Number(second),\n millis\n )\n );\n // `Date.UTC` reads a year under 100 as shorthand for the 1900s, so year 50\n // would land in 1950. The database said 0050 and meant it.\n if (Number(year) < 100) parsed.setUTCFullYear(Number(year));\n return parsed;\n}\n\n/** Whether a table property is a date column that can convert its own values. */\nfunction isDateColumn(colDef: unknown): colDef is DecodableColumn {\n if (!colDef || typeof colDef !== \"object\") return false;\n const candidate = colDef as Partial<DecodableColumn>;\n return (\n typeof candidate.mapFromDriverValue === \"function\" &&\n typeof candidate.mapToDriverValue === \"function\" &&\n DATE_DATA_TYPE.test(String(candidate.dataType))\n );\n}\n\n/**\n * Whether a date column records the zone its value belongs to.\n *\n * A column declared WITH a time zone stores an instant, so a driver reading it\n * back gets the same moment whatever zone either end is in -- there is nothing\n * ambiguous to resolve and nothing to correct. Rendering one as text would\n * spell it in the session's zone, and reading that as UTC would move it.\n */\nfunction carriesTimeZone(colDef: unknown): boolean {\n return (colDef as { withTimezone?: unknown }).withTimezone === true;\n}\n\n/**\n * Abstract base class for database adapters.\n *\n * @remarks\n * All dialect-specific adapters must extend this class and implement the abstract methods.\n * Default implementations are provided for CRUD operations, which can be overridden for\n * optimization or dialect-specific behavior.\n *\n * ## Required Implementations\n *\n * Subclasses must implement:\n * - `dialect` - Database dialect identifier\n * - `connect()` - Establish database connection\n * - `disconnect()` - Close database connection\n * - `executeQuery()` - Execute raw SQL query\n * - `transaction()` - Execute operations within a transaction\n * - `getCapabilities()` - Report database feature support\n *\n * ## Optional Overrides\n *\n * Subclasses can override default CRUD methods for optimization:\n * - `select()`, `selectOne()` - Custom query optimization\n * - `insert()`, `insertMany()` - Bulk insert optimization\n * - `update()`, `delete()` - Custom update/delete logic\n * - `upsert()` - Dialect-specific upsert syntax\n *\n * @example\n * ```typescript\n * export class PostgresAdapter extends DrizzleAdapter {\n * readonly dialect = 'postgresql' as const;\n *\n * async connect() {\n * this.pool = new Pool({ connectionString: this.config.url });\n * // ... connection logic\n * }\n *\n * async executeQuery<T>(sql: string, params?: SqlParam[]) {\n * const result = await this.pool.query(sql, params);\n * return result.rows as T[];\n * }\n *\n * // ... other required methods\n * }\n * ```\n *\n * @public\n */\n/**\n * Rows affected by a write, normalised across the driver shapes Drizzle returns.\n *\n * mysql2 resolves to `[ResultSetHeader, FieldPacket[]]`, so treating any array\n * as a row list reports the tuple length — a constant 2 whether the statement\n * matched nothing, one row, or many. Callers that branch on the count (a\n * conditional claim, a retention loop) silently get the wrong answer on MySQL,\n * so the header is read first. node-postgres reports `rowCount` and\n * better-sqlite3 reports `changes`; a plain array is a RETURNING row list, whose\n * length is the count.\n */\nfunction affectedRowCount(result: unknown): number {\n if (Array.isArray(result)) {\n const header = result[0] as { affectedRows?: unknown } | undefined;\n if (header && typeof header.affectedRows === \"number\") {\n return header.affectedRows;\n }\n return result.length;\n }\n const record = result as Record<string, unknown> | null | undefined;\n const rowCount = record?.rowCount;\n if (typeof rowCount === \"number\") return rowCount;\n const changes = record?.changes;\n if (typeof changes === \"number\") return changes;\n return 0;\n}\n\n/**\n * The fragment of Drizzle's update builder `updateCount` uses, spelled dialect-neutrally.\n *\n * Declared rather than reached for through a permissive generic: the three dialects' builders carry\n * different type parameters but agree on this chain, so naming just the chain keeps the compiler\n * checking the call while leaving the parts that genuinely differ outside the contract. `set` is\n * awaitable on its own, which is what makes an update with no WHERE a complete statement rather\n * than a builder waiting for one.\n */\ninterface UpdateCapableDb {\n update(table: unknown): {\n set(values: Record<string, unknown>): PromiseLike<unknown> & {\n where(condition: unknown): PromiseLike<unknown>;\n };\n };\n}\n\n/** The one-column shape a count projection selects. */\ninterface CountRow {\n value: unknown;\n}\n\n/**\n * A `$dynamic()` count select, whose WHERE is applied only when there is one.\n *\n * Both branches are awaitable, which is the property that makes the conditional\n * work: the statement is a complete query with or without a condition, so\n * neither arm is a builder still waiting for something.\n */\ninterface CountableSelect extends PromiseLike<CountRow[]> {\n where(condition: unknown): PromiseLike<CountRow[]>;\n}\n\n/**\n * A `SELECT DISTINCT` that can still be named as a subquery after a WHERE.\n *\n * `where` returns the same shape rather than a thenable, because this select is\n * never executed on its own — it is aliased and counted over.\n */\ninterface AliasableSelect {\n where(condition: unknown): AliasableSelect;\n as(alias: string): unknown;\n}\n\n/**\n * The fragment of Drizzle's select builder `count` uses, spelled dialect-neutrally.\n *\n * Declared for the same reason as {@link UpdateCapableDb}: the three dialects' builders carry\n * different type parameters but agree on these chains, so naming just the chains keeps the compiler\n * checking the calls while leaving the parts that genuinely differ outside the contract. Casting to\n * `any` instead would compile whatever it was handed, so a dialect changing one of these signatures\n * would break counts at runtime with nothing failing at build time.\n */\ninterface CountCapableDb {\n select(projection: Record<string, unknown>): {\n from(source: unknown): PromiseLike<CountRow[]> & {\n $dynamic(): CountableSelect;\n };\n };\n selectDistinct(projection: Record<string, unknown>): {\n from(table: unknown): { $dynamic(): AliasableSelect };\n };\n}\n\nexport abstract class DrizzleAdapter {\n // ============================================================\n // Abstract Methods (MUST be implemented by subclasses)\n // ============================================================\n\n /**\n * Database dialect identifier.\n *\n * @remarks\n * Must be set by subclass to identify the database type.\n */\n abstract readonly dialect: SupportedDialect;\n\n /**\n * Establish connection to the database.\n *\n * @remarks\n * This method should be idempotent - calling it multiple times\n * should not create multiple connections.\n *\n * @throws {DatabaseError} If connection fails\n */\n abstract connect(): Promise<void>;\n\n /**\n * Close database connection and release resources.\n *\n * @remarks\n * This method should be idempotent - calling it multiple times\n * should be safe.\n */\n abstract disconnect(): Promise<void>;\n\n /**\n * Execute a raw SQL query.\n *\n * @param sql - SQL query to execute\n * @param params - Query parameters\n * @returns Array of result rows\n *\n * @throws {DatabaseError} If query execution fails\n */\n abstract executeQuery<T = unknown>(\n sql: string,\n params?: SqlParam[]\n ): Promise<T[]>;\n\n /**\n * Execute operations within a database transaction.\n *\n * @remarks\n * The transaction is automatically committed on success or rolled back on error.\n * Supports nested transactions via savepoints on databases that support them.\n *\n * Two kinds of error leave this method, and a caller has to be able to tell\n * them apart. An error carrying the Nextly application brand — see\n * `isApplicationError` — arrives exactly as it was thrown, because that is\n * the application refusing the write rather than the database failing to\n * perform it, and rewriting it would discard the code and payload the caller\n * is meant to act on.\n *\n * Everything else arrives as a `DatabaseError` with its kind classified, and\n * that deliberately includes an unbranded error the callback itself threw:\n * the brand is the only thing distinguishing a deliberate refusal from a\n * driver failure that surfaced through callback code, and guessing from the\n * throw site would put raw driver text on the wire under a caller's own\n * error shape.\n *\n * The rollback is the same either way.\n *\n * @param callback - Function to execute within transaction\n * @param options - Transaction options\n * @returns Result from the callback\n *\n * @throws {DatabaseError} If the transaction itself fails, or if the callback\n * threw an error that does not carry the application brand\n * @throws The callback's own error, unchanged, when it carries that brand\n */\n abstract transaction<T>(\n callback: (ctx: TransactionContext) => Promise<T>,\n options?: TransactionOptions\n ): Promise<T>;\n\n /**\n * Get database capabilities.\n *\n * @remarks\n * Returns static capability flags for this adapter's dialect.\n * Used by services to conditionally enable features or implement fallbacks.\n *\n * @returns Database capability flags\n */\n abstract getCapabilities(): DatabaseCapabilities;\n\n /**\n * Get the raw Drizzle ORM instance for direct queries.\n *\n * @remarks\n * This method provides escape hatch access to the raw Drizzle instance.\n * Use this when you need to run complex queries that the adapter API\n * doesn't support, or for legacy code migration.\n *\n * **Note:** Prefer using adapter methods when possible as they provide:\n * - Database-agnostic API\n * - Consistent error handling\n * - Proper connection pooling\n *\n * @param relations - Optional drizzle v1 relations config (defineRelations\n * output) that enables the typed relational query API on the instance\n * @returns Raw Drizzle ORM database instance\n *\n * @example\n * ```typescript\n * // For legacy code that needs direct Drizzle access\n * const db = adapter.getDrizzle(myRelations); // defineRelations output\n * const result = await db.insert(users).values({ ... }).returning();\n * ```\n */\n abstract getDrizzle<T = unknown>(relations?: AnyRelations): T;\n\n // ============================================================\n // Drizzle Query API Support\n // ============================================================\n\n /**\n * Table resolver for looking up Drizzle table objects by name.\n * When set, CRUD methods use Drizzle's query API instead of raw SQL.\n * Set via setTableResolver() after boot-time schema loading.\n */\n protected tableResolver: TableResolver | null = null;\n\n /**\n * Set the table resolver for Drizzle query API support.\n * When a resolver is set, CRUD methods (select, insert, update, delete, upsert)\n * will use Drizzle's query API (db.select().from(), etc.) instead of raw SQL\n * string building. Falls back to raw SQL if the resolver doesn't have the table.\n *\n * @param resolver - TableResolver implementation (e.g. SchemaRegistry)\n */\n setTableResolver(resolver: TableResolver): void {\n this.tableResolver = resolver;\n }\n\n /**\n * Get a Drizzle table object by name from the resolver.\n * Returns null if no resolver is set or table is not found.\n */\n protected getTableObject(tableName: string): unknown {\n return this.tableResolver?.getTable(tableName) ?? null;\n }\n\n /**\n * Run a Drizzle-built statement and return its rows.\n *\n * @remarks\n * The CRUD methods resolve their table through the schema registry and reject\n * any name it does not declare, which leaves no way to read from a table the\n * ORM does not know — one mid-rename, above all — except by assembling SQL and\n * quoting identifiers by hand. This takes Drizzle's `sql` template instead, so\n * the dialect in use decides the quoting and the parameter binding.\n *\n * Concrete rather than abstract so existing adapters keep working unchanged.\n * The three drivers disagree about both the call and the result: node-postgres\n * returns `{ rows }`, mysql2 a `[rows, fields]` tuple, and better-sqlite3 has\n * no `execute` at all and answers `all`. Keeping that here rather than at each\n * call site is the point — a caller reasoning about it would be reasoning\n * about a driver it cannot see.\n *\n * @param statement - Drizzle `sql` template to run\n * @returns Rows the statement produced\n */\n async queryStatement<T = Record<string, unknown>>(\n statement: SQL\n ): Promise<T[]> {\n if (this.getCapabilities().dialect === \"sqlite\") {\n const db = this.getDrizzle<{ all(query: SQL): T[] | Promise<T[]> }>();\n return await db.all(statement);\n }\n const db = this.getDrizzle<{ execute(query: SQL): Promise<unknown> }>();\n const result = await db.execute(statement);\n // `{ rows }` is node-postgres. A bare array is mysql2's `[rows, fields]`\n // tuple, told apart by its first element being an array — the only test that\n // does not depend on trusting one driver to keep its shape.\n if (Array.isArray(result)) {\n return (Array.isArray(result[0]) ? result[0] : result) as T[];\n }\n if (\n typeof result === \"object\" &&\n result !== null &&\n Array.isArray((result as { rows?: unknown }).rows)\n ) {\n return (result as { rows: T[] }).rows;\n }\n // Refused rather than reported as no rows. All three drivers answer one of\n // the shapes above, so anything else means the result was not understood —\n // and \"I could not read this\" must not reach a caller as \"there is nothing\n // there\", which is an answer it would act on.\n throw this.createDatabaseError(\n \"query\",\n \"Drizzle statement returned a result shape this adapter does not recognise; refusing to report it as an empty result.\",\n undefined\n );\n }\n\n /**\n * Map data keys from SQL column names (snake_case) to Drizzle JS property names (camelCase).\n * Drizzle schemas define columns as e.g. `createdAt: timestamp(\"created_at\")` — the JS\n * property is `createdAt` but the SQL column is `created_at`. Services pass snake_case keys\n * because they match the DB column names. This method maps them to the JS names Drizzle expects.\n */\n protected mapDataToColumnNames(\n tableObj: unknown,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n if (!tableObj || typeof tableObj !== \"object\") return data;\n\n // Build maps: SQL column name -> JS property name, and JS name -> column metadata\n const sqlToJs = new Map<string, string>();\n const jsonColumns = new Set<string>();\n\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (\n !colDef ||\n typeof colDef !== \"object\" ||\n !(\"name\" in colDef) ||\n typeof colDef.name !== \"string\"\n )\n continue;\n const sqlName = (colDef as { name: string }).name;\n sqlToJs.set(sqlName, jsName);\n\n // Detect JSON/JSONB columns — Drizzle auto-serializes objects for these,\n // so pre-stringified values must be parsed to avoid double-encoding.\n const dataType = (colDef as { dataType?: string }).dataType;\n const columnType = (colDef as { columnType?: string }).columnType;\n // Detect JSON/JSONB columns — Drizzle auto-serializes objects for these,\n // so pre-stringified values must be parsed to avoid double-encoding.\n // IMPORTANT: For SQLite, only match text columns declared with { mode: \"json\" }\n // (columnType \"SQLiteTextJson\", dataType \"json\"). Plain SQLiteText columns\n // (dataType \"string\") store pre-serialized strings and must NOT be re-parsed,\n // otherwise better-sqlite3 receives objects it cannot bind.\n if (\n dataType === \"json\" ||\n columnType === \"PgJsonb\" ||\n columnType === \"PgJson\" ||\n columnType === \"MySqlJson\" ||\n columnType === \"SQLiteTextJson\" // SQLite JSON-mode text columns only\n ) {\n jsonColumns.add(jsName);\n }\n }\n\n // If no mappings found, return data as-is\n if (sqlToJs.size === 0) return data;\n\n const mapped: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n const jsKey = sqlToJs.get(key) ?? key;\n // Parse pre-stringified JSON for JSON/JSONB columns to avoid double-encoding\n if (jsonColumns.has(jsKey) && typeof value === \"string\") {\n try {\n mapped[jsKey] = JSON.parse(value);\n } catch {\n mapped[jsKey] = value;\n }\n } else {\n mapped[jsKey] = value;\n }\n }\n return mapped;\n }\n\n /**\n * Map data keys from Drizzle JS property names to SQL column names for the\n * raw-SQL transaction insert path. The transaction context builds INSERT\n * statements from Object.keys(data) used directly as column identifiers, so a\n * table whose Drizzle property names differ from its SQL column names\n * (camelCase core tables like nextly_versions) needs its keys translated\n * first. For tables whose property names already equal their column names\n * (the dynamic dc_/single_/comp_ tables) every lookup is identity, so\n * existing callers are unaffected.\n */\n protected mapKeysToSqlColumns(\n tableObj: unknown,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n if (!tableObj || typeof tableObj !== \"object\") return data;\n\n const jsToSql = new Map<string, string>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (\n colDef &&\n typeof colDef === \"object\" &&\n \"name\" in colDef &&\n typeof (colDef as { name?: unknown }).name === \"string\"\n ) {\n jsToSql.set(jsName, (colDef as { name: string }).name);\n }\n }\n if (jsToSql.size === 0) return data;\n\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n out[jsToSql.get(key) ?? key] = value;\n }\n return out;\n }\n\n /**\n * Map a list of column identifiers (Drizzle property names) to their SQL\n * column names, for the raw-SQL transaction insert paths that build a\n * RETURNING clause from `options.returning`. Same identity behavior as\n * `mapKeysToSqlColumns`: names that are already SQL columns (the dynamic\n * dc_/single_/comp_ tables) pass through unchanged.\n */\n protected mapColumnNamesToSql(tableObj: unknown, names: string[]): string[] {\n if (!tableObj || typeof tableObj !== \"object\") return names;\n\n const jsToSql = new Map<string, string>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (\n colDef &&\n typeof colDef === \"object\" &&\n \"name\" in colDef &&\n typeof (colDef as { name?: unknown }).name === \"string\"\n ) {\n jsToSql.set(jsName, (colDef as { name: string }).name);\n }\n }\n if (jsToSql.size === 0) return names;\n\n return names.map(n => jsToSql.get(n) ?? n);\n }\n\n /**\n * Remap a raw-SQL result row's KEYS from SQL column names to Drizzle property\n * names, so the raw-SQL transaction insert paths return the same key casing\n * as the non-transactional (Drizzle) insert. Keys only - values are left\n * untouched, so this does not change how JSON/date columns are decoded. For\n * tables whose property names already equal their SQL columns (the dynamic\n * dc_/single_/comp_ tables) every lookup is identity, so existing callers see\n * no change.\n */\n protected mapRowKeysToJs<T = unknown>(tableObj: unknown, row: T): T {\n if (\n !tableObj ||\n typeof tableObj !== \"object\" ||\n !row ||\n typeof row !== \"object\"\n ) {\n return row;\n }\n\n const sqlToJs = new Map<string, string>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (\n colDef &&\n typeof colDef === \"object\" &&\n \"name\" in colDef &&\n typeof (colDef as { name?: unknown }).name === \"string\"\n ) {\n sqlToJs.set((colDef as { name: string }).name, jsName);\n }\n }\n if (sqlToJs.size === 0) return row;\n\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row as Record<string, unknown>)) {\n out[sqlToJs.get(key) ?? key] = value;\n }\n return out as T;\n }\n\n /**\n * Decode a raw-SQL result row's DATE column values the way a Drizzle query\n * would, so a write answers with the same representation a read of the same\n * column gives.\n *\n * A Drizzle query path runs every value through its column definition; a\n * raw-SQL path does not, so a dialect that stores a timestamp as a number\n * answers a write with that number while every read answers a `Date`. Only\n * date columns are touched, and a value that is already a `Date` is left\n * alone, so a driver that decodes on its own is unaffected.\n *\n * Runs after {@link mapRowKeysToJs}: keys are Drizzle property names by then,\n * which is what the table definition is keyed by.\n */\n protected mapDateValuesFromDriver<T = unknown>(tableObj: unknown, row: T): T {\n if (\n !tableObj ||\n typeof tableObj !== \"object\" ||\n !row ||\n typeof row !== \"object\"\n ) {\n return row;\n }\n\n let decoded: Record<string, unknown> | undefined;\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (!isDateColumn(colDef)) continue;\n const value = (row as Record<string, unknown>)[jsName];\n // `undefined` means the column was not projected; `null` is a stored\n // absence. Neither is a driver representation to decode.\n if (value == null || value instanceof Date) continue;\n decoded ??= { ...(row as Record<string, unknown>) };\n decoded[jsName] = colDef.mapFromDriverValue(value);\n }\n return (decoded as T | undefined) ?? row;\n }\n\n /**\n * Encode a row's DATE values the way a Drizzle query would before binding\n * them, so what lands in the column does not depend on the server's timezone.\n *\n * A column declared without a time zone stores a wall clock and records\n * nothing about which zone it belongs to, so both ends have to agree. Drizzle\n * writes UTC and reads UTC. A driver handed a `Date` writes the LOCAL wall\n * clock instead, and the same row then reads back shifted by the offset --\n * on a UTC server the two agree and nothing is visibly wrong, which is why\n * this survives CI.\n *\n * Only date columns are touched. A value that is not a `Date` is left as it\n * is, so a caller that already encoded one is not encoded twice.\n *\n * Keys may be spelled either way at this point, so both the Drizzle property\n * name and the SQL column name resolve.\n */\n protected mapDateValuesToDriver(\n tableObj: unknown,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n if (!tableObj || typeof tableObj !== \"object\" || !data) return data;\n\n const dateColumns = new Map<string, DecodableColumn>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (!isDateColumn(colDef)) continue;\n dateColumns.set(jsName, colDef);\n const sqlName = (colDef as { name?: unknown }).name;\n if (typeof sqlName === \"string\") dateColumns.set(sqlName, colDef);\n }\n if (dateColumns.size === 0) return data;\n\n let encoded: Record<string, unknown> | undefined;\n for (const [key, value] of Object.entries(data)) {\n if (!(value instanceof Date)) continue;\n const column = dateColumns.get(key);\n if (!column) continue;\n encoded ??= { ...data };\n encoded[key] = column.mapToDriverValue(value);\n }\n return encoded ?? data;\n }\n\n /**\n * Bring a row about to be written through a raw-SQL statement into the shape\n * a Drizzle query would have bound: SQL column names for keys, encoded values\n * for date columns.\n *\n * The mirror of {@link mapRowFromRawSql}. The raw-SQL write paths exist\n * because a dialect needs SQL a Drizzle query cannot express, not because\n * their callers want different values in the table.\n */\n protected mapRowToRawSql(\n tableObj: unknown,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n return this.mapDateValuesToDriver(\n tableObj,\n this.mapKeysToSqlColumns(tableObj, data)\n );\n }\n\n /**\n * Bring a raw-SQL result row into the shape a Drizzle query would have\n * produced: Drizzle property names for keys, decoded values for date columns.\n *\n * The raw-SQL write paths exist because a dialect needs SQL a Drizzle query\n * cannot express, not because their callers want a different row shape, so\n * every one of them ends here.\n */\n protected mapRowFromRawSql<T = unknown>(\n tableObj: unknown,\n row: T,\n aliases: ReadonlyArray<{ alias: string; jsName: string }> = []\n ): T {\n const mapped = this.mapDateValuesFromDriver(\n tableObj,\n this.mapRowKeysToJs(tableObj, row)\n );\n return this.applyWallClockAliases(mapped, aliases);\n }\n\n /**\n * The date columns a statement is about to return, and the alias each one's\n * wall clock is spelled out under.\n *\n * A driver turns a timestamp into a `Date` using ITS zone before any of this\n * code runs, and that conversion is lossy: a wall clock inside a\n * daylight-saving gap is a local time that does not exist, so the driver\n * normalizes it and the original is gone. Asking the database for the wall\n * clock as text alongside the row is the only way to read it exactly.\n *\n * `\"*\"` covers every date column; a projection covers only the ones it asked\n * for, so a caller still gets back what it requested and nothing more.\n */\n protected dateWallClockAliases(\n tableObj: unknown,\n returning: string[] | \"*\" | undefined\n ): Array<{ sqlName: string; alias: string; jsName: string }> {\n if (!tableObj || typeof tableObj !== \"object\" || returning === undefined) {\n return [];\n }\n const requested =\n returning === \"*\" ? undefined : new Set(returning.map(String));\n\n // Every name the row can already carry, so an alias cannot land on one and\n // overwrite or delete it. A column really called `__nx_wc0` is far-fetched,\n // but one set makes it impossible rather than unlikely.\n const taken = new Set<string>();\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n taken.add(jsName);\n const columnName = (colDef as { name?: unknown }).name;\n if (typeof columnName === \"string\") taken.add(columnName);\n }\n\n let next = 0;\n const freeAlias = (): string => {\n let candidate = `${WALL_CLOCK_ALIAS_STEM}${next++}`;\n while (taken.has(candidate)) {\n candidate = `${WALL_CLOCK_ALIAS_STEM}${next++}`;\n }\n taken.add(candidate);\n return candidate;\n };\n\n const aliases: Array<{ sqlName: string; alias: string; jsName: string }> =\n [];\n for (const [jsName, colDef] of Object.entries(\n tableObj as Record<string, unknown>\n )) {\n if (!isDateColumn(colDef)) continue;\n // A column carrying its own zone is already unambiguous; spelling it out\n // would render it in the session's zone and reading that as UTC would\n // move an instant that was correct to begin with.\n if (carriesTimeZone(colDef)) continue;\n const sqlName = (colDef as { name?: unknown }).name;\n if (typeof sqlName !== \"string\") continue;\n if (requested && !requested.has(sqlName) && !requested.has(jsName)) {\n continue;\n }\n aliases.push({ sqlName, alias: freeAlias(), jsName });\n }\n return aliases;\n }\n\n /**\n * Replace each date in a row with the wall clock the database spelled out,\n * read as UTC, and drop the aliases that carried it.\n *\n * The statement writes a UTC wall clock, so reading one back as UTC is what\n * makes a write and a later read agree. Whatever the column actually stored\n * is what arrives -- a column keeping only whole seconds reports whole\n * seconds -- because this is the database's own text, not a value\n * reconstructed from the one that was bound.\n */\n protected applyWallClockAliases<T>(\n row: T,\n aliases: ReadonlyArray<{ alias: string; jsName: string }>\n ): T {\n if (!row || typeof row !== \"object\" || aliases.length === 0) return row;\n const record = row as Record<string, unknown>;\n\n let resolved: Record<string, unknown> | undefined;\n for (const { alias, jsName } of aliases) {\n if (!(alias in record)) continue;\n resolved ??= { ...record };\n const text = resolved[alias];\n delete resolved[alias];\n if (typeof text !== \"string\") continue;\n const parsed = parseWallClockAsUtc(text);\n if (parsed !== undefined) resolved[jsName] = parsed;\n }\n return (resolved as T | undefined) ?? row;\n }\n\n /**\n * Build a Drizzle column projection object (`{ propertyName: column }`) from a\n * requested column list, used by `select` (columns) and `insert` (returning).\n * A requested name resolves against either the Drizzle property name\n * (camelCase) or the SQL column name (snake_case); the projection is keyed by\n * the property name so the row shape matches a full select. Returns undefined\n * for `\"*\"` or when nothing resolves, so callers fall back to all columns.\n */\n protected buildColumnProjection(\n tableObj: unknown,\n names: string[] | \"*\" | undefined\n ): Record<string, unknown> | undefined {\n if (\n names == null ||\n names === \"*\" ||\n !tableObj ||\n typeof tableObj !== \"object\"\n ) {\n return undefined;\n }\n const { projection } = this.resolveColumns(tableObj, names);\n return Object.keys(projection).length ? projection : undefined;\n }\n\n /**\n * The requested column names split into what this table has and what it does not.\n *\n * One resolution, reported both ways, because two callers need different halves\n * of the same answer: a projection drops what it cannot find, while a distinct\n * count has to REFUSE it. Resolving twice would let the two disagree about what\n * \"found\" means — the SQL-name alias below is exactly the kind of detail a\n * second implementation gets wrong — and the count would then reject a column\n * the projection happily uses.\n *\n * Both spellings resolve: a caller may name the Drizzle property or the SQL\n * column, and either maps to the same projection key.\n */\n protected resolveColumns(\n tableObj: unknown,\n names: readonly string[]\n ): { projection: Record<string, unknown>; unresolved: string[] } {\n const cols = getColumns(tableObj as never);\n const byAnyName: Record<string, { jsName: string; col: unknown }> = {};\n for (const [jsName, col] of Object.entries(cols)) {\n byAnyName[jsName] = { jsName, col };\n const sqlName = (col as { name?: unknown })?.name;\n if (typeof sqlName === \"string\") byAnyName[sqlName] = { jsName, col };\n }\n const projection: Record<string, unknown> = {};\n const unresolved: string[] = [];\n for (const name of names) {\n const hit = byAnyName[name];\n if (hit) projection[hit.jsName] = hit.col;\n else unresolved.push(name);\n }\n return { projection, unresolved };\n }\n\n // ============================================================\n // Connection Status (Default implementations, can override)\n // ============================================================\n\n /**\n * Check if the adapter is currently connected.\n *\n * @remarks\n * Default implementation returns false. Subclasses should override\n * to provide accurate connection status.\n *\n * @returns True if connected, false otherwise\n */\n isConnected(): boolean {\n return false;\n }\n\n /**\n * Get connection pool statistics.\n *\n * @remarks\n * Returns null by default. Subclasses with connection pooling\n * should override to provide pool statistics.\n *\n * @returns Pool statistics or null if not applicable\n */\n getPoolStats(): PoolStats | null {\n return null;\n }\n\n // ============================================================\n // Timeout Utilities\n // ============================================================\n\n /**\n * Default query timeout in milliseconds.\n *\n * @remarks\n * This value is used by executeWithTimeout() when no explicit timeout\n * is provided. Subclasses should set this from their config.\n *\n * @default 15000 (15 seconds)\n *\n * @protected\n */\n protected defaultQueryTimeoutMs: number = 15000;\n\n /**\n * Execute an async operation with a timeout.\n *\n * @remarks\n * Wraps an async operation with a timeout that aborts if the operation\n * exceeds the specified duration. Uses Promise.race for clean timeout\n * handling without memory leaks.\n *\n * When the timeout is reached, a DatabaseError with kind 'timeout' is thrown.\n * Note that this does NOT cancel the underlying database query - it only\n * prevents the calling code from waiting indefinitely. For true query\n * cancellation, use database-level statement timeouts (PostgreSQL) or\n * similar mechanisms.\n *\n * @param operation - Async operation to execute\n * @param timeoutMs - Timeout in milliseconds (defaults to defaultQueryTimeoutMs)\n * @returns Result of the operation\n *\n * @throws {DatabaseError} With kind 'timeout' if operation exceeds timeout\n *\n * @example\n * ```typescript\n * // Use default timeout\n * const result = await adapter.executeWithTimeout(\n * () => adapter.select('users', { limit: 1000 })\n * );\n *\n * // Use custom timeout for specific operation\n * const result = await adapter.executeWithTimeout(\n * () => adapter.select('large_table'),\n * 60000 // 60 seconds for large queries\n * );\n * ```\n *\n * @public\n */\n async executeWithTimeout<T>(\n operation: () => Promise<T>,\n timeoutMs?: number\n ): Promise<T> {\n const timeout = timeoutMs ?? this.defaultQueryTimeoutMs;\n\n // If timeout is 0 or negative, execute without timeout\n if (timeout <= 0) {\n return operation();\n }\n\n // Create a timeout promise that rejects after the specified duration\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n this.createDatabaseError(\n \"timeout\",\n `Query execution timed out after ${timeout}ms`\n )\n );\n }, timeout);\n });\n\n try {\n // Race between the operation and the timeout\n const result = await Promise.race([operation(), timeoutPromise]);\n return result;\n } finally {\n // Always clear the timeout to prevent memory leaks\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Set the default query timeout.\n *\n * @remarks\n * This method allows runtime configuration of the default timeout.\n * Subclasses should call this in their constructor or connect() method\n * based on their configuration.\n *\n * @param timeoutMs - Timeout in milliseconds (0 to disable)\n *\n * @protected\n */\n protected setDefaultQueryTimeout(timeoutMs: number): void {\n this.defaultQueryTimeoutMs = timeoutMs;\n }\n\n /**\n * Get the current default query timeout.\n *\n * @returns Current default timeout in milliseconds\n *\n * @public\n */\n getDefaultQueryTimeout(): number {\n return this.defaultQueryTimeoutMs;\n }\n\n // ============================================================\n // CRUD Operations (Default implementations, can override)\n // ============================================================\n\n /**\n * Select multiple records from a table.\n *\n * @remarks\n * Default implementation builds a SELECT query and executes it.\n * Subclasses can override for optimization or dialect-specific features.\n *\n * @param table - Table name\n * @param options - Select options (filtering, sorting, pagination)\n * @returns Array of matching records\n *\n * @throws {DatabaseError} If query fails\n *\n * @example\n * ```typescript\n * const users = await adapter.select('users', {\n * where: { and: [{ column: 'role', op: '=', value: 'admin' }] },\n * orderBy: [{ column: 'created_at', direction: 'desc' }],\n * limit: 10\n * });\n * ```\n */\n async select<T = unknown>(\n table: string,\n options?: SelectOptions,\n executor?: unknown\n ): Promise<T[]> {\n // Drizzle query API path: use when table resolver has a Drizzle table object\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Run on the transaction's executor when one is supplied, otherwise the\n // pooled instance. Without this, a read inside a transaction would use\n // the pool and miss rows written earlier in the same uncommitted tx.\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = executor ?? this.getDrizzle<any>();\n // Honor the columns projection when provided: select only the requested\n // columns instead of every column, so callers can avoid transferring\n // large columns (e.g. JSON snapshots) they do not need. Falls back to a\n // full select when no columns are requested or none resolve.\n const projection = options?.columns?.length\n ? this.buildColumnProjection(tableObj, options.columns)\n : undefined;\n let query = projection\n ? db.select(projection).from(tableObj)\n : db.select().from(tableObj);\n\n if (options?.where) {\n const whereCondition = buildDrizzleWhere(\n tableObj as never,\n options.where\n );\n if (whereCondition) {\n query = query.where(whereCondition);\n }\n }\n\n // Guarded, so `getColumns` is not reached for a select that does not\n // order. Hoisting it out of this check ran it on every select and broke\n // callers whose table handle cannot answer it.\n if (options?.orderBy?.length) {\n const orderClauses = buildDrizzleOrderBy(\n getColumns(tableObj as never),\n options.orderBy\n );\n if (orderClauses.length) {\n query = query.orderBy(...orderClauses);\n }\n }\n\n if (options?.limit !== undefined) {\n query = query.limit(options.limit);\n }\n\n if (options?.offset !== undefined) {\n query = query.offset(options.offset);\n }\n\n // A lock request is only meaningful inside a transaction, on EVERY\n // dialect. On the row-locking dialects the pooled connection autocommits\n // the SELECT, releasing the lock the instant it returns; on SQLite the\n // lock IS the transaction (BEGIN IMMEDIATE serializes writers), so a\n // pooled call takes no lock at all. Either way a `forUpdate` without a\n // transaction executor is silent false safety and reopens the TOCTOU\n // window it was meant to close, so fail fast regardless of dialect.\n if (options?.forUpdate && !executor) {\n throw this.createDatabaseError(\n \"query\",\n \"forUpdate requires a transaction executor: a lock request on the pooled connection takes no durable lock and cannot prevent a concurrent write.\",\n undefined\n );\n }\n\n // Row-lock the selected rows for the rest of the transaction and read the\n // latest committed values (not the transaction's snapshot). SQLite has no\n // FOR UPDATE and needs none (BEGIN IMMEDIATE serializes its writers), so\n // it is skipped there.\n if (options?.forUpdate && this.dialect !== \"sqlite\") {\n query = query.for(\"update\");\n }\n\n return (await query) as T[];\n } catch (error) {\n throw this.handleQueryError(error, \"select\", table);\n }\n }\n\n // Table not found in schema registry - cannot use Drizzle query API\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Select a single record from a table.\n *\n * @remarks\n * Default implementation uses `select()` with limit 1 and returns first result.\n * Returns null if no matching record is found.\n *\n * @param table - Table name\n * @param options - Select options\n * @returns First matching record or null\n *\n * @throws {DatabaseError} If query fails\n *\n * @example\n * ```typescript\n * const user = await adapter.selectOne('users', {\n * where: { and: [{ column: 'email', op: '=', value: 'user@example.com' }] }\n * });\n * ```\n */\n /** The registered table object, or a refusal naming what is missing. */\n private requireTableObject(table: string): unknown {\n const tableObj = this.getTableObject(table);\n if (tableObj) return tableObj;\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * The columns a distinct count groups by, or `undefined` for a row count.\n *\n * 🔴 EVERY named column must resolve, not merely one of them. A `distinctOn`\n * naming no column this table has would fall through to a row count, and one\n * naming a valid column beside a misspelled or since-removed column would\n * count distinct over a NARROWER key than the caller asked for. Both answer a\n * different question than the one asked, silently; the second is the worse of\n * the two, because a subset key groups more rows together and so UNDERCOUNTS,\n * which reads as a plausible number rather than as a fault. Refused here,\n * where the mistake was made, rather than surfacing as a wrong figure.\n */\n private countProjection(\n tableObj: unknown,\n table: string,\n options: CountOptions | undefined\n ): Record<string, unknown> | undefined {\n const distinctOn = options?.distinctOn;\n if (!distinctOn?.length) return undefined;\n const { projection, unresolved } = this.resolveColumns(\n tableObj,\n distinctOn\n );\n if (unresolved.length > 0) {\n throw this.createDatabaseError(\n \"query\",\n `distinctOn names ${unresolved.length === 1 ? \"a column\" : \"columns\"} that do not exist on \"${table}\": ${unresolved.join(\", \")}`,\n undefined\n );\n }\n return projection;\n }\n\n /**\n * `COUNT(*)` over a `SELECT DISTINCT` subquery.\n *\n * Its own function because it is a genuinely different query from the plain\n * count rather than a variation on one, and because building both inline made\n * the public method a chain of decisions the complexity gate objected to\n * before a reader would have.\n */\n private async countDistinctRows(\n db: CountCapableDb,\n tableObj: unknown,\n projection: Record<string, unknown>,\n where: unknown\n ): Promise<number> {\n const inner = db.selectDistinct(projection).from(tableObj).$dynamic();\n const distinctRows = where ? inner.where(where) : inner;\n const [row] = await db\n .select({ value: count() })\n .from(distinctRows.as(\"nextly_distinct\"));\n return Number(row?.value ?? 0);\n }\n\n /** `COUNT(*)` over the table itself. */\n private async countAllRows(\n db: CountCapableDb,\n tableObj: unknown,\n where: unknown\n ): Promise<number> {\n const base = db.select({ value: count() }).from(tableObj).$dynamic();\n const [row] = await (where ? base.where(where) : base);\n return Number(row?.value ?? 0);\n }\n\n /**\n * How many rows match, or how many DISTINCT combinations of some columns do.\n *\n * The data layer had no count at all: collection totals go through\n * `countEntries`, an access-controlled path built for collection tables, and\n * nothing could count a system table. A caller wanting one selected the rows\n * and measured the array, which transfers every row to learn a number and\n * cannot be bounded without making the number wrong.\n *\n * 🔴 `distinctOn` compiles to `COUNT(*)` over a `SELECT DISTINCT` SUBQUERY,\n * never to `COUNT(DISTINCT a, b)`. The inline form is not portable and fails\n * in the direction that is hardest to notice -- MySQL accepts it, PostgreSQL\n * needs a row constructor, and SQLite rejects it outright with \"wrong number\n * of arguments to function count()\" -- so a query written against one engine\n * is a syntax error on another. The subquery is the single form all three\n * accept, and building it here rather than at each call site is what keeps\n * the answer identical per dialect.\n */\n async count(\n table: string,\n options?: CountOptions,\n executor?: unknown\n ): Promise<number> {\n const tableObj = this.requireTableObject(table);\n try {\n // Transaction executor when supplied, otherwise the pooled instance —\n // narrowed to the fragment of the select builder these two counts use,\n // the same seam `update` takes with `UpdateCapableDb`.\n const db = (executor ??\n this.getDrizzle<CountCapableDb>()) as CountCapableDb;\n const where = options?.where\n ? buildDrizzleWhere(tableObj as never, options.where)\n : undefined;\n const projection = this.countProjection(tableObj, table, options);\n return projection\n ? await this.countDistinctRows(db, tableObj, projection, where)\n : await this.countAllRows(db, tableObj, where);\n } catch (error) {\n throw this.handleQueryError(error, \"count\", table);\n }\n }\n\n async selectOne<T = unknown>(\n table: string,\n options?: SelectOptions,\n executor?: unknown\n ): Promise<T | null> {\n const results = await this.select<T>(\n table,\n { ...options, limit: 1 },\n executor\n );\n return results.length > 0 ? results[0] : null;\n }\n\n /**\n * Insert a single record into a table.\n *\n * @remarks\n * Default implementation handles databases with and without RETURNING support.\n * For databases without RETURNING (MySQL), performs INSERT followed by SELECT.\n *\n * @param table - Table name\n * @param data - Record data to insert\n * @param options - Insert options\n * @returns Inserted record (with RETURNING columns if specified)\n *\n * @throws {DatabaseError} If insert fails\n *\n * @example\n * ```typescript\n * const user = await adapter.insert('users', {\n * email: 'user@example.com',\n * name: 'John Doe'\n * }, { returning: ['id', 'email', 'created_at'] });\n * ```\n */\n async insert<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options?: InsertOptions\n ): Promise<T> {\n // Drizzle query API path\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Map snake_case keys to Drizzle JS property names\n const mappedData = this.mapDataToColumnNames(tableObj, data);\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = this.getDrizzle<any>();\n const caps = this.getCapabilities();\n\n const returning = options?.returning;\n // An empty array means \"no columns back\": skip RETURNING entirely and,\n // on MySQL, skip the select-back reread. Useful for callers that ignore\n // the insert result and don't want a large row (e.g. a JSON snapshot)\n // materialized. `\"*\"` returns all; a specific list is projected.\n const wantsReturning =\n returning != null &&\n !(Array.isArray(returning) && returning.length === 0);\n\n if (caps.supportsReturning && wantsReturning) {\n const projection = this.buildColumnProjection(tableObj, returning);\n const insertQuery = db.insert(tableObj).values(mappedData);\n const result = await (projection\n ? insertQuery.returning(projection)\n : insertQuery.returning());\n return (Array.isArray(result) ? result[0] : result) as T;\n }\n\n const result = await db.insert(tableObj).values(mappedData);\n\n // For databases without RETURNING (MySQL): select back the inserted\n // record, projecting only the requested columns so unrequested ones\n // (a large JSON snapshot) are not read and decoded.\n if (\n !caps.supportsReturning &&\n wantsReturning &&\n data.id !== undefined\n ) {\n return (await this.selectOne<T>(table, {\n columns: returning === \"*\" ? undefined : returning,\n where: {\n and: [{ column: \"id\", op: \"=\", value: data.id as SqlParam }],\n },\n })) as T;\n }\n\n return (Array.isArray(result) ? result[0] : result) as T;\n } catch (error) {\n throw this.handleQueryError(error, \"insert\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Insert multiple records into a table.\n *\n * @remarks\n * Default implementation performs individual inserts in sequence.\n * Subclasses can override for bulk insert optimization (e.g., COPY in PostgreSQL).\n *\n * @param table - Table name\n * @param data - Array of records to insert\n * @param options - Insert options\n * @returns Inserted records (with RETURNING columns if specified)\n *\n * @throws {DatabaseError} If insert fails\n *\n * @example\n * ```typescript\n * const users = await adapter.insertMany('users', [\n * { email: 'user1@example.com', name: 'User 1' },\n * { email: 'user2@example.com', name: 'User 2' }\n * ], { returning: ['id'] });\n * ```\n */\n async insertMany<T = unknown>(\n table: string,\n data: Record<string, unknown>[],\n options?: InsertOptions\n ): Promise<T[]> {\n if (data.length === 0) {\n return [];\n }\n\n // Default implementation: insert one by one\n // Subclasses can override for bulk optimization\n const results: T[] = [];\n for (const record of data) {\n const result = await this.insert<T>(table, record, options);\n results.push(result);\n }\n return results;\n }\n\n /**\n * Update records in a table.\n *\n * @remarks\n * Default implementation builds an UPDATE query with WHERE clause.\n * Returns updated records if RETURNING is supported and requested.\n *\n * @param table - Table name\n * @param data - Data to update\n * @param where - Conditions for records to update\n * @param options - Update options\n * @returns Updated records (with RETURNING columns if specified)\n *\n * @throws {DatabaseError} If update fails\n *\n * @example\n * ```typescript\n * const updated = await adapter.update('users',\n * { status: 'active' },\n * { and: [{ column: 'id', op: '=', value: userId }] },\n * { returning: ['id', 'status', 'updated_at'] }\n * );\n * ```\n */\n async update<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n options?: UpdateOptions,\n executor?: unknown\n ): Promise<T[]> {\n // Drizzle query API path\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Transaction executor when supplied, otherwise the pooled instance.\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = executor ?? this.getDrizzle<any>();\n const caps = this.getCapabilities();\n // Map snake_case keys to Drizzle JS property names\n const mappedData = this.mapDataToColumnNames(tableObj, data);\n let query = db.update(tableObj).set(mappedData);\n\n const whereCondition = buildDrizzleWhere(tableObj as never, where);\n if (whereCondition) {\n query = query.where(whereCondition);\n }\n\n if (caps.supportsReturning && options?.returning) {\n return (await query.returning()) as T[];\n }\n\n await query;\n\n // For databases without RETURNING: select back the updated records on\n // the same executor so a transactional update reads its own writes.\n if (!caps.supportsReturning && options?.returning) {\n return await this.select<T>(table, { where }, executor);\n }\n\n return [] as T[];\n } catch (error) {\n throw this.handleQueryError(error, \"update\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Update records in a table and report how many rows the statement affected.\n *\n * The count is the whole return value, mirroring `delete`. `update` cannot answer this: without\n * `returning` it discards the driver's count, and WITH `returning` on a dialect that lacks\n * RETURNING it re-SELECTs using the same WHERE — so a conditional update that just changed a\n * column named in that WHERE reads back zero rows and a write that landed reports as unmatched.\n * Reading the driver's own count has no second query to disagree with the first.\n *\n * 🔴 MySQL reports CHANGED rows, not matched rows: an UPDATE that matches a row but writes values\n * identical to what it holds counts zero. A caller using this as a compare-and-set must therefore\n * include a column the write always moves — a version bump, a timestamp with enough resolution —\n * so that matched implies changed. Postgres (`rowCount`) and SQLite (`changes`) count matched\n * rows and do not need the precaution, which is exactly why it cannot be dropped: the dialect\n * where the distinction exists is the one with no RETURNING to fall back on.\n */\n async updateCount(\n table: string,\n data: Record<string, unknown>,\n where: WhereClause,\n executor?: unknown\n ): Promise<number> {\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Transaction executor when supplied, otherwise the pooled instance — narrowed to the\n // fragment of the update builder this method uses rather than the whole dialect-specific\n // surface, which is the same seam `getDrizzle<{ execute }>()` above takes. `where` returns\n // a thenable rather than a further builder, so awaiting either branch is what the type\n // says: the statement is issued whether or not a condition was added.\n const db = (executor ??\n this.getDrizzle<UpdateCapableDb>()) as UpdateCapableDb;\n const mappedData = this.mapDataToColumnNames(tableObj, data);\n const statement = db.update(tableObj).set(mappedData);\n\n const whereCondition = buildDrizzleWhere(tableObj as never, where);\n const result = await (whereCondition\n ? statement.where(whereCondition)\n : statement);\n return affectedRowCount(result);\n } catch (error) {\n throw this.handleQueryError(error, \"update\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Delete records from a table.\n *\n * @remarks\n * Default implementation builds a DELETE query with WHERE clause.\n * Returns the number of deleted records.\n *\n * @param table - Table name\n * @param where - Conditions for records to delete\n * @param options - Delete options\n * @returns Number of deleted records\n *\n * @throws {DatabaseError} If delete fails\n *\n * @example\n * ```typescript\n * const count = await adapter.delete('users', {\n * and: [{ column: 'status', op: '=', value: 'inactive' }]\n * });\n * console.log(`Deleted ${count} users`);\n * ```\n */\n async delete(\n table: string,\n where: WhereClause,\n _options?: DeleteOptions,\n executor?: unknown\n ): Promise<number> {\n // Drizzle query API path\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Transaction executor when supplied, otherwise the pooled instance.\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = executor ?? this.getDrizzle<any>();\n let query = db.delete(tableObj);\n\n const whereCondition = buildDrizzleWhere(tableObj as never, where);\n if (whereCondition) {\n query = query.where(whereCondition);\n }\n\n const result = await query;\n return affectedRowCount(result);\n } catch (error) {\n throw this.handleQueryError(error, \"delete\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n /**\n * Upsert (INSERT or UPDATE) a record.\n *\n * @remarks\n * Default implementation uses dialect-specific ON CONFLICT syntax.\n * PostgreSQL/SQLite: ON CONFLICT ... DO UPDATE\n * MySQL: ON DUPLICATE KEY UPDATE\n *\n * @param table - Table name\n * @param data - Record data\n * @param options - Upsert options (must specify conflict columns)\n * @returns Upserted record (with RETURNING columns if specified)\n *\n * @throws {DatabaseError} If upsert fails\n *\n * @example\n * ```typescript\n * const user = await adapter.upsert('users', {\n * email: 'user@example.com',\n * name: 'Updated Name'\n * }, {\n * conflictColumns: ['email'],\n * updateColumns: ['name'],\n * returning: ['id', 'email', 'name']\n * });\n * ```\n */\n async upsert<T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options: UpsertOptions,\n executor?: unknown\n ): Promise<T> {\n // Drizzle query API path\n const tableObj = this.getTableObject(table);\n if (tableObj) {\n try {\n // Transaction executor when supplied, otherwise the pooled instance.\n // getDrizzle() returns unknown - explicit any generic for dialect-specific Drizzle API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const db = executor ?? this.getDrizzle<any>();\n const caps = this.getCapabilities();\n const columns = getColumns(tableObj as never);\n\n // Build conflict target columns\n const conflictTarget = options.conflictColumns\n .map(col => columns[col])\n .filter(Boolean);\n\n // Build update set (exclude conflict columns from update data)\n const conflictSet = new Set(options.conflictColumns);\n const updateData: Record<string, unknown> = {};\n const updateColumns = options.updateColumns ?? Object.keys(data);\n for (const key of updateColumns) {\n if (!conflictSet.has(key) && key in data) {\n updateData[key] = data[key];\n }\n }\n\n let query;\n if (caps.supportsOnConflict) {\n // PostgreSQL/SQLite: ON CONFLICT DO UPDATE\n query = db.insert(tableObj).values(data).onConflictDoUpdate({\n target: conflictTarget,\n set: updateData,\n });\n } else {\n // MySQL: fallback to insert, catch duplicate key, then update\n // This is handled by the MySQL adapter override\n query = db.insert(tableObj).values(data);\n }\n\n if (caps.supportsReturning) {\n const result = await query.returning();\n return (Array.isArray(result) ? result[0] : result) as T;\n }\n\n await query;\n\n // For databases without RETURNING: select back using conflict columns\n // on the same executor so a transactional upsert reads its own write.\n if (\n options.conflictColumns.length &&\n data[options.conflictColumns[0]] !== undefined\n ) {\n return (await this.selectOne<T>(\n table,\n {\n where: {\n and: [\n {\n column: options.conflictColumns[0],\n op: \"=\",\n value: data[options.conflictColumns[0]] as SqlParam,\n },\n ],\n },\n },\n executor\n )) as T;\n }\n\n return data as T;\n } catch (error) {\n throw this.handleQueryError(error, \"upsert\", table);\n }\n }\n\n throw this.createDatabaseError(\n \"query\",\n `Table \"${table}\" not found in schema registry. Ensure setTableResolver() has been called during boot.`,\n undefined\n );\n }\n\n // ============================================================\n // Migration Support (Default implementations, can override)\n // ============================================================\n\n /**\n * Run pending migrations.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * migration tracking and execution logic.\n *\n * @param migrations - Array of migrations to run\n * @returns Migration result with applied and pending migrations\n *\n * @throws {DatabaseError} If migration fails\n */\n // Base implementation throws synchronously; dialect adapters override with async logic.\n // eslint-disable-next-line @typescript-eslint/require-await\n async migrate(_migrations: Migration[]): Promise<MigrationResult> {\n // Base implementation: migrate() requires dialect-specific migrator import.\n // Dialect adapters (PostgresAdapter, MySqlAdapter, SqliteAdapter) should\n // override this with their specific drizzle-orm migrator.\n throw this.createDatabaseError(\n \"query\",\n \"migrate() must be implemented by dialect-specific adapter. \" +\n \"Use PostgresAdapter, MySqlAdapter, or SqliteAdapter.\",\n undefined\n );\n }\n\n /**\n * Rollback the last migration.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * migration rollback logic.\n *\n * @returns Migration result after rollback\n *\n * @throws {DatabaseError} If rollback fails\n */\n // Base implementation throws synchronously; dialect adapters override with async logic.\n // eslint-disable-next-line @typescript-eslint/require-await\n async rollback(): Promise<MigrationResult> {\n // Base implementation: rollback requires dialect-specific handling.\n // Dialect adapters should override this.\n throw this.createDatabaseError(\n \"query\",\n \"rollback() must be implemented by dialect-specific adapter. \" +\n \"Use PostgresAdapter, MySqlAdapter, or SqliteAdapter.\",\n undefined\n );\n }\n\n /**\n * Get migration status.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * migration status checking.\n *\n * @returns Current migration status\n *\n * @throws {DatabaseError} If status check fails\n */\n async getMigrationStatus(): Promise<MigrationResult> {\n // Query the drizzle migrations tracking table for applied migrations\n try {\n const rows = await this.executeQuery<{\n id: number;\n hash: string;\n created_at: number;\n }>(`SELECT * FROM \"__drizzle_migrations\" ORDER BY created_at ASC`);\n\n const applied = rows.map(r => ({\n id: String(r.id),\n name: r.hash,\n appliedAt: new Date(r.created_at),\n checksum: r.hash,\n }));\n return {\n applied,\n pending: [],\n current: applied.length > 0 ? applied[applied.length - 1].id : null,\n };\n } catch {\n // Table may not exist yet if no migrations have been applied\n return { applied: [], pending: [], current: null };\n }\n }\n\n // ============================================================\n // Schema Operations (Default implementations, can override)\n // ============================================================\n\n /**\n * Create a new table.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * table creation logic.\n *\n * @param definition - Table definition\n * @param options - Creation options\n *\n * @throws {DatabaseError} If table creation fails\n */\n async createTable(\n definition: TableDefinition,\n options?: CreateTableOptions\n ): Promise<void> {\n // Build CREATE TABLE SQL from the TableDefinition\n const columnDefs = definition.columns.map(col => {\n let colSql = `${this.escapeIdentifier(col.name)} ${col.type.toUpperCase()}`;\n if (col.primaryKey) colSql += \" PRIMARY KEY\";\n if (col.nullable === false) colSql += \" NOT NULL\";\n if (col.unique) colSql += \" UNIQUE\";\n if (col.default !== undefined) {\n colSql += ` DEFAULT ${renderDefaultValue(col.default, col.name)}`;\n }\n return colSql;\n });\n\n const ifNotExists = options?.ifNotExists !== false ? \"IF NOT EXISTS \" : \"\";\n const query = `CREATE TABLE ${ifNotExists}${this.escapeIdentifier(definition.name)} (\\n ${columnDefs.join(\",\\n \")}\\n)`;\n\n try {\n await this.executeQuery(query);\n } catch (error) {\n throw this.handleQueryError(error, \"createTable\", definition.name);\n }\n }\n\n /**\n * Drop a table.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * table dropping logic.\n *\n * @param tableName - Name of table to drop\n * @param options - Drop options\n *\n * @throws {DatabaseError} If table drop fails\n */\n async dropTable(\n tableName: string,\n options?: DropTableOptions\n ): Promise<void> {\n const ifExists = options?.ifExists !== false ? \"IF EXISTS \" : \"\";\n const cascade = options?.cascade ? \" CASCADE\" : \"\";\n const query = `DROP TABLE ${ifExists}${this.escapeIdentifier(tableName)}${cascade}`;\n\n try {\n await this.executeQuery(query);\n } catch (error) {\n throw this.handleQueryError(error, \"dropTable\", tableName);\n }\n }\n\n /**\n * Alter an existing table.\n *\n * @remarks\n * Default implementation is a placeholder. Subclasses should implement\n * table alteration logic.\n *\n * @param tableName - Name of table to alter\n * @param operations - Alteration operations\n * @param options - Alter options\n *\n * @throws {DatabaseError} If table alteration fails\n */\n async alterTable(\n tableName: string,\n operations: AlterTableOperation[],\n _options?: AlterTableOptions\n ): Promise<void> {\n const quotedTable = this.escapeIdentifier(tableName);\n\n for (const op of operations) {\n let query: string;\n\n switch (op.kind) {\n case \"add_column\": {\n let colDef = `${this.escapeIdentifier(op.column.name)} ${op.column.type.toUpperCase()}`;\n if (op.column.nullable === false) colDef += \" NOT NULL\";\n if (op.column.unique) colDef += \" UNIQUE\";\n if (op.column.default !== undefined) {\n const defaultVal =\n typeof op.column.default === \"object\" &&\n op.column.default !== null &&\n \"sql\" in op.column.default\n ? op.column.default.sql\n : typeof op.column.default === \"string\"\n ? `'${op.column.default}'`\n : String(op.column.default);\n colDef += ` DEFAULT ${defaultVal}`;\n }\n query = `ALTER TABLE ${quotedTable} ADD COLUMN ${colDef}`;\n break;\n }\n case \"drop_column\": {\n const cascade = op.cascade ? \" CASCADE\" : \"\";\n query = `ALTER TABLE ${quotedTable} DROP COLUMN ${this.escapeIdentifier(op.columnName)}${cascade}`;\n break;\n }\n case \"rename_column\":\n query = `ALTER TABLE ${quotedTable} RENAME COLUMN ${this.escapeIdentifier(op.from)} TO ${this.escapeIdentifier(op.to)}`;\n break;\n case \"modify_column\": {\n // ALTER COLUMN ... TYPE is PostgreSQL syntax; MySQL uses MODIFY COLUMN\n // Dialect adapters can override for specific syntax\n query = `ALTER TABLE ${quotedTable} ALTER COLUMN ${this.escapeIdentifier(op.column.name)} TYPE ${op.column.type.toUpperCase()}`;\n break;\n }\n case \"add_constraint\":\n {\n // Constraint SQL depends on the constraint type\n const constraintCols = op.constraint.columns ?? [];\n const colList = constraintCols\n .map(c => this.escapeIdentifier(c))\n .join(\", \");\n if (op.constraint.type === \"check\" && op.constraint.expression) {\n query = `ALTER TABLE ${quotedTable} ADD CONSTRAINT ${this.escapeIdentifier(op.constraint.name)} CHECK (${op.constraint.expression})`;\n } else {\n query = `ALTER TABLE ${quotedTable} ADD CONSTRAINT ${this.escapeIdentifier(op.constraint.name)} ${op.constraint.type.toUpperCase()} (${colList})`;\n }\n break;\n }\n break;\n case \"drop_constraint\": {\n const cascadeConstraint = op.cascade ? \" CASCADE\" : \"\";\n query = `ALTER TABLE ${quotedTable} DROP CONSTRAINT ${this.escapeIdentifier(op.constraintName)}${cascadeConstraint}`;\n break;\n }\n default:\n throw this.createDatabaseError(\n \"query\",\n `Unsupported alter table operation: ${(op as { kind: string }).kind}`,\n undefined\n );\n }\n\n try {\n await this.executeQuery(query);\n } catch (error) {\n throw this.handleQueryError(error, \"alterTable\", tableName);\n }\n }\n }\n\n /**\n * Check if a table exists in the database.\n *\n * @remarks\n * Uses dialect-specific information schema queries to check table existence.\n * This is useful for development mode auto-sync to determine whether to\n * CREATE or DROP/CREATE tables.\n *\n * @param tableName - Name of table to check\n * @param schema - Optional schema name (defaults to 'public' for PostgreSQL)\n * @returns True if table exists, false otherwise\n *\n * @throws {DatabaseError} If query fails\n *\n * @example\n * ```typescript\n * const exists = await adapter.tableExists('users');\n * if (exists) {\n * await adapter.dropTable('users');\n * }\n * await adapter.createTable(userTableDef);\n * ```\n */\n async tableExists(tableName: string, schema?: string): Promise<boolean> {\n try {\n let sql: string;\n const params: SqlParam[] = [];\n\n switch (this.dialect) {\n case \"postgresql\":\n sql = `\n SELECT EXISTS (\n SELECT FROM information_schema.tables\n WHERE table_schema = COALESCE($1, (\n SELECT n.nspname FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE c.oid = to_regclass($2)\n ))\n AND table_name = $2\n ) as exists\n `;\n // Unqualified DDL and DML resolve across the whole search path, not against one\n // schema. Naming `public` reported a populated table as absent whenever a deployment\n // used a schema of its own, and naming only the FIRST entry misses a table that lives\n // further along it. `to_regclass` resolves exactly as the statements do, so the\n // lookup and the ALTER cannot disagree about which table is meant. A caller that\n // reads \"absent\" as \"nothing to conflict with\" would otherwise act on the wrong one.\n params.push(schema ?? null, tableName);\n break;\n\n case \"mysql\":\n sql = `\n SELECT COUNT(*) as count\n FROM information_schema.tables\n WHERE table_schema = DATABASE()\n AND table_name = ?\n `;\n params.push(tableName);\n break;\n\n case \"sqlite\":\n sql = `\n SELECT COUNT(*) as count\n FROM sqlite_master\n WHERE type = 'table'\n AND name = ?\n `;\n params.push(tableName);\n break;\n\n default:\n throw this.createDatabaseError(\n \"query\",\n `tableExists not implemented for dialect: ${String(this.dialect)}`,\n undefined\n );\n }\n\n const results = await this.executeQuery<Record<string, unknown>>(\n sql,\n params\n );\n\n if (results.length === 0) {\n return false;\n }\n\n const row = results[0];\n\n // PostgreSQL returns { exists: true/false }\n if (\"exists\" in row) {\n return row.exists === true || row.exists === \"t\" || row.exists === 1;\n }\n\n // MySQL/SQLite return { count: number }\n if (\"count\" in row) {\n return Number(row.count) > 0;\n }\n\n return false;\n } catch (error) {\n throw this.handleQueryError(error, \"tableExists\", tableName);\n }\n }\n\n /**\n * Get list of all tables in the database.\n *\n * @remarks\n * Uses dialect-specific information schema queries to list tables.\n * Useful for detecting orphaned tables or validating schema state.\n *\n * @param schema - Optional schema name (defaults to 'public' for PostgreSQL)\n * @returns Array of table names\n *\n * @throws {DatabaseError} If query fails\n */\n async listTables(schema?: string): Promise<string[]> {\n try {\n let sql: string;\n const params: SqlParam[] = [];\n\n switch (this.dialect) {\n case \"postgresql\":\n sql = `\n SELECT table_name\n FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n ORDER BY table_name\n `;\n params.push(schema ?? \"public\");\n break;\n\n case \"mysql\":\n // The alias matters: MySQL 8's information_schema returns the\n // column key as uppercase TABLE_NAME without it, so `row.table_name`\n // was undefined and every caller mapping the rows crashed.\n sql = `\n SELECT table_name AS table_name\n FROM information_schema.tables\n WHERE table_schema = DATABASE()\n AND table_type = 'BASE TABLE'\n ORDER BY table_name\n `;\n break;\n\n case \"sqlite\":\n sql = `\n SELECT name as table_name\n FROM sqlite_master\n WHERE type = 'table'\n AND name NOT LIKE 'sqlite_%'\n ORDER BY name\n `;\n break;\n\n default:\n throw this.createDatabaseError(\n \"query\",\n `listTables not implemented for dialect: ${String(this.dialect)}`,\n undefined\n );\n }\n\n const results = await this.executeQuery<{ table_name: string }>(\n sql,\n params\n );\n\n return results.map(row => row.table_name);\n } catch (error) {\n throw this.handleQueryError(error, \"listTables\", \"\");\n }\n }\n\n // ============================================================\n // Protected Utilities\n // ============================================================\n\n // Old raw SQL query builders (buildSelectQuery, buildInsertQuery, buildUpdateQuery,\n // buildDeleteQuery, buildUpsertQuery, buildWhereClause, buildPlaceholder,\n // buildPlaceholders) have been removed. CRUD methods now use Drizzle query API\n // via the TableResolver set during boot. See drizzle-where.ts for where clause\n // translation.\n\n // NOTE: The following content up to escapeIdentifier has been removed.\n // If you're looking for the old query builder methods, see git history\n // (commit before \"refactor: remove dead SQL builder code\").\n\n /**\n * Escape a table or column identifier.\n *\n * @remarks\n * Default uses double quotes (SQL standard).\n * MySQL adapter should override to use backticks.\n *\n * @param identifier - Identifier to escape\n * @returns Escaped identifier\n *\n * @protected\n */\n protected escapeIdentifier(identifier: string): string {\n // SQL standard: double quotes\n // MySQL uses backticks, override in MySqlAdapter\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n }\n\n /**\n * Create a DatabaseError with proper error kind classification.\n *\n * @remarks\n * Protected helper for subclasses to create consistent errors.\n * Subclasses can override to add dialect-specific error classification.\n *\n * @param kind - Error kind\n * @param message - Error message\n * @param cause - Original error\n * @returns DatabaseError instance\n *\n * @protected\n */\n protected createDatabaseError(\n kind: DatabaseErrorKind,\n message: string,\n cause?: Error\n ): DatabaseError {\n return createDatabaseError({\n kind,\n message,\n cause,\n });\n }\n\n /**\n * Helper to create transaction context CRUD forwarding methods.\n *\n * @param txDb - Thunk returning the transaction-bound Drizzle executor\n * @returns Object providing forwarded CRUD and getDrizzle methods\n *\n * @protected\n */\n protected createTransactionForwarders(\n txDb: () => unknown\n ): TransactionCrudForwarders {\n return createTransactionForwarders(this, txDb);\n }\n\n /**\n * Classify an error into a DatabaseError.\n *\n * @remarks\n * Subclasses can override this method to add dialect-specific error code classification.\n *\n * @param error - Original error\n * @param sql - SQL statement that caused the error (optional)\n * @returns DatabaseError instance\n *\n * @protected\n */\n protected classifyError(error: unknown, sql?: string): DatabaseError {\n if (isDatabaseError(error)) {\n return error;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n return this.createDatabaseError(\n \"query\",\n sql ? `Query failed: ${errorMessage}` : errorMessage,\n error instanceof Error ? error : undefined\n );\n }\n\n /**\n * Handle query errors and convert to DatabaseError.\n *\n * @remarks\n * Protected helper for consistent error handling across CRUD operations.\n * Delegates to `classifyError` and attaches operation and table context if not present.\n * Subclasses override `classifyError` to provide dialect-specific error code classification.\n *\n * @param error - Original error\n * @param operation - Operation that failed\n * @param table - Table name\n * @returns DatabaseError instance\n *\n * @protected\n */\n protected handleQueryError(\n error: unknown,\n operation: string,\n table: string\n ): DatabaseError {\n const dbError = this.classifyError(error);\n\n // Add operation context if not already present\n if (!dbError.message.includes(operation)) {\n dbError.message = `${operation} operation failed on table '${table}': ${dbError.message}`;\n }\n\n if (!dbError.table) {\n dbError.table = table;\n }\n\n return dbError;\n }\n}\n\n/**\n * Render a `ColumnDefinition.default` as a SQL fragment\n * for embedding in a `DEFAULT` clause. DDL is not protected by Drizzle's\n * prepared statements — these expressions are concatenated into raw SQL —\n * so we treat the default as untrusted input even though it currently\n * flows from server-side schema definitions: an admin-defined dynamic\n * collection would otherwise turn into RCE-on-DB instead of just CMS\n * admin.\n *\n * Rules:\n *\n * - **null / number / boolean** → rendered as a SQL literal.\n * - **string** → quoted; embedded `'` doubled; `;`, `\\`, control\n * characters, and null bytes rejected so they can't break out of\n * the surrounding quote pair into adjacent DDL.\n * - **`{ sql: \"…\" }`** → only the explicit allowlist of named\n * functions below is honored (case-insensitive). Anything else is\n * a hard error: the previous code embedded the raw `sql` string\n * verbatim, which is the SQL injection primitive the audit flagged.\n */\nconst ALLOWED_DEFAULT_SQL_EXPRESSIONS = new Set([\n \"current_timestamp\",\n \"now()\",\n \"gen_random_uuid()\",\n \"uuid_generate_v4()\",\n \"current_date\",\n \"current_time\",\n]);\n\nfunction renderDefaultValue(value: unknown, columnName: string): string {\n if (value === null) return \"NULL\";\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new Error(\n `DEFAULT for column \"${columnName}\" must be a finite number (got ${value}).`\n );\n }\n return String(value);\n }\n if (typeof value === \"boolean\") {\n return value ? \"TRUE\" : \"FALSE\";\n }\n if (typeof value === \"string\") {\n if (/[;\\\\\\n\\r\\0]/.test(value)) {\n throw new Error(\n `DEFAULT string for column \"${columnName}\" contains characters that are not allowed in DDL (no semicolons, backslashes, control chars, or null bytes).`\n );\n }\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n if (typeof value === \"object\" && value !== null && \"sql\" in value) {\n const raw = value.sql;\n if (typeof raw !== \"string\") {\n throw new Error(\n `DEFAULT for column \"${columnName}\" has a { sql } expression that is not a string.`\n );\n }\n const normalized = raw.trim().toLowerCase();\n if (!ALLOWED_DEFAULT_SQL_EXPRESSIONS.has(normalized)) {\n throw new Error(\n `DEFAULT for column \"${columnName}\" uses a SQL expression \"${raw}\" that is not on the allowlist. Allowed: ${[...ALLOWED_DEFAULT_SQL_EXPRESSIONS].join(\", \")}.`\n );\n }\n return raw.trim();\n }\n throw new Error(\n `DEFAULT for column \"${columnName}\" has an unsupported type (${typeof value}).`\n );\n}\n","/**\n * @nextly/adapter-drizzle\n *\n * Shared Drizzle ORM adapter logic for Nextly database adapters.\n * This package provides the base adapter class and utilities used by\n * dialect-specific adapters (PostgreSQL, MySQL, SQLite).\n *\n * @remarks\n * This is the main entry point that exports only the core adapter class.\n * Specialized utilities are available via subpath exports for optimal tree-shaking.\n *\n * ## Subpath Exports\n *\n * **Types:**\n * ```typescript\n * import type {\n * DatabaseCapabilities,\n * TransactionContext,\n * WhereClause,\n * SelectOptions,\n * } from '@nextly/adapter-drizzle/types';\n * ```\n *\n * **Query Builder:**\n * ```typescript\n * import { QueryBuilder } from '@nextly/adapter-drizzle/query-builder';\n * ```\n *\n * **Migrations:**\n * ```typescript\n * import {\n * calculateChecksum,\n * sortMigrations,\n * migrationHelpers,\n * } from '@nextly/adapter-drizzle/migrations';\n * ```\n *\n * **Schema Utilities:**\n * ```typescript\n * import { schemaUtils } from '@nextly/adapter-drizzle/schema';\n * ```\n *\n * @packageDocumentation\n */\n\n/**\n * Package version\n * @public\n */\nexport const version = \"0.1.0\";\n\n// ============================================================\n// Core Adapter Export\n// ============================================================\n\n/**\n * Base database adapter abstract class.\n *\n * @remarks\n * All dialect-specific adapters extend this class. It provides:\n * - Abstract methods that must be implemented (connect, disconnect, executeQuery, transaction)\n * - Default CRUD implementations that can be overridden for optimization\n * - Protected query builders for dialect-specific SQL generation\n * - Error handling and database capability reporting\n *\n * ## Required Abstract Methods\n * - `dialect` - Database dialect identifier\n * - `connect()` - Establish database connection\n * - `disconnect()` - Close database connection\n * - `executeQuery()` - Execute raw SQL query\n * - `transaction()` - Execute work within a transaction\n * - `getCapabilities()` - Report database features\n *\n * ## Default CRUD Methods (Overridable)\n * - `select()`, `selectOne()` - Query records\n * - `insert()`, `insertMany()` - Insert records\n * - `update()` - Update records\n * - `delete()` - Delete records\n * - `upsert()` - Insert or update records\n *\n * @example\n * Basic adapter implementation:\n * ```typescript\n * import { DrizzleAdapter } from '@nextly/adapter-drizzle';\n * import type {\n * DatabaseCapabilities,\n * SqlParam,\n * TransactionContext,\n * } from '@nextly/adapter-drizzle/types';\n *\n * export class PostgresAdapter extends DrizzleAdapter {\n * readonly dialect = 'postgresql' as const;\n *\n * async connect(): Promise<void> {\n * // Connect to PostgreSQL\n * }\n *\n * async disconnect(): Promise<void> {\n * // Close connection\n * }\n *\n * async executeQuery<T>(sql: string, params?: SqlParam[]): Promise<T[]> {\n * // Execute query\n * }\n *\n * async transaction<T>(\n * work: (tx: TransactionContext) => Promise<T>\n * ): Promise<T> {\n * // Transaction logic\n * }\n *\n * getCapabilities(): DatabaseCapabilities {\n * return {\n * dialect: 'postgresql',\n * supportsJsonb: true,\n * supportsReturning: true,\n * // ... other capabilities\n * };\n * }\n * }\n * ```\n *\n * @public\n */\nexport { DrizzleAdapter } from \"./adapter\";\nexport type {\n TransactionCrudDelegator,\n TransactionCrudForwarders,\n} from \"./transaction-forwarders\";\nexport type { TableResolver } from \"./types/core\";\n\n// Why no F17 re-exports here: the main index follows a strict tree-shaking\n// policy (only DrizzleAdapter + version are exported). F17's\n// checkDialectVersion / NEXTLY_MIN_DB_VERSIONS / UnsupportedDialectVersionError\n// live behind the dedicated subpath @nextlyhq/adapter-drizzle/version-check.\n"]}
|