tempest-db-js 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/expressions.ts","../src/index.ts","../src/engine.ts","../src/migrations/operations.ts","../src/migrations/codegen.ts","../src/migrations/ddl.ts","../src/migrations/diff.ts","../src/migrations/graph.ts","../src/migrations/ir.ts","../src/migrations/introspect.ts","../src/migrations/renames.ts","../src/migrations/runner.ts","../src/migrations/replay.ts","../src/migrations/cli.ts","../src/bin.ts"],"names":["createRequire","resolve","existsSync","pathToFileURL","createInterface"],"mappings":"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","file":"bin.cjs","sourcesContent":["/**\n * tempest-db-js — portable SQL expression rendering.\n *\n * A `sql.now()` / `sql.uuidv4()` token is dialect-neutral in the AST and in the\n * migration IR; this is the single place it becomes concrete SQL. Kept in its own\n * module (types only, no runtime imports) so both the query dialect and the DDL\n * renderer share one mapping instead of drifting apart.\n */\n\nimport type { Dialect } from \"./url.js\";\n\n/** The dialect-neutral expression tokens (the non-fragment `PortableExpression`s). */\nexport type PortableToken = \"now\" | \"current_date\" | \"current_time\" | \"uuidv4\";\n\n/**\n * Render a portable expression token to SQL for the dialect.\n *\n * @param token The dialect-neutral token.\n * @param dialect The target dialect.\n * @returns The SQL text for that token.\n */\nexport function renderPortableToken(token: PortableToken, dialect: Dialect): string {\n switch (token) {\n case \"now\":\n return dialect === \"postgresql\" ? \"now()\" : \"CURRENT_TIMESTAMP\";\n case \"current_date\":\n return \"CURRENT_DATE\";\n case \"current_time\":\n return \"CURRENT_TIME\";\n case \"uuidv4\":\n if (dialect === \"postgresql\") return \"gen_random_uuid()\";\n if (dialect === \"mysql\") return \"(UUID())\";\n return \"(lower(hex(randomblob(16))))\";\n }\n}\n","/**\n * tempest-db-js — feasibility spike for Phase 1.\n *\n * Proves the central design claim: a class-based, SQLAlchemy-style model whose\n * fields are runtime column-builders can drive full static row-type inference in\n * TypeScript, despite TS erasing types at runtime.\n *\n * This is a SPIKE, not the final API. It validates the type machinery only.\n */\n\n/** Phantom marker carrying the static TS type a column maps to. */\ndeclare const TYPE: unique symbol;\n\n/** Column flags that influence the inferred row/insert shape. */\ninterface ColumnFlags {\n readonly primaryKey: boolean;\n readonly notNull: boolean;\n readonly hasDefault: boolean;\n /**\n * A `UNIQUE` constraint on the column. Does NOT influence the inferred type —\n * it is DDL-only metadata (mirrors SQLAlchemy's `mapped_column(unique=True)`).\n */\n readonly unique: boolean;\n}\n\nconst DEFAULT_FLAGS: ColumnFlags = {\n primaryKey: false,\n notNull: false,\n hasDefault: false,\n unique: false,\n};\n\n/**\n * The canonical, dialect-neutral kind of a column type. Mirrors SQLAlchemy's\n * generic types (e.g. `String` → varchar, `Text` → text). Dialect renderers\n * (Phase 4/6) map each kind + meta to concrete SQL per database.\n */\nexport type ColumnTypeKind =\n | \"smallint\"\n | \"integer\"\n | \"bigint\"\n | \"numeric\"\n | \"real\"\n | \"double\"\n | \"varchar\"\n | \"text\"\n | \"char\"\n | \"boolean\"\n | \"date\"\n | \"time\"\n | \"datetime\"\n | \"timestamp\"\n | \"blob\"\n | \"json\"\n | \"uuid\"\n | \"enum\"\n | \"array\";\n\n/** Parameters that refine a column type and feed the migration IR / DDL. */\nexport interface ColumnTypeMeta {\n /** Max length for `varchar`/`char`. */\n readonly length?: number | undefined;\n /** Total digits for `numeric`. */\n readonly precision?: number | undefined;\n /** Digits after the decimal point for `numeric`. */\n readonly scale?: number | undefined;\n /** `WITH TIME ZONE` for `timestamp`/`time`. */\n readonly withTimezone?: boolean | undefined;\n /** Allowed values for `enum`. */\n readonly values?: readonly string[] | undefined;\n /** Render as `JSONB` (PostgreSQL) instead of `JSON`. */\n readonly jsonb?: boolean | undefined;\n /** The element type of an `array` column (`text[]`, `integer[]`). */\n readonly element?: ColumnType | undefined;\n}\n\n/** A structured, dialect-neutral column type descriptor. */\nexport interface ColumnType {\n readonly kind: ColumnTypeKind;\n readonly meta: ColumnTypeMeta;\n}\n\n/**\n * A portable default expression. The token is dialect-neutral; the renderer\n * (Phase 4/6) maps it to the right SQL per database — e.g. `\"now\"` becomes\n * `CURRENT_TIMESTAMP` on SQLite and `now()` on PostgreSQL. Use `{ raw }` as an\n * escape hatch for a verbatim SQL fragment, or `{ parts }` for a parameterized\n * fragment built by the `sql.expr` tagged template (one bound parameter per gap\n * between consecutive parts).\n */\nexport type PortableExpression =\n | \"now\"\n | \"current_date\"\n | \"current_time\"\n | \"uuidv4\"\n | { readonly raw: string }\n | { readonly parts: readonly string[] };\n\n/**\n * A column default. Either a constant literal value or a server-side expression\n * evaluated by the database (mirrors SQLAlchemy's `default` vs `server_default`).\n * Feeds the migration IR (`DefaultIR`).\n */\nexport type DefaultValue =\n | { readonly kind: \"literal\"; readonly value: unknown }\n | { readonly kind: \"expression\"; readonly expression: PortableExpression };\n\n/**\n * Brand marking a value as a SQL expression rather than a bound parameter.\n *\n * A plain object reaching `set()`/`values()` is a mistake (it would be bound as a\n * parameter and silently written as JSON or null); an object carrying this symbol\n * is deliberate, and the dialect renders it inline instead of binding it. Mirrors\n * how `Condition` is branded, so the check is a symbol lookup, not duck typing.\n */\nconst EXPRESSION = Symbol.for(\"tempest-db-js.expression\");\n\n/**\n * A SQL expression, usable both as a column default (`.default(sql.now())`) and\n * as a write value (`.set({ attempts: sql.raw(\"attempts + 1\") })`). The dialect\n * renders `expression` inline and binds `params` in the order of the fragment's\n * gaps.\n */\nexport interface SqlExpression {\n readonly [EXPRESSION]: true;\n readonly kind: \"expression\";\n readonly expression: PortableExpression;\n /** Parameters bound into the fragment's gaps, in order (empty for a token). */\n readonly params: readonly unknown[];\n}\n\n/** Build a branded {@link SqlExpression} from a portable token or fragment. */\nfunction expression(\n token: PortableExpression,\n params: readonly unknown[] = [],\n): SqlExpression {\n return { [EXPRESSION]: true, kind: \"expression\", expression: token, params };\n}\n\n/**\n * Runtime guard: is this value a branded {@link SqlExpression}?\n *\n * @param value Any value handed to `set()`, `values()` or `.default()`.\n * @returns True when the value carries the expression brand.\n */\nexport function isSqlExpression(value: unknown): value is SqlExpression {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as Record<PropertyKey, unknown>)[EXPRESSION] === true\n );\n}\n\n/**\n * Portable server-side expressions, à la SQLAlchemy's `func`.\n *\n * Every entry doubles as a column default and as a write value, so\n * `.default(sql.now())` and `.set({ updatedAt: sql.now() })` both work.\n */\nexport const sql = {\n /** Current timestamp at insert (`CURRENT_TIMESTAMP` / `now()`). */\n now: (): SqlExpression => expression(\"now\"),\n /** Current date. */\n currentDate: (): SqlExpression => expression(\"current_date\"),\n /** Current time. */\n currentTime: (): SqlExpression => expression(\"current_time\"),\n /** A freshly generated UUID v4 (`gen_random_uuid()` / portable fallback). */\n uuidv4: (): SqlExpression => expression(\"uuidv4\"),\n /**\n * Escape hatch: a verbatim SQL expression rendered as-is, with no parameters.\n *\n * The fragment is interpolated into the statement untouched, so it must never\n * carry user input — use {@link sql.expr} when a value has to be bound.\n *\n * @param fragment The SQL text (e.g. `\"attempts + 1\"`).\n * @returns The expression, usable as a default and as a write value.\n */\n raw: (fragment: string): SqlExpression => expression({ raw: fragment }),\n /**\n * A parameterized SQL expression, written as a tagged template. Static text is\n * SQL; every `${...}` interpolation becomes a bound parameter, so the fragment\n * is injection-safe by construction.\n *\n * Cannot be used as a column default — a `DEFAULT` clause has nowhere to bind\n * parameters; use {@link sql.raw} there.\n *\n * @param parts The static SQL segments supplied by the template tag.\n * @param values The interpolated values, bound in order.\n * @returns The expression, usable as a write value.\n *\n * @example\n * ```ts\n * update(Account).set({ balance: sql.expr`balance - ${amount}` }).where({ id });\n * // UPDATE \"accounts\" SET \"balance\" = balance - $1 WHERE \"id\" = $2\n * ```\n */\n expr: (parts: TemplateStringsArray, ...values: unknown[]): SqlExpression =>\n expression({ parts: Array.from(parts) }, values),\n} as const;\n\n/** Narrow a `.default()` argument to a `DefaultValue` expression/literal marker. */\nfunction isDefaultValue(value: unknown): value is DefaultValue {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"kind\" in value &&\n ((value as { kind: unknown }).kind === \"literal\" ||\n (value as { kind: unknown }).kind === \"expression\")\n );\n}\n\n/** True when an expression carries bound parameters (illegal in a DDL default). */\nfunction bindsParameters(value: DefaultValue): boolean {\n return (\n value.kind === \"expression\" &&\n typeof value.expression === \"object\" &&\n \"parts\" in value.expression\n );\n}\n\n/**\n * A referential action for a foreign key's `ON DELETE` / `ON UPDATE` clause.\n * Dialect-neutral tokens rendered uppercase at the DDL edge (mirrors\n * SQLAlchemy's `ForeignKey(ondelete=..., onupdate=...)`).\n */\nexport type FkAction = \"cascade\" | \"restrict\" | \"set null\" | \"set default\" | \"no action\";\n\n/**\n * A resolved foreign-key reference: the target `table.column` plus optional\n * referential actions. Produced by `Column.references(\"table.column\", ...)`.\n */\nexport interface ForeignKeyRef {\n readonly table: string;\n readonly column: string;\n readonly onDelete?: FkAction | undefined;\n readonly onUpdate?: FkAction | undefined;\n}\n\n/** Options for a foreign-key reference (referential actions). */\nexport interface ForeignKeyOptions {\n readonly onDelete?: FkAction | undefined;\n readonly onUpdate?: FkAction | undefined;\n}\n\n/** Parse a `\"table.column\"` reference string into a {@link ForeignKeyRef}. */\nfunction parseReference(ref: string, options?: ForeignKeyOptions): ForeignKeyRef {\n const dot = ref.lastIndexOf(\".\");\n if (dot <= 0 || dot === ref.length - 1) {\n throw new Error(`Invalid foreign key reference \"${ref}\"; expected \"table.column\".`);\n }\n return {\n table: ref.slice(0, dot),\n column: ref.slice(dot + 1),\n onDelete: options?.onDelete,\n onUpdate: options?.onUpdate,\n };\n}\n\n/**\n * A typed column builder. Holds runtime metadata (structured `type`, `flags`,\n * `default`, `onUpdate`, foreign-key `reference`) and a phantom static type `T`\n * used purely for inference.\n */\nclass Column<T, F extends ColumnFlags = ColumnFlags> {\n /** Phantom: never read at runtime, only inspected by the type system. */\n declare readonly [TYPE]: T;\n\n constructor(\n readonly type: ColumnType,\n readonly flags: F,\n /** The default applied on insert, or `null` for none. */\n readonly defaultValue: DefaultValue | null = null,\n /** The value re-applied on update (e.g. `updated_at`), or `null`. */\n readonly onUpdateValue: DefaultValue | null = null,\n /** The foreign-key reference this column points to, or `null` for none. */\n readonly reference: ForeignKeyRef | null = null,\n /** An explicit database column name overriding the property name, or `null`. */\n readonly dbName: string | null = null,\n ) {}\n\n /** Clone this column with one facet replaced, carrying every other over. */\n private derive<F2 extends ColumnFlags>(patch: {\n flags?: F2;\n defaultValue?: DefaultValue | null;\n onUpdateValue?: DefaultValue | null;\n reference?: ForeignKeyRef | null;\n dbName?: string | null;\n }): Column<T, F2> {\n return new Column<T, F2>(\n this.type,\n (patch.flags ?? this.flags) as F2,\n patch.defaultValue !== undefined ? patch.defaultValue : this.defaultValue,\n patch.onUpdateValue !== undefined ? patch.onUpdateValue : this.onUpdateValue,\n patch.reference !== undefined ? patch.reference : this.reference,\n patch.dbName !== undefined ? patch.dbName : this.dbName,\n );\n }\n\n primaryKey(): Column<T, F & { primaryKey: true; hasDefault: true }> {\n return this.derive({ flags: { ...this.flags, primaryKey: true, hasDefault: true } });\n }\n\n notNull(): Column<T, F & { notNull: true }> {\n return this.derive({ flags: { ...this.flags, notNull: true } });\n }\n\n /**\n * Add a `UNIQUE` constraint to the column (mirrors SQLAlchemy's\n * `mapped_column(unique=True)`). DDL-only — does not change the inferred type.\n */\n unique(): Column<T, F & { unique: true }> {\n return this.derive({ flags: { ...this.flags, unique: true } });\n }\n\n /**\n * Map this property to a differently-named database column, à la SQLAlchemy's\n * `mapped_column(\"consumer_name\")` (Django's `db_column`, Prisma's `@map`).\n *\n * The override applies everywhere the name reaches SQL — select, insert,\n * update, delete, where, order by, group by, returning, conflict targets, the\n * migration IR and the drift check — while the TypeScript row keeps the\n * property name. Use it to keep a `snake_case` schema behind a `camelCase`\n * model; {@link Model.naming} does the same for a whole table at once.\n *\n * @param dbName The real column name in the database.\n * @returns A new column bound to that name.\n * @throws Error When `dbName` is empty.\n *\n * @example\n * ```ts\n * class ApiKey extends Model {\n * static tablename = \"api_keys\";\n * consumerName = column.text().name(\"consumer_name\").notNull();\n * }\n * ```\n */\n name(dbName: string): Column<T, F> {\n if (dbName.length === 0) {\n throw new Error(\"column.name() requires a non-empty database column name.\");\n }\n return this.derive({ dbName });\n }\n\n /**\n * Declare a foreign-key reference to another table's column, à la SQLAlchemy's\n * `mapped_column(ForeignKey(\"table.column\", ondelete=...))`. DDL-only — does\n * not change the inferred type.\n *\n * @param ref The target as `\"table.column\"` (e.g. `\"users.id\"`).\n * @param options Optional `onDelete` / `onUpdate` referential actions.\n * @returns A new column carrying the reference.\n * @throws Error When `ref` is not a valid `\"table.column\"` string.\n */\n references(ref: string, options?: ForeignKeyOptions): Column<T, F> {\n return this.derive({ reference: parseReference(ref, options) });\n }\n\n /**\n * Set the insert-time default: a constant value of type `T`, or a portable\n * server-side expression from {@link sql} (e.g. `sql.now()`, `sql.uuidv4()`).\n *\n * @param value The literal default, or a {@link sql} expression.\n * @returns A new column carrying the default.\n * @throws Error When given a `sql.expr` fragment — a `DEFAULT` clause has\n * nowhere to bind parameters; use `sql.raw()` for a verbatim expression.\n */\n default(value: T | DefaultValue): Column<T, F & { hasDefault: true }> {\n const resolved: DefaultValue = isDefaultValue(value)\n ? value\n : { kind: \"literal\", value };\n if (bindsParameters(resolved)) {\n throw new Error(\n \"sql.expr`...` binds parameters and cannot be a column default — use sql.raw() for a verbatim DEFAULT expression.\",\n );\n }\n return this.derive({\n flags: { ...this.flags, hasDefault: true },\n defaultValue: resolved,\n });\n }\n\n /**\n * Re-apply a value whenever the row is updated (e.g. an `updated_at` column\n * with `sql.now()`). Mirrors SQLAlchemy's `onupdate`.\n *\n * @param value The literal value, or a {@link sql} expression.\n * @returns A new column carrying the on-update value.\n * @throws Error When given a `sql.expr` fragment (see {@link Column.default}).\n */\n onUpdate(value: T | DefaultValue): Column<T, F> {\n const resolved: DefaultValue = isDefaultValue(value)\n ? value\n : { kind: \"literal\", value };\n if (bindsParameters(resolved)) {\n throw new Error(\n \"sql.expr`...` binds parameters and cannot be an onUpdate default — use sql.raw() for a verbatim expression.\",\n );\n }\n return this.derive({ onUpdateValue: resolved });\n }\n}\n\n/** Build a `Column` of static type `T` from a kind + optional meta. */\nfunction makeColumn<T>(\n kind: ColumnTypeKind,\n meta: ColumnTypeMeta = {},\n): Column<T, ColumnFlags> {\n return new Column<T, ColumnFlags>({ kind, meta }, DEFAULT_FLAGS);\n}\n\n/**\n * Column factory mirroring SQLAlchemy's typed column constructors. Each entry\n * pairs a distinct SQL type with the TypeScript type it maps to.\n *\n * Notable mappings:\n * - `varchar(n)` (`VARCHAR(n)`) is distinct from `text` (`TEXT`).\n * - `bigInteger` maps to `bigint` (not `number`) to keep 64-bit precision.\n * - `numeric`/`decimal` map to `string` — JavaScript has no exact decimal, and\n * stringifying preserves precision instead of losing it to a float.\n * - `json<T>()` carries the parsed value type; `jsonb` is the PostgreSQL variant.\n * - `enum(...)` infers a string-literal union from its values.\n */\nexport const column = {\n /** `SMALLINT` → `number`. */\n smallInteger: (): Column<number, ColumnFlags> => makeColumn<number>(\"smallint\"),\n /** `INTEGER` → `number`. */\n integer: (): Column<number, ColumnFlags> => makeColumn<number>(\"integer\"),\n /** `BIGINT` → `bigint` (64-bit precision preserved). */\n bigInteger: (): Column<bigint, ColumnFlags> => makeColumn<bigint>(\"bigint\"),\n /** `NUMERIC(precision, scale)` → `string` (exact decimal, no float loss). */\n numeric: (precision?: number, scale?: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"numeric\", { precision, scale }),\n /** Alias of {@link column.numeric}. */\n decimal: (precision?: number, scale?: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"numeric\", { precision, scale }),\n /** `REAL` → `number`. */\n real: (): Column<number, ColumnFlags> => makeColumn<number>(\"real\"),\n /** `DOUBLE PRECISION` → `number`. */\n double: (): Column<number, ColumnFlags> => makeColumn<number>(\"double\"),\n /** `VARCHAR(length)` → `string`. Distinct from {@link column.text}. */\n varchar: (length: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"varchar\", { length }),\n /** Alias of {@link column.varchar} (SQLAlchemy's `String`). */\n string: (length: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"varchar\", { length }),\n /** `CHAR(length)` → `string` (fixed-width). */\n char: (length: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"char\", { length }),\n /** `TEXT` → `string` (unbounded). Distinct from {@link column.varchar}. */\n text: (): Column<string, ColumnFlags> => makeColumn<string>(\"text\"),\n /** `BOOLEAN` → `boolean`. */\n boolean: (): Column<boolean, ColumnFlags> => makeColumn<boolean>(\"boolean\"),\n /** `DATE` → `Date`. */\n date: (): Column<Date, ColumnFlags> => makeColumn<Date>(\"date\"),\n /** `TIME` → `string`. Pass `{ timezone: true }` for `WITH TIME ZONE`. */\n time: (options?: { timezone?: boolean }): Column<string, ColumnFlags> =>\n makeColumn<string>(\"time\", { withTimezone: options?.timezone }),\n /**\n * `DATETIME`/`TIMESTAMP` → `Date` (SQLAlchemy's generic `DateTime`). Pass\n * `{ timezone: true }` for `WITH TIME ZONE`. Pair with `.default(sql.now())`\n * and `.onUpdate(sql.now())` for managed `created_at`/`updated_at` columns.\n */\n datetime: (options?: { timezone?: boolean }): Column<Date, ColumnFlags> =>\n makeColumn<Date>(\"datetime\", { withTimezone: options?.timezone }),\n /** `TIMESTAMP` → `Date` (SQL-specific). Pass `{ timezone: true }`. */\n timestamp: (options?: { timezone?: boolean }): Column<Date, ColumnFlags> =>\n makeColumn<Date>(\"timestamp\", { withTimezone: options?.timezone }),\n /** `BLOB`/`BYTEA` → `Uint8Array`. */\n blob: (): Column<Uint8Array, ColumnFlags> => makeColumn<Uint8Array>(\"blob\"),\n /** `JSON` → the given parsed value type `T` (defaults to `unknown`). */\n json: <T = unknown>(): Column<T, ColumnFlags> => makeColumn<T>(\"json\"),\n /** `JSONB` (PostgreSQL) → the given parsed value type `T`. */\n jsonb: <T = unknown>(): Column<T, ColumnFlags> =>\n makeColumn<T>(\"json\", { jsonb: true }),\n /** `UUID` → `string`. */\n uuid: (): Column<string, ColumnFlags> => makeColumn<string>(\"uuid\"),\n /** `ENUM(...values)` → a string-literal union of the given values. */\n enum: <const E extends string>(...values: E[]): Column<E, ColumnFlags> =>\n makeColumn<E>(\"enum\", { values }),\n /**\n * A PostgreSQL array column (`text[]`, `integer[]`) → `T[]`.\n *\n * PostgreSQL only: SQLite and MySQL have no native array type, and rendering\n * one as JSON there would give the same model different semantics per dialect\n * (`@>` and `&&` work on one and not the other), so the DDL renderer throws\n * for those dialects instead of falling back silently.\n *\n * @param element The element column (its type, not its flags, is what is used).\n * @returns A column whose inferred type is an array of the element's type.\n *\n * @example\n * ```ts\n * class ApiKey extends Model {\n * static tablename = \"api_keys\";\n * scopes = column.array(column.text()).notNull().default([\"send\"]);\n * }\n * ```\n */\n array: <T>(element: Column<T, ColumnFlags>): Column<T[], ColumnFlags> =>\n makeColumn<T[]>(\"array\", { element: element.type }),\n} as const;\n\n/**\n * A table-level constraint declared via a model's `static tableArgs`. Mirrors\n * SQLAlchemy's `__table_args__` entries (`UniqueConstraint`, `ForeignKeyConstraint`).\n * Use the {@link unique} and {@link foreignKey} helpers to build these.\n */\nexport type TableConstraint =\n | {\n readonly kind: \"unique\";\n readonly name?: string | undefined;\n readonly columns: readonly string[];\n }\n | {\n readonly kind: \"foreignKey\";\n readonly name?: string | undefined;\n readonly columns: readonly string[];\n readonly refTable: string;\n readonly refColumns: readonly string[];\n readonly onDelete?: FkAction | undefined;\n readonly onUpdate?: FkAction | undefined;\n };\n\n/**\n * Declare a (possibly composite) `UNIQUE` table constraint over the given\n * columns. Mirrors SQLAlchemy's `UniqueConstraint(\"a\", \"b\")`.\n *\n * @param columns The column names covered by the constraint.\n * @returns A unique {@link TableConstraint}.\n * @throws Error When no columns are given.\n */\nexport function unique(...columns: string[]): TableConstraint {\n if (columns.length === 0) {\n throw new Error(\"unique() requires at least one column.\");\n }\n return { kind: \"unique\", columns };\n}\n\n/**\n * Declare a (possibly composite) foreign-key table constraint. Mirrors\n * SQLAlchemy's `ForeignKeyConstraint([...], [...], ondelete=...)`.\n *\n * @param columns The local column names.\n * @param refTable The referenced table name.\n * @param refColumns The referenced column names (same length as `columns`).\n * @param options Optional constraint `name` and referential actions.\n * @returns A foreign-key {@link TableConstraint}.\n * @throws Error When the column arrays are empty or mismatched in length.\n */\nexport function foreignKey(\n columns: string[],\n refTable: string,\n refColumns: string[],\n options?: { name?: string; onDelete?: FkAction; onUpdate?: FkAction },\n): TableConstraint {\n if (columns.length === 0 || columns.length !== refColumns.length) {\n throw new Error(\n \"foreignKey() requires matching, non-empty local and referenced column lists.\",\n );\n }\n return {\n kind: \"foreignKey\",\n name: options?.name,\n columns,\n refTable,\n refColumns,\n onDelete: options?.onDelete,\n onUpdate: options?.onUpdate,\n };\n}\n\n/**\n * How property names map to database column names when a column declares no\n * explicit {@link Column.name}.\n *\n * - `\"preserve\"` (default) — the column name is the property name, verbatim.\n * - `\"snake_case\"` — `consumerName` becomes `consumer_name`.\n */\nexport type NamingStrategy = \"preserve\" | \"snake_case\";\n\n/** Convert a `camelCase` / `PascalCase` identifier to `snake_case`. */\nexport function toSnakeCase(name: string): string {\n return name\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1_$2\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .toLowerCase();\n}\n\n/** Base class every model extends, SQLAlchemy-declarative style. */\n// biome-ignore lint/complexity/noStaticOnlyClass: declarative base users subclass; column fields live on instances.\nexport abstract class Model {\n static tablename: string;\n /**\n * Optional table-level constraints (composite unique / foreign keys), returned\n * by a thunk so forward references resolve lazily. Mirrors SQLAlchemy's\n * `__table_args__`.\n */\n static tableArgs?: () => readonly TableConstraint[];\n /**\n * How to derive column names from property names (default `\"preserve\"`). Set\n * `\"snake_case\"` to keep a `snake_case` schema behind a `camelCase` model\n * without annotating every column; {@link Column.name} overrides it per column.\n */\n static naming?: NamingStrategy;\n}\n\n/** Memoized column maps, keyed by model class (identity is stable per class). */\nconst columnsCache = new WeakMap<ModelClass, Record<string, Column<unknown>>>();\n\n/**\n * Reflect a model class into its column map at runtime, keyed by column name.\n *\n * Instantiates the class once and collects every field that is a `Column`. Used\n * by the serialization layer and (Phase 6) the migration schema reflector.\n *\n * The result is **memoized per class** — a model's columns never change at\n * runtime, and this is called once per row on hot read paths (coercion, joins),\n * so re-instantiating the class every time would dominate large result sets.\n *\n * @param model The model class (subclass of `Model`).\n * @returns A record of column name → `Column` instance (do not mutate).\n */\nexport function columnsOf(model: ModelClass): Record<string, Column<unknown>> {\n const cached = columnsCache.get(model);\n if (cached) return cached;\n const instance = new (model as new () => Model)();\n const out: Record<string, Column<unknown>> = {};\n for (const [key, value] of Object.entries(instance)) {\n if (value instanceof Column) {\n out[key] = value as Column<unknown>;\n }\n }\n columnsCache.set(model, out);\n return out;\n}\n\n/** A mapping between property names and database column names. */\nexport type NameMap = Readonly<Record<string, string>>;\n\n/** Memoized property → column maps (`null` when every name is the identity). */\nconst nameMapCache = new WeakMap<ModelClass, NameMap | null>();\n\n/** Memoized column → property maps (`null` when every name is the identity). */\nconst propMapCache = new WeakMap<ModelClass, NameMap | null>();\n\n/**\n * The property → database-column map for a model, or `null` when every column\n * keeps its property name.\n *\n * `null` is the common case and the fast path: builders and the row coercer skip\n * translation entirely, so a model that renames nothing costs nothing. The map\n * is memoized per class, like {@link columnsOf}.\n *\n * @param model The model class.\n * @returns The name map, or `null` when no column is renamed.\n * @throws Error When two properties resolve to the same column name.\n */\nexport function columnNamesOf(model: ModelClass): NameMap | null {\n const cached = nameMapCache.get(model);\n if (cached !== undefined) return cached;\n const strategy: NamingStrategy = model.naming ?? \"preserve\";\n const map: Record<string, string> = {};\n const seen = new Map<string, string>();\n let renamed = false;\n for (const [prop, col] of Object.entries(columnsOf(model))) {\n const dbName = col.dbName ?? (strategy === \"snake_case\" ? toSnakeCase(prop) : prop);\n const collision = seen.get(dbName);\n if (collision !== undefined) {\n throw new Error(\n `${model.tablename}: properties \"${collision}\" and \"${prop}\" both map to column \"${dbName}\".`,\n );\n }\n seen.set(dbName, prop);\n map[prop] = dbName;\n if (dbName !== prop) renamed = true;\n }\n const result = renamed ? (map as NameMap) : null;\n nameMapCache.set(model, result);\n return result;\n}\n\n/**\n * The database-column → property map for a model, or `null` when every column\n * keeps its property name. The inverse of {@link columnNamesOf}, used to map\n * driver rows back into property space.\n *\n * @param model The model class.\n * @returns The inverse name map, or `null` when no column is renamed.\n */\nexport function columnPropsOf(model: ModelClass): NameMap | null {\n const cached = propMapCache.get(model);\n if (cached !== undefined) return cached;\n const forward = columnNamesOf(model);\n let result: NameMap | null = null;\n if (forward) {\n const inverse: Record<string, string> = {};\n for (const [prop, dbName] of Object.entries(forward)) inverse[dbName] = prop;\n result = inverse as NameMap;\n }\n propMapCache.set(model, result);\n return result;\n}\n\n/** Resolve one property name to its database column name. */\nexport function dbColumn(names: NameMap | null | undefined, prop: string): string {\n return names?.[prop] ?? prop;\n}\n\n/** Pull the static type out of a Column. */\ntype ColType<C> = C extends Column<infer T, infer _F> ? T : never;\n\n/** Keys of the model instance whose values are Columns. */\ntype ColumnKeys<M> = {\n [K in keyof M]: M[K] extends Column<unknown, ColumnFlags> ? K : never;\n}[keyof M];\n\n/** Constructor type for a Model subclass. */\ntype ModelClass = (new () => Model) & {\n tablename: string;\n tableArgs?: () => readonly TableConstraint[];\n naming?: NamingStrategy;\n};\n\n/** Flatten an intersection into a single object literal for clean inference. */\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\n/** The nullability-aware value a column contributes to a row. */\ntype ColValue<Col> = Col extends Column<infer T, infer F>\n ? F extends { notNull: true } | { primaryKey: true }\n ? T\n : T | null\n : never;\n\n/** True when a column has a default (or is a PK) — i.e. optional on insert. */\ntype HasDefault<Col> = Col extends Column<unknown, infer F>\n ? F extends { hasDefault: true }\n ? true\n : false\n : false;\n\n/** True when a column accepts NULL — neither `notNull` nor a primary key. */\ntype IsNullable<Col> = Col extends Column<unknown, infer F>\n ? F extends { notNull: true } | { primaryKey: true }\n ? false\n : true\n : false;\n\n/**\n * Keys of the model whose columns may be omitted on insert.\n *\n * A column is optional when it has a default **or** when it accepts NULL: SQL\n * applies `NULL` to an omitted column that declares no other default, so\n * requiring the caller to write `note: null` adds noise that reads like a\n * deliberate decision to blank the column. Passing `null` explicitly still works.\n */\ntype OptionalInsertKeys<I> = {\n [K in ColumnKeys<I>]: HasDefault<I[K]> extends true\n ? K\n : IsNullable<I[K]> extends true\n ? K\n : never;\n}[ColumnKeys<I>];\n\n/**\n * Infer the SELECT row shape from a model class: every column field becomes its\n * mapped static type. Columns marked notNull/primaryKey are non-nullable; others\n * are `T | null` (SQL semantics — an unconstrained column can be NULL).\n */\nexport type InferModel<C extends ModelClass> = {\n [K in ColumnKeys<InstanceType<C>>]: ColValue<InstanceType<C>[K]>;\n};\n\n/**\n * Infer the INSERT shape: a column is optional when it has a default (or is a PK)\n * **or** when it is nullable — matching SQL, where an omitted column with no\n * `DEFAULT` clause is written as `NULL`. Only `notNull` columns without a default\n * are required. Nullability is preserved on both sides.\n */\nexport type InferInsert<C extends ModelClass> = Simplify<\n {\n [K in OptionalInsertKeys<InstanceType<C>>]?: ColValue<InstanceType<C>[K]>;\n } & {\n [K in Exclude<\n ColumnKeys<InstanceType<C>>,\n OptionalInsertKeys<InstanceType<C>>\n >]: ColValue<InstanceType<C>[K]>;\n }\n>;\n\nexport { Column, type ColType, type ColumnFlags, type ModelClass };\n\nexport {\n and,\n col,\n type CondNode,\n type Condition,\n Expression,\n type ExprNode,\n fn,\n isCondition,\n isExpression,\n not,\n or,\n toCondNode,\n val,\n type WhereArg,\n} from \"./conditions.js\";\n\nexport {\n Agg,\n type AggregateTerm,\n avg,\n count,\n type LockClause,\n type LockOptions,\n max,\n min,\n isSubquery,\n type Operator,\n type OperatorsFor,\n OPERATORS,\n type OrderTerm,\n type SelectNode,\n SelectBuilder,\n select,\n type SortDirection,\n type Subquery,\n sum,\n type WhereInput,\n} from \"./query.js\";\n\nexport {\n DeleteBuilder,\n type DeleteNode,\n del,\n InsertBuilder,\n type InsertNode,\n insert,\n type OnConflict,\n type OnConflictOptions,\n type OnConflictUpdateOptions,\n type Returning,\n type WritePatch,\n type WriteValues,\n UpdateBuilder,\n type UpdateNode,\n update,\n} from \"./mutations.js\";\n\nexport {\n type Dialect,\n detectDialect,\n InvalidDatabaseUrl,\n type ParsedDatabaseUrl,\n parseDatabaseUrl,\n} from \"./url.js\";\n\nexport {\n fromDict,\n parse,\n stringify,\n toDict,\n toJSON,\n ValidationError,\n} from \"./serialize.js\";\n\nexport {\n BaseDialect,\n type CompiledQuery,\n getDialect,\n MysqlDialect,\n Params,\n PostgresDialect,\n type QueryNode,\n SqliteDialect,\n} from \"./dialect.js\";\n\nexport {\n type ColRef,\n join,\n JoinBuilder,\n type JoinClause,\n type JoinNode,\n type JoinOn,\n type JoinSelection,\n type JoinWhereInput,\n type Sources,\n} from \"./join.js\";\n\nexport {\n BaseRepository,\n type PaginationFilter,\n type PaginationResult,\n RecordNotFound,\n} from \"./repository.js\";\n\nexport {\n ActiveRecord,\n type ActiveRecordManager,\n activeRecord,\n} from \"./active-record.js\";\n\nexport {\n type BelongsTo,\n belongsTo,\n type HasMany,\n hasMany,\n loadRelations,\n type Relation,\n type RelationValue,\n type WithRelations,\n} from \"./relations.js\";\n\nexport {\n AsyncEngine,\n AsyncResult,\n AsyncSession,\n type AsyncDriver,\n createEngine,\n createSyncEngine,\n type DriverResult,\n type EngineOptions,\n type Executable,\n NoResultError,\n NodeSqliteDriver,\n type NoticeLogger,\n type PoolOptions,\n QueryExecutionError,\n type QueryLogger,\n type ReservedAsyncDriver,\n type RowOf,\n type SyncDriver,\n SyncEngine,\n SyncResult,\n SyncSession,\n toAsyncDriver,\n} from \"./engine.js\";\n","/**\n * tempest-db-js — Phase 4b: engine, session, real execution.\n *\n * Async by default (`createEngine`), with an optional sync engine for SQLite\n * (`createSyncEngine`). The database is identified by its URL (Phase 4a's\n * `parseDatabaseUrl`); the dialect compiles the builder AST to `{ sql, params }`\n * (Phase 4a's `getDialect`); a driver runs it; rows are coerced back to native\n * types via `coerceRow` (the serialization layer).\n *\n * SQLite execution is real and tested here through Node's built-in `node:sqlite`.\n * `better-sqlite3` and `postgres` (postgres.js) are lazy-loaded peer drivers.\n */\n\nimport { createRequire } from \"node:module\";\nimport { col, fn } from \"./conditions.js\";\nimport { type BaseDialect, getDialect } from \"./dialect.js\";\nimport { type ModelClass, columnNamesOf, columnsOf } from \"./index.js\";\nimport type { JoinBuilder, JoinNode } from \"./join.js\";\nimport type { InsertBuilder, InsertNode, UpdateBuilder } from \"./mutations.js\";\nimport { type SelectBuilder, select } from \"./query.js\";\nimport { coerceRow } from \"./serialize.js\";\nimport { type Dialect, parseDatabaseUrl } from \"./url.js\";\n\n/** A synchronous `require`, usable from both ESM and CJS builds. */\nconst nodeRequire = createRequire(import.meta.url);\n\n// ---------------------------------------------------------------------------\n// driver layer\n// ---------------------------------------------------------------------------\n\n/** The outcome of running one statement. */\nexport interface DriverResult {\n /** Returned rows (SELECT or `RETURNING`); empty otherwise. */\n readonly rows: Record<string, unknown>[];\n /** Rows affected by an INSERT/UPDATE/DELETE. */\n readonly changes: number;\n}\n\n/** A synchronous driver (SQLite). */\nexport interface SyncDriver {\n execute(sql: string, params: readonly unknown[]): DriverResult;\n /** Lazily iterate rows (for `.stream()`), if the driver supports it. */\n iterate?(\n sql: string,\n params: readonly unknown[],\n ): IterableIterator<Record<string, unknown>>;\n close(): void;\n}\n\n/** An asynchronous driver (PostgreSQL, or an async-wrapped SQLite). */\nexport interface AsyncDriver {\n execute(sql: string, params: readonly unknown[]): Promise<DriverResult>;\n /** Lazily iterate rows (for `.stream()`), if the driver supports it. */\n iterate?(\n sql: string,\n params: readonly unknown[],\n ): AsyncIterableIterator<Record<string, unknown>>;\n /**\n * Reserve a single pinned connection for the duration of a transaction.\n * Pooled drivers (PostgreSQL) MUST implement this so `BEGIN`/`COMMIT` and the\n * statements between them all run on the same connection. Single-connection\n * drivers (SQLite) may omit it — `transaction` then runs on the shared handle.\n */\n reserve?(): Promise<ReservedAsyncDriver>;\n close(): Promise<void>;\n}\n\n/** An {@link AsyncDriver} pinned to one connection, used inside a transaction. */\nexport interface ReservedAsyncDriver extends AsyncDriver {\n /** Return the pinned connection to the pool. */\n release(): Promise<void>;\n}\n\n/** Encode a JS value into something a SQLite driver can bind. */\nfunction encodeSqliteParam(value: unknown): unknown {\n if (value === undefined || value === null) return null;\n if (typeof value === \"boolean\") return value ? 1 : 0;\n if (value instanceof Date) return value.toISOString();\n if (value instanceof Uint8Array) return value;\n if (typeof value === \"object\") return JSON.stringify(value);\n return value; // number, bigint, string\n}\n\n/** SQLite driver backed by Node's built-in `node:sqlite` (zero install). */\nexport class NodeSqliteDriver implements SyncDriver {\n // biome-ignore lint/suspicious/noExplicitAny: node:sqlite DatabaseSync has no shipped types here.\n private readonly db: any;\n /**\n * Prepared-statement cache keyed by SQL text. tempest-db-js always\n * parameterizes, so a query shape maps to one stable SQL string — reusing the\n * compiled statement avoids re-`prepare()` on every call (the dominant cost of\n * per-row inserts and point lookups).\n */\n // biome-ignore lint/suspicious/noExplicitAny: node:sqlite StatementSync has no shipped types here.\n private readonly statements = new Map<string, any>();\n\n // biome-ignore lint/suspicious/noExplicitAny: accept an already-open DatabaseSync handle.\n constructor(database: any) {\n this.db = database;\n }\n\n /**\n * Open a `node:sqlite` database at the given path (or `:memory:`).\n *\n * @param path The database file, or `\":memory:\"`.\n * @param options Passed straight to `DatabaseSync` (`readOnly`, `timeout`, …).\n * @returns A driver over the open handle.\n */\n static open(\n path: string,\n options?: Readonly<Record<string, unknown>>,\n ): NodeSqliteDriver {\n // Lazy require so importing tempest-db-js never forces the built-in module to load.\n const { DatabaseSync } = nodeRequire(\"node:sqlite\") as {\n DatabaseSync: new (path: string, options?: Record<string, unknown>) => unknown;\n };\n return new NodeSqliteDriver(\n options ? new DatabaseSync(path, { ...options }) : new DatabaseSync(path),\n );\n }\n\n /** Return the cached prepared statement for `sql`, preparing it on first use. */\n // biome-ignore lint/suspicious/noExplicitAny: statement type is unavailable here.\n private prepare(sql: string): any {\n const cached = this.statements.get(sql);\n if (cached) return cached;\n const stmt = this.db.prepare(sql);\n this.statements.set(sql, stmt);\n return stmt;\n }\n\n execute(sql: string, params: readonly unknown[]): DriverResult {\n const stmt = this.prepare(sql);\n const bound = params.map(encodeSqliteParam);\n if (returnsRows(sql)) {\n return { rows: stmt.all(...bound) as Record<string, unknown>[], changes: 0 };\n }\n const info = stmt.run(...bound);\n return { rows: [], changes: Number(info.changes ?? 0) };\n }\n\n *iterate(\n sql: string,\n params: readonly unknown[],\n ): IterableIterator<Record<string, unknown>> {\n const stmt = this.prepare(sql);\n const bound = params.map(encodeSqliteParam);\n yield* stmt.iterate(...bound) as IterableIterator<Record<string, unknown>>;\n }\n\n close(): void {\n this.statements.clear();\n this.db.close();\n }\n}\n\n/** True when a statement yields rows (SELECT, PRAGMA, or any `RETURNING`). */\nfunction returnsRows(sql: string): boolean {\n return /^\\s*(select|pragma)/i.test(sql) || /\\breturning\\b/i.test(sql);\n}\n\n// ---------------------------------------------------------------------------\n// executable builders & row extraction\n// ---------------------------------------------------------------------------\n\n/* biome-ignore lint/suspicious/noExplicitAny: builder generics are irrelevant to execution dispatch. */\ntype AnySelect = SelectBuilder<any, any, any>;\n/* biome-ignore lint/suspicious/noExplicitAny: see above. */\ntype AnyInsert = InsertBuilder<any, any, any>;\n/* biome-ignore lint/suspicious/noExplicitAny: only the guarded flag matters. */\ntype GuardedUpdate = UpdateBuilder<any, true, any>;\n/* biome-ignore lint/suspicious/noExplicitAny: only the guarded flag matters. */\ntype GuardedDelete = import(\"./mutations.js\").DeleteBuilder<any, true, any>;\n/* biome-ignore lint/suspicious/noExplicitAny: join sources are irrelevant to dispatch. */\ntype AnyJoin = JoinBuilder<any>;\n\n/**\n * A builder that is safe to execute. UPDATE/DELETE are accepted only once\n * guarded (after `.where()` or `.unguarded()`) — an unguarded full-table write\n * is a compile error at the execution boundary.\n */\nexport type Executable = AnySelect | AnyInsert | GuardedUpdate | GuardedDelete | AnyJoin;\n\n/** The element type a builder yields on execution. */\nexport type RowOf<B> = B extends { readonly __row: infer R } ? R : never;\n\n/** Internals shared between single-table builders, read structurally at runtime. */\ninterface SingleBuilder {\n readonly node: Parameters<BaseDialect[\"compile\"]>[0];\n readonly source: ModelClass;\n}\n\n/** Internals of a join builder, read structurally at runtime. */\ninterface JoinRunnable {\n readonly node: JoinNode;\n readonly sources: Readonly<Record<string, ModelClass>>;\n}\n\n/** Split one flat `alias.column` row into a coerced composite `{ alias: {...} }`. */\nfunction splitJoinRow(\n node: JoinNode,\n sources: Readonly<Record<string, ModelClass>>,\n raw: Record<string, unknown>,\n): Record<string, unknown> {\n const leftAliases = new Set(\n node.joins.filter((j) => j.kind === \"left\").map((j) => j.alias),\n );\n const out: Record<string, unknown> = {};\n for (const [alias, model] of Object.entries(sources)) {\n const sub: Record<string, unknown> = {};\n const names = columnNamesOf(model);\n let allNull = true;\n for (const colName of Object.keys(columnsOf(model))) {\n const value = raw[`${alias}.${colName}`];\n if (value !== null && value !== undefined) allNull = false;\n sub[names?.[colName] ?? colName] = value;\n }\n out[alias] = leftAliases.has(alias) && allNull ? null : coerceRow(model, sub);\n }\n return out;\n}\n\n/** Coerce one raw driver row into the builder's native row shape. */\nfunction coerceOne(builder: unknown, raw: Record<string, unknown>): unknown {\n const node = (builder as { node: { kind: string } }).node;\n if (node.kind === \"join_select\") {\n const b = builder as unknown as JoinRunnable;\n return splitJoinRow(b.node, b.sources, raw);\n }\n const b = builder as unknown as SingleBuilder;\n return coerceRow(b.source, raw);\n}\n\n/** Coerce raw driver rows into the builder's native row shape. */\nfunction mapRows(builder: unknown, raw: Record<string, unknown>[]): unknown[] {\n return raw.map((r) => coerceOne(builder, r));\n}\n\n// ---------------------------------------------------------------------------\n// results\n// ---------------------------------------------------------------------------\n\n/** Raised by `.one()` when the row count is not exactly one. */\nexport class NoResultError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NoResultError\";\n }\n}\n\n/** A short, safe preview of a bound parameter for an error message. */\nfunction previewParam(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (value instanceof Uint8Array) return `<${value.length} bytes>`;\n const text = typeof value === \"string\" ? value : String(value);\n return text.length > 64 ? `${text.slice(0, 61)}...` : text;\n}\n\n/**\n * Raised when the driver rejects a statement. Wraps the original driver error\n * and attaches the offending SQL and its bound parameters, so a failure points\n * at the exact query instead of an opaque driver message.\n */\nexport class QueryExecutionError extends Error {\n constructor(\n /** The original error thrown by the driver. */\n override readonly cause: unknown,\n /** The SQL that failed. */\n readonly sql: string,\n /** The bound parameters, in order. */\n readonly params: readonly unknown[],\n ) {\n const reason = cause instanceof Error ? cause.message : String(cause);\n super(\n `Query failed: ${reason}\\n SQL: ${sql}\\n params: [${params\n .map(previewParam)\n .join(\", \")}]`,\n );\n this.name = \"QueryExecutionError\";\n }\n}\n\n/**\n * A hook invoked for every statement a session runs (query logging / tracing).\n * Errors thrown by the logger are ignored so logging never breaks execution.\n */\nexport type QueryLogger = (event: {\n readonly sql: string;\n readonly params: readonly unknown[];\n}) => void;\n\n/** Invoke a query logger, swallowing any error it throws. */\nfunction emitLog(\n logger: QueryLogger | undefined,\n sql: string,\n params: readonly unknown[],\n): void {\n if (!logger) return;\n try {\n logger({ sql, params });\n } catch {\n // logging must never break execution\n }\n}\n\nfunction firstScalar(row: Record<string, unknown> | undefined): unknown {\n if (!row) return null;\n const keys = Object.keys(row);\n return keys.length > 0 ? row[keys[0] as string] : null;\n}\n\n/** Synchronous result view over already-fetched rows. */\nexport class SyncResult<Row> {\n constructor(\n private readonly rows: Row[],\n private readonly changes: number,\n ) {}\n\n all(): Row[] {\n return this.rows;\n }\n first(): Row | null {\n return this.rows[0] ?? null;\n }\n one(): Row {\n if (this.rows.length !== 1) {\n throw new NoResultError(`expected exactly one row, got ${this.rows.length}`);\n }\n return this.rows[0] as Row;\n }\n oneOrNull(): Row | null {\n if (this.rows.length > 1) {\n throw new NoResultError(`expected at most one row, got ${this.rows.length}`);\n }\n return this.rows[0] ?? null;\n }\n scalar(): unknown {\n return firstScalar(this.rows[0] as Record<string, unknown> | undefined);\n }\n scalars(): unknown[] {\n return this.rows.map((r) => firstScalar(r as Record<string, unknown>));\n }\n rowsAffected(): number {\n return this.changes;\n }\n}\n\n/** Asynchronous result view (terminals return Promises). */\nexport class AsyncResult<Row> {\n constructor(private readonly inner: Promise<SyncResult<Row>>) {}\n\n async all(): Promise<Row[]> {\n return (await this.inner).all();\n }\n async first(): Promise<Row | null> {\n return (await this.inner).first();\n }\n async one(): Promise<Row> {\n return (await this.inner).one();\n }\n async oneOrNull(): Promise<Row | null> {\n return (await this.inner).oneOrNull();\n }\n async scalar(): Promise<unknown> {\n return (await this.inner).scalar();\n }\n async scalars(): Promise<unknown[]> {\n return (await this.inner).scalars();\n }\n async rowsAffected(): Promise<number> {\n return (await this.inner).rowsAffected();\n }\n}\n\n// ---------------------------------------------------------------------------\n// sessions\n// ---------------------------------------------------------------------------\n\nlet savepointCounter = 0;\n\n/**\n * True when a builder asks for `RETURNING` on a dialect that has none, so the\n * session must insert and read the row back instead of compiling one statement.\n */\nfunction needsInsertReadBack(\n dialect: BaseDialect,\n node: Parameters<BaseDialect[\"compile\"]>[0],\n): node is InsertNode {\n return dialect.name === \"mysql\" && node.kind === \"insert\" && node.returning !== null;\n}\n\n/** The model's single primary-key property name, for the insert read-back. */\nfunction singlePrimaryKey(model: ModelClass): string {\n const keys = Object.entries(columnsOf(model))\n .filter(([, column]) => column.flags.primaryKey)\n .map(([name]) => name);\n if (keys.length !== 1) {\n throw new Error(\n `${model.tablename} needs exactly one primary key to read an insert back on a dialect without RETURNING; found ${keys.length}.`,\n );\n }\n return keys[0] as string;\n}\n\n/** Reject a `raw()` call whose parameters are not an array. */\nfunction assertRawParams(params: readonly unknown[]): void {\n if (!Array.isArray(params)) {\n throw new TypeError(\n \"session.raw(sql, params) takes an array of bound parameters — never interpolate values into the SQL string.\",\n );\n }\n}\n\n/** A synchronous unit of work (SQLite). */\nexport class SyncSession {\n constructor(\n private readonly driver: SyncDriver,\n private readonly dialect: BaseDialect,\n /** Optional per-statement logger (query tracing). */\n private readonly logger?: QueryLogger,\n ) {}\n\n /** Log, run, and error-wrap one raw statement. */\n private exec(sql: string, params: readonly unknown[]): DriverResult {\n emitLog(this.logger, sql, params);\n try {\n return this.driver.execute(sql, params);\n } catch (error) {\n throw new QueryExecutionError(error, sql, params);\n }\n }\n\n /**\n * Run a raw, parameterized SQL statement (synchronous) — the runtime counterpart of the\n * migrations' `Op.execute`.\n *\n * A query builder never covers all of SQL, and without an escape hatch a single\n * unsupported query forces a whole second database stack alongside this one. Use\n * it for what the builder cannot yet express, and keep everything else typed.\n *\n * The statement goes through the same path as a compiled one: it is logged via\n * `onQuery`, wrapped in {@link QueryExecutionError} on failure, and runs on the\n * reserved connection inside `transaction()`.\n *\n * @param sql The statement text. Placeholders only (`$1` / `?` per dialect) —\n * never interpolate a value into this string.\n * @param params The bound parameters, in placeholder order.\n * @param options Pass `as` to coerce the returned rows with a model's column\n * types (and its column-name mapping).\n * @returns The result view over the returned rows.\n * @throws Error When `params` is not an array — the guard against calling this\n * with an interpolated string and no parameters by mistake.\n *\n * @example\n * ```ts\n * const claimed = await session.raw<OutboundRow>(\n * `UPDATE outbound_messages SET status = 'sending'\n * WHERE id = ANY($1) RETURNING *`,\n * [ids],\n * { as: Outbound },\n * ).all();\n * ```\n */\n raw<Row = Record<string, unknown>>(\n sql: string,\n params: readonly unknown[] = [],\n options?: { readonly as?: ModelClass },\n ): SyncResult<Row> {\n assertRawParams(params);\n const result = this.exec(sql, params);\n const model = options?.as;\n const rows = (\n model ? result.rows.map((row) => coerceRow(model, row)) : result.rows\n ) as Row[];\n return new SyncResult<Row>(rows, result.changes);\n }\n\n /** Compile, run, and coerce a builder into a result. */\n execute<B extends Executable>(builder: B): SyncResult<RowOf<B>> {\n const node = (builder as unknown as { node: Parameters<BaseDialect[\"compile\"]>[0] })\n .node;\n const { sql, params } = this.dialect.compile(node);\n const result = this.exec(sql, params);\n const rows = mapRows(builder, result.rows) as RowOf<B>[];\n return new SyncResult<RowOf<B>>(rows, result.changes);\n }\n\n /** Run `fn` inside a transaction: commit on success, rollback on throw. */\n transaction<T>(fn: (tx: SyncSession) => T): T {\n this.exec(\"BEGIN\", []);\n try {\n const out = fn(this);\n this.exec(\"COMMIT\", []);\n return out;\n } catch (error) {\n this.exec(\"ROLLBACK\", []);\n throw error;\n }\n }\n\n /** Run `fn` inside a SAVEPOINT (nested transaction). */\n beginNested<T>(fn: (sp: SyncSession) => T): T {\n savepointCounter += 1;\n const name = `qsp_${savepointCounter}`;\n this.exec(`SAVEPOINT ${name}`, []);\n try {\n const out = fn(this);\n this.exec(`RELEASE ${name}`, []);\n return out;\n } catch (error) {\n this.exec(`ROLLBACK TO ${name}`, []);\n throw error;\n }\n }\n\n /**\n * Lazily iterate result rows without materializing them all. Falls back to a\n * buffered fetch when the driver has no native iteration.\n */\n *stream<B extends Executable>(builder: B): IterableIterator<RowOf<B>> {\n const node = (builder as unknown as { node: Parameters<BaseDialect[\"compile\"]>[0] })\n .node;\n const { sql, params } = this.dialect.compile(node);\n emitLog(this.logger, sql, params);\n if (this.driver.iterate) {\n try {\n for (const raw of this.driver.iterate(sql, params)) {\n yield coerceOne(builder, raw) as RowOf<B>;\n }\n } catch (error) {\n throw new QueryExecutionError(error, sql, params);\n }\n return;\n }\n for (const raw of this.exec(sql, params).rows) {\n yield coerceOne(builder, raw) as RowOf<B>;\n }\n }\n\n close(): void {\n this.driver.close();\n }\n\n /** `using session = ...` closes the driver when the scope exits. */\n [Symbol.dispose](): void {\n this.close();\n }\n}\n\n/** An asynchronous unit of work. */\nexport class AsyncSession {\n constructor(\n private readonly driver: AsyncDriver,\n private readonly dialect: BaseDialect,\n /** Optional per-statement logger (query tracing). */\n private readonly logger?: QueryLogger,\n ) {}\n\n /** Log, run, and error-wrap one raw statement. */\n private async exec(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n emitLog(this.logger, sql, params);\n try {\n return await this.driver.execute(sql, params);\n } catch (error) {\n throw new QueryExecutionError(error, sql, params);\n }\n }\n\n /**\n * Run a raw, parameterized SQL statement — the runtime counterpart of the\n * migrations' `Op.execute`.\n *\n * A query builder never covers all of SQL, and without an escape hatch a single\n * unsupported query forces a whole second database stack alongside this one. Use\n * it for what the builder cannot yet express, and keep everything else typed.\n *\n * The statement goes through the same path as a compiled one: it is logged via\n * `onQuery`, wrapped in {@link QueryExecutionError} on failure, and runs on the\n * reserved connection inside `transaction()`.\n *\n * @param sql The statement text. Placeholders only (`$1` / `?` per dialect) —\n * never interpolate a value into this string.\n * @param params The bound parameters, in placeholder order.\n * @param options Pass `as` to coerce the returned rows with a model's column\n * types (and its column-name mapping).\n * @returns The result view over the returned rows.\n * @throws Error When `params` is not an array — the guard against calling this\n * with an interpolated string and no parameters by mistake.\n *\n * @example\n * ```ts\n * const claimed = await session.raw<OutboundRow>(\n * `UPDATE outbound_messages SET status = 'sending'\n * WHERE id = ANY($1) RETURNING *`,\n * [ids],\n * { as: Outbound },\n * ).all();\n * ```\n */\n raw<Row = Record<string, unknown>>(\n sql: string,\n params: readonly unknown[] = [],\n options?: { readonly as?: ModelClass },\n ): AsyncResult<Row> {\n assertRawParams(params);\n const model = options?.as;\n const inner = this.exec(sql, params).then((result) => {\n const rows = (\n model ? result.rows.map((row) => coerceRow(model, row)) : result.rows\n ) as Row[];\n return new SyncResult<Row>(rows, result.changes);\n });\n return new AsyncResult<Row>(inner);\n }\n\n execute<B extends Executable>(builder: B): AsyncResult<RowOf<B>> {\n const node = (builder as unknown as { node: Parameters<BaseDialect[\"compile\"]>[0] })\n .node;\n if (needsInsertReadBack(this.dialect, node)) {\n return new AsyncResult<RowOf<B>>(\n this.insertAndReadBack(builder as unknown as SingleBuilder, node),\n );\n }\n const { sql, params } = this.dialect.compile(node);\n const inner = this.exec(sql, params).then((result) => {\n const rows = mapRows(builder, result.rows) as RowOf<B>[];\n return new SyncResult<RowOf<B>>(rows, result.changes);\n });\n return new AsyncResult<RowOf<B>>(inner);\n }\n\n /**\n * Honor `.returning()` on a dialect without `RETURNING`, by inserting and then\n * reading the row back by key.\n *\n * Both statements must run on **one** connection, because `LAST_INSERT_ID()` is\n * per-connection: outside a transaction the pooled driver is reserved for the\n * pair; inside one, the session already holds a pinned connection (a reserved\n * driver exposes no `reserve`), so it runs there directly.\n *\n * @param builder The insert builder, for its source model.\n * @param node The insert AST, whose `returning` drives the read-back.\n * @returns The result view over the read-back row.\n * @throws Error When the insert writes more than one row — `LAST_INSERT_ID()`\n * identifies only the first, and the rest are consecutive only under some\n * auto-increment lock modes.\n */\n private async insertAndReadBack<Row>(\n builder: SingleBuilder,\n node: InsertNode,\n ): Promise<SyncResult<Row>> {\n if (node.values.length !== 1) {\n throw new Error(\n `${this.dialect.name} has no RETURNING, and reading back a multi-row insert is not reliable — insert one row at a time, or drop .returning().`,\n );\n }\n const model = builder.source;\n const pk = singlePrimaryKey(model);\n const supplied = (node.values[0] as Record<string, unknown>)[pk];\n const readBack = select(model).where(\n supplied === undefined || supplied === null\n ? col(pk).eq(fn.call(\"LAST_INSERT_ID\"))\n : { [pk]: supplied },\n );\n const insertSql = this.dialect.compile({ ...node, returning: null });\n const selectSql = this.dialect.compile(\n node.returning === \"*\" || node.returning === null\n ? readBack.node\n : { ...readBack.node, columns: node.returning },\n );\n const run = async (driver: AsyncDriver): Promise<SyncResult<Row>> => {\n const scoped = new AsyncSession(driver, this.dialect, this.logger);\n const written = await scoped.exec(insertSql.sql, insertSql.params);\n const read = await scoped.exec(selectSql.sql, selectSql.params);\n const rows = read.rows.map((row) => coerceRow(model, row)) as Row[];\n return new SyncResult<Row>(rows, written.changes);\n };\n if (!this.driver.reserve) return run(this.driver);\n const reserved = await this.driver.reserve();\n try {\n return await run(reserved);\n } finally {\n await reserved.release();\n }\n }\n\n /** Lazily iterate result rows. Uses driver streaming when available. */\n async *stream<B extends Executable>(builder: B): AsyncIterableIterator<RowOf<B>> {\n const node = (builder as unknown as { node: Parameters<BaseDialect[\"compile\"]>[0] })\n .node;\n const { sql, params } = this.dialect.compile(node);\n emitLog(this.logger, sql, params);\n if (this.driver.iterate) {\n try {\n for await (const raw of this.driver.iterate(sql, params)) {\n yield coerceOne(builder, raw) as RowOf<B>;\n }\n } catch (error) {\n throw new QueryExecutionError(error, sql, params);\n }\n return;\n }\n const result = await this.exec(sql, params);\n for (const raw of result.rows) {\n yield coerceOne(builder, raw) as RowOf<B>;\n }\n }\n\n async transaction<T>(fn: (tx: AsyncSession) => Promise<T>): Promise<T> {\n // Pooled drivers (PostgreSQL) must pin one connection: BEGIN/COMMIT and every\n // statement between them have to run on the same connection, or postgres.js\n // rejects the raw transaction. Single-connection drivers (SQLite) skip this.\n if (this.driver.reserve) {\n const reserved = await this.driver.reserve();\n const scoped = new AsyncSession(reserved, this.dialect, this.logger);\n try {\n await scoped.exec(\"BEGIN\", []);\n const out = await fn(scoped);\n await scoped.exec(\"COMMIT\", []);\n return out;\n } catch (error) {\n await scoped.exec(\"ROLLBACK\", []);\n throw error;\n } finally {\n await reserved.release();\n }\n }\n await this.exec(\"BEGIN\", []);\n try {\n const out = await fn(this);\n await this.exec(\"COMMIT\", []);\n return out;\n } catch (error) {\n await this.exec(\"ROLLBACK\", []);\n throw error;\n }\n }\n\n async close(): Promise<void> {\n await this.driver.close();\n }\n\n /** `await using session = ...` closes the driver when the scope exits. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// engines\n// ---------------------------------------------------------------------------\n\n/** Connection-pool tuning (PostgreSQL; ignored by SQLite). */\nexport interface PoolOptions {\n /** Max connections in the pool. */\n readonly size?: number;\n /** Close a connection after it sits idle this long (ms). */\n readonly idleTimeoutMs?: number;\n /** Give up acquiring a connection after this long (ms). */\n readonly connectTimeoutMs?: number;\n}\n\n/**\n * A server-side notice (a PostgreSQL `NOTICE`). The shape is the driver's own —\n * passed through untouched rather than normalized, since what is useful in it\n * differs per database.\n */\nexport type NoticeLogger = (notice: Record<string, unknown>) => void;\n\n/** Options shared by both engine flavors. */\nexport interface EngineOptions {\n /** Override the driver detected from the URL (e.g. `\"better-sqlite3\"`). */\n readonly driver?: string;\n /** Connection-pool tuning (PostgreSQL only). */\n readonly pool?: PoolOptions;\n /**\n * Called for every statement a session runs — SQL + bound params. Use for\n * query logging/tracing. Thrown errors are swallowed so it never breaks a query.\n */\n readonly onQuery?: QueryLogger;\n /**\n * Called for every server-side notice (`CREATE TABLE IF NOT EXISTS` on an\n * existing table, `DROP ... IF EXISTS` on a missing one, and so on).\n *\n * **Without this, notices are silenced.** postgres.js defaults to printing them\n * with `console.log`, which drops a nine-line object into the host service's\n * stdout in the middle of its structured log — on every boot, since a migration\n * runner is usually the first thing to run. Writing to the host's stdout is the\n * application's decision, not a library's, so the default is to say nothing and\n * let you route them:\n *\n * ```ts\n * createEngine(url, { onNotice: (n) => logger.debug({ pg: n }, \"postgres notice\") });\n * ```\n *\n * Thrown errors are swallowed, like `onQuery`.\n */\n readonly onNotice?: NoticeLogger;\n /**\n * Options passed straight to the underlying driver, applied **last** so they\n * win over everything this layer derives (`pool`, `onNotice`).\n *\n * The escape hatch for what the typed surface does not model and is not going\n * to — postgres.js `connection`/`types`/`transform`/`ssl`, mysql2's own\n * settings, `node:sqlite`'s `readOnly` — so a gap need not become a feature\n * request.\n */\n readonly driverOptions?: Readonly<Record<string, unknown>>;\n}\n\n/** Invoke a notice logger, swallowing any error it throws. */\nfunction emitNotice(logger: NoticeLogger | undefined, notice: unknown): void {\n if (!logger) return;\n try {\n logger(notice as Record<string, unknown>);\n } catch {\n // logging must never break a connection\n }\n}\n\n/** A synchronous engine (SQLite only). */\nexport class SyncEngine {\n readonly dialect: Dialect = \"sqlite\";\n\n constructor(\n private readonly driver: SyncDriver,\n private readonly logger?: QueryLogger,\n ) {}\n\n session(): SyncSession {\n return new SyncSession(this.driver, getDialect(\"sqlite\"), this.logger);\n }\n\n transaction<T>(fn: (tx: SyncSession) => T): T {\n return this.session().transaction(fn);\n }\n\n close(): void {\n this.driver.close();\n }\n\n /** `using engine = createSyncEngine(...)` closes the pool when the scope exits. */\n [Symbol.dispose](): void {\n this.close();\n }\n}\n\n/** An asynchronous engine. */\nexport class AsyncEngine {\n constructor(\n private readonly driver: AsyncDriver,\n readonly dialect: Dialect,\n private readonly logger?: QueryLogger,\n ) {}\n\n session(): AsyncSession {\n return new AsyncSession(this.driver, getDialect(this.dialect), this.logger);\n }\n\n transaction<T>(fn: (tx: AsyncSession) => Promise<T>): Promise<T> {\n return this.session().transaction(fn);\n }\n\n async close(): Promise<void> {\n await this.driver.close();\n }\n\n /** `await using engine = createEngine(...)` closes the pool when the scope exits. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n\n/**\n * Adapt a sync **or** async driver to the async interface.\n *\n * `await` normalizes both: a sync driver returns a plain value, an async one a\n * promise, and awaiting either yields the result. That is what lets the migration\n * CLI take one code path instead of branching on a difference it cannot detect\n * from the object's shape.\n *\n * @param driver Either driver flavor.\n * @returns An async driver delegating to it.\n */\nexport function toAsyncDriver(driver: SyncDriver | AsyncDriver): AsyncDriver {\n return {\n async execute(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n return await driver.execute(sql, params);\n },\n async close(): Promise<void> {\n await driver.close();\n },\n };\n}\n\n/** Wrap a sync driver so it satisfies the async interface (SQLite async path). */\nfunction asAsync(driver: SyncDriver): AsyncDriver {\n const syncIterate = driver.iterate?.bind(driver);\n return {\n execute: (sql, params) => Promise.resolve(driver.execute(sql, params)),\n close: () => Promise.resolve(driver.close()),\n ...(syncIterate\n ? {\n iterate: async function* (sql: string, params: readonly unknown[]) {\n yield* syncIterate(sql, params);\n },\n }\n : {}),\n };\n}\n\n/** Open a SQLite sync driver from a parsed URL, passing driver options through. */\nfunction openSqliteDriver(path: string, options?: EngineOptions): SyncDriver {\n return NodeSqliteDriver.open(path, options?.driverOptions);\n}\n\n/**\n * Create a **synchronous** engine from a database URL. SQLite only — PostgreSQL\n * has no sane synchronous driver in Node, so a Postgres URL throws, pointing at\n * the async `createEngine`.\n *\n * @param url A SQLite URL, e.g. `\"sqlite:///app.db\"` or `\"sqlite://:memory:\"`.\n * @param options Engine options.\n * @returns A `SyncEngine`.\n */\nexport function createSyncEngine(url: string, options?: EngineOptions): SyncEngine {\n const parsed = parseDatabaseUrl(url);\n if (parsed.dialect !== \"sqlite\") {\n throw new Error(\n `createSyncEngine supports only SQLite; ${parsed.dialect} is async-only — use createEngine.`,\n );\n }\n return new SyncEngine(\n openSqliteDriver(parsed.database ?? \":memory:\", options),\n options?.onQuery,\n );\n}\n\n/**\n * Create an **asynchronous** engine from a database URL (the default). Works for\n * both SQLite (sync driver wrapped as async) and PostgreSQL (postgres.js,\n * lazy-loaded).\n *\n * @param url A database URL, e.g. `\"postgresql://app@localhost/app\"` or\n * `\"sqlite:///app.db\"`.\n * @param options Engine options.\n * @returns An `AsyncEngine`.\n */\nexport function createEngine(url: string, options?: EngineOptions): AsyncEngine {\n const parsed = parseDatabaseUrl(url);\n if (parsed.dialect === \"sqlite\") {\n return new AsyncEngine(\n asAsync(openSqliteDriver(parsed.database ?? \":memory:\", options)),\n \"sqlite\",\n options?.onQuery,\n );\n }\n if (parsed.dialect === \"mysql\") {\n // MySQL: mysql2 is lazy-loaded the first time a query runs.\n return new AsyncEngine(\n createMysqlDriver(parsed.raw, options),\n \"mysql\",\n options?.onQuery,\n );\n }\n // PostgreSQL: postgres.js is lazy-loaded the first time a query runs.\n return new AsyncEngine(\n createPostgresDriver(parsed.raw, options),\n \"postgresql\",\n options?.onQuery,\n );\n}\n\n/** Encode a JS value into something the MySQL driver (mysql2) can bind. */\nfunction encodeMysqlParam(value: unknown): unknown {\n if (value === undefined || value === null) return null;\n if (typeof value === \"boolean\") return value ? 1 : 0;\n if (value instanceof Uint8Array) return value;\n if (value instanceof Date) return value;\n if (typeof value === \"object\") return JSON.stringify(value);\n return value; // number, bigint, string\n}\n\n/** Shape a mysql2 result into our `DriverResult`. */\nfunction toMysqlResult(rows: unknown): DriverResult {\n if (Array.isArray(rows)) {\n return { rows: rows as Record<string, unknown>[], changes: 0 };\n }\n // A ResultSetHeader (INSERT/UPDATE/DELETE): no rows, affectedRows is the count.\n const header = rows as { affectedRows?: number };\n return { rows: [], changes: header.affectedRows ?? 0 };\n}\n\n/**\n * MySQL driver backed by mysql2/promise (lazy-loaded peer dependency).\n *\n * Transactions reserve a single pooled connection via {@link AsyncDriver.reserve}\n * so `BEGIN`/`COMMIT` and the statements between them run on one connection.\n * MySQL has no `RETURNING`; the dialect throws if it is requested.\n */\nfunction createMysqlDriver(url: string, options?: EngineOptions): AsyncDriver {\n const pool = options?.pool;\n // biome-ignore lint/suspicious/noExplicitAny: mysql2 pool typed at call site.\n let poolHandle: any;\n const ensure = async (): Promise<void> => {\n if (poolHandle) return;\n const moduleName = \"mysql2/promise\";\n // biome-ignore lint/suspicious/noExplicitAny: dynamic import of the peer dep.\n const mod = (await import(/* @vite-ignore */ moduleName)) as any;\n const opts: Record<string, unknown> = { uri: url };\n if (pool?.size !== undefined) opts.connectionLimit = pool.size;\n if (pool?.idleTimeoutMs !== undefined) opts.idleTimeout = pool.idleTimeoutMs;\n if (pool?.connectTimeoutMs !== undefined) opts.connectTimeout = pool.connectTimeoutMs;\n Object.assign(opts, options?.driverOptions ?? {});\n poolHandle = mod.createPool(opts);\n };\n const runOn = async (\n // biome-ignore lint/suspicious/noExplicitAny: mysql2 queryable (pool or connection).\n queryable: any,\n sql: string,\n params: readonly unknown[],\n ): Promise<DriverResult> => {\n const [rows] = await queryable.query(sql, params.map(encodeMysqlParam));\n return toMysqlResult(rows);\n };\n return {\n async execute(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n await ensure();\n return runOn(poolHandle, sql, params);\n },\n async reserve(): Promise<ReservedAsyncDriver> {\n await ensure();\n // biome-ignore lint/suspicious/noExplicitAny: reserved connection from mysql2.\n const conn: any = await poolHandle.getConnection();\n return {\n execute: (sql, params) => runOn(conn, sql, params),\n async release(): Promise<void> {\n conn.release();\n },\n async close(): Promise<void> {\n conn.release();\n },\n };\n },\n async close(): Promise<void> {\n if (poolHandle) await poolHandle.end();\n },\n };\n}\n\n/** Shape a postgres.js result array into our `DriverResult`. */\nfunction toPostgresResult(rows: unknown): DriverResult {\n const arr = rows as Record<string, unknown>[] & { count?: number };\n return { rows: Array.from(arr), changes: arr.count ?? arr.length };\n}\n\n/**\n * PostgreSQL driver backed by postgres.js (lazy-loaded peer dependency).\n *\n * Transactions reserve a single connection via {@link AsyncDriver.reserve} —\n * postgres.js pools connections, so a raw `BEGIN` on the shared client would run\n * on a different connection than the statements that follow (and is rejected with\n * `UNSAFE_TRANSACTION`). The reserved connection runs `BEGIN`/`COMMIT`/`ROLLBACK`\n * and every statement between them on one socket, then is released back.\n */\nfunction createPostgresDriver(url: string, options?: EngineOptions): AsyncDriver {\n const pool = options?.pool;\n // biome-ignore lint/suspicious/noExplicitAny: postgres.js client typed at call site.\n let client: any;\n const ensure = async (): Promise<void> => {\n if (client) return;\n // Non-literal specifier so the optional peer dep is not type-resolved at build.\n const moduleName = \"postgres\";\n // biome-ignore lint/suspicious/noExplicitAny: dynamic import of the peer dep.\n const mod = (await import(/* @vite-ignore */ moduleName)) as any;\n // Map our PoolOptions onto postgres.js's option names (seconds, not ms).\n const opts: Record<string, unknown> = {};\n if (pool?.size !== undefined) opts.max = pool.size;\n if (pool?.idleTimeoutMs !== undefined)\n opts.idle_timeout = Math.ceil(pool.idleTimeoutMs / 1000);\n if (pool?.connectTimeoutMs !== undefined) {\n opts.connect_timeout = Math.ceil(pool.connectTimeoutMs / 1000);\n }\n opts.onnotice = (notice: unknown): void => emitNotice(options?.onNotice, notice);\n Object.assign(opts, options?.driverOptions ?? {});\n client = (mod.default ?? mod)(url, opts);\n };\n return {\n async execute(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n await ensure();\n // postgres.js `unsafe` runs a parameterized string with positional params.\n return toPostgresResult(await client.unsafe(sql, params as unknown[]));\n },\n async reserve(): Promise<ReservedAsyncDriver> {\n await ensure();\n // biome-ignore lint/suspicious/noExplicitAny: reserved connection from postgres.js.\n const conn: any = await client.reserve();\n return {\n async execute(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n return toPostgresResult(await conn.unsafe(sql, params as unknown[]));\n },\n async release(): Promise<void> {\n conn.release();\n },\n async close(): Promise<void> {\n conn.release();\n },\n };\n },\n async close(): Promise<void> {\n if (client) await client.end();\n },\n };\n}\n","/**\n * tempest-db-js — Phase 6: typed migration operations.\n *\n * Every schema change is a typed `Operation` with a known inverse. This is what\n * gives autogenerated, reversible `down()` and dialect-rendered DDL — never a\n * hand-written `.sql` blob (the anti-Drizzle core).\n */\n\nimport type { ColumnIR, NamedConstraint, TableIR } from \"./ir.js\";\n\n/** A single, reversible schema operation. */\nexport type Operation =\n | { readonly kind: \"create_table\"; readonly table: TableIR }\n | { readonly kind: \"drop_table\"; readonly table: TableIR }\n | { readonly kind: \"rename_table\"; readonly from: string; readonly to: string }\n | { readonly kind: \"add_column\"; readonly table: string; readonly column: ColumnIR }\n | { readonly kind: \"drop_column\"; readonly table: string; readonly column: ColumnIR }\n | {\n readonly kind: \"alter_column\";\n readonly table: string;\n readonly name: string;\n readonly from: ColumnIR;\n readonly to: ColumnIR;\n }\n | {\n readonly kind: \"rename_column\";\n readonly table: string;\n readonly from: string;\n readonly to: string;\n }\n | {\n // Rebuild a table from `from` to `to`. On SQLite this is the batch /\n // table-rebuild path (SQLite cannot ALTER COLUMN); on PostgreSQL it is\n // realized as per-column ALTER/ADD/DROP.\n readonly kind: \"recreate_table\";\n readonly from: TableIR;\n readonly to: TableIR;\n }\n | {\n // Add a table-level unique / foreign-key constraint. On SQLite this needs\n // a table-rebuild (recreate_table); PostgreSQL / MySQL use ALTER TABLE ADD.\n readonly kind: \"add_constraint\";\n readonly table: string;\n readonly constraint: NamedConstraint;\n }\n | {\n readonly kind: \"drop_constraint\";\n readonly table: string;\n readonly constraint: NamedConstraint;\n }\n | { readonly kind: \"execute\"; readonly up: string; readonly down: string | null };\n\n/** Raised when an operation has no safe inverse (e.g. a one-way `execute`). */\nexport class IrreversibleMigration extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"IrreversibleMigration\";\n }\n}\n\n/**\n * Compute the inverse of an operation, for autogenerated `down()`.\n *\n * @param op The forward operation.\n * @returns The operation that undoes it.\n * @throws IrreversibleMigration When `op` cannot be safely reversed.\n */\nexport function invert(op: Operation): Operation {\n switch (op.kind) {\n case \"create_table\":\n return { kind: \"drop_table\", table: op.table };\n case \"drop_table\":\n return { kind: \"create_table\", table: op.table };\n case \"rename_table\":\n return { kind: \"rename_table\", from: op.to, to: op.from };\n case \"add_column\":\n return { kind: \"drop_column\", table: op.table, column: op.column };\n case \"drop_column\":\n return { kind: \"add_column\", table: op.table, column: op.column };\n case \"alter_column\":\n return {\n kind: \"alter_column\",\n table: op.table,\n name: op.name,\n from: op.to,\n to: op.from,\n };\n case \"rename_column\":\n return { kind: \"rename_column\", table: op.table, from: op.to, to: op.from };\n case \"recreate_table\":\n return { kind: \"recreate_table\", from: op.to, to: op.from };\n case \"add_constraint\":\n return { kind: \"drop_constraint\", table: op.table, constraint: op.constraint };\n case \"drop_constraint\":\n return { kind: \"add_constraint\", table: op.table, constraint: op.constraint };\n case \"execute\":\n if (op.down === null) {\n throw new IrreversibleMigration(\"execute() operation has no down SQL\");\n }\n return { kind: \"execute\", up: op.down, down: op.up };\n }\n}\n\n/** Invert a list of operations: reverse order, each inverted. */\nexport function invertAll(ops: readonly Operation[]): Operation[] {\n return [...ops].reverse().map(invert);\n}\n","/**\n * tempest-db-js — Phase 6: migration autogeneration.\n *\n * Turns a diff's `Operation[]` into an editable TypeScript migration file with\n * `up()` and an autogenerated, inverted `down()`. Operations are embedded as\n * plain-data literals (they are JSON-serializable), so the file stays readable\n * and hand-editable — never an opaque `.sql` blob.\n */\n\nimport { type Operation, invertAll } from \"./operations.js\";\n\n/** Inputs for one generated migration file. */\nexport interface MigrationDraft {\n readonly revision: string;\n readonly downRevision: readonly string[];\n readonly label: string;\n readonly operations: readonly Operation[];\n}\n\n/** Serialize operations as an indented array literal for the generated file. */\nfunction renderOps(ops: readonly Operation[]): string {\n if (ops.length === 0) return \"[]\";\n const body = ops.map((op) => ` ${JSON.stringify(op)},`).join(\"\\n\");\n return `[\\n${body}\\n ]`;\n}\n\n/**\n * Render a migration file body as TypeScript source.\n *\n * The generated `down()` inverts `up()`; if any operation is irreversible, the\n * generation still succeeds but `down()` throws at run time with a clear message\n * (so reversibility is never silently broken).\n *\n * @param draft The revision id, parents, label, and forward operations.\n * @returns The migration file source.\n */\nexport function generateMigration(draft: MigrationDraft): string {\n let down: string;\n try {\n down = renderOps(invertAll(draft.operations));\n } catch (error) {\n down = `(() => { throw new Error(${JSON.stringify(\n `irreversible migration: ${(error as Error).message}`,\n )}); })()`;\n }\n\n return `import type { Migration, Op } from \"tempest-db-js/migrations\";\n\nexport const revision = ${JSON.stringify(draft.revision)};\nexport const downRevision: string[] = ${JSON.stringify(draft.downRevision)};\nexport const label = ${JSON.stringify(draft.label)};\n\nconst upOps = ${renderOps(draft.operations)};\n\nconst downOps = ${down};\n\nexport const up = (op: Op): void => {\n for (const operation of upOps) op.run(operation);\n};\n\nexport const down = (op: Op): void => {\n for (const operation of downOps) op.run(operation);\n};\n\nexport default { revision, downRevision, label, up, down } satisfies Migration;\n`;\n}\n\n/** Build a short, stable revision id from a label + parent set. */\nexport function makeRevisionId(label: string, parents: readonly string[]): string {\n // Deterministic non-crypto hash (FNV-1a) — no Date/Math.random (build-stable).\n let hash = 0x811c9dc5;\n for (const ch of `${label}|${[...parents].sort().join(\",\")}`) {\n hash ^= ch.charCodeAt(0);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","/**\n * tempest-db-js — Phase 6/9: DDL rendering.\n *\n * Renders the dialect-neutral IR + operations to concrete SQL per dialect. This\n * is the ONLY place migration SQL is produced — the same operation yields the\n * right DDL for SQLite, PostgreSQL or MySQL.\n */\n\nimport { renderPortableToken } from \"../expressions.js\";\nimport type { ColumnType, DefaultValue, FkAction } from \"../index.js\";\nimport type { Dialect } from \"../url.js\";\nimport type {\n ColumnIR,\n ForeignKeyIR,\n NamedConstraint,\n TableIR,\n UniqueConstraintIR,\n} from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\n\n/** Quote an identifier for the dialect (backticks on MySQL, double-quotes else). */\nfunction quoteId(name: string, dialect: Dialect): string {\n return dialect === \"mysql\"\n ? `\\`${name.replace(/`/g, \"``\")}\\``\n : `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction quoteLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\n/** Map a column type to its SQL type string for the dialect. */\nexport function renderColumnType(type: ColumnType, dialect: Dialect): string {\n const { kind, meta } = type;\n if (dialect === \"sqlite\") {\n switch (kind) {\n case \"smallint\":\n case \"integer\":\n case \"bigint\":\n case \"boolean\":\n return \"INTEGER\";\n case \"real\":\n case \"double\":\n return \"REAL\";\n case \"numeric\":\n return \"NUMERIC\";\n case \"blob\":\n return \"BLOB\";\n case \"array\":\n throw new Error(unsupportedArray(\"sqlite\"));\n default:\n return \"TEXT\"; // varchar/char/text/uuid/enum/json/date/time/datetime/timestamp\n }\n }\n if (dialect === \"mysql\") {\n switch (kind) {\n case \"smallint\":\n return \"SMALLINT\";\n case \"integer\":\n return \"INT\";\n case \"bigint\":\n return \"BIGINT\";\n case \"numeric\":\n return meta.precision !== undefined\n ? `DECIMAL(${meta.precision}${meta.scale !== undefined ? `, ${meta.scale}` : \"\"})`\n : \"DECIMAL\";\n case \"real\":\n return \"FLOAT\";\n case \"double\":\n return \"DOUBLE\";\n case \"varchar\":\n return `VARCHAR(${meta.length ?? 255})`;\n case \"char\":\n return `CHAR(${meta.length ?? 255})`;\n case \"text\":\n return \"TEXT\";\n case \"boolean\":\n return \"TINYINT(1)\";\n case \"date\":\n return \"DATE\";\n case \"time\":\n return \"TIME\";\n case \"datetime\":\n case \"timestamp\":\n return \"DATETIME\";\n case \"blob\":\n return \"BLOB\";\n case \"json\":\n return \"JSON\";\n case \"uuid\":\n return \"CHAR(36)\";\n case \"enum\":\n return `ENUM(${(meta.values ?? []).map(quoteLiteral).join(\", \")})`;\n case \"array\":\n throw new Error(unsupportedArray(\"mysql\"));\n }\n }\n // PostgreSQL\n switch (kind) {\n case \"smallint\":\n return \"SMALLINT\";\n case \"integer\":\n return \"INTEGER\";\n case \"bigint\":\n return \"BIGINT\";\n case \"numeric\":\n return meta.precision !== undefined\n ? `NUMERIC(${meta.precision}${meta.scale !== undefined ? `, ${meta.scale}` : \"\"})`\n : \"NUMERIC\";\n case \"real\":\n return \"REAL\";\n case \"double\":\n return \"DOUBLE PRECISION\";\n case \"varchar\":\n return meta.length !== undefined ? `VARCHAR(${meta.length})` : \"VARCHAR\";\n case \"char\":\n return meta.length !== undefined ? `CHAR(${meta.length})` : \"CHAR\";\n case \"text\":\n return \"TEXT\";\n case \"boolean\":\n return \"BOOLEAN\";\n case \"date\":\n return \"DATE\";\n case \"time\":\n return meta.withTimezone ? \"TIME WITH TIME ZONE\" : \"TIME\";\n case \"datetime\":\n case \"timestamp\":\n return meta.withTimezone ? \"TIMESTAMP WITH TIME ZONE\" : \"TIMESTAMP\";\n case \"blob\":\n return \"BYTEA\";\n case \"json\":\n return meta.jsonb ? \"JSONB\" : \"JSON\";\n case \"uuid\":\n return \"UUID\";\n case \"enum\":\n // Named PG enum types are handled in renderCreateTable; fall back to TEXT.\n return \"TEXT\";\n case \"array\":\n return `${renderColumnType(arrayElement(meta.element), dialect)}[]`;\n }\n}\n\n/** The message for an array column on a dialect without native arrays. */\nfunction unsupportedArray(dialect: Dialect): string {\n return `column.array() is PostgreSQL-only — ${dialect} has no native array type. Model the column as JSON there, accepting that array operators will not work.`;\n}\n\n/** The element type of an array column, or a hard error when it is missing. */\nfunction arrayElement(element: ColumnType | undefined): ColumnType {\n if (!element) {\n throw new Error(\n \"An array column has no element type — build it with column.array().\",\n );\n }\n return element;\n}\n\n/** Render a default value into a SQL `DEFAULT` expression for the dialect. */\nexport function renderDefault(\n def: DefaultValue,\n dialect: Dialect,\n type?: ColumnType,\n): string {\n if (def.kind === \"expression\") {\n const expr = def.expression;\n if (typeof expr === \"object\") {\n if (\"raw\" in expr) return expr.raw;\n throw new Error(\n \"sql.expr`...` binds parameters and cannot be rendered as a DEFAULT — use sql.raw().\",\n );\n }\n return renderPortableToken(expr, dialect);\n }\n const value = def.value;\n if (value === null) return \"NULL\";\n if (Array.isArray(value) && type?.kind === \"array\") {\n const elementType = renderColumnType(arrayElement(type.meta.element), dialect);\n const items = value.map((v) => renderDefault({ kind: \"literal\", value: v }, dialect));\n return `ARRAY[${items.join(\", \")}]::${elementType}[]`;\n }\n if (typeof value === \"boolean\") {\n return dialect === \"postgresql\" ? (value ? \"TRUE\" : \"FALSE\") : value ? \"1\" : \"0\";\n }\n if (typeof value === \"number\" || typeof value === \"bigint\") return String(value);\n if (value instanceof Date) return quoteLiteral(value.toISOString());\n if (typeof value === \"object\") return quoteLiteral(JSON.stringify(value));\n return quoteLiteral(String(value));\n}\n\n/** Render a referential action for an `ON DELETE` / `ON UPDATE` clause. */\nfunction renderFkAction(action: FkAction): string {\n return action.toUpperCase();\n}\n\n/** Render the `[ON DELETE ..] [ON UPDATE ..]` tail shared by inline + table FKs. */\nfunction renderFkActions(fk: {\n onDelete?: FkAction | undefined;\n onUpdate?: FkAction | undefined;\n}): string {\n let sql = \"\";\n if (fk.onDelete) sql += ` ON DELETE ${renderFkAction(fk.onDelete)}`;\n if (fk.onUpdate) sql += ` ON UPDATE ${renderFkAction(fk.onUpdate)}`;\n return sql;\n}\n\n/**\n * The column-level constraint suffix: ` UNIQUE` and/or an inline\n * ` REFERENCES \"table\" (\"column\") [ON DELETE ..] [ON UPDATE ..]`. Appended to\n * every rendered column definition (including the enum/serial branches).\n */\nfunction columnConstraintSuffix(col: ColumnIR, dialect: Dialect): string {\n let sql = \"\";\n if (col.unique) sql += \" UNIQUE\";\n if (col.references) {\n const ref = col.references;\n sql += ` REFERENCES ${quoteId(ref.table, dialect)} (${quoteId(ref.column, dialect)})`;\n sql += renderFkActions(ref);\n }\n return sql;\n}\n\n/** Render a table-level `CONSTRAINT \"name\" UNIQUE (...)` clause. */\nfunction renderUniqueConstraint(uc: UniqueConstraintIR, dialect: Dialect): string {\n const cols = uc.columns.map((c) => quoteId(c, dialect)).join(\", \");\n return `CONSTRAINT ${quoteId(uc.name, dialect)} UNIQUE (${cols})`;\n}\n\n/** Render a table-level `CONSTRAINT \"name\" FOREIGN KEY (...) REFERENCES ...` clause. */\nfunction renderForeignKeyConstraint(fk: ForeignKeyIR, dialect: Dialect): string {\n const cols = fk.columns.map((c) => quoteId(c, dialect)).join(\", \");\n const refCols = fk.refColumns.map((c) => quoteId(c, dialect)).join(\", \");\n return (\n `CONSTRAINT ${quoteId(fk.name, dialect)} FOREIGN KEY (${cols}) ` +\n `REFERENCES ${quoteId(fk.refTable, dialect)} (${refCols})${renderFkActions(fk)}`\n );\n}\n\n/** The table-level constraint clauses (unique + foreign key) for a table. */\nfunction tableConstraintClauses(table: TableIR, dialect: Dialect): string[] {\n return [\n ...table.uniqueConstraints.map((uc) => renderUniqueConstraint(uc, dialect)),\n ...table.foreignKeys.map((fk) => renderForeignKeyConstraint(fk, dialect)),\n ];\n}\n\n/**\n * Render one column definition: `\"name\" TYPE [NOT NULL] [DEFAULT x] [UNIQUE]\n * [REFERENCES ...]`.\n */\nexport function renderColumnDef(col: ColumnIR, dialect: Dialect): string {\n let sql = `${quoteId(col.name, dialect)} ${renderColumnType(col.type, dialect)}`;\n if (col.notNull) sql += \" NOT NULL\";\n if (col.default !== null) {\n sql += ` DEFAULT ${renderDefault(col.default, dialect, col.type)}`;\n }\n sql += columnConstraintSuffix(col, dialect);\n return sql;\n}\n\n/** The PostgreSQL named-enum type for a column (`<table>_<column>`). */\nfunction enumTypeName(table: string, column: string): string {\n return `${table}_${column}`;\n}\n\n/** True when a column is the sole integer-family PK with no explicit default. */\nfunction isAutoIncrementPk(table: TableIR, col: ColumnIR): boolean {\n return (\n table.primaryKey.length === 1 &&\n table.primaryKey[0] === col.name &&\n col.default === null &&\n (col.type.kind === \"smallint\" ||\n col.type.kind === \"integer\" ||\n col.type.kind === \"bigint\")\n );\n}\n\n/** The PostgreSQL auto-incrementing serial type for an integer-family kind. */\nfunction postgresSerialType(kind: ColumnType[\"kind\"]): string {\n if (kind === \"bigint\") return \"BIGSERIAL\";\n if (kind === \"smallint\") return \"SMALLSERIAL\";\n return \"SERIAL\";\n}\n\n/**\n * Render a CREATE TABLE (plus, on PostgreSQL, any `CREATE TYPE ... AS ENUM` for\n * enum columns, which must precede the table). Returns the statement list.\n *\n * Auto-increment for a lone integer-family primary key (SQLAlchemy semantics):\n * - SQLite: free via `INTEGER PRIMARY KEY` (rowid alias).\n * - PostgreSQL: `SERIAL`/`BIGSERIAL`.\n * - MySQL: `AUTO_INCREMENT` on the column (which must also be a key).\n */\nfunction renderCreateTable(table: TableIR, dialect: Dialect): string[] {\n const typeStmts: string[] = [];\n const cols = Object.values(table.columns).map((c) => {\n if (dialect === \"postgresql\" && c.type.kind === \"enum\") {\n const typeName = enumTypeName(table.name, c.name);\n const values = (c.type.meta.values ?? []).map(quoteLiteral).join(\", \");\n typeStmts.push(`CREATE TYPE ${quoteId(typeName, dialect)} AS ENUM (${values})`);\n let def = `${quoteId(c.name, dialect)} ${quoteId(typeName, dialect)}`;\n if (c.notNull) def += \" NOT NULL\";\n if (c.default !== null) {\n def += ` DEFAULT ${renderDefault(c.default, dialect, c.type)}`;\n }\n return def + columnConstraintSuffix(c, dialect);\n }\n if (dialect === \"postgresql\" && isAutoIncrementPk(table, c)) {\n return `${quoteId(c.name, dialect)} ${postgresSerialType(c.type.kind)}${columnConstraintSuffix(c, dialect)}`;\n }\n if (dialect === \"mysql\" && isAutoIncrementPk(table, c)) {\n return `${quoteId(c.name, dialect)} ${renderColumnType(c.type, dialect)} NOT NULL AUTO_INCREMENT${columnConstraintSuffix(c, dialect)}`;\n }\n return renderColumnDef(c, dialect);\n });\n if (table.primaryKey.length > 0) {\n cols.push(\n `PRIMARY KEY (${table.primaryKey.map((c) => quoteId(c, dialect)).join(\", \")})`,\n );\n }\n cols.push(...tableConstraintClauses(table, dialect));\n return [\n ...typeStmts,\n `CREATE TABLE ${quoteId(table.name, dialect)} (\\n ${cols.join(\",\\n \")}\\n)`,\n ];\n}\n\n/**\n * Render an operation to one or more SQL statements for the dialect.\n *\n * @param op The operation.\n * @param dialect The target dialect.\n * @returns The SQL statements (usually one).\n * @throws Error When the operation is unsupported on the dialect (e.g. SQLite\n * `alter_column`, which needs the table-rebuild path).\n */\nexport function renderOperation(op: Operation, dialect: Dialect): string[] {\n switch (op.kind) {\n case \"create_table\":\n return renderCreateTable(op.table, dialect);\n case \"drop_table\":\n return [`DROP TABLE ${quoteId(op.table.name, dialect)}`];\n case \"rename_table\":\n return dialect === \"mysql\"\n ? [`RENAME TABLE ${quoteId(op.from, dialect)} TO ${quoteId(op.to, dialect)}`]\n : [\n `ALTER TABLE ${quoteId(op.from, dialect)} RENAME TO ${quoteId(op.to, dialect)}`,\n ];\n case \"add_column\":\n return [\n `ALTER TABLE ${quoteId(op.table, dialect)} ADD COLUMN ${renderColumnDef(op.column, dialect)}`,\n ];\n case \"drop_column\":\n return [\n `ALTER TABLE ${quoteId(op.table, dialect)} DROP COLUMN ${quoteId(op.column.name, dialect)}`,\n ];\n case \"rename_column\":\n return [\n `ALTER TABLE ${quoteId(op.table, dialect)} RENAME COLUMN ${quoteId(op.from, dialect)} TO ${quoteId(op.to, dialect)}`,\n ];\n case \"alter_column\":\n return renderAlterColumn(op.table, op.to, dialect);\n case \"recreate_table\":\n return dialect === \"sqlite\"\n ? renderSqliteRebuild(op.from, op.to)\n : renderTableDiff(op.from, op.to, dialect);\n case \"add_constraint\":\n return renderAddConstraint(op.table, op.constraint, dialect);\n case \"drop_constraint\":\n return renderDropConstraint(op.table, op.constraint, dialect);\n case \"execute\":\n return [op.up];\n }\n}\n\n/**\n * Render an `ALTER TABLE ... ADD CONSTRAINT`. SQLite cannot add constraints in\n * place — it needs a table-rebuild (`recreate_table`), so this throws there.\n */\nfunction renderAddConstraint(\n table: string,\n constraint: NamedConstraint,\n dialect: Dialect,\n): string[] {\n if (dialect === \"sqlite\") {\n throw new Error(\n `add_constraint on SQLite needs a table-rebuild (recreate_table); constraint ${constraint.constraint.name} on ${table}`,\n );\n }\n const clause =\n constraint.type === \"unique\"\n ? renderUniqueConstraint(constraint.constraint, dialect)\n : renderForeignKeyConstraint(constraint.constraint, dialect);\n return [`ALTER TABLE ${quoteId(table, dialect)} ADD ${clause}`];\n}\n\n/**\n * Render an `ALTER TABLE ... DROP CONSTRAINT`. PostgreSQL uses the generic\n * `DROP CONSTRAINT`; MySQL uses `DROP INDEX` (unique) / `DROP FOREIGN KEY` (fk).\n * SQLite needs a table-rebuild, so this throws there.\n */\nfunction renderDropConstraint(\n table: string,\n constraint: NamedConstraint,\n dialect: Dialect,\n): string[] {\n if (dialect === \"sqlite\") {\n throw new Error(\n `drop_constraint on SQLite needs a table-rebuild (recreate_table); constraint ${constraint.constraint.name} on ${table}`,\n );\n }\n const t = quoteId(table, dialect);\n const name = quoteId(constraint.constraint.name, dialect);\n if (dialect === \"mysql\") {\n return [\n constraint.type === \"unique\"\n ? `ALTER TABLE ${t} DROP INDEX ${name}`\n : `ALTER TABLE ${t} DROP FOREIGN KEY ${name}`,\n ];\n }\n return [`ALTER TABLE ${t} DROP CONSTRAINT ${name}`];\n}\n\n/**\n * SQLite batch / table-rebuild: create a new table with the target schema, copy\n * the columns common to both, swap names. This is how SQLite realizes column\n * changes it cannot `ALTER` (drop/alter type/constraint changes).\n */\nfunction renderSqliteRebuild(from: TableIR, to: TableIR): string[] {\n const tmp = `__new_${to.name}`;\n const common = Object.keys(to.columns).filter((c) => c in from.columns);\n const cols = Object.values(to.columns).map((c) => renderColumnDef(c, \"sqlite\"));\n if (to.primaryKey.length > 0) {\n cols.push(\n `PRIMARY KEY (${to.primaryKey.map((c) => quoteId(c, \"sqlite\")).join(\", \")})`,\n );\n }\n cols.push(...tableConstraintClauses(to, \"sqlite\"));\n const commonSql = common.map((c) => quoteId(c, \"sqlite\")).join(\", \");\n return [\n \"PRAGMA foreign_keys=off\",\n `CREATE TABLE ${quoteId(tmp, \"sqlite\")} (\\n ${cols.join(\",\\n \")}\\n)`,\n common.length > 0\n ? `INSERT INTO ${quoteId(tmp, \"sqlite\")} (${commonSql}) SELECT ${commonSql} FROM ${quoteId(from.name, \"sqlite\")}`\n : `-- no common columns to copy from ${from.name}`,\n `DROP TABLE ${quoteId(from.name, \"sqlite\")}`,\n `ALTER TABLE ${quoteId(tmp, \"sqlite\")} RENAME TO ${quoteId(to.name, \"sqlite\")}`,\n \"PRAGMA foreign_keys=on\",\n ];\n}\n\n/** PostgreSQL/MySQL realize a table recreate as per-column ADD/DROP/ALTER. */\nfunction renderTableDiff(from: TableIR, to: TableIR, dialect: Dialect): string[] {\n const stmts: string[] = [];\n for (const [name, col] of Object.entries(to.columns)) {\n if (!(name in from.columns)) {\n stmts.push(\n `ALTER TABLE ${quoteId(to.name, dialect)} ADD COLUMN ${renderColumnDef(col, dialect)}`,\n );\n } else {\n stmts.push(...renderAlterColumn(to.name, col, dialect));\n }\n }\n for (const name of Object.keys(from.columns)) {\n if (!(name in to.columns)) {\n stmts.push(\n `ALTER TABLE ${quoteId(to.name, dialect)} DROP COLUMN ${quoteId(name, dialect)}`,\n );\n }\n }\n return stmts;\n}\n\n/**\n * Render an ALTER COLUMN. SQLite needs table-rebuild (unsupported here); MySQL\n * uses a single `MODIFY COLUMN` (type + NOT NULL + DEFAULT together); PostgreSQL\n * uses separate `ALTER COLUMN ... TYPE / SET|DROP NOT NULL / SET|DROP DEFAULT`.\n */\nfunction renderAlterColumn(table: string, to: ColumnIR, dialect: Dialect): string[] {\n if (dialect === \"sqlite\") {\n throw new Error(\n `alter_column on SQLite needs a table-rebuild (recreate_table); column ${table}.${to.name}`,\n );\n }\n if (dialect === \"mysql\") {\n return [\n `ALTER TABLE ${quoteId(table, dialect)} MODIFY COLUMN ${renderColumnDef(to, dialect)}`,\n ];\n }\n const t = quoteId(table, dialect);\n const c = quoteId(to.name, dialect);\n const stmts = [\n `ALTER TABLE ${t} ALTER COLUMN ${c} TYPE ${renderColumnType(to.type, dialect)}`,\n ];\n stmts.push(\n to.notNull\n ? `ALTER TABLE ${t} ALTER COLUMN ${c} SET NOT NULL`\n : `ALTER TABLE ${t} ALTER COLUMN ${c} DROP NOT NULL`,\n );\n stmts.push(\n to.default !== null\n ? `ALTER TABLE ${t} ALTER COLUMN ${c} SET DEFAULT ${renderDefault(to.default, dialect, to.type)}`\n : `ALTER TABLE ${t} ALTER COLUMN ${c} DROP DEFAULT`,\n );\n return stmts;\n}\n","/**\n * tempest-db-js — Phase 6: the schema differ.\n *\n * Compares two `SchemaIR`s (current vs target) and emits the typed `Operation[]`\n * that turns one into the other. Purely structural — no SQL, no DB.\n */\n\nimport type {\n ColumnIR,\n ForeignKeyIR,\n NamedConstraint,\n SchemaIR,\n TableIR,\n UniqueConstraintIR,\n} from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\n\n/** Stable structural identity of a column, for change detection. */\nfunction columnSignature(col: ColumnIR): string {\n return JSON.stringify({\n type: col.type,\n notNull: col.notNull,\n primaryKey: col.primaryKey,\n default: col.default,\n unique: col.unique,\n references: col.references,\n });\n}\n\n/** Stable structural identity of a table-level constraint (name excluded). */\nfunction uniqueSignature(uc: UniqueConstraintIR): string {\n return JSON.stringify({ columns: uc.columns });\n}\n\nfunction foreignKeySignature(fk: ForeignKeyIR): string {\n return JSON.stringify({\n columns: fk.columns,\n refTable: fk.refTable,\n refColumns: fk.refColumns,\n onDelete: fk.onDelete ?? null,\n onUpdate: fk.onUpdate ?? null,\n });\n}\n\n/**\n * Diff the table-level constraints of an existing table, keyed by name. Emits\n * `drop_constraint` for removed/changed and `add_constraint` for added/changed.\n */\nfunction diffConstraints(current: TableIR, target: TableIR): Operation[] {\n const ops: Operation[] = [];\n const table = target.name;\n\n const currentUq = new Map(current.uniqueConstraints.map((u) => [u.name, u]));\n const targetUq = new Map(target.uniqueConstraints.map((u) => [u.name, u]));\n for (const [name, cur] of currentUq) {\n const tgt = targetUq.get(name);\n if (!tgt || uniqueSignature(cur) !== uniqueSignature(tgt)) {\n ops.push(dropUnique(table, cur));\n }\n }\n for (const [name, tgt] of targetUq) {\n const cur = currentUq.get(name);\n if (!cur || uniqueSignature(cur) !== uniqueSignature(tgt)) {\n ops.push(addUnique(table, tgt));\n }\n }\n\n const currentFk = new Map(current.foreignKeys.map((f) => [f.name, f]));\n const targetFk = new Map(target.foreignKeys.map((f) => [f.name, f]));\n for (const [name, cur] of currentFk) {\n const tgt = targetFk.get(name);\n if (!tgt || foreignKeySignature(cur) !== foreignKeySignature(tgt)) {\n ops.push(dropForeignKey(table, cur));\n }\n }\n for (const [name, tgt] of targetFk) {\n const cur = currentFk.get(name);\n if (!cur || foreignKeySignature(cur) !== foreignKeySignature(tgt)) {\n ops.push(addForeignKey(table, tgt));\n }\n }\n\n return ops;\n}\n\nfunction uniqueNamed(uc: UniqueConstraintIR): NamedConstraint {\n return { type: \"unique\", constraint: uc };\n}\nfunction foreignKeyNamed(fk: ForeignKeyIR): NamedConstraint {\n return { type: \"foreignKey\", constraint: fk };\n}\nfunction addUnique(table: string, uc: UniqueConstraintIR): Operation {\n return { kind: \"add_constraint\", table, constraint: uniqueNamed(uc) };\n}\nfunction dropUnique(table: string, uc: UniqueConstraintIR): Operation {\n return { kind: \"drop_constraint\", table, constraint: uniqueNamed(uc) };\n}\nfunction addForeignKey(table: string, fk: ForeignKeyIR): Operation {\n return { kind: \"add_constraint\", table, constraint: foreignKeyNamed(fk) };\n}\nfunction dropForeignKey(table: string, fk: ForeignKeyIR): Operation {\n return { kind: \"drop_constraint\", table, constraint: foreignKeyNamed(fk) };\n}\n\n/**\n * Diff `current` → `target`, returning the operations to migrate forward.\n *\n * Order: create new tables, then per-table column adds/alters/drops, then drop\n * removed tables last (so nothing depends on a table being dropped first).\n *\n * @param current The current schema (e.g. from migration replay).\n * @param target The desired schema (e.g. from model reflection).\n * @returns The forward operations.\n */\nexport function diffSchema(current: SchemaIR, target: SchemaIR): Operation[] {\n const ops: Operation[] = [];\n const drops: Operation[] = [];\n\n for (const [name, targetTable] of Object.entries(target.tables)) {\n const currentTable = current.tables[name];\n if (!currentTable) {\n ops.push({ kind: \"create_table\", table: targetTable });\n continue;\n }\n // existing table → diff columns\n for (const [colName, targetCol] of Object.entries(targetTable.columns)) {\n const currentCol = currentTable.columns[colName];\n if (!currentCol) {\n ops.push({ kind: \"add_column\", table: name, column: targetCol });\n } else if (columnSignature(currentCol) !== columnSignature(targetCol)) {\n ops.push({\n kind: \"alter_column\",\n table: name,\n name: colName,\n from: currentCol,\n to: targetCol,\n });\n }\n }\n for (const [colName, currentCol] of Object.entries(currentTable.columns)) {\n if (!targetTable.columns[colName]) {\n ops.push({ kind: \"drop_column\", table: name, column: currentCol });\n }\n }\n ops.push(...diffConstraints(currentTable, targetTable));\n }\n\n for (const [name, currentTable] of Object.entries(current.tables)) {\n if (!target.tables[name]) {\n drops.push({ kind: \"drop_table\", table: currentTable });\n }\n }\n\n return [...ops, ...drops];\n}\n","/**\n * tempest-db-js — Phase 6: the revision DAG.\n *\n * Migrations form a directed acyclic graph via `downRevision` (a list of parents,\n * so branches and merges are first-class). This module orders them for applying\n * (topological, deterministic) and finds heads.\n */\n\n/** The minimal graph shape a migration must expose. */\nexport interface RevisionNode {\n readonly revision: string;\n readonly downRevision: readonly string[];\n}\n\n/** Raised when the revision graph contains a cycle. */\nexport class CyclicMigrationGraph extends Error {\n constructor(remaining: readonly string[]) {\n super(`migration graph has a cycle among: ${remaining.join(\", \")}`);\n this.name = \"CyclicMigrationGraph\";\n }\n}\n\n/** Raised when a `downRevision` points at a revision that does not exist. */\nexport class UnknownRevision extends Error {\n constructor(revision: string, parent: string) {\n super(`revision ${revision} references unknown parent ${parent}`);\n this.name = \"UnknownRevision\";\n }\n}\n\n/**\n * Topologically order migrations so every parent precedes its children. Ties are\n * broken by revision id for reproducible builds. Throws on cycles or dangling\n * parents.\n *\n * @param migrations The migrations to order.\n * @returns The migrations in apply order.\n */\nexport function topoOrder<T extends RevisionNode>(migrations: readonly T[]): T[] {\n const byId = new Map<string, T>();\n for (const m of migrations) byId.set(m.revision, m);\n\n const indegree = new Map<string, number>();\n const children = new Map<string, string[]>();\n for (const m of migrations) {\n indegree.set(m.revision, m.downRevision.length);\n for (const parent of m.downRevision) {\n if (!byId.has(parent)) throw new UnknownRevision(m.revision, parent);\n const list = children.get(parent) ?? [];\n list.push(m.revision);\n children.set(parent, list);\n }\n }\n\n // roots: indegree 0, sorted for determinism\n const ready = migrations\n .filter((m) => (indegree.get(m.revision) ?? 0) === 0)\n .map((m) => m.revision)\n .sort();\n\n const ordered: T[] = [];\n while (ready.length > 0) {\n const id = ready.shift() as string;\n ordered.push(byId.get(id) as T);\n const next = (children.get(id) ?? []).sort();\n for (const child of next) {\n const deg = (indegree.get(child) ?? 0) - 1;\n indegree.set(child, deg);\n if (deg === 0) {\n ready.push(child);\n ready.sort();\n }\n }\n }\n\n if (ordered.length !== migrations.length) {\n const remaining = migrations\n .map((m) => m.revision)\n .filter((r) => !ordered.some((o) => o.revision === r));\n throw new CyclicMigrationGraph(remaining);\n }\n return ordered;\n}\n\n/** Revisions that are nobody's parent — the current head(s) of the graph. */\nexport function heads<T extends RevisionNode>(migrations: readonly T[]): string[] {\n const parents = new Set<string>();\n for (const m of migrations) for (const p of m.downRevision) parents.add(p);\n return migrations\n .map((m) => m.revision)\n .filter((r) => !parents.has(r))\n .sort();\n}\n","/**\n * tempest-db-js — Phase 6: the Schema IR (intermediate representation).\n *\n * A canonical, dialect-neutral description of a database schema. Every source of\n * truth — model reflection (here), migration replay, or DB introspection —\n * produces the SAME `SchemaIR`, so the differ compares like with like and SQL is\n * only ever emitted at the dialect edge (the anti-\"SQL-stitching\" core).\n */\n\nimport {\n type ColumnType,\n type DefaultValue,\n type FkAction,\n type ForeignKeyRef,\n type ModelClass,\n columnNamesOf,\n columnsOf,\n} from \"../index.js\";\n\n/** A column's default in the IR. */\nexport type DefaultIR = DefaultValue | null;\n\n/** One column. */\nexport interface ColumnIR {\n readonly name: string;\n readonly type: ColumnType;\n readonly notNull: boolean;\n readonly primaryKey: boolean;\n readonly default: DefaultIR;\n /** A column-level `UNIQUE` constraint. */\n readonly unique: boolean;\n /** A column-level foreign-key reference, or `null` for none. */\n readonly references: ForeignKeyRef | null;\n}\n\n/** A (composite) `UNIQUE` table constraint in the IR. */\nexport interface UniqueConstraintIR {\n readonly name: string;\n readonly columns: readonly string[];\n}\n\n/** A (composite) foreign-key table constraint in the IR. */\nexport interface ForeignKeyIR {\n readonly name: string;\n readonly columns: readonly string[];\n readonly refTable: string;\n readonly refColumns: readonly string[];\n readonly onDelete?: FkAction | undefined;\n readonly onUpdate?: FkAction | undefined;\n}\n\n/**\n * A named table-level constraint, tagged by kind. Carried whole by the\n * `add_constraint` / `drop_constraint` operations so each is reversible.\n */\nexport type NamedConstraint =\n | { readonly type: \"unique\"; readonly constraint: UniqueConstraintIR }\n | { readonly type: \"foreignKey\"; readonly constraint: ForeignKeyIR };\n\n/** One table. */\nexport interface TableIR {\n readonly name: string;\n readonly columns: Record<string, ColumnIR>;\n /** Primary-key column names (composite = more than one). */\n readonly primaryKey: readonly string[];\n /** Table-level unique constraints (from `tableArgs`). */\n readonly uniqueConstraints: readonly UniqueConstraintIR[];\n /** Table-level foreign-key constraints (from `tableArgs`). */\n readonly foreignKeys: readonly ForeignKeyIR[];\n}\n\n/** A whole schema, keyed by table name. */\nexport interface SchemaIR {\n readonly tables: Record<string, TableIR>;\n}\n\n/** Deterministic constraint name when the user did not supply one. */\nfunction constraintName(\n prefix: \"uq\" | \"fk\",\n table: string,\n columns: readonly string[],\n): string {\n return `${prefix}_${table}_${columns.join(\"_\")}`;\n}\n\n/**\n * Reflect one model class into a `TableIR`.\n *\n * The IR is keyed by **database** column names, so a model that maps\n * `consumerName` to `consumer_name` produces the same IR that introspecting the\n * live database does — otherwise the drift check would report every renamed\n * column as missing.\n *\n * @param model The model class.\n * @returns The table IR in database-name space.\n */\nexport function reflectTable(model: ModelClass): TableIR {\n const names = columnNamesOf(model);\n const toColumn = (prop: string): string => names?.[prop] ?? prop;\n const columns: Record<string, ColumnIR> = {};\n const primaryKey: string[] = [];\n for (const [prop, col] of Object.entries(columnsOf(model))) {\n const isPk = col.flags.primaryKey;\n const name = toColumn(prop);\n columns[name] = {\n name,\n type: col.type,\n notNull: col.flags.notNull || isPk,\n primaryKey: isPk,\n default: col.defaultValue,\n unique: col.flags.unique,\n references: col.reference,\n };\n if (isPk) primaryKey.push(name);\n }\n\n const uniqueConstraints: UniqueConstraintIR[] = [];\n const foreignKeys: ForeignKeyIR[] = [];\n for (const c of model.tableArgs?.() ?? []) {\n const cols = c.columns.map(toColumn);\n if (c.kind === \"unique\") {\n uniqueConstraints.push({\n name: c.name ?? constraintName(\"uq\", model.tablename, cols),\n columns: cols,\n });\n } else {\n foreignKeys.push({\n name: c.name ?? constraintName(\"fk\", model.tablename, cols),\n columns: cols,\n refTable: c.refTable,\n refColumns: c.refColumns,\n onDelete: c.onDelete,\n onUpdate: c.onUpdate,\n });\n }\n }\n\n return { name: model.tablename, columns, primaryKey, uniqueConstraints, foreignKeys };\n}\n\n/**\n * Reflect a set of model classes into a `SchemaIR`. This is the **target** state\n * the differ compares the current (replayed) schema against.\n *\n * @param models The model classes that make up the schema.\n * @returns The reflected schema IR.\n */\nexport function reflectSchema(models: readonly ModelClass[]): SchemaIR {\n const tables: Record<string, TableIR> = {};\n for (const model of models) {\n const table = reflectTable(model);\n tables[table.name] = table;\n }\n return { tables };\n}\n\n/** An empty schema (the baseline before any migration). */\nexport function emptySchema(): SchemaIR {\n return { tables: {} };\n}\n","/**\n * tempest-db-js — Phase 6d: SQLite introspection + drift detection.\n *\n * Reads the live schema from a SQLite database (via `PRAGMA table_info`) into a\n * `SchemaIR`, and compares it against the models to detect **drift** — the DB\n * diverging from what the migrations/models say it should be. Comparison is done\n * at SQLite's storage-affinity level, so coarse SQLite typing (every string is\n * `TEXT`) does not produce false positives.\n */\n\nimport type { AsyncDriver, SyncDriver } from \"../engine.js\";\nimport type { ColumnType } from \"../index.js\";\nimport type { ModelClass } from \"../index.js\";\nimport type { Dialect } from \"../url.js\";\nimport { renderColumnType } from \"./ddl.js\";\nimport {\n type ColumnIR,\n type ForeignKeyIR,\n type SchemaIR,\n type TableIR,\n type UniqueConstraintIR,\n reflectSchema,\n} from \"./ir.js\";\n\n/** SQLite's five storage classes / affinities. */\nexport type SqliteAffinity = \"INTEGER\" | \"TEXT\" | \"REAL\" | \"BLOB\" | \"NUMERIC\";\n\n/** Apply SQLite's affinity rules to a declared type string. */\nexport function sqliteAffinity(declared: string): SqliteAffinity {\n const t = declared.toUpperCase();\n if (t.includes(\"INT\")) return \"INTEGER\";\n if (t.includes(\"CHAR\") || t.includes(\"CLOB\") || t.includes(\"TEXT\")) return \"TEXT\";\n if (t.includes(\"BLOB\") || t === \"\") return \"BLOB\";\n if (t.includes(\"REAL\") || t.includes(\"FLOA\") || t.includes(\"DOUB\")) return \"REAL\";\n return \"NUMERIC\";\n}\n\n/** Map a SQLite affinity back to the closest IR column kind. */\nfunction affinityToKind(affinity: SqliteAffinity): ColumnType[\"kind\"] {\n switch (affinity) {\n case \"INTEGER\":\n return \"integer\";\n case \"REAL\":\n return \"real\";\n case \"BLOB\":\n return \"blob\";\n case \"NUMERIC\":\n return \"numeric\";\n default:\n return \"text\";\n }\n}\n\ninterface PragmaColumn {\n name: string;\n type: string;\n notnull: number;\n pk: number;\n}\n\ninterface PragmaForeignKey {\n id: number;\n seq: number;\n table: string;\n from: string;\n to: string;\n on_update: string;\n on_delete: string;\n}\n\ninterface PragmaIndex {\n seq: number;\n name: string;\n unique: number;\n origin: string;\n}\n\ninterface PragmaIndexColumn {\n seqno: number;\n cid: number;\n name: string;\n}\n\n/** Read a table's foreign keys via `PRAGMA foreign_key_list`, grouped by id. */\nfunction sqliteForeignKeys(driver: SyncDriver, table: string): ForeignKeyIR[] {\n const rows = driver.execute(`PRAGMA foreign_key_list(${JSON.stringify(table)})`, [])\n .rows as unknown as PragmaForeignKey[];\n return sqliteForeignKeysFromPragma(table, rows);\n}\n\n/** Read a table's unique constraints via `PRAGMA index_list`/`index_info`. */\nfunction sqliteUniques(driver: SyncDriver, table: string): UniqueConstraintIR[] {\n const indexes = driver.execute(`PRAGMA index_list(${JSON.stringify(table)})`, [])\n .rows as unknown as PragmaIndex[];\n const uniques: UniqueConstraintIR[] = [];\n for (const idx of indexes) {\n if (!isUniqueIndex(idx)) continue;\n const cols = driver.execute(`PRAGMA index_info(${JSON.stringify(idx.name)})`, [])\n .rows as unknown as PragmaIndexColumn[];\n const unique = sqliteUniqueFromPragma(table, cols);\n if (unique) uniques.push(unique);\n }\n return uniques;\n}\n\n/**\n * Read the current SQLite schema into a `SchemaIR`. Lossy by nature (SQLite\n * collapses types into affinities), so types come back as the affinity's kind.\n *\n * @param driver A sync SQLite driver.\n * @returns The introspected schema.\n */\nexport function introspectSqlite(driver: SyncDriver): SchemaIR {\n const tablesRows = driver.execute(SQLITE_TABLES_SQL, []).rows;\n const tables: Record<string, TableIR> = {};\n for (const row of tablesRows) {\n const tableName = String(row.name);\n const info = driver.execute(`PRAGMA table_info(${JSON.stringify(tableName)})`, [])\n .rows as unknown as PragmaColumn[];\n const { columns, primaryKey } = sqliteColumnsFromPragma(info);\n tables[tableName] = {\n name: tableName,\n columns,\n primaryKey,\n uniqueConstraints: sqliteUniques(driver, tableName),\n foreignKeys: sqliteForeignKeys(driver, tableName),\n };\n }\n return { tables };\n}\n\n/**\n * Compare the live SQLite schema against the models and report drift. Comparison\n * is at the affinity level (so `varchar` vs `TEXT` is not flagged), plus\n * nullability, primary-key, and presence of tables/columns.\n *\n * @param driver A sync SQLite driver.\n * @param models The model classes that define the intended schema.\n * @returns A list of human-readable drift messages — empty means no drift.\n */\n/**\n * Normalize a table's constraints into comparable key sets, merging the\n * column-level (`.unique()` / `.references()`) and table-level (`tableArgs`)\n * forms so drift comparison is agnostic to how a constraint was declared.\n */\nfunction constraintKeys(table: TableIR): { fks: Set<string>; uniques: Set<string> } {\n const fks = new Set<string>();\n const uniques = new Set<string>();\n for (const col of Object.values(table.columns)) {\n if (col.unique) uniques.add(col.name);\n if (col.references) {\n fks.add(`${col.name}=>${col.references.table}(${col.references.column})`);\n }\n }\n for (const uc of table.uniqueConstraints) {\n uniques.add([...uc.columns].sort().join(\",\"));\n }\n for (const fk of table.foreignKeys) {\n fks.add(`${fk.columns.join(\",\")}=>${fk.refTable}(${fk.refColumns.join(\",\")})`);\n }\n return { fks, uniques };\n}\n\nexport function checkDrift(driver: SyncDriver, models: readonly ModelClass[]): string[] {\n return compareSqliteSchemas(introspectSqlite(driver), reflectSchema(models));\n}\n\n/**\n * Compare an introspected SQLite schema against the reflected models.\n *\n * Split out from {@link checkDrift} so the sync and async drivers share one\n * comparison — a second copy would drift from this one the first time a rule\n * changes.\n *\n * @param actual The schema read from the database.\n * @param expected The schema reflected from the models.\n * @returns A list of human-readable drift messages — empty means no drift.\n */\nexport function compareSqliteSchemas(actual: SchemaIR, expected: SchemaIR): string[] {\n const issues: string[] = [];\n\n for (const [tableName, expectedTable] of Object.entries(expected.tables)) {\n const actualTable = actual.tables[tableName];\n if (!actualTable) {\n issues.push(`table \"${tableName}\" is missing from the database`);\n continue;\n }\n for (const [colName, expectedCol] of Object.entries(expectedTable.columns)) {\n const actualCol = actualTable.columns[colName];\n if (!actualCol) {\n issues.push(`column \"${tableName}.${colName}\" is missing from the database`);\n continue;\n }\n const expAff = sqliteAffinity(renderColumnType(expectedCol.type, \"sqlite\"));\n const actAff = sqliteAffinity(renderColumnType(actualCol.type, \"sqlite\"));\n if (expAff !== actAff) {\n issues.push(\n `column \"${tableName}.${colName}\" affinity differs: model ${expAff}, db ${actAff}`,\n );\n }\n if (expectedCol.notNull !== actualCol.notNull) {\n issues.push(`column \"${tableName}.${colName}\" nullability differs`);\n }\n if (expectedCol.primaryKey !== actualCol.primaryKey) {\n issues.push(`column \"${tableName}.${colName}\" primary-key flag differs`);\n }\n }\n for (const colName of Object.keys(actualTable.columns)) {\n if (!expectedTable.columns[colName]) {\n issues.push(\n `column \"${tableName}.${colName}\" exists in the database but not in the model`,\n );\n }\n }\n\n const expectedKeys = constraintKeys(expectedTable);\n const actualKeys = constraintKeys(actualTable);\n for (const fk of expectedKeys.fks) {\n if (!actualKeys.fks.has(fk)) {\n issues.push(`foreign key \"${tableName}: ${fk}\" is missing from the database`);\n }\n }\n for (const fk of actualKeys.fks) {\n if (!expectedKeys.fks.has(fk)) {\n issues.push(\n `foreign key \"${tableName}: ${fk}\" exists in the database but not in the model`,\n );\n }\n }\n for (const uq of expectedKeys.uniques) {\n if (!actualKeys.uniques.has(uq)) {\n issues.push(\n `unique constraint \"${tableName}: (${uq})\" is missing from the database`,\n );\n }\n }\n for (const uq of actualKeys.uniques) {\n if (!expectedKeys.uniques.has(uq)) {\n issues.push(\n `unique constraint \"${tableName}: (${uq})\" exists in the database but not in the model`,\n );\n }\n }\n }\n\n for (const tableName of Object.keys(actual.tables)) {\n if (!expected.tables[tableName]) {\n issues.push(`table \"${tableName}\" exists in the database but not in the models`);\n }\n }\n\n return issues;\n}\n\n/** Build a table's column map + primary key from `PRAGMA table_info` rows. */\nfunction sqliteColumnsFromPragma(info: readonly PragmaColumn[]): {\n columns: Record<string, ColumnIR>;\n primaryKey: string[];\n} {\n const columns: Record<string, ColumnIR> = {};\n const primaryKey: string[] = [];\n for (const col of info) {\n const isPk = Number(col.pk) > 0;\n columns[col.name] = {\n name: col.name,\n type: { kind: affinityToKind(sqliteAffinity(col.type)), meta: {} },\n notNull: Number(col.notnull) === 1 || isPk,\n primaryKey: isPk,\n default: null,\n unique: false,\n references: null,\n };\n if (isPk) primaryKey.push(col.name);\n }\n return { columns, primaryKey };\n}\n\n/** Assemble foreign keys from `PRAGMA foreign_key_list` rows. */\nfunction sqliteForeignKeysFromPragma(\n table: string,\n rows: readonly PragmaForeignKey[],\n): ForeignKeyIR[] {\n const byId = new Map<number, PragmaForeignKey[]>();\n for (const row of rows) {\n const group = byId.get(row.id) ?? [];\n group.push(row);\n byId.set(row.id, group);\n }\n const fks: ForeignKeyIR[] = [];\n for (const group of byId.values()) {\n const ordered = [...group].sort((a, b) => a.seq - b.seq);\n fks.push({\n name: `fk_${table}_${ordered.map((r) => r.from).join(\"_\")}`,\n columns: ordered.map((r) => r.from),\n refTable: ordered[0]?.table ?? \"\",\n refColumns: ordered.map((r) => r.to),\n });\n }\n return fks;\n}\n\n/** Assemble one unique constraint from `PRAGMA index_info` rows. */\nfunction sqliteUniqueFromPragma(\n table: string,\n rows: readonly PragmaIndexColumn[],\n): UniqueConstraintIR | null {\n const cols = [...rows].sort((a, b) => a.seqno - b.seqno).map((c) => c.name);\n if (cols.length === 0) return null;\n return { name: `uq_${table}_${cols.join(\"_\")}`, columns: cols };\n}\n\n/** True when a `PRAGMA index_list` row describes a real UNIQUE constraint. */\nfunction isUniqueIndex(idx: PragmaIndex): boolean {\n return Number(idx.unique) === 1 && idx.origin !== \"pk\";\n}\n\n/** The `sqlite_master` query listing user tables (excluding the version table). */\nconst SQLITE_TABLES_SQL =\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name != 'tempest_db_js_migrations'\";\n\n/**\n * Read the current SQLite schema into a `SchemaIR` over an **async** driver.\n *\n * The sequencing differs from {@link introspectSqlite} — each `PRAGMA` depends on\n * the previous result, so it cannot be one awaited batch — but every row → IR\n * mapping is the shared code above.\n *\n * @param driver An async SQLite driver.\n * @returns The introspected schema.\n */\nexport async function introspectSqliteAsync(driver: AsyncDriver): Promise<SchemaIR> {\n const tablesRows = (await driver.execute(SQLITE_TABLES_SQL, [])).rows;\n const tables: Record<string, TableIR> = {};\n for (const row of tablesRows) {\n const tableName = String(row.name);\n const info = (\n await driver.execute(`PRAGMA table_info(${JSON.stringify(tableName)})`, [])\n ).rows as unknown as PragmaColumn[];\n const { columns, primaryKey } = sqliteColumnsFromPragma(info);\n\n const fkRows = (\n await driver.execute(`PRAGMA foreign_key_list(${JSON.stringify(tableName)})`, [])\n ).rows as unknown as PragmaForeignKey[];\n\n const indexes = (\n await driver.execute(`PRAGMA index_list(${JSON.stringify(tableName)})`, [])\n ).rows as unknown as PragmaIndex[];\n const uniqueConstraints: UniqueConstraintIR[] = [];\n for (const idx of indexes) {\n if (!isUniqueIndex(idx)) continue;\n const cols = (\n await driver.execute(`PRAGMA index_info(${JSON.stringify(idx.name)})`, [])\n ).rows as unknown as PragmaIndexColumn[];\n const unique = sqliteUniqueFromPragma(tableName, cols);\n if (unique) uniqueConstraints.push(unique);\n }\n\n tables[tableName] = {\n name: tableName,\n columns,\n primaryKey,\n uniqueConstraints,\n foreignKeys: sqliteForeignKeysFromPragma(tableName, fkRows),\n };\n }\n return { tables };\n}\n\n/**\n * Drift check over an **async** driver, routed by dialect. This is what\n * `tempest-db check` runs, so the CLI reaches the same comparison for every\n * supported database instead of only SQLite.\n *\n * @param driver An async driver for the live database.\n * @param dialect The dialect the driver speaks.\n * @param models The model classes that define the intended schema.\n * @returns A list of drift messages — empty means no drift.\n */\nexport async function checkDriftAsync(\n driver: AsyncDriver,\n dialect: Dialect,\n models: readonly ModelClass[],\n): Promise<string[]> {\n if (dialect === \"postgresql\") return checkDriftPostgres(driver, models);\n if (dialect === \"sqlite\") {\n return compareSqliteSchemas(\n await introspectSqliteAsync(driver),\n reflectSchema(models),\n );\n }\n return [\n \"drift checking is not implemented for MySQL — its information_schema introspection is still missing\",\n ];\n}\n\n/**\n * Map a PostgreSQL `information_schema` row to the closest IR column type.\n *\n * An array column reports `data_type = \"ARRAY\"` with the element type hidden in\n * `udt_name` as `_text` / `_int4`, so it is unpacked here into a nested element\n * type — otherwise every `text[]` column would read back as plain text and the\n * drift check would fire forever.\n *\n * @param dataType The `information_schema.columns.data_type` value.\n * @param udtName The `information_schema.columns.udt_name` value.\n * @returns The IR column type.\n */\nfunction pgTypeToColumnType(dataType: string, udtName: string): ColumnType {\n if (dataType.toLowerCase() === \"array\") {\n return {\n kind: \"array\",\n meta: { element: { kind: pgUdtToKind(udtName.replace(/^_/, \"\")), meta: {} } },\n };\n }\n return { kind: pgTypeToKind(dataType, udtName), meta: {} };\n}\n\n/** Map a PostgreSQL internal type name (`text`, `int4`) to the closest IR kind. */\nfunction pgUdtToKind(udtName: string): ColumnType[\"kind\"] {\n switch (udtName) {\n case \"int2\":\n return \"smallint\";\n case \"int4\":\n return \"integer\";\n case \"int8\":\n return \"bigint\";\n case \"float4\":\n return \"real\";\n case \"float8\":\n return \"double\";\n case \"numeric\":\n return \"numeric\";\n case \"varchar\":\n return \"varchar\";\n case \"bpchar\":\n return \"char\";\n case \"bool\":\n return \"boolean\";\n case \"date\":\n return \"date\";\n case \"time\":\n case \"timetz\":\n return \"time\";\n case \"timestamp\":\n case \"timestamptz\":\n return \"timestamp\";\n case \"bytea\":\n return \"blob\";\n case \"json\":\n case \"jsonb\":\n return \"json\";\n case \"uuid\":\n return \"uuid\";\n default:\n return \"text\";\n }\n}\n\n/** Map a PostgreSQL `information_schema` type name to the closest IR kind. */\nfunction pgTypeToKind(dataType: string, udtName: string): ColumnType[\"kind\"] {\n const t = dataType.toLowerCase();\n if (t === \"user-defined\") return \"enum\"; // a named enum type\n if (t === \"smallint\") return \"smallint\";\n if (t === \"integer\") return \"integer\";\n if (t === \"bigint\") return \"bigint\";\n if (t === \"numeric\") return \"numeric\";\n if (t === \"real\") return \"real\";\n if (t === \"double precision\") return \"double\";\n if (t === \"character varying\") return \"varchar\";\n if (t === \"character\") return \"char\";\n if (t === \"text\") return \"text\";\n if (t === \"boolean\") return \"boolean\";\n if (t === \"date\") return \"date\";\n if (t.startsWith(\"time\")) return t.startsWith(\"timestamp\") ? \"timestamp\" : \"time\";\n if (t === \"bytea\") return \"blob\";\n if (t === \"json\") return \"json\";\n if (t === \"jsonb\") return \"json\";\n if (t === \"uuid\") return \"uuid\";\n return udtName === \"jsonb\" ? \"json\" : \"text\";\n}\n\n/**\n * Read the current PostgreSQL schema into a `SchemaIR` from `information_schema`.\n *\n * Not exercised by the in-repo test suite (no PostgreSQL in CI); mirrors\n * {@link introspectSqlite} for the async driver.\n *\n * @param driver An async PostgreSQL driver.\n * @returns The introspected schema.\n */\nexport async function introspectPostgres(driver: AsyncDriver): Promise<SchemaIR> {\n const tablesResult = await driver.execute(\n \"SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE' AND table_name != 'tempest_db_js_migrations'\",\n [],\n );\n const tables: Record<string, TableIR> = {};\n for (const row of tablesResult.rows) {\n const tableName = String(row.table_name);\n const colsResult = await driver.execute(\n \"SELECT column_name, data_type, udt_name, is_nullable FROM information_schema.columns WHERE table_name = $1\",\n [tableName],\n );\n const pkResult = await driver.execute(\n `SELECT a.attname AS name FROM pg_index i\n JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n WHERE i.indrelid = $1::regclass AND i.indisprimary`,\n [tableName],\n );\n const pkSet = new Set(pkResult.rows.map((r) => String(r.name)));\n const columns: Record<string, ColumnIR> = {};\n const primaryKey: string[] = [];\n for (const col of colsResult.rows) {\n const name = String(col.column_name);\n const isPk = pkSet.has(name);\n columns[name] = {\n name,\n type: pgTypeToColumnType(String(col.data_type), String(col.udt_name)),\n notNull: col.is_nullable === \"NO\" || isPk,\n primaryKey: isPk,\n default: null,\n unique: false,\n references: null,\n };\n if (isPk) primaryKey.push(name);\n }\n tables[tableName] = {\n name: tableName,\n columns,\n primaryKey,\n uniqueConstraints: await postgresUniques(driver, tableName),\n foreignKeys: await postgresForeignKeys(driver, tableName),\n };\n }\n return { tables };\n}\n\n/** Read a table's foreign keys from `pg_constraint` (best-effort, no CI). */\nasync function postgresForeignKeys(\n driver: AsyncDriver,\n table: string,\n): Promise<ForeignKeyIR[]> {\n const result = await driver.execute(\n `SELECT c.conname AS name,\n (SELECT array_agg(a.attname ORDER BY k.ord)\n FROM unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord)\n JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.attnum) AS cols,\n cf.relname AS ref_table,\n (SELECT array_agg(a.attname ORDER BY k.ord)\n FROM unnest(c.confkey) WITH ORDINALITY AS k(attnum, ord)\n JOIN pg_attribute a ON a.attrelid = c.confrelid AND a.attnum = k.attnum) AS ref_cols\n FROM pg_constraint c\n JOIN pg_class cf ON cf.oid = c.confrelid\n WHERE c.contype = 'f' AND c.conrelid = $1::regclass`,\n [table],\n );\n return result.rows.map((r) => ({\n name: String(r.name),\n columns: (r.cols as string[]) ?? [],\n refTable: String(r.ref_table),\n refColumns: (r.ref_cols as string[]) ?? [],\n }));\n}\n\n/** Read a table's unique constraints from `pg_constraint` (best-effort, no CI). */\nasync function postgresUniques(\n driver: AsyncDriver,\n table: string,\n): Promise<UniqueConstraintIR[]> {\n const result = await driver.execute(\n `SELECT c.conname AS name,\n (SELECT array_agg(a.attname ORDER BY k.ord)\n FROM unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord)\n JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.attnum) AS cols\n FROM pg_constraint c\n WHERE c.contype = 'u' AND c.conrelid = $1::regclass`,\n [table],\n );\n return result.rows.map((r) => ({\n name: String(r.name),\n columns: (r.cols as string[]) ?? [],\n }));\n}\n\n/** The comparable name of a column type — `text[]` for arrays, the kind otherwise. */\nfunction describeKind(type: ColumnType): string {\n if (type.kind !== \"array\") return type.kind;\n return `${type.meta.element ? describeKind(type.meta.element) : \"unknown\"}[]`;\n}\n\n/**\n * Drift check for PostgreSQL: compares the live schema (introspected) against the\n * models by column kind, nullability, primary-key, and presence. Structural —\n * not exercised in CI (no PostgreSQL).\n *\n * @param driver An async PostgreSQL driver.\n * @param models The model classes that define the intended schema.\n * @returns A list of drift messages — empty means no drift.\n */\nexport async function checkDriftPostgres(\n driver: AsyncDriver,\n models: readonly ModelClass[],\n): Promise<string[]> {\n const actual = await introspectPostgres(driver);\n const expected = reflectSchema(models);\n const issues: string[] = [];\n for (const [tableName, expectedTable] of Object.entries(expected.tables)) {\n const actualTable = actual.tables[tableName];\n if (!actualTable) {\n issues.push(`table \"${tableName}\" is missing from the database`);\n continue;\n }\n for (const [colName, expectedCol] of Object.entries(expectedTable.columns)) {\n const actualCol = actualTable.columns[colName];\n if (!actualCol) {\n issues.push(`column \"${tableName}.${colName}\" is missing from the database`);\n continue;\n }\n if (describeKind(expectedCol.type) !== describeKind(actualCol.type)) {\n issues.push(\n `column \"${tableName}.${colName}\" type differs: model ${describeKind(expectedCol.type)}, db ${describeKind(actualCol.type)}`,\n );\n }\n if (expectedCol.notNull !== actualCol.notNull) {\n issues.push(`column \"${tableName}.${colName}\" nullability differs`);\n }\n }\n for (const colName of Object.keys(actualTable.columns)) {\n if (!expectedTable.columns[colName]) {\n issues.push(\n `column \"${tableName}.${colName}\" exists in the database but not in the model`,\n );\n }\n }\n\n const expectedKeys = constraintKeys(expectedTable);\n const actualKeys = constraintKeys(actualTable);\n for (const fk of expectedKeys.fks) {\n if (!actualKeys.fks.has(fk)) {\n issues.push(`foreign key \"${tableName}: ${fk}\" is missing from the database`);\n }\n }\n for (const uq of expectedKeys.uniques) {\n if (!actualKeys.uniques.has(uq)) {\n issues.push(\n `unique constraint \"${tableName}: (${uq})\" is missing from the database`,\n );\n }\n }\n }\n for (const tableName of Object.keys(actual.tables)) {\n if (!expected.tables[tableName]) {\n issues.push(`table \"${tableName}\" exists in the database but not in the models`);\n }\n }\n return issues;\n}\n","/**\n * tempest-db-js — Phase 6: rename detection.\n *\n * The differ ({@link diffSchema}) is deliberately conservative: a renamed column\n * looks like a drop + add, and a renamed table like a drop + create. That is the\n * *safe* default (never guesses), but it loses data. This module turns those\n * add/drop pairs into rename *candidates* the CLI can confirm — interactively at\n * a TTY, or explicitly via flags — and folds confirmed ones back into a single\n * `rename_table` / `rename_column` operation.\n *\n * Everything here is pure and structural (no SQL, no DB, no I/O), so the\n * detection and folding are fully testable; the actual prompting lives in the\n * `tempest-db` bin.\n */\n\nimport type { ColumnIR } from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\n\n/** A possible rename the differ emitted as a drop + add/create pair. */\nexport type RenameCandidate =\n | { readonly kind: \"table\"; readonly from: string; readonly to: string }\n | {\n readonly kind: \"column\";\n readonly table: string;\n readonly from: string;\n readonly to: string;\n };\n\n/** Structural identity of a column, ignoring its name. */\nfunction columnShape(col: ColumnIR): string {\n return JSON.stringify({\n type: col.type,\n notNull: col.notNull,\n primaryKey: col.primaryKey,\n default: col.default,\n unique: col.unique,\n references: col.references,\n });\n}\n\n/** Structural identity of a table's columns, ignoring the table name. */\nfunction tableShape(columns: Readonly<Record<string, ColumnIR>>): string {\n return Object.entries(columns)\n .map(([name, col]) => `${name}:${columnShape(col)}`)\n .sort()\n .join(\"|\");\n}\n\n/**\n * Detect rename candidates in a forward operation list.\n *\n * A table rename is a `create_table` + `drop_table` whose column shapes match\n * exactly. A column rename is an `add_column` + `drop_column` on the same table\n * whose column shapes match exactly. Only unambiguous 1:1 shape matches are\n * reported — if two dropped columns share a shape, neither is offered (the\n * mapping would be a guess).\n *\n * @param ops The forward operations from {@link diffSchema}.\n * @returns The rename candidates found (never mutates `ops`).\n */\nexport function detectRenames(ops: readonly Operation[]): RenameCandidate[] {\n const candidates: RenameCandidate[] = [];\n\n // --- table renames ---\n const creates = ops.filter((o) => o.kind === \"create_table\");\n const tableDrops = ops.filter((o) => o.kind === \"drop_table\");\n const takenCreate = new Set<string>();\n const takenDrop = new Set<string>();\n for (const create of creates) {\n const createShape = tableShape(create.table.columns);\n const matches = tableDrops.filter(\n (d) => !takenDrop.has(d.table.name) && tableShape(d.table.columns) === createShape,\n );\n // Only a unique match is a safe rename; ambiguity → leave as drop + create.\n const uniqueCreate =\n creates.filter(\n (c) =>\n !takenCreate.has(c.table.name) && tableShape(c.table.columns) === createShape,\n ).length === 1;\n if (matches.length === 1 && uniqueCreate) {\n const drop = matches[0] as Extract<Operation, { kind: \"drop_table\" }>;\n if (drop.table.name !== create.table.name) {\n candidates.push({ kind: \"table\", from: drop.table.name, to: create.table.name });\n takenCreate.add(create.table.name);\n takenDrop.add(drop.table.name);\n }\n }\n }\n\n // --- column renames (per table) ---\n const adds = ops.filter((o) => o.kind === \"add_column\");\n const colDrops = ops.filter((o) => o.kind === \"drop_column\");\n const tables = new Set([...adds.map((o) => o.table), ...colDrops.map((o) => o.table)]);\n for (const table of tables) {\n const tableAdds = adds.filter((o) => o.table === table);\n const tableColDrops = colDrops.filter((o) => o.table === table);\n const takenAdd = new Set<string>();\n const takenColDrop = new Set<string>();\n for (const add of tableAdds) {\n const shape = columnShape(add.column);\n const dropMatches = tableColDrops.filter(\n (d) => !takenColDrop.has(d.column.name) && columnShape(d.column) === shape,\n );\n const addMatches = tableAdds.filter(\n (a) => !takenAdd.has(a.column.name) && columnShape(a.column) === shape,\n );\n if (dropMatches.length === 1 && addMatches.length === 1) {\n const drop = dropMatches[0] as Extract<Operation, { kind: \"drop_column\" }>;\n candidates.push({\n kind: \"column\",\n table,\n from: drop.column.name,\n to: add.column.name,\n });\n takenAdd.add(add.column.name);\n takenColDrop.add(drop.column.name);\n }\n }\n }\n\n return candidates;\n}\n\n/** Match a table-rename candidate against an op pair. */\nfunction isTableRename(\n op: Operation,\n r: Extract<RenameCandidate, { kind: \"table\" }>,\n): boolean {\n return (\n (op.kind === \"create_table\" && op.table.name === r.to) ||\n (op.kind === \"drop_table\" && op.table.name === r.from)\n );\n}\n\n/** Match a column-rename candidate against an op pair. */\nfunction isColumnRename(\n op: Operation,\n r: Extract<RenameCandidate, { kind: \"column\" }>,\n): boolean {\n return (\n (op.kind === \"add_column\" && op.table === r.table && op.column.name === r.to) ||\n (op.kind === \"drop_column\" && op.table === r.table && op.column.name === r.from)\n );\n}\n\n/**\n * Fold confirmed renames into an operation list: each confirmed candidate's\n * drop + add/create pair is removed and replaced by a single rename operation,\n * inserted at the position of the first op it replaces (preserving order).\n *\n * @param ops The forward operations from {@link diffSchema}.\n * @param confirmed The rename candidates the user accepted.\n * @returns A new operation list with renames applied.\n */\nexport function applyRenames(\n ops: readonly Operation[],\n confirmed: readonly RenameCandidate[],\n): Operation[] {\n const out: Operation[] = [];\n const emitted = new Set<RenameCandidate>();\n\n for (const op of ops) {\n const match = confirmed.find((r) =>\n r.kind === \"table\" ? isTableRename(op, r) : isColumnRename(op, r),\n );\n if (!match) {\n out.push(op);\n continue;\n }\n // Emit the rename once (at the first op of the pair); skip both members.\n if (!emitted.has(match)) {\n emitted.add(match);\n out.push(\n match.kind === \"table\"\n ? { kind: \"rename_table\", from: match.from, to: match.to }\n : { kind: \"rename_column\", table: match.table, from: match.from, to: match.to },\n );\n }\n }\n return out;\n}\n","/**\n * tempest-db-js — Phase 6: the migration runner.\n *\n * The `Op` facade records operations; the `MigrationRunner` renders them to SQL\n * (per dialect) and runs them through a sync driver, tracking applied revisions\n * in a `tempest_db_js_migrations` table. Upgrades/downgrades respect the revision DAG.\n *\n * SQLite execution is real (via `node:sqlite`); the same code path serves any\n * sync driver.\n */\n\nimport type { AsyncDriver, SyncDriver } from \"../engine.js\";\nimport type { Dialect } from \"../url.js\";\nimport { renderOperation } from \"./ddl.js\";\nimport { topoOrder } from \"./graph.js\";\nimport type { ColumnIR, NamedConstraint, TableIR } from \"./ir.js\";\nimport { type Operation, invertAll } from \"./operations.js\";\n\n/**\n * The facade injected into `up()`/`down()`. Each method records an operation;\n * the runner renders and executes them after the function returns.\n */\nexport class Op {\n readonly operations: Operation[] = [];\n\n /** Record a raw operation (used by autogenerated migrations). */\n run(operation: Operation): void {\n this.operations.push(operation);\n }\n\n createTable(table: TableIR): void {\n this.run({ kind: \"create_table\", table });\n }\n dropTable(table: TableIR): void {\n this.run({ kind: \"drop_table\", table });\n }\n renameTable(from: string, to: string): void {\n this.run({ kind: \"rename_table\", from, to });\n }\n addColumn(table: string, column: ColumnIR): void {\n this.run({ kind: \"add_column\", table, column });\n }\n dropColumn(table: string, column: ColumnIR): void {\n this.run({ kind: \"drop_column\", table, column });\n }\n alterColumn(table: string, name: string, from: ColumnIR, to: ColumnIR): void {\n this.run({ kind: \"alter_column\", table, name, from, to });\n }\n renameColumn(table: string, from: string, to: string): void {\n this.run({ kind: \"rename_column\", table, from, to });\n }\n /** Rebuild a table (SQLite batch-mode / PostgreSQL per-column alters). */\n recreateTable(from: TableIR, to: TableIR): void {\n this.run({ kind: \"recreate_table\", from, to });\n }\n /** Add a table-level unique / foreign-key constraint. */\n addConstraint(table: string, constraint: NamedConstraint): void {\n this.run({ kind: \"add_constraint\", table, constraint });\n }\n /** Drop a table-level unique / foreign-key constraint. */\n dropConstraint(table: string, constraint: NamedConstraint): void {\n this.run({ kind: \"drop_constraint\", table, constraint });\n }\n /** Raw SQL escape hatch (e.g. a data migration). `down` may be `null`. */\n execute(up: string, down: string | null = null): void {\n this.run({ kind: \"execute\", up, down });\n }\n}\n\n/** A migration file's shape. */\nexport interface Migration {\n readonly revision: string;\n readonly downRevision: readonly string[];\n readonly label?: string;\n up(op: Op): void;\n down(op: Op): void;\n}\n\nconst VERSION_TABLE = \"tempest_db_js_migrations\";\n\n/** Runs migrations against a sync driver, tracking applied revisions. */\nexport class MigrationRunner {\n constructor(\n private readonly driver: SyncDriver,\n private readonly dialect: Dialect,\n ) {}\n\n /** Create the version-tracking table if it does not exist. */\n ensureVersionTable(): void {\n this.driver.execute(\n `CREATE TABLE IF NOT EXISTS \"${VERSION_TABLE}\" (revision TEXT PRIMARY KEY, applied_at TEXT NOT NULL, down_revision TEXT NOT NULL)`,\n [],\n );\n }\n\n /** The set of applied revision ids. */\n applied(): Set<string> {\n this.ensureVersionTable();\n const { rows } = this.driver.execute(`SELECT revision FROM \"${VERSION_TABLE}\"`, []);\n return new Set(rows.map((r) => String(r.revision)));\n }\n\n private runOps(ops: readonly Operation[]): void {\n for (const op of ops) {\n for (const stmt of renderOperation(op, this.dialect)) {\n const trimmed = stmt.trim();\n if (trimmed.length === 0 || trimmed.startsWith(\"--\")) continue;\n this.driver.execute(stmt, []);\n }\n }\n }\n\n private record(migration: Migration, appliedAt: string): void {\n this.driver.execute(\n `INSERT INTO \"${VERSION_TABLE}\" (revision, applied_at, down_revision) VALUES (?, ?, ?)`,\n [migration.revision, appliedAt, migration.downRevision.join(\",\")],\n );\n }\n\n private forget(revision: string): void {\n this.driver.execute(`DELETE FROM \"${VERSION_TABLE}\" WHERE revision = ?`, [revision]);\n }\n\n /**\n * Apply all pending migrations up to the head(s), in DAG order.\n *\n * @param migrations All known migrations.\n * @param appliedAt Timestamp string to stamp (pass one in — the runtime has no\n * wall clock of its own here).\n * @returns The revision ids that were applied this run.\n */\n upgrade(migrations: readonly Migration[], appliedAt: string): string[] {\n const done = this.applied();\n const ordered = topoOrder(migrations);\n const ran: string[] = [];\n for (const migration of ordered) {\n if (done.has(migration.revision)) continue;\n const op = new Op();\n migration.up(op);\n this.runOps(op.operations);\n this.record(migration, appliedAt);\n ran.push(migration.revision);\n }\n return ran;\n }\n\n /**\n * Revert the last `steps` applied migrations (default 1), newest first.\n *\n * @param migrations All known migrations.\n * @param steps How many applied revisions to roll back.\n * @returns The revision ids that were reverted.\n */\n downgrade(migrations: readonly Migration[], steps = 1): string[] {\n const done = this.applied();\n const ordered = topoOrder(migrations).filter((m) => done.has(m.revision));\n const toRevert = ordered.slice(-steps).reverse();\n const reverted: string[] = [];\n for (const migration of toRevert) {\n const op = new Op();\n // Prefer the migration's own down(); fall back to inverting up().\n if (migration.down.length >= 0) {\n try {\n migration.down(op);\n } catch {\n op.operations.length = 0;\n }\n }\n if (op.operations.length === 0) {\n const upOp = new Op();\n migration.up(upOp);\n op.operations.push(...invertAll(upOp.operations));\n }\n this.runOps(op.operations);\n this.forget(migration.revision);\n reverted.push(migration.revision);\n }\n return reverted;\n }\n}\n\n// ---------------------------------------------------------------------------\n// async runner (PostgreSQL / any async driver)\n// ---------------------------------------------------------------------------\n\n/** Quote an identifier for the dialect (backticks on MySQL, double-quotes else). */\nfunction quoteIdent(name: string, dialect: Dialect): string {\n return dialect === \"mysql\"\n ? `\\`${name.replace(/`/g, \"``\")}\\``\n : `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\n/** The n-th (1-based) placeholder for the dialect (`$n` on PostgreSQL, `?` else). */\nfunction placeholder(index: number, dialect: Dialect): string {\n return dialect === \"postgresql\" ? `$${index}` : \"?\";\n}\n\n/**\n * Runs migrations against an **async** driver (PostgreSQL, or any async driver),\n * tracking applied revisions. Mirrors {@link MigrationRunner} but every statement\n * is awaited, and identifier quoting + placeholder style follow the dialect —\n * so the version table and its bookkeeping are portable across SQLite/PG/MySQL.\n */\nexport class AsyncMigrationRunner {\n private readonly vt: string;\n\n constructor(\n private readonly driver: AsyncDriver,\n private readonly dialect: Dialect,\n ) {\n this.vt = quoteIdent(VERSION_TABLE, dialect);\n }\n\n /** Create the version-tracking table if it does not exist. */\n async ensureVersionTable(): Promise<void> {\n await this.driver.execute(\n `CREATE TABLE IF NOT EXISTS ${this.vt} (revision ${this.textType()} PRIMARY KEY, applied_at ${this.textType()} NOT NULL, down_revision ${this.textType()} NOT NULL)`,\n [],\n );\n }\n\n /** A portable \"text\" column type for the version table. */\n private textType(): string {\n // MySQL cannot index an unbounded TEXT primary key; use VARCHAR there.\n return this.dialect === \"mysql\" ? \"VARCHAR(255)\" : \"TEXT\";\n }\n\n /** The set of applied revision ids. */\n async applied(): Promise<Set<string>> {\n await this.ensureVersionTable();\n const { rows } = await this.driver.execute(`SELECT revision FROM ${this.vt}`, []);\n return new Set(rows.map((r) => String(r.revision)));\n }\n\n private async runOps(ops: readonly Operation[]): Promise<void> {\n for (const op of ops) {\n for (const stmt of renderOperation(op, this.dialect)) {\n const trimmed = stmt.trim();\n if (trimmed.length === 0 || trimmed.startsWith(\"--\")) continue;\n await this.driver.execute(stmt, []);\n }\n }\n }\n\n private async record(migration: Migration, appliedAt: string): Promise<void> {\n const p = (i: number) => placeholder(i, this.dialect);\n await this.driver.execute(\n `INSERT INTO ${this.vt} (revision, applied_at, down_revision) VALUES (${p(1)}, ${p(2)}, ${p(3)})`,\n [migration.revision, appliedAt, migration.downRevision.join(\",\")],\n );\n }\n\n private async forget(revision: string): Promise<void> {\n await this.driver.execute(\n `DELETE FROM ${this.vt} WHERE revision = ${placeholder(1, this.dialect)}`,\n [revision],\n );\n }\n\n /**\n * Apply all pending migrations up to the head(s), in DAG order.\n *\n * @param migrations All known migrations.\n * @param appliedAt Timestamp string to stamp on each applied revision.\n * @returns The revision ids that were applied this run.\n */\n async upgrade(migrations: readonly Migration[], appliedAt: string): Promise<string[]> {\n const done = await this.applied();\n const ordered = topoOrder(migrations);\n const ran: string[] = [];\n for (const migration of ordered) {\n if (done.has(migration.revision)) continue;\n const op = new Op();\n migration.up(op);\n await this.runOps(op.operations);\n await this.record(migration, appliedAt);\n ran.push(migration.revision);\n }\n return ran;\n }\n\n /**\n * Revert the last `steps` applied migrations (default 1), newest first.\n *\n * @param migrations All known migrations.\n * @param steps How many applied revisions to roll back.\n * @returns The revision ids that were reverted.\n */\n async downgrade(migrations: readonly Migration[], steps = 1): Promise<string[]> {\n const done = await this.applied();\n const ordered = topoOrder(migrations).filter((m) => done.has(m.revision));\n const toRevert = ordered.slice(-steps).reverse();\n const reverted: string[] = [];\n for (const migration of toRevert) {\n const op = new Op();\n try {\n migration.down(op);\n } catch {\n op.operations.length = 0;\n }\n if (op.operations.length === 0) {\n const upOp = new Op();\n migration.up(upOp);\n op.operations.push(...invertAll(upOp.operations));\n }\n await this.runOps(op.operations);\n await this.forget(migration.revision);\n reverted.push(migration.revision);\n }\n return reverted;\n }\n}\n","/**\n * tempest-db-js — Phase 6: migration replay → virtual schema IR.\n *\n * Applies a migration's operations to an in-memory `SchemaIR`, building the\n * \"current\" schema without touching a database. This is the hybrid source of\n * truth for autogenerate: diff the replayed schema against the reflected models.\n */\n\nimport { topoOrder } from \"./graph.js\";\nimport { type SchemaIR, type TableIR, emptySchema } from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\nimport { type Migration, Op } from \"./runner.js\";\n\n/** Apply one operation to a schema, returning the updated schema. */\nexport function applyOperation(schema: SchemaIR, op: Operation): SchemaIR {\n const tables: Record<string, TableIR> = { ...schema.tables };\n switch (op.kind) {\n case \"create_table\":\n tables[op.table.name] = op.table;\n break;\n case \"drop_table\":\n delete tables[op.table.name];\n break;\n case \"rename_table\": {\n const t = tables[op.from];\n if (t) {\n delete tables[op.from];\n tables[op.to] = { ...t, name: op.to };\n }\n break;\n }\n case \"recreate_table\":\n delete tables[op.from.name];\n tables[op.to.name] = op.to;\n break;\n case \"add_column\": {\n const t = tables[op.table];\n if (t) {\n tables[op.table] = {\n ...t,\n columns: { ...t.columns, [op.column.name]: op.column },\n };\n }\n break;\n }\n case \"drop_column\": {\n const t = tables[op.table];\n if (t) {\n const columns = { ...t.columns };\n delete columns[op.column.name];\n tables[op.table] = { ...t, columns };\n }\n break;\n }\n case \"alter_column\": {\n const t = tables[op.table];\n if (t) {\n tables[op.table] = {\n ...t,\n columns: { ...t.columns, [op.name]: op.to },\n };\n }\n break;\n }\n case \"rename_column\": {\n const t = tables[op.table];\n const col = t?.columns[op.from];\n if (t && col) {\n const columns = { ...t.columns };\n delete columns[op.from];\n columns[op.to] = { ...col, name: op.to };\n tables[op.table] = { ...t, columns };\n }\n break;\n }\n case \"add_constraint\": {\n const t = tables[op.table];\n if (t) {\n tables[op.table] =\n op.constraint.type === \"unique\"\n ? {\n ...t,\n uniqueConstraints: [...t.uniqueConstraints, op.constraint.constraint],\n }\n : { ...t, foreignKeys: [...t.foreignKeys, op.constraint.constraint] };\n }\n break;\n }\n case \"drop_constraint\": {\n const t = tables[op.table];\n if (t) {\n const dropName = op.constraint.constraint.name;\n tables[op.table] =\n op.constraint.type === \"unique\"\n ? {\n ...t,\n uniqueConstraints: t.uniqueConstraints.filter((u) => u.name !== dropName),\n }\n : {\n ...t,\n foreignKeys: t.foreignKeys.filter((f) => f.name !== dropName),\n };\n }\n break;\n }\n case \"execute\":\n // raw SQL is opaque to the IR\n break;\n }\n return { tables };\n}\n\n/**\n * Replay migrations (in DAG order) into a virtual `SchemaIR` — the \"current\"\n * schema, computed without a database.\n *\n * @param migrations All known migrations.\n * @returns The schema after applying every migration's `up()`.\n */\nexport function replaySchema(migrations: readonly Migration[]): SchemaIR {\n let schema = emptySchema();\n for (const migration of topoOrder(migrations)) {\n const op = new Op();\n migration.up(op);\n for (const operation of op.operations) {\n schema = applyOperation(schema, operation);\n }\n }\n return schema;\n}\n","/**\n * tempest-db-js — migration CLI (programmatic core).\n *\n * `runMigrationCli(argv, config)` dispatches Alembic-style commands against a\n * driver + a set of migrations + (optionally) the models. It returns lines and\n * an exit code rather than touching `process`, so it is fully testable; a thin\n * `bin` wrapper just maps `process.argv`/`process.exit` onto it.\n */\n\nimport { type AsyncDriver, type SyncDriver, toAsyncDriver } from \"../engine.js\";\nimport type { ModelClass } from \"../index.js\";\nimport type { Dialect } from \"../url.js\";\nimport { generateMigration, makeRevisionId } from \"./codegen.js\";\nimport { renderOperation } from \"./ddl.js\";\nimport { diffSchema } from \"./diff.js\";\nimport { heads as graphHeads, topoOrder } from \"./graph.js\";\nimport { checkDriftAsync } from \"./introspect.js\";\nimport { reflectSchema } from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\nimport { type RenameCandidate, applyRenames, detectRenames } from \"./renames.js\";\nimport { replaySchema } from \"./replay.js\";\nimport { AsyncMigrationRunner, type Migration, Op } from \"./runner.js\";\n\n/** Configuration the CLI operates against. */\nexport interface CliConfig {\n /**\n * The driver for the live database — sync (SQLite) or async (PostgreSQL,\n * MySQL). Both are accepted: the CLI adapts either to the async runner, so a\n * Postgres migration runs through the same commands as a SQLite one.\n */\n readonly driver: SyncDriver | AsyncDriver;\n readonly dialect: Dialect;\n readonly migrations: readonly Migration[];\n readonly models?: readonly ModelClass[];\n /** Timestamp string stamped on applied revisions (no wall clock here). */\n readonly appliedAt?: string;\n}\n\n/** The result of a CLI run. */\nexport interface CliResult {\n readonly code: number;\n readonly lines: string[];\n}\n\n/**\n * Identity helper for authoring a typed migration config file. Gives editor\n * autocompletion and type-checking on the object the `tempest-db` bin loads.\n *\n * @example\n * ```ts\n * // tempest-db.config.mjs\n * import { defineMigrationConfig } from \"tempest-db-js/migrations\";\n * import { NodeSqliteDriver } from \"tempest-db-js\";\n * import { migrations } from \"./migrations/index.js\";\n * import { User } from \"./models.js\";\n *\n * export default defineMigrationConfig({\n * driver: NodeSqliteDriver.open(\"app.db\"),\n * dialect: \"sqlite\",\n * migrations,\n * models: [User],\n * });\n * ```\n *\n * @param config The migration config to pass through unchanged.\n * @returns The same config, typed as `CliConfig`.\n */\nexport function defineMigrationConfig(config: CliConfig): CliConfig {\n return config;\n}\n\nfunction ok(lines: string[]): CliResult {\n return { code: 0, lines };\n}\nfunction fail(lines: string[]): CliResult {\n return { code: 1, lines };\n}\n\n/**\n * Parse rename flags into explicit rename candidates.\n *\n * `--rename-table <from>:<to>` and `--rename-column <table>.<from>:<to>` may each\n * be repeated. Malformed specs are ignored (the safe drop + add stays).\n *\n * @param rest The command arguments.\n * @returns The explicitly requested renames.\n */\nfunction parseRenameFlags(rest: readonly string[]): RenameCandidate[] {\n const out: RenameCandidate[] = [];\n for (let i = 0; i < rest.length; i += 1) {\n const arg = rest[i];\n if (arg === \"--rename-table\") {\n const [from, to] = (rest[i + 1] ?? \"\").split(\":\");\n i += 1;\n if (from && to) out.push({ kind: \"table\", from, to });\n } else if (arg === \"--rename-column\") {\n const [left, to] = (rest[i + 1] ?? \"\").split(\":\");\n i += 1;\n const dot = left?.lastIndexOf(\".\") ?? -1;\n if (left && to && dot > 0) {\n out.push({\n kind: \"column\",\n table: left.slice(0, dot),\n from: left.slice(dot + 1),\n to,\n });\n }\n }\n }\n return out;\n}\n\n/** Pending migrations (DAG order) not yet applied. */\nasync function pending(\n config: CliConfig,\n runner: AsyncMigrationRunner,\n): Promise<Migration[]> {\n const done = await runner.applied();\n return topoOrder(config.migrations).filter((m) => !done.has(m.revision));\n}\n\n/**\n * Run one CLI command.\n *\n * Commands: `current`, `history`, `heads`, `upgrade [--sql]`, `downgrade [N]`,\n * `check`, `revision -m <msg> [--autogenerate]`.\n *\n * Async for every dialect: the config's driver is adapted with\n * {@link toAsyncDriver}, so SQLite and PostgreSQL take the same path and the CLI\n * is not silently SQLite-only.\n *\n * @param argv The command and its arguments (without the program name).\n * @param config The driver, migrations, and models to operate on.\n * @returns Output lines and an exit code.\n */\nexport async function runMigrationCli(\n argv: readonly string[],\n config: CliConfig,\n): Promise<CliResult> {\n const [command, ...rest] = argv;\n const driver = toAsyncDriver(config.driver);\n const runner = new AsyncMigrationRunner(driver, config.dialect);\n const appliedAt = config.appliedAt ?? \"1970-01-01T00:00:00.000Z\";\n\n switch (command) {\n case \"current\": {\n const applied = [...(await runner.applied())].sort();\n return ok(applied.length > 0 ? applied : [\"(no migrations applied)\"]);\n }\n\n case \"heads\":\n return ok(graphHeads(config.migrations));\n\n case \"history\": {\n const done = await runner.applied();\n return ok(\n topoOrder(config.migrations).map(\n (m) =>\n `${done.has(m.revision) ? \"✓\" : \"·\"} ${m.revision}${m.label ? ` — ${m.label}` : \"\"}`,\n ),\n );\n }\n\n case \"upgrade\": {\n if (rest.includes(\"--sql\")) {\n const lines: string[] = [];\n for (const migration of await pending(config, runner)) {\n const op = new Op();\n migration.up(op);\n lines.push(`-- ${migration.revision}`);\n for (const operation of op.operations) {\n for (const stmt of renderOperation(operation, config.dialect))\n lines.push(`${stmt};`);\n }\n }\n return ok(lines.length > 0 ? lines : [\"-- nothing to upgrade\"]);\n }\n const ran = await runner.upgrade(config.migrations, appliedAt);\n return ok(ran.length > 0 ? ran.map((r) => `applied ${r}`) : [\"nothing to upgrade\"]);\n }\n\n case \"downgrade\": {\n const steps = rest[0] ? Number(rest[0]) : 1;\n const reverted = await runner.downgrade(config.migrations, steps);\n return ok(\n reverted.length > 0\n ? reverted.map((r) => `reverted ${r}`)\n : [\"nothing to downgrade\"],\n );\n }\n\n case \"check\": {\n if (!config.models) return fail([\"check requires models in the config\"]);\n const drift = await checkDriftAsync(driver, config.dialect, config.models);\n // Pending model changes not yet captured by a migration.\n const undiffed = diffSchema(\n replaySchema(config.migrations),\n reflectSchema(config.models),\n );\n const issues = [\n ...drift.map((d) => `drift: ${d}`),\n ...undiffed.map((o) => `uncaptured: ${o.kind}`),\n ];\n return issues.length > 0 ? fail(issues) : ok([\"no drift; models match migrations\"]);\n }\n\n case \"revision\": {\n if (!config.models)\n return fail([\"revision --autogenerate requires models in the config\"]);\n const msgIndex = rest.indexOf(\"-m\");\n const label = msgIndex >= 0 ? (rest[msgIndex + 1] ?? \"revision\") : \"revision\";\n const parents = graphHeads(config.migrations);\n let ops: Operation[] = rest.includes(\"--autogenerate\")\n ? diffSchema(replaySchema(config.migrations), reflectSchema(config.models))\n : [];\n if (rest.includes(\"--autogenerate\")) {\n // Fold add/drop pairs into renames: `--autorename` accepts every\n // detected candidate; otherwise only the explicit `--rename-*` flags.\n const confirmed = rest.includes(\"--autorename\")\n ? detectRenames(ops)\n : parseRenameFlags(rest);\n if (confirmed.length > 0) ops = applyRenames(ops, confirmed);\n }\n const source = generateMigration({\n revision: makeRevisionId(label, parents),\n downRevision: parents,\n label,\n operations: ops,\n });\n return ok(source.split(\"\\n\"));\n }\n\n default:\n return fail([\n `unknown command ${JSON.stringify(command)}`,\n \"commands: current | history | heads | upgrade [--sql] | downgrade [N] | check | revision -m <msg> [--autogenerate]\",\n ]);\n }\n}\n","#!/usr/bin/env node\n/**\n * tempest-db-js — `tempest-db` executable.\n *\n * A thin wrapper around {@link runMigrationCli}: it discovers a config module,\n * loads it, injects a real timestamp, dispatches the command, prints the output\n * lines, and maps the result code onto `process.exit`. All the migration logic\n * lives in the (fully testable) programmatic core — this file only touches\n * `process`, the filesystem, and the wall clock.\n *\n * @example\n * ```bash\n * tempest-db upgrade\n * tempest-db revision -m \"add users\" --autogenerate\n * tempest-db --config db/tempest.config.mjs current\n * ```\n */\n\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport { pathToFileURL } from \"node:url\";\nimport type { CliConfig } from \"./migrations/cli.js\";\nimport { runMigrationCli } from \"./migrations/cli.js\";\nimport { diffSchema } from \"./migrations/diff.js\";\nimport { reflectSchema } from \"./migrations/ir.js\";\nimport { type RenameCandidate, detectRenames } from \"./migrations/renames.js\";\nimport { replaySchema } from \"./migrations/replay.js\";\n\n/** Config file names looked up in the current directory, in order. */\nconst DEFAULT_CONFIG_NAMES: readonly string[] = [\n \"tempest-db.config.mjs\",\n \"tempest-db.config.js\",\n \"tempest-db.config.cjs\",\n];\n\n/**\n * Pull the `--config <path>` flag out of the argv, returning the path (if any)\n * and the remaining arguments for the CLI command itself.\n *\n * @param argv The process arguments (without node + script).\n * @returns The explicit config path (or `null`) and the leftover argv.\n */\nfunction extractConfigFlag(argv: readonly string[]): {\n configPath: string | null;\n rest: string[];\n} {\n const rest: string[] = [];\n let configPath: string | null = null;\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n if (arg === \"--config\" || arg === \"-c\") {\n configPath = argv[i + 1] ?? null;\n i += 1;\n } else if (arg?.startsWith(\"--config=\")) {\n configPath = arg.slice(\"--config=\".length);\n } else if (arg !== undefined) {\n rest.push(arg);\n }\n }\n return { configPath, rest };\n}\n\n/**\n * Resolve the config file path: the explicit `--config` value, or the first of\n * the default names that exists in the current directory.\n *\n * @param explicit The `--config` value, or `null` to search defaults.\n * @returns The absolute config path, or `null` if none was found.\n */\nfunction resolveConfigPath(explicit: string | null): string | null {\n if (explicit) return resolve(process.cwd(), explicit);\n for (const name of DEFAULT_CONFIG_NAMES) {\n const candidate = resolve(process.cwd(), name);\n if (existsSync(candidate)) return candidate;\n }\n return null;\n}\n\n/**\n * Dynamically import a config module and extract the `CliConfig` from its\n * `default` export (or a named `config` export as a fallback).\n *\n * @param path The absolute path to the config module.\n * @returns The loaded migration config.\n * @throws If the module has neither a default nor a `config` export.\n */\nasync function loadConfig(path: string): Promise<CliConfig> {\n const mod = (await import(pathToFileURL(path).href)) as {\n default?: CliConfig;\n config?: CliConfig;\n };\n const config = mod.default ?? mod.config;\n if (!config) {\n throw new Error(\n `config at ${path} must default-export (or export \\`config\\`) a CliConfig`,\n );\n }\n return config;\n}\n\n/** Turn a confirmed candidate into the `--rename-*` flag args the CLI parses. */\nfunction renameToFlags(r: RenameCandidate): string[] {\n return r.kind === \"table\"\n ? [\"--rename-table\", `${r.from}:${r.to}`]\n : [\"--rename-column\", `${r.table}.${r.from}:${r.to}`];\n}\n\n/**\n * When running `revision --autogenerate` at an interactive TTY, detect rename\n * candidates and ask the user to confirm each; return the `--rename-*` flags for\n * the accepted ones. No-op when not autogenerating, when `--autorename` or\n * explicit `--rename-*` flags are already present, when there are no models, or\n * when stdin is not a TTY (CI, pipes).\n *\n * @param config The loaded migration config.\n * @param rest The CLI command arguments.\n * @returns Extra `--rename-*` args to append before dispatching.\n */\nasync function promptRenames(\n config: CliConfig,\n rest: readonly string[],\n): Promise<string[]> {\n const decided =\n rest.includes(\"--autorename\") ||\n rest.includes(\"--rename-table\") ||\n rest.includes(\"--rename-column\");\n if (\n rest[0] !== \"revision\" ||\n !rest.includes(\"--autogenerate\") ||\n decided ||\n !config.models ||\n !process.stdin.isTTY\n ) {\n return [];\n }\n\n const ops = diffSchema(replaySchema(config.migrations), reflectSchema(config.models));\n const candidates = detectRenames(ops);\n if (candidates.length === 0) return [];\n\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const flags: string[] = [];\n try {\n for (const c of candidates) {\n const what =\n c.kind === \"table\"\n ? `table \"${c.from}\" → \"${c.to}\"`\n : `column \"${c.table}.${c.from}\" → \"${c.table}.${c.to}\"`;\n const answer = (await rl.question(`Rename ${what}? [y/N] `)).trim().toLowerCase();\n if (answer === \"y\" || answer === \"yes\") flags.push(...renameToFlags(c));\n }\n } finally {\n rl.close();\n }\n return flags;\n}\n\n/**\n * Run the `tempest-db` CLI end to end: discover + load the config, dispatch the\n * command, print output, and exit with the CLI's status code.\n *\n * @param argv The process arguments (without node + script).\n * @returns A promise resolving once the command has printed and exit is set.\n */\nexport async function main(argv: readonly string[]): Promise<void> {\n const { configPath, rest } = extractConfigFlag(argv);\n const resolved = resolveConfigPath(configPath);\n if (!resolved) {\n process.stderr.write(\n `tempest-db: no config found. Create one of ${DEFAULT_CONFIG_NAMES.join(\n \", \",\n )} or pass --config <path>.\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n let config: CliConfig;\n try {\n config = await loadConfig(resolved);\n } catch (error) {\n process.stderr.write(`tempest-db: ${(error as Error).message}\\n`);\n process.exitCode = 1;\n return;\n }\n\n const withClock: CliConfig = {\n ...config,\n appliedAt: config.appliedAt ?? new Date().toISOString(),\n };\n const renameFlags = await promptRenames(withClock, rest);\n const result = await runMigrationCli([...rest, ...renameFlags], withClock);\n const sink = result.code === 0 ? process.stdout : process.stderr;\n for (const line of result.lines) sink.write(`${line}\\n`);\n process.exitCode = result.code;\n}\n\n// Only auto-run when invoked as a program (not when imported by a test).\nif (import.meta.url === pathToFileURL(process.argv[1] ?? \"\").href) {\n void main(process.argv.slice(2));\n}\n"]}
1
+ {"version":3,"sources":["../src/conditions.ts","../src/expressions.ts","../src/query.ts","../src/url.ts","../src/search.ts","../src/index.ts","../src/dialect.ts","../src/engine.ts","../src/backup.ts","../src/migrations/operations.ts","../src/migrations/codegen.ts","../src/migrations/ddl.ts","../src/migrations/diff.ts","../src/migrations/graph.ts","../src/migrations/ir.ts","../src/migrations/introspect.ts","../src/migrations/renames.ts","../src/migrations/runner.ts","../src/migrations/replay.ts","../src/migrations/cli.ts","../src/bin.ts"],"names":["placeholder","sql","createRequire","promisify","execFile","copyFile","resolve","existsSync","pathToFileURL","createInterface"],"mappings":"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","file":"bin.cjs","sourcesContent":["/**\n * tempest-db-js — logical combinators for `where` (and/or/not).\n *\n * A `where` value is either the object form (an implicit AND of its fields) or a\n * `Condition` built with `and`/`or`/`not`. Both normalize to a `CondNode` tree\n * that every builder stores and the dialect compiles recursively — so select,\n * update, delete and join all share one condition language.\n */\n\nimport type { Operator, WhereInput } from \"./query.js\";\n\n/** Field-map condition (implicit AND of its entries). */\nexport interface CondFields {\n readonly kind: \"fields\";\n readonly fields: Record<string, unknown>;\n}\n\n/**\n * One side of a comparison: a column reference, a bound value, or a SQL function\n * applied to other expressions.\n *\n * A column reference carries the **property** name, not the database column —\n * the dialect resolves it through the node's name map, so `col()` cannot become a\n * back door around an explicit `.name()` mapping.\n */\nexport type ExprNode =\n | { readonly kind: \"column\"; readonly name: string }\n | { readonly kind: \"value\"; readonly value: unknown }\n | { readonly kind: \"fn\"; readonly name: string; readonly args: readonly ExprNode[] }\n | {\n readonly kind: \"case\";\n readonly branches: readonly {\n readonly when: CondNode;\n readonly result: ExprNode;\n }[];\n readonly fallback: ExprNode | null;\n }\n | { readonly kind: \"cast\"; readonly operand: ExprNode; readonly to: CastType }\n | { readonly kind: \"scalar\"; readonly select: unknown }\n | { readonly kind: \"star\" }\n | {\n readonly kind: \"window\";\n /** The function being windowed (`row_number()`, `sum(total)`, …). */\n readonly fn: ExprNode;\n /** `PARTITION BY` columns, by property name. */\n readonly partitionBy: readonly string[];\n /** `ORDER BY` inside the window. */\n readonly orderBy: readonly {\n readonly column: string;\n readonly direction: \"asc\" | \"desc\";\n }[];\n /** An explicit frame clause (`ROWS BETWEEN …`), or `null` for the default. */\n readonly frame: string | null;\n }\n | {\n readonly kind: \"rank\";\n readonly columns: readonly string[];\n readonly term: string;\n readonly language: string;\n };\n\n/**\n * A target type for {@link cast}.\n *\n * Kept as a portable vocabulary rather than raw SQL: each dialect maps it to the\n * name it actually accepts (`integer` is `INTEGER` on PostgreSQL and `SIGNED` on\n * MySQL), so the same model does not need a different cast per database.\n */\nexport type CastType =\n | \"integer\"\n | \"bigint\"\n | \"real\"\n | \"numeric\"\n | \"text\"\n | \"boolean\"\n | \"date\"\n | \"datetime\"\n | \"timestamp\"\n | \"uuid\"\n | \"json\"\n | \"jsonb\"\n | \"blob\";\n\n/** Logical condition nodes. */\nexport type CondNode =\n | CondFields\n | { readonly kind: \"and\"; readonly parts: readonly CondNode[] }\n | { readonly kind: \"or\"; readonly parts: readonly CondNode[] }\n | { readonly kind: \"not\"; readonly part: CondNode }\n | {\n readonly kind: \"compare\";\n readonly left: ExprNode;\n readonly op: Operator;\n readonly right: ExprNode;\n }\n | {\n readonly kind: \"exists\";\n /** The subquery's SELECT node. */\n readonly select: unknown;\n /** True for `NOT EXISTS`. */\n readonly negate: boolean;\n }\n | {\n readonly kind: \"fullText\";\n readonly columns: readonly string[];\n readonly term: string;\n readonly language: string;\n /**\n * The substring condition to compile where there is no text-search engine.\n * Built once, here, so the dialects do not each reimplement the fallback.\n */\n readonly fallback: CondNode;\n };\n\nconst CONDITION = Symbol.for(\"tempest-db-js.condition\");\n\n/** A composed condition produced by `and`/`or`/`not`. */\nexport interface Condition {\n readonly [CONDITION]: true;\n readonly node: CondNode;\n}\n\n/** Runtime guard: is this value a composed `Condition`? */\nexport function isCondition(value: unknown): value is Condition {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as Record<PropertyKey, unknown>)[CONDITION] === true\n );\n}\n\n/** Normalize a where argument (object form or `Condition`) to a `CondNode`. */\nexport function toCondNode(input: Condition | Record<string, unknown>): CondNode {\n return isCondition(input) ? input.node : { kind: \"fields\", fields: input };\n}\n\nfunction wrap(node: CondNode): Condition {\n return { [CONDITION]: true, node };\n}\n\n/**\n * A `where` argument: the object form (keys typed against `Row`) or a `Condition`.\n *\n * @typeParam Row - the row type whose columns the field keys are checked against.\n * Defaults to a permissive shape; pass it explicitly (e.g. `or<UserRow>(...)`)\n * for full key + operator checking inside combinators.\n */\nexport type WhereArg<Row = Record<string, unknown>> = WhereInput<Row> | Condition;\n\n/** Normalize a comparison operand: an {@link Expression}, or a bound value. */\nfunction toExprNode(operand: unknown): ExprNode {\n return isExpression(operand) ? operand.node : { kind: \"value\", value: operand };\n}\n\n/**\n * Reject an {@link Expression} among operands that are bound as values.\n *\n * `IN` and `BETWEEN` bind their operands, so an expression slipped into the list\n * would be serialized by the driver instead of rendered as SQL — the same silent\n * corruption that `set()` guards against.\n *\n * @param op The operator name, for the message.\n * @param operands The operands to check.\n * @throws Error When any operand is an expression.\n */\nfunction assertValueOperands(op: string, operands: readonly unknown[]): void {\n if (operands.some(isExpression)) {\n throw new Error(\n `The \"${op}\" operator binds its operands, so it takes values, not expressions.`,\n );\n }\n}\n\n/** Runtime guard: is this operand a built {@link Expression}? */\nexport function isExpression(value: unknown): value is Expression {\n return value instanceof Expression;\n}\n\n/**\n * One side of a comparison, built with {@link col}, {@link val} or {@link fn}.\n *\n * The comparison methods mirror the `where` operators, but both sides are\n * expressions — which is what makes `col(\"total\").gt(col(\"paid\"))` and a\n * functional-index lookup like `fn.lower(\"email\").eq(fn.lower(val(probe)))`\n * expressible at all. An operand that is not an `Expression` is bound as a\n * parameter, so `.eq(probe)` stays safe by default.\n */\nexport class Expression<T = unknown> {\n /** Phantom: the value type this expression produces, read only by the types. */\n declare readonly __t?: T;\n\n constructor(\n /** The expression AST the dialect renders. */\n readonly node: ExprNode,\n ) {}\n\n /** Compare this expression against another expression or a bound value. */\n private compare(op: Operator, operand: unknown): Condition {\n return wrap({ kind: \"compare\", left: this.node, op, right: toExprNode(operand) });\n }\n\n /** `=` (or `IS NULL` for a null value). */\n eq(operand: unknown): Condition {\n return this.compare(\"eq\", operand);\n }\n /** `<>` (or `IS NOT NULL` for a null value). */\n ne(operand: unknown): Condition {\n return this.compare(\"ne\", operand);\n }\n /** `>`. */\n gt(operand: unknown): Condition {\n return this.compare(\"gt\", operand);\n }\n /** `>=`. */\n gte(operand: unknown): Condition {\n return this.compare(\"gte\", operand);\n }\n /** `<`. */\n lt(operand: unknown): Condition {\n return this.compare(\"lt\", operand);\n }\n /** `<=`. */\n lte(operand: unknown): Condition {\n return this.compare(\"lte\", operand);\n }\n /** `LIKE` — `%` and `_` in the operand are wildcards. */\n like(pattern: string | Expression): Condition {\n return this.compare(\"like\", pattern);\n }\n /** `ILIKE` — case-insensitive **pattern** matching, wildcards included. */\n ilike(pattern: string | Expression): Condition {\n return this.compare(\"ilike\", pattern);\n }\n /** Case-insensitive equality (`lower(a) = lower(b)`), with no wildcards. */\n ieq(operand: unknown): Condition {\n return this.compare(\"ieq\", operand);\n }\n /**\n * `IN (...)` over a list of values.\n *\n * @param values The values to test against.\n * @returns The condition.\n * @throws Error When an entry is an {@link Expression} — a list operand is\n * bound, so an expression there would be serialized as a parameter instead of\n * rendered as SQL.\n */\n in(values: readonly unknown[]): Condition {\n assertValueOperands(\"in\", values);\n return this.compare(\"in\", values);\n }\n /**\n * `NOT IN (...)` over a list of values.\n *\n * @param values The values to exclude.\n * @returns The condition.\n * @throws Error When an entry is an {@link Expression} (see {@link Expression.in}).\n */\n notIn(values: readonly unknown[]): Condition {\n assertValueOperands(\"notIn\", values);\n return this.compare(\"notIn\", values);\n }\n /**\n * `BETWEEN lo AND hi` (inclusive).\n *\n * @param lo The lower bound.\n * @param hi The upper bound.\n * @returns The condition.\n * @throws Error When a bound is an {@link Expression} (see {@link Expression.in}).\n */\n between(lo: unknown, hi: unknown): Condition {\n assertValueOperands(\"between\", [lo, hi]);\n return this.compare(\"between\", [lo, hi]);\n }\n /** `IS NULL` (true) / `IS NOT NULL` (false). */\n isNull(value = true): Condition {\n return this.compare(\"isNull\", value);\n }\n}\n\n/**\n * Wrap a raw condition node as a {@link Condition}.\n *\n * The escape hatch for the helpers that build a node kind of their own (full-text\n * search), so they do not have to re-export the brand.\n *\n * @param node The node to wrap.\n * @returns The branded condition.\n */\nexport function conditionFromNode(node: CondNode): Condition {\n return wrap(node);\n}\n\n/**\n * Wrap a raw expression node as an {@link Expression}.\n *\n * @param node The node to wrap.\n * @returns The expression.\n */\nexport function expressionFromNode<T = unknown>(node: ExprNode): Expression<T> {\n return new Expression<T>(node);\n}\n\n/**\n * A column reference, by **property** name.\n *\n * Pass the row type for key-safety: `col<UserRow>(\"total\")` rejects a name that\n * is not a column. The name is resolved through the model's column-name map at\n * compile time, exactly like the object form of `where`.\n *\n * @param name The model property name.\n * @returns An expression referencing that column.\n *\n * @example\n * ```ts\n * select(Order).where(col<OrderRow>(\"total\").gt(col<OrderRow>(\"paid\")));\n * // SELECT * FROM \"orders\" WHERE \"total\" > \"paid\"\n * ```\n */\nexport function col<Row = Record<string, unknown>>(name: keyof Row & string): Expression {\n return new Expression({ kind: \"column\", name });\n}\n\n/**\n * A bound value, for the places that take an expression and would otherwise read\n * a bare string as a column name (the arguments of {@link fn}).\n *\n * @param value The value to bind as a parameter.\n * @returns An expression that renders as a placeholder.\n */\nexport function val(value: unknown): Expression {\n return new Expression({ kind: \"value\", value });\n}\n\n/**\n * A `CASE WHEN ... THEN ... ELSE ... END` expression.\n *\n * The branch conditions are the same `where` language used everywhere else — the\n * object form or a `Condition` — so no second grammar shows up just for `CASE`.\n * The branch results are expressions, and a bare value there is **bound**, not\n * interpolated.\n *\n * The classic use is a conditional aggregate: summing only the rows that match,\n * in one pass over the table instead of one query per bucket.\n *\n * @param branches `[condition, result]` pairs, evaluated in order.\n * @param fallback The `ELSE` result. Omitted, a row matching no branch is `NULL`.\n * @returns An expression usable anywhere an expression is.\n * @throws Error When no branch is given — `CASE END` is not valid SQL.\n *\n * @example\n * ```ts\n * select(Order).aggregate([\"customer\"], {\n * paid: sum(caseWhen([[{ status: \"paid\" }, col(\"total\")]], val(0))),\n * });\n * // SUM(CASE WHEN \"status\" = $1 THEN \"total\" ELSE $2 END) AS \"paid\"\n * ```\n */\nexport function caseWhen<Row = Record<string, unknown>>(\n branches: readonly (readonly [WhereArg<Row>, unknown])[],\n fallback?: unknown,\n): Expression {\n if (branches.length === 0) {\n throw new Error(\"caseWhen() needs at least one [condition, result] branch.\");\n }\n return new Expression({\n kind: \"case\",\n branches: branches.map(([when, result]) => ({\n when: toCondNode(when as Condition | Record<string, unknown>),\n result: toExprNode(result),\n })),\n fallback: fallback === undefined ? null : toExprNode(fallback),\n });\n}\n\n/**\n * A `CAST(x AS type)` expression.\n *\n * @param operand The expression to convert; a bare string is a column name.\n * @param to The target type, from the portable {@link CastType} vocabulary.\n * @returns An expression for the cast.\n *\n * @example\n * ```ts\n * select(Event).where(cast(\"externalId\", \"integer\").eq(42));\n * // WHERE CAST(\"externalId\" AS INTEGER) = $1\n * ```\n */\nexport function cast(operand: Expression | string, to: CastType): Expression {\n return new Expression({ kind: \"cast\", operand: toArg(operand), to });\n}\n\n/** Function names are interpolated verbatim, so they must be plain identifiers. */\nconst FUNCTION_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/** Coerce a function argument: a bare string is a column, everything else a value. */\nfunction toArg(arg: Expression | string): ExprNode {\n return typeof arg === \"string\" ? { kind: \"column\", name: arg } : arg.node;\n}\n\n/**\n * Build a call to a SQL function.\n *\n * A bare string argument is a **column name** — that is the useful default here\n * (`fn.lower(\"username\")`), and it is why a literal has to be wrapped in\n * {@link val}. The function name is interpolated into the statement, so it is\n * validated as a plain identifier and must never come from user input; the\n * arguments are always rendered through the expression compiler.\n *\n * @param name The SQL function name.\n * @param args Column names or expressions.\n * @returns An expression for the call.\n * @throws Error When `name` is not a plain SQL identifier.\n */\nfunction call(name: string, ...args: (Expression | string)[]): Expression {\n if (!FUNCTION_NAME.test(name)) {\n throw new Error(\n `fn.call() takes a plain SQL function name; got ${JSON.stringify(name)}.`,\n );\n }\n return new Expression({ kind: \"fn\", name, args: args.map(toArg) });\n}\n\n/**\n * SQL functions usable on either side of a comparison.\n *\n * The named entries are the ones every supported dialect implements. Anything\n * else — `date_trunc`, `strftime`, a custom function — goes through\n * {@link fn.call}, which does not pretend to be portable.\n *\n * @example\n * ```ts\n * select(AdminUser).where(fn.lower(\"username\").eq(fn.lower(val(probe))));\n * // WHERE lower(\"username\") = lower($1)\n * ```\n */\nexport const fn = {\n /** `lower(x)`. */\n lower: (arg: Expression | string): Expression => call(\"lower\", arg),\n /** `upper(x)`. */\n upper: (arg: Expression | string): Expression => call(\"upper\", arg),\n /** `trim(x)`. */\n trim: (arg: Expression | string): Expression => call(\"trim\", arg),\n /** `length(x)`. */\n length: (arg: Expression | string): Expression => call(\"length\", arg),\n /** `abs(x)`. */\n abs: (arg: Expression | string): Expression => call(\"abs\", arg),\n /** `coalesce(a, b, ...)`. */\n coalesce: (...args: (Expression | string)[]): Expression => call(\"coalesce\", ...args),\n /**\n * Any other SQL function, by name. Portability is the caller's problem —\n * `date_trunc` is PostgreSQL, `strftime` is SQLite.\n */\n call,\n} as const;\n\n/** Combine conditions with `AND`. */\nexport function and<Row = Record<string, unknown>>(\n ...inputs: WhereArg<NoInfer<Row>>[]\n): Condition {\n return wrap({\n kind: \"and\",\n parts: inputs.map((i) => toCondNode(i as Record<string, unknown>)),\n });\n}\n\n/** Combine conditions with `OR`. */\nexport function or<Row = Record<string, unknown>>(\n ...inputs: WhereArg<NoInfer<Row>>[]\n): Condition {\n return wrap({\n kind: \"or\",\n parts: inputs.map((i) => toCondNode(i as Record<string, unknown>)),\n });\n}\n\n/** Negate a condition with `NOT`. */\nexport function not<Row = Record<string, unknown>>(\n input: WhereArg<NoInfer<Row>>,\n): Condition {\n return wrap({ kind: \"not\", part: toCondNode(input as Record<string, unknown>) });\n}\n","/**\n * tempest-db-js — portable SQL expression rendering.\n *\n * A `sql.now()` / `sql.uuidv4()` token is dialect-neutral in the AST and in the\n * migration IR; this is the single place it becomes concrete SQL. Kept in its own\n * module (types only, no runtime imports) so both the query dialect and the DDL\n * renderer share one mapping instead of drifting apart.\n */\n\nimport type { Dialect } from \"./url.js\";\n\n/** The dialect-neutral expression tokens (the non-fragment `PortableExpression`s). */\nexport type PortableToken = \"now\" | \"current_date\" | \"current_time\" | \"uuidv4\";\n\n/**\n * Render a reference to the incoming row of an upsert.\n *\n * PostgreSQL and SQLite expose it as the `excluded` pseudo-table; MySQL has no\n * such table and spells the same idea as `VALUES(col)` inside\n * `ON DUPLICATE KEY UPDATE`.\n *\n * @param column The already-quoted column identifier.\n * @param bare The column name without quoting, for MySQL's `VALUES()` form.\n * @param dialect The target dialect.\n * @returns The SQL text.\n */\nexport function renderExcluded(column: string, bare: string, dialect: Dialect): string {\n return dialect === \"mysql\" ? `VALUES(${bare})` : `excluded.${column}`;\n}\n\n/**\n * Render a portable expression token to SQL for the dialect.\n *\n * @param token The dialect-neutral token.\n * @param dialect The target dialect.\n * @returns The SQL text for that token.\n */\nexport function renderPortableToken(token: PortableToken, dialect: Dialect): string {\n switch (token) {\n case \"now\":\n if (dialect === \"postgresql\") return \"now()\";\n // SQLite's CURRENT_TIMESTAMP is \"YYYY-MM-DD HH:MM:SS\": no `T`, no\n // milliseconds, no zone. JS parses that as **local** time, so a row written\n // at 21:00Z read back as 00:00Z on a UTC-3 machine, and comparing the column\n // against a bound ISO string compared \" \" with \"T\" and silently matched\n // nothing. `strftime` writes exactly the format this package binds and reads.\n if (dialect === \"sqlite\") return \"strftime('%Y-%m-%dT%H:%M:%fZ', 'now')\";\n return \"CURRENT_TIMESTAMP\";\n case \"current_date\":\n return \"CURRENT_DATE\";\n case \"current_time\":\n return \"CURRENT_TIME\";\n case \"uuidv4\":\n if (dialect === \"postgresql\") return \"gen_random_uuid()\";\n if (dialect === \"mysql\") return \"(UUID())\";\n return \"(lower(hex(randomblob(16))))\";\n }\n}\n","/**\n * tempest-db-js — Phase 2 feasibility spike: the typed query builder.\n *\n * The builder is PURE AST + phantom types. It does not touch a database — that is\n * Phase 4 (`session.execute`). This file proves that:\n * - `select(User)` infers the full row type,\n * - `select(User, [\"id\", \"name\"])` infers a `Pick` projection,\n * - `.where(...)` / `.orderBy(...)` reject keys that are not columns,\n * all at compile time.\n *\n * This is a SPIKE, not the final API.\n */\n\nimport { aliasOf } from \"./aliased.js\";\nimport {\n type CondNode,\n type Condition,\n type ExprNode,\n type Expression,\n conditionFromNode,\n expressionFromNode,\n toCondNode,\n} from \"./conditions.js\";\nimport {\n type InferModel,\n type ModelClass,\n type NameMap,\n codecsOf,\n columnNamesOf,\n} from \"./index.js\";\n\n// --------------------------------------------------------------------------\n// AST\n// --------------------------------------------------------------------------\n\n/** The value type an expression produces, for `compute`'s row type. */\nexport type ExpressionValue<E> = E extends Expression<infer T> ? T : unknown;\n\n/** Flatten an intersection into one object literal, for readable inference. */\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\n/** Sort direction for ORDER BY. */\nexport type SortDirection = \"asc\" | \"desc\";\n\n/** One ORDER BY term. */\nexport interface OrderTerm {\n /** The column to sort by, or an expression (a full-text rank, for instance). */\n readonly column: string | ExprNode;\n readonly direction: SortDirection;\n}\n\n/** One aggregate expression in a grouped SELECT (`COUNT(*) AS \"n\"`). */\nexport interface AggregateTerm {\n readonly fn: \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n /**\n * What is aggregated: a column name, `\"*\"` (only valid for `count`), or an\n * expression — which is how a conditional aggregate\n * (`SUM(CASE WHEN ... END)`) is expressed.\n */\n readonly column: string | \"*\" | ExprNode;\n /** The result alias. */\n readonly alias: string;\n}\n\n/**\n * A row-level locking clause (`SELECT ... FOR UPDATE`).\n *\n * `wait` decides what happens when another transaction already holds the lock:\n * `\"block\"` waits, `\"skipLocked\"` skips those rows (the job-queue claim), and\n * `\"noWait\"` fails immediately.\n */\nexport interface LockClause {\n readonly strength: \"update\" | \"share\";\n readonly wait: \"block\" | \"skipLocked\" | \"noWait\";\n /** Tables to lock (`FOR UPDATE OF t`); empty locks every table in the query. */\n readonly of: readonly string[];\n}\n\n/** Options accepted by {@link SelectBuilder.forUpdate} / {@link SelectBuilder.forShare}. */\nexport interface LockOptions {\n /** Skip rows another transaction has locked instead of waiting for them. */\n readonly skipLocked?: boolean;\n /** Fail immediately instead of waiting for a locked row. */\n readonly noWait?: boolean;\n /** Restrict the lock to these tables (`FOR UPDATE OF ...`). */\n readonly of?: readonly string[];\n}\n\n/** Serializable AST for a SELECT. Dialects (Phase 4) compile this to SQL. */\nexport interface SelectNode {\n readonly kind: \"select\";\n readonly table: string;\n /** The name the table is read under (`FROM \"users\" AS \"sub\"`), when aliased. */\n readonly alias?: string | undefined;\n /** Projected columns, or \"*\" for the whole row. */\n readonly columns: readonly string[] | \"*\";\n /** Emit `SELECT DISTINCT` when true. */\n readonly distinct: boolean;\n /** Aggregate expressions; when non-empty, this is a grouped/aggregate query. */\n readonly aggregates: readonly AggregateTerm[];\n /** `GROUP BY` columns. */\n readonly groupBy: readonly string[];\n readonly where: CondNode | undefined;\n /** `HAVING` condition, keyed by aggregate alias or grouped column. */\n readonly having?: CondNode | undefined;\n readonly orderBy: readonly OrderTerm[];\n /** Per-column codecs for custom types, by property name, when the model has any. */\n readonly codecs?:\n | Readonly<Record<string, import(\"./index.js\").ColumnCodec>>\n | undefined;\n /** `WITH` entries this statement carries, in order. */\n readonly with?: readonly import(\"./cte.js\").CteNode[] | undefined;\n /** Extra projected expressions, by result alias (window functions, CASE, …). */\n readonly computed?: Readonly<Record<string, ExprNode>> | undefined;\n readonly limit: number | undefined;\n readonly offset: number | undefined;\n /** Row-level locking clause, or `undefined` for none. */\n readonly lock?: LockClause | undefined;\n /** Property → column map, or `undefined` when every name is the identity. */\n readonly names?: NameMap | undefined;\n}\n\n// --------------------------------------------------------------------------\n// where input typing (Phase 3 — operators typed per column type)\n// --------------------------------------------------------------------------\n\n/**\n * A SELECT projecting exactly one column of type `T`, usable as the operand of\n * `in` / `notIn`.\n *\n * Build it with {@link SelectBuilder.asSubquery}, which both narrows the\n * projection to one column and gives the operand its element type.\n */\nexport interface Subquery<T> {\n /** Phantom: the element type the subquery yields, read only by the type system. */\n readonly __element?: T;\n /** The AST the outer statement embeds. */\n readonly node: SelectNode;\n}\n\n/**\n * `EXISTS (subquery)` — true when the subquery returns at least one row.\n *\n * The right shape for \"is there any…\" questions: the database can stop at the\n * first match, which an `IN` over a materialized list cannot. Correlate it by\n * referencing an outer column with a qualified `col(\"users.id\")`.\n *\n * @param subquery The inner SELECT, as a builder or a `.asSubquery()` result.\n * @returns A condition, composable with `and`/`or`/`not`.\n *\n * @example\n * ```ts\n * select(User).where(\n * exists(select(Order).where({ userId: col(\"users.id\"), status: \"open\" })),\n * );\n * // WHERE EXISTS (SELECT * FROM \"orders\" WHERE \"userId\" = \"users\".\"id\" AND ...)\n * ```\n */\nexport function exists(subquery: SubqueryLike): Condition {\n return conditionFromNode({ kind: \"exists\", select: nodeOf(subquery), negate: false });\n}\n\n/**\n * `NOT EXISTS (subquery)` — true when the subquery returns no row.\n *\n * @param subquery The inner SELECT.\n * @returns The condition.\n */\nexport function notExists(subquery: SubqueryLike): Condition {\n return conditionFromNode({ kind: \"exists\", select: nodeOf(subquery), negate: true });\n}\n\n/**\n * A scalar subquery — a `SELECT` of one column used where a value goes.\n *\n * Takes the result of `.asSubquery(column)` rather than a bare builder, because\n * that is what pins the projection to exactly **one** column: a scalar subquery\n * returning two columns is a runtime error in every database, and this makes it a\n * compile error instead.\n *\n * @param subquery A single-column subquery.\n * @returns An expression usable in `where`, `orderBy` or an aggregate.\n *\n * @example\n * ```ts\n * select(User).where(\n * scalar(select(Order, [\"total\"]).where({ userId: col(\"users.id\") })\n * .orderBy(\"createdAt\", \"desc\").limit(1).asSubquery(\"total\")).gt(100),\n * );\n * ```\n */\nexport function scalar<T>(subquery: Subquery<T>): Expression {\n return expressionFromNode({ kind: \"scalar\", select: subquery.node });\n}\n\n/** What the subquery helpers accept: a builder, or a narrowed subquery. */\n/* biome-ignore lint/suspicious/noExplicitAny: any select shape may be embedded. */\nexport type SubqueryLike = SelectBuilder<any, any, any> | Subquery<unknown>;\n\n/**\n * Read the SELECT node out of either accepted shape.\n *\n * @param subquery The builder or subquery.\n * @returns Its AST node.\n */\nfunction nodeOf(subquery: SubqueryLike): SelectNode {\n return (subquery as { node: SelectNode }).node;\n}\n\n/** Runtime guard: is this `in`/`notIn` operand a subquery rather than a list? */\nexport function isSubquery(value: unknown): value is Subquery<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { node?: { kind?: unknown } }).node?.kind === \"select\"\n );\n}\n\n/**\n * A comparison operand: a value of the column's type, or another expression.\n *\n * Accepting an {@link Expression} is what makes a correlated subquery readable —\n * `where({ userId: col(\"users.id\") })` compares two columns instead of binding\n * the string `\"users.id\"` as a parameter.\n */\nexport type Operand<T> = T | Expression;\n\n/** Operators valid on every column type. */\ninterface BaseOperators<T> {\n /** Equal to. */\n eq?: Operand<T>;\n /** Not equal to. */\n ne?: Operand<T>;\n /**\n * One of the given values (`IN`) — a list, or a single-column\n * {@link Subquery} built with `.asSubquery(column)`.\n */\n in?: readonly T[] | Subquery<T>;\n /** None of the given values (`NOT IN`), as a list or a {@link Subquery}. */\n notIn?: readonly T[] | Subquery<T>;\n /** `IS NULL` (true) / `IS NOT NULL` (false). */\n isNull?: boolean;\n}\n\n/** Extra operators for ordered types (numbers, bigint, dates). */\ninterface OrderedOperators<T> extends BaseOperators<T> {\n /** Greater than. */\n gt?: Operand<T>;\n /** Greater than or equal. */\n gte?: Operand<T>;\n /** Less than. */\n lt?: Operand<T>;\n /** Less than or equal. */\n lte?: Operand<T>;\n /** Inclusive range `BETWEEN lo AND hi`. */\n between?: readonly [T, T];\n}\n\n/** Extra operators for string-like types. */\ninterface StringOperators<T> extends BaseOperators<T> {\n /** `LIKE` pattern (case-sensitive). `%` and `_` are wildcards. */\n like?: string;\n /**\n * `ILIKE` **pattern** (case-insensitive). This is pattern matching, not\n * equality: `%` and `_` in the operand are wildcards, so `{ ilike: \"%\" }`\n * matches every row. Never feed it unescaped user input — for a\n * case-insensitive *equality* test use {@link StringOperators.ieq}, and to\n * match a literal that may contain wildcards, wrap it in `escapeLike`.\n */\n ilike?: string;\n /**\n * Case-insensitive equality — compiles to `lower(col) = lower($1)`, with no\n * wildcards. The safe operator for a case-insensitive lookup (login, email),\n * and the one that matches a `lower(col)` functional index.\n */\n ieq?: Operand<T>;\n /**\n * Case-insensitive **substring** match of a literal — the safe operator for a\n * search box.\n *\n * The operand is text the user typed, not a pattern: `%` and `_` in it are\n * escaped, so searching for `100%` matches `100%` instead of every row. It\n * compiles to `ILIKE '%…%' ESCAPE '\\\\'` (`LIKE` where there is no `ILIKE`).\n */\n iContains?: string;\n}\n\n/** Extra operators for array columns (PostgreSQL). */\ninterface ArrayOperators<T> extends BaseOperators<T> {\n /** `@>` — the column contains every element of the operand. */\n contains?: T;\n /** `<@` — every element of the column is in the operand. */\n containedBy?: T;\n /** `&&` — the column and the operand share at least one element. */\n overlaps?: T;\n}\n\n/**\n * The operator object allowed for a column of (non-null) type `T`:\n * - `T[]` → equality, `in`, `contains`/`containedBy`/`overlaps` (PostgreSQL)\n * - `string` → equality, `in`, `like`/`ilike`/`ieq`\n * - `number` / `bigint` / `Date` → equality, `in`, ordered comparisons, `between`\n * - `boolean` → equality, `isNull`\n * - anything else (json/blob) → equality and `in` only\n */\nexport type OperatorsFor<T> = [T] extends [readonly unknown[]]\n ? ArrayOperators<T>\n : [T] extends [string]\n ? StringOperators<T>\n : [T] extends [number]\n ? OrderedOperators<T>\n : [T] extends [bigint]\n ? OrderedOperators<T>\n : [T] extends [Date]\n ? OrderedOperators<T>\n : [T] extends [boolean]\n ? BaseOperators<T>\n : BaseOperators<T>;\n\n/**\n * `where` shape: each key must be a real column; each value accepts either a\n * bare value (shorthand for `eq`) or an operator object restricted to operators\n * valid for that column's type. A `like` on a `number` column, or `gt` on a\n * `string`, is a compile error.\n */\nexport type WhereInput<Row = Record<string, unknown>> = {\n [K in keyof Row]?: Row[K] | Expression | OperatorsFor<NonNullable<Row[K]>>;\n};\n\n/** The full set of operator keys, for the dialect compiler to recognize. */\nexport const OPERATORS = [\n \"eq\",\n \"ne\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"like\",\n \"ilike\",\n \"ieq\",\n \"iContains\",\n \"in\",\n \"notIn\",\n \"between\",\n \"isNull\",\n \"contains\",\n \"containedBy\",\n \"overlaps\",\n] as const;\n\n/** One supported operator name. */\nexport type Operator = (typeof OPERATORS)[number];\n\n// --------------------------------------------------------------------------\n// aggregate expressions\n// --------------------------------------------------------------------------\n\n/** An aggregate expression carrying its result type `T` as a phantom. */\nexport class Agg<T> {\n declare readonly __t: T;\n constructor(\n readonly fn: AggregateTerm[\"fn\"],\n readonly column: string | \"*\" | ExprNode,\n ) {}\n}\n\n/** `COUNT(*)` — the number of rows in the group (never null). */\nexport function count(): Agg<number> {\n return new Agg<number>(\"count\", \"*\");\n}\n/** `SUM(column)` — null when the group has no non-null values. */\nexport function sum(column: string | Expression): Agg<number | null> {\n return new Agg<number | null>(\"sum\", typeof column === \"string\" ? column : column.node);\n}\n/** `AVG(column)` — null when the group has no non-null values. */\nexport function avg(column: string | Expression): Agg<number | null> {\n return new Agg<number | null>(\"avg\", typeof column === \"string\" ? column : column.node);\n}\n/** `MIN(column)` — numeric columns; null on an empty group. */\nexport function min(column: string | Expression): Agg<number | null> {\n return new Agg<number | null>(\"min\", typeof column === \"string\" ? column : column.node);\n}\n/** `MAX(column)` — numeric columns; null on an empty group. */\nexport function max(column: string | Expression): Agg<number | null> {\n return new Agg<number | null>(\"max\", typeof column === \"string\" ? column : column.node);\n}\n\n/** Extract the phantom result type of an aggregate expression. */\ntype AggResult<A> = A extends Agg<infer T> ? T : never;\n\n/** Flatten an intersection into a single object literal. */\ntype SimplifyProj<T> = { [K in keyof T]: T[K] } & {};\n\n// --------------------------------------------------------------------------\n// builder\n// --------------------------------------------------------------------------\n\n/**\n * Immutable, chainable SELECT builder.\n *\n * @typeParam Full - the complete row type (constrains where/orderBy keys).\n * @typeParam Proj - the projected result type returned on execution.\n */\nexport class SelectBuilder<Full, Proj = Full, Grouped extends boolean = false> {\n /** Phantom: the result element type, read only by the type system. */\n declare readonly __row: Proj;\n /** Phantom: `true` once `aggregate()` has made `having()` meaningful. */\n declare readonly __grouped: Grouped;\n\n constructor(\n readonly node: SelectNode,\n /** The source model, used to coerce rows on execution. */\n readonly source: ModelClass,\n ) {}\n\n private with(patch: Partial<SelectNode>): SelectBuilder<Full, Proj, Grouped> {\n return new SelectBuilder<Full, Proj, Grouped>(\n { ...this.node, ...patch },\n this.source,\n );\n }\n\n /** Add a WHERE filter: the object form (keys typed) or an `and`/`or`/`not`. */\n where(input: WhereInput<Full> | Condition): SelectBuilder<Full, Proj, Grouped> {\n return this.with({ where: toCondNode(input as Record<string, unknown>) });\n }\n\n /**\n * Filter by the result of the aggregation (`HAVING`).\n *\n * Only available on a grouped builder — `.having()` before `.aggregate()` is a\n * compile error, not invalid SQL at runtime. Keys are the aggregate aliases you\n * named plus the grouped columns; `WHERE` still filters rows *before* grouping,\n * which is a different question.\n *\n * @param input The condition, keyed by alias or grouped column.\n * @returns A builder carrying the `HAVING` clause.\n *\n * @example\n * ```ts\n * select(Outbound)\n * .where({ status: \"queued\" })\n * .aggregate([\"consumer\"], { n: count() })\n * .having({ n: { gt: 100 } });\n * // ... GROUP BY \"consumer\" HAVING COUNT(*) > $2\n * ```\n */\n having(\n this: SelectBuilder<Full, Proj, true>,\n input: WhereInput<Proj> | Condition,\n ): SelectBuilder<Full, Proj, true> {\n return new SelectBuilder<Full, Proj, true>(\n { ...this.node, having: toCondNode(input as Record<string, unknown>) },\n this.source,\n );\n }\n\n /** Emit `SELECT DISTINCT` — drop duplicate rows. */\n distinct(): SelectBuilder<Full, Proj, Grouped> {\n return this.with({ distinct: true });\n }\n\n /**\n * Group by columns and compute aggregates. The result row is the grouped\n * columns (typed from the model) plus one field per aggregate alias.\n *\n * @param groupBy The columns to group by (checked against the model). Pass `[]`\n * for a whole-table aggregate.\n * @param spec A map of result alias → aggregate expression ({@link count},\n * {@link sum}, {@link avg}, {@link min}, {@link max}).\n * @returns A builder whose row is `Pick<Full, K> & { [alias]: aggResult }`.\n *\n * @example\n * ```ts\n * select(Order).aggregate([\"status\"], { n: count(), total: sum(\"amount\") });\n * // rows: { status: string; n: number; total: number | null }[]\n * ```\n */\n aggregate<K extends keyof Full & string, S extends Record<string, Agg<unknown>>>(\n groupBy: readonly K[],\n spec: S,\n ): SelectBuilder<\n Full,\n SimplifyProj<Pick<Full, K> & { [A in keyof S]: AggResult<S[A]> }>,\n true\n > {\n const aggregates: AggregateTerm[] = Object.entries(spec).map(([alias, agg]) => ({\n fn: agg.fn,\n column: agg.column,\n alias,\n }));\n return new SelectBuilder(\n { ...this.node, aggregates, groupBy },\n this.source,\n ) as unknown as SelectBuilder<\n Full,\n SimplifyProj<Pick<Full, K> & { [A in keyof S]: AggResult<S[A]> }>,\n true\n >;\n }\n\n /**\n * Order by a column of the model, or — on a grouped query — by an aggregate\n * alias. Unlike `HAVING`, every dialect accepts the output alias in `ORDER BY`,\n * so the alias is emitted as written.\n *\n * @param column A model column, or a projected alias.\n * @param direction `\"asc\"` (default) or `\"desc\"`.\n * @returns A builder carrying the ordering term.\n */\n /**\n * Project extra expressions alongside the columns, by alias.\n *\n * This is where a window function lands: unlike `aggregate()`, it does **not**\n * group — every row stays, with the computed value attached.\n *\n * @param map Alias → expression.\n * @returns A builder whose row type carries the aliases.\n *\n * @example\n * ```ts\n * select(Sale).compute({\n * rank: over(rowNumber(), { partitionBy: [\"region\"], orderBy: [[\"total\", \"desc\"]] }),\n * });\n * ```\n */\n compute<M extends Record<string, Expression<unknown>>>(\n map: M,\n ): SelectBuilder<\n Full,\n Simplify<Proj & { [K in keyof M]: ExpressionValue<M[K]> }>,\n Grouped\n > {\n const computed: Record<string, ExprNode> = { ...(this.node.computed ?? {}) };\n for (const [alias, expression] of Object.entries(map)) {\n computed[alias] = expression.node;\n }\n return this.with({ computed }) as unknown as SelectBuilder<\n Full,\n Simplify<Proj & { [K in keyof M]: ExpressionValue<M[K]> }>,\n Grouped\n >;\n }\n\n orderBy(\n column: (keyof Full & string) | (keyof Proj & string) | Expression,\n direction: SortDirection = \"asc\",\n ): SelectBuilder<Full, Proj, Grouped> {\n return this.with({\n orderBy: [\n ...this.node.orderBy,\n { column: typeof column === \"string\" ? column : column.node, direction },\n ],\n });\n }\n\n /** Limit the number of rows. */\n limit(n: number): SelectBuilder<Full, Proj, Grouped> {\n return this.with({ limit: n });\n }\n\n /** Skip the first `n` rows. */\n offset(n: number): SelectBuilder<Full, Proj, Grouped> {\n return this.with({ offset: n });\n }\n\n /**\n * Narrow this SELECT to a single column and mark it as a subquery, so it can be\n * the operand of `in` / `notIn`.\n *\n * The whole query — `where`, `orderBy`, `limit`, and a locking clause — is\n * embedded in the outer statement, which is what collapses the claim-a-batch\n * pattern into one round trip instead of selecting ids and sending them back.\n *\n * @param column The single column to project (checked against the model).\n * @returns A subquery carrying that column's type.\n *\n * @example\n * ```ts\n * update(Outbound)\n * .set({ status: \"sending\", attempts: sql.raw(\"attempts + 1\") })\n * .where({\n * id: {\n * in: select(Outbound)\n * .where({ status: \"queued\" })\n * .orderBy(\"nextAttemptAt\")\n * .limit(10)\n * .forUpdate({ skipLocked: true })\n * .asSubquery(\"id\"),\n * },\n * })\n * .returning();\n * ```\n */\n asSubquery<K extends keyof Full & string>(column: K): Subquery<Full[K]> {\n return { node: { ...this.node, columns: [column] } } as Subquery<Full[K]>;\n }\n\n /**\n * Lock the selected rows for update (`SELECT ... FOR UPDATE`), à la\n * SQLAlchemy's `with_for_update()`.\n *\n * `{ skipLocked: true }` is the job-queue claim: competing workers each take a\n * disjoint batch instead of blocking on — or worse, double-processing — the\n * same rows.\n *\n * PostgreSQL and MySQL 8.0+ only. SQLite has no row-level locking, and its\n * dialect throws rather than emitting a `SELECT` that silently locks nothing —\n * a lock that does not exist only fails under production concurrency.\n *\n * @param options `skipLocked` / `noWait` wait behavior, and `of` to restrict\n * the lock to specific tables.\n * @returns A builder carrying the locking clause.\n * @throws Error When both `skipLocked` and `noWait` are set.\n *\n * @example\n * ```ts\n * const batch = await session.execute(\n * select(Outbound)\n * .where({ status: \"queued\" })\n * .orderBy(\"nextAttemptAt\")\n * .limit(10)\n * .forUpdate({ skipLocked: true }),\n * ).all();\n * ```\n */\n forUpdate(options?: LockOptions): SelectBuilder<Full, Proj, Grouped> {\n return this.with({ lock: buildLock(\"update\", options) });\n }\n\n /**\n * Take a shared read lock on the selected rows (`SELECT ... FOR SHARE`), the\n * weaker counterpart of {@link SelectBuilder.forUpdate}.\n *\n * @param options `skipLocked` / `noWait` wait behavior, and `of` tables.\n * @returns A builder carrying the locking clause.\n * @throws Error When both `skipLocked` and `noWait` are set.\n */\n forShare(options?: LockOptions): SelectBuilder<Full, Proj, Grouped> {\n return this.with({ lock: buildLock(\"share\", options) });\n }\n}\n\n/** Normalize {@link LockOptions} into the AST's {@link LockClause}. */\nfunction buildLock(\n strength: LockClause[\"strength\"],\n options: LockOptions | undefined,\n): LockClause {\n if (options?.skipLocked && options?.noWait) {\n throw new Error(\"forUpdate/forShare accept skipLocked or noWait, not both.\");\n }\n const wait: LockClause[\"wait\"] = options?.skipLocked\n ? \"skipLocked\"\n : options?.noWait\n ? \"noWait\"\n : \"block\";\n return { strength, wait, of: options?.of ?? [] };\n}\n\n// --------------------------------------------------------------------------\n// entrypoint\n// --------------------------------------------------------------------------\n\n/** Build a SELECT over every column of the model. */\nexport function select<C extends ModelClass>(\n model: C,\n): SelectBuilder<InferModel<C>, InferModel<C>>;\n\n/** Build a SELECT projecting only the given columns. */\nexport function select<C extends ModelClass, K extends keyof InferModel<C> & string>(\n model: C,\n columns: readonly K[],\n): SelectBuilder<InferModel<C>, Pick<InferModel<C>, K>>;\n\nexport function select(\n model: ModelClass,\n columns?: readonly string[],\n): SelectBuilder<unknown, unknown> {\n const base = aliasOf(model);\n return new SelectBuilder(\n {\n kind: \"select\",\n table: base ? base.tablename : model.tablename,\n alias: base ? model.tablename : undefined,\n columns: columns ?? \"*\",\n distinct: false,\n aggregates: [],\n groupBy: [],\n where: undefined,\n orderBy: [],\n limit: undefined,\n offset: undefined,\n names: columnNamesOf(model) ?? undefined,\n codecs: codecsOf(model) ?? undefined,\n },\n model,\n );\n}\n","/**\n * tempest-db-js — database URL parsing & dialect detection.\n *\n * Mirrors SQLAlchemy's `make_url`: a single connection string identifies the\n * dialect (and optional driver), so switching databases is just swapping the\n * URL — `sqlite://./app.db` ↔ `postgresql://user:pass@host/db`.\n *\n * The driver suffix (`postgresql+pg`, `sqlite+better-sqlite3`, or SQLAlchemy's\n * async flavors like `postgresql+asyncpg`) is parsed out and ignored for dialect\n * detection, so URLs copied from a Python service still work here.\n */\n\n/** A database dialect tempest-db-js can target. */\nexport type Dialect = \"sqlite\" | \"postgresql\" | \"mysql\";\n\n/** A parsed database URL, dialect-neutral. */\nexport interface ParsedDatabaseUrl {\n /** The detected dialect. */\n readonly dialect: Dialect;\n /** Driver after the `+` in the scheme (e.g. `better-sqlite3`), or `null`. */\n readonly driver: string | null;\n /** Host (PostgreSQL/MySQL), or `null` for SQLite. */\n readonly host: string | null;\n /** Port, or `null`. */\n readonly port: number | null;\n /** Username, or `null`. */\n readonly user: string | null;\n /** Password, or `null`. */\n readonly password: string | null;\n /** Database name (PostgreSQL) or file path (SQLite). `:memory:` for in-memory. */\n readonly database: string | null;\n /** Extra query-string options (`?sslmode=require`). */\n readonly options: Readonly<Record<string, string>>;\n /** The original URL, untouched. */\n readonly raw: string;\n}\n\n/** Raised when a URL cannot be parsed or its dialect is unsupported. */\nexport class InvalidDatabaseUrl extends Error {\n constructor(url: string, reason: string) {\n super(`Invalid database URL ${JSON.stringify(url)}: ${reason}`);\n this.name = \"InvalidDatabaseUrl\";\n }\n}\n\n/** Map a scheme's base name to a tempest-db-js dialect. */\nconst DIALECT_ALIASES: Readonly<Record<string, Dialect>> = {\n sqlite: \"sqlite\",\n sqlite3: \"sqlite\",\n postgresql: \"postgresql\",\n postgres: \"postgresql\",\n pg: \"postgresql\",\n mysql: \"mysql\",\n mariadb: \"mysql\",\n};\n\n/** Split `\"postgresql+asyncpg\"` into `[\"postgresql\", \"asyncpg\"]`. */\nfunction splitScheme(scheme: string): { base: string; driver: string | null } {\n const plus = scheme.indexOf(\"+\");\n if (plus === -1) return { base: scheme.toLowerCase(), driver: null };\n return {\n base: scheme.slice(0, plus).toLowerCase(),\n driver: scheme.slice(plus + 1) || null,\n };\n}\n\n/** Decode a URL component, leaving it untouched if it is not encoded. */\nfunction decode(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\n/**\n * Parse a SQLite URL. Forms supported (SQLAlchemy-compatible):\n * - `sqlite://:memory:` / `sqlite::memory:` → in-memory\n * - `sqlite:///relative/path.db` → relative path\n * - `sqlite:////absolute/path.db` → absolute path\n * - `sqlite://./app.db` / `sqlite:app.db` → relative path (convenience)\n */\nfunction parseSqlite(\n raw: string,\n driver: string | null,\n rest: string,\n): ParsedDatabaseUrl {\n let database: string;\n if (rest.endsWith(\":memory:\")) {\n database = \":memory:\";\n } else if (rest.startsWith(\"///\")) {\n // sqlite:///rel → \"rel\" ; sqlite:////abs → \"/abs\"\n database = rest.slice(3) || \":memory:\";\n } else if (rest.startsWith(\"//\")) {\n database = rest.slice(2) || \":memory:\";\n } else {\n database = rest || \":memory:\";\n }\n return {\n dialect: \"sqlite\",\n driver,\n host: null,\n port: null,\n user: null,\n password: null,\n database: decode(database),\n options: {},\n raw,\n };\n}\n\n/**\n * Parse a network-style URL (PostgreSQL or MySQL) via the WHATWG URL parser.\n * Both share the `scheme://user:pass@host:port/db?opts` shape, so one parser\n * serves both — only the resulting `dialect` differs.\n */\nfunction parseNetworkUrl(\n raw: string,\n driver: string | null,\n rest: string,\n dialect: \"postgresql\" | \"mysql\",\n): ParsedDatabaseUrl {\n // Rebuild with a clean scheme so the WHATWG URL parser accepts it.\n let parsed: URL;\n try {\n parsed = new URL(`${dialect}:${rest}`);\n } catch {\n throw new InvalidDatabaseUrl(raw, \"could not parse host/credentials\");\n }\n const database = decode(parsed.pathname.replace(/^\\//, \"\")) || null;\n const options: Record<string, string> = {};\n for (const [key, value] of parsed.searchParams) options[key] = value;\n return {\n dialect,\n driver,\n host: parsed.hostname || null,\n port: parsed.port ? Number(parsed.port) : null,\n user: parsed.username ? decode(parsed.username) : null,\n password: parsed.password ? decode(parsed.password) : null,\n database,\n options,\n raw,\n };\n}\n\n/**\n * Parse a database URL into its dialect and connection parts.\n *\n * @param url A connection string, e.g. `\"postgresql://app:app@localhost/app\"`\n * or `\"sqlite:///app.db\"`. An async driver suffix (`+asyncpg`, `+aiosqlite`)\n * is accepted and ignored for dialect detection.\n * @returns The parsed, dialect-neutral connection descriptor.\n * @throws InvalidDatabaseUrl When the URL has no scheme or an unknown dialect.\n */\nexport function parseDatabaseUrl(url: string): ParsedDatabaseUrl {\n const schemeEnd = url.indexOf(\":\");\n if (schemeEnd === -1) {\n throw new InvalidDatabaseUrl(\n url,\n \"missing scheme (expected e.g. sqlite:// or postgresql://)\",\n );\n }\n const { base, driver } = splitScheme(url.slice(0, schemeEnd));\n const dialect = DIALECT_ALIASES[base];\n if (!dialect) {\n throw new InvalidDatabaseUrl(url, `unknown dialect ${JSON.stringify(base)}`);\n }\n const rest = url.slice(schemeEnd + 1);\n if (dialect === \"sqlite\") return parseSqlite(url, driver, rest);\n return parseNetworkUrl(url, driver, rest, dialect);\n}\n\n/** Detect just the dialect of a URL, ignoring the rest. */\nexport function detectDialect(url: string): Dialect {\n return parseDatabaseUrl(url).dialect;\n}\n","/**\n * tempest-db-js — text search that survives what users actually type.\n *\n * Two layers, because they answer different questions:\n *\n * - {@link contains} — tokenized, **escaped** substring matching. Identical on\n * every dialect, needs no extension, no index and no migration. This is what\n * \"find the row whose name contains what the user typed\" should use.\n * - {@link fullText} / {@link fullTextRank} — PostgreSQL's `to_tsvector` /\n * `websearch_to_tsquery` / `ts_rank`: stemming, stop words and a relevance\n * score. On any other database they fall back to the first layer, which is the\n * honest degradation — the query still returns the right rows, just without\n * stemming.\n */\n\nimport { type Condition, type Expression, and, or } from \"./conditions.js\";\nimport { conditionFromNode, expressionFromNode } from \"./conditions.js\";\nimport type { WhereInput } from \"./query.js\";\n\n/**\n * A PostgreSQL text-search configuration (`regconfig`), such as `\"english\"` or\n * `\"portuguese\"`. `\"simple\"` disables stemming and stop-word removal.\n */\nexport type TextSearchLanguage = string;\n\n/** Options shared by the full-text helpers. */\nexport interface TextSearchOptions {\n /** The PostgreSQL text-search configuration. Defaults to `\"english\"`. */\n readonly language?: TextSearchLanguage;\n}\n\n/** Options for {@link contains}. */\nexport interface ContainsOptions {\n /**\n * Whether a row must match **every** token (default) or any one of them.\n *\n * `\"all\"` is what a search box wants: typing more words narrows the result.\n */\n readonly match?: \"all\" | \"any\";\n}\n\n/**\n * Escape the `LIKE` wildcards in a literal, for use with `like` / `ilike`.\n *\n * `%` and `_` are wildcards, and `\\` escapes them — so a user searching for\n * `100%` matches every row unless the literal is escaped first. The pattern this\n * produces is meant to be used with an `ESCAPE '\\'` clause, which is what the\n * {@link ContainsOptions} operator emits; PostgreSQL assumes that escape by\n * default, SQLite has none until it is given one.\n *\n * @param value The literal the user typed.\n * @returns The same text with `\\`, `%` and `_` escaped.\n */\nexport function escapeLike(value: string): string {\n return value.replace(/[\\\\%_]/g, (char) => `\\\\${char}`);\n}\n\n/**\n * Split a search term into the tokens a row has to match.\n *\n * @param term What the user typed.\n * @returns The non-empty whitespace-separated tokens.\n */\nexport function tokenize(term: string): string[] {\n return term.split(/\\s+/).filter((token) => token.length > 0);\n}\n\n/**\n * Case-insensitive substring search across one or more columns.\n *\n * The term is tokenized, and each token is matched — **escaped** — against every\n * listed column; a row matches when every token appears in at least one of them.\n * Behaves the same on every dialect, with no index or extension needed.\n *\n * @param columns The columns to search, by property name.\n * @param term What the user typed.\n * @param options `match: \"any\"` to require a single token instead of all of them.\n * @returns A condition for `where`, matching nothing when the term is blank.\n * @throws Error When no column is given.\n *\n * @example\n * ```ts\n * select(User).where(contains([\"name\", \"email\"], \"100% ana\"));\n * // (name ILIKE '%100\\%%' ESCAPE '\\' OR email ILIKE ...) AND (name ILIKE '%ana%' ...)\n * ```\n */\nexport function contains<Row = Record<string, unknown>>(\n columns: readonly string[],\n term: string,\n options?: ContainsOptions,\n): Condition {\n if (columns.length === 0) {\n throw new Error(\"contains() needs at least one column to search.\");\n }\n const tokens = tokenize(term);\n if (tokens.length === 0) return alwaysFalse();\n const perToken = tokens.map((token) =>\n or<Row>(\n ...columns.map((column) => ({ [column]: { iContains: token } }) as WhereInput<Row>),\n ),\n );\n if (options?.match === \"any\") return or<Row>(...perToken);\n return perToken.length === 1 ? (perToken[0] as Condition) : and<Row>(...perToken);\n}\n\n/** A condition matching no row, for a search whose term carried no tokens. */\nfunction alwaysFalse(): Condition {\n return conditionFromNode({\n kind: \"compare\",\n left: { kind: \"value\", value: 1 },\n op: \"eq\",\n right: { kind: \"value\", value: 0 },\n });\n}\n\n/**\n * PostgreSQL full-text search over one or more columns, with a portable fallback.\n *\n * On PostgreSQL this compiles to `to_tsvector(config, col || ' ' || col) @@\n * websearch_to_tsquery(config, term)`, so the search stems (`buying` matches\n * `buy`), drops stop words, and understands the quoting and `-exclusion` syntax\n * users already know from web search boxes.\n *\n * On any other database it compiles to {@link contains} instead — the same rows a\n * substring search would find, without stemming. That is a documented\n * degradation, not a silent one: a dev SQLite database keeps working, and the\n * difference is in ranking quality, not correctness.\n *\n * @param columns The columns to search, by property name.\n * @param term What the user typed.\n * @param options The text-search configuration.\n * @returns A condition for `where`.\n * @throws Error When no column is given.\n */\nexport function fullText<Row = Record<string, unknown>>(\n columns: readonly string[],\n term: string,\n options?: TextSearchOptions,\n): Condition {\n if (columns.length === 0) {\n throw new Error(\"fullText() needs at least one column to search.\");\n }\n return conditionFromNode({\n kind: \"fullText\",\n columns: [...columns],\n term,\n language: options?.language ?? \"english\",\n fallback: contains<Row>(columns, term).node,\n });\n}\n\n/**\n * The relevance score of a full-text match, for `orderBy`.\n *\n * On PostgreSQL this is `ts_rank(...)`, the number that makes \"best match first\"\n * mean something. Elsewhere it renders as a constant, so ordering by it is a\n * no-op and the query falls back to whatever other ordering is given — ranking is\n * the part that genuinely does not exist without a text-search engine.\n *\n * @param columns The same columns passed to {@link fullText}.\n * @param term The same term.\n * @param options The same configuration.\n * @returns An expression usable in `orderBy`.\n * @throws Error When no column is given.\n *\n * @example\n * ```ts\n * select(Post)\n * .where(fullText([\"title\", \"body\"], term, { language: \"portuguese\" }))\n * .orderBy(fullTextRank([\"title\", \"body\"], term, { language: \"portuguese\" }), \"desc\");\n * ```\n */\nexport function fullTextRank(\n columns: readonly string[],\n term: string,\n options?: TextSearchOptions,\n): Expression {\n if (columns.length === 0) {\n throw new Error(\"fullTextRank() needs at least one column to rank on.\");\n }\n return expressionFromNode({\n kind: \"rank\",\n columns: [...columns],\n term,\n language: options?.language ?? \"english\",\n });\n}\n","/**\n * tempest-db-js — feasibility spike for Phase 1.\n *\n * Proves the central design claim: a class-based, SQLAlchemy-style model whose\n * fields are runtime column-builders can drive full static row-type inference in\n * TypeScript, despite TS erasing types at runtime.\n *\n * This is a SPIKE, not the final API. It validates the type machinery only.\n */\n\nimport {\n type CondNode,\n type Condition,\n type ExprNode,\n toCondNode,\n} from \"./conditions.js\";\n\n/** Phantom marker carrying the static TS type a column maps to. */\ndeclare const TYPE: unique symbol;\n\n/** Column flags that influence the inferred row/insert shape. */\ninterface ColumnFlags {\n readonly primaryKey: boolean;\n readonly notNull: boolean;\n readonly hasDefault: boolean;\n /**\n * A `UNIQUE` constraint on the column. Does NOT influence the inferred type —\n * it is DDL-only metadata (mirrors SQLAlchemy's `mapped_column(unique=True)`).\n */\n readonly unique: boolean;\n}\n\nconst DEFAULT_FLAGS: ColumnFlags = {\n primaryKey: false,\n notNull: false,\n hasDefault: false,\n unique: false,\n};\n\n/**\n * The canonical, dialect-neutral kind of a column type. Mirrors SQLAlchemy's\n * generic types (e.g. `String` → varchar, `Text` → text). Dialect renderers\n * (Phase 4/6) map each kind + meta to concrete SQL per database.\n */\nexport type ColumnTypeKind =\n | \"smallint\"\n | \"integer\"\n | \"bigint\"\n | \"numeric\"\n | \"real\"\n | \"double\"\n | \"varchar\"\n | \"text\"\n | \"char\"\n | \"boolean\"\n | \"date\"\n | \"time\"\n | \"datetime\"\n | \"timestamp\"\n | \"blob\"\n | \"json\"\n | \"uuid\"\n | \"enum\"\n | \"array\";\n\n/** Parameters that refine a column type and feed the migration IR / DDL. */\nexport interface ColumnTypeMeta {\n /** Max length for `varchar`/`char`. */\n readonly length?: number | undefined;\n /** Total digits for `numeric`. */\n readonly precision?: number | undefined;\n /** Digits after the decimal point for `numeric`. */\n readonly scale?: number | undefined;\n /** `WITH TIME ZONE` for `timestamp`/`time`. */\n readonly withTimezone?: boolean | undefined;\n /** Allowed values for `enum`. */\n readonly values?: readonly string[] | undefined;\n /** Render as `JSONB` (PostgreSQL) instead of `JSON`. */\n readonly jsonb?: boolean | undefined;\n /** The element type of an `array` column (`text[]`, `integer[]`). */\n readonly element?: ColumnType | undefined;\n}\n\n/** A structured, dialect-neutral column type descriptor. */\nexport interface ColumnType {\n readonly kind: ColumnTypeKind;\n readonly meta: ColumnTypeMeta;\n}\n\n/**\n * A portable default expression. The token is dialect-neutral; the renderer\n * (Phase 4/6) maps it to the right SQL per database — e.g. `\"now\"` becomes\n * `CURRENT_TIMESTAMP` on SQLite and `now()` on PostgreSQL. Use `{ raw }` as an\n * escape hatch for a verbatim SQL fragment, or `{ parts }` for a parameterized\n * fragment built by the `sql.expr` tagged template (one bound parameter per gap\n * between consecutive parts).\n */\nexport type PortableExpression =\n | \"now\"\n | \"current_date\"\n | \"current_time\"\n | \"uuidv4\"\n | { readonly raw: string }\n | { readonly parts: readonly string[] }\n /** The incoming value of a column, inside an upsert's `DO UPDATE` clause. */\n | { readonly excluded: string };\n\n/**\n * A column default. Either a constant literal value or a server-side expression\n * evaluated by the database (mirrors SQLAlchemy's `default` vs `server_default`).\n * Feeds the migration IR (`DefaultIR`).\n */\nexport type DefaultValue =\n | { readonly kind: \"literal\"; readonly value: unknown }\n | { readonly kind: \"expression\"; readonly expression: PortableExpression };\n\n/**\n * Brand marking a value as a SQL expression rather than a bound parameter.\n *\n * A plain object reaching `set()`/`values()` is a mistake (it would be bound as a\n * parameter and silently written as JSON or null); an object carrying this symbol\n * is deliberate, and the dialect renders it inline instead of binding it. Mirrors\n * how `Condition` is branded, so the check is a symbol lookup, not duck typing.\n */\nconst EXPRESSION = Symbol.for(\"tempest-db-js.expression\");\n\n/**\n * A SQL expression, usable both as a column default (`.default(sql.now())`) and\n * as a write value (`.set({ attempts: sql.raw(\"attempts + 1\") })`). The dialect\n * renders `expression` inline and binds `params` in the order of the fragment's\n * gaps.\n */\nexport interface SqlExpression {\n readonly [EXPRESSION]: true;\n readonly kind: \"expression\";\n readonly expression: PortableExpression;\n /** Parameters bound into the fragment's gaps, in order (empty for a token). */\n readonly params: readonly unknown[];\n}\n\n/** Build a branded {@link SqlExpression} from a portable token or fragment. */\nfunction expression(\n token: PortableExpression,\n params: readonly unknown[] = [],\n): SqlExpression {\n return { [EXPRESSION]: true, kind: \"expression\", expression: token, params };\n}\n\n/**\n * Turn a stored column default (or `onUpdate` value) into something the write\n * path can render.\n *\n * A default is kept as a {@link DefaultValue} — the shape the migration IR wants\n * — while `set()` and `values()` want either a bindable value or a branded\n * {@link SqlExpression}. This is the one conversion between the two.\n *\n * @param value The stored default.\n * @returns A literal to bind, or a branded expression to render inline.\n */\nexport function defaultAsWriteValue(value: DefaultValue): unknown {\n return value.kind === \"literal\" ? value.value : expression(value.expression);\n}\n\n/**\n * Runtime guard: is this value a branded {@link SqlExpression}?\n *\n * @param value Any value handed to `set()`, `values()` or `.default()`.\n * @returns True when the value carries the expression brand.\n */\nexport function isSqlExpression(value: unknown): value is SqlExpression {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as Record<PropertyKey, unknown>)[EXPRESSION] === true\n );\n}\n\n/**\n * Portable server-side expressions, à la SQLAlchemy's `func`.\n *\n * Every entry doubles as a column default and as a write value, so\n * `.default(sql.now())` and `.set({ updatedAt: sql.now() })` both work.\n */\nexport const sql = {\n /** Current timestamp at insert (`CURRENT_TIMESTAMP` / `now()`). */\n now: (): SqlExpression => expression(\"now\"),\n /** Current date. */\n currentDate: (): SqlExpression => expression(\"current_date\"),\n /** Current time. */\n currentTime: (): SqlExpression => expression(\"current_time\"),\n /** A freshly generated UUID v4 (`gen_random_uuid()` / portable fallback). */\n uuidv4: (): SqlExpression => expression(\"uuidv4\"),\n /**\n * The **incoming** value of a column, valid only inside an upsert's\n * `onConflictDoUpdate` patch.\n *\n * A multi-row upsert cannot spell the new value as a literal — each row has its\n * own — so the assignment has to name the row being inserted:\n * `EXCLUDED.\"total\"` on PostgreSQL and SQLite, `VALUES(total)` on MySQL.\n *\n * @param column The column's property name.\n * @returns The expression, for use as a write value.\n */\n excluded: (column: string): SqlExpression => expression({ excluded: column }),\n /**\n * Escape hatch: a verbatim SQL expression rendered as-is, with no parameters.\n *\n * The fragment is interpolated into the statement untouched, so it must never\n * carry user input — use {@link sql.expr} when a value has to be bound.\n *\n * @param fragment The SQL text (e.g. `\"attempts + 1\"`).\n * @returns The expression, usable as a default and as a write value.\n */\n raw: (fragment: string): SqlExpression => expression({ raw: fragment }),\n /**\n * A parameterized SQL expression, written as a tagged template. Static text is\n * SQL; every `${...}` interpolation becomes a bound parameter, so the fragment\n * is injection-safe by construction.\n *\n * Cannot be used as a column default — a `DEFAULT` clause has nowhere to bind\n * parameters; use {@link sql.raw} there.\n *\n * @param parts The static SQL segments supplied by the template tag.\n * @param values The interpolated values, bound in order.\n * @returns The expression, usable as a write value.\n *\n * @example\n * ```ts\n * update(Account).set({ balance: sql.expr`balance - ${amount}` }).where({ id });\n * // UPDATE \"accounts\" SET \"balance\" = balance - $1 WHERE \"id\" = $2\n * ```\n */\n expr: (parts: TemplateStringsArray, ...values: unknown[]): SqlExpression =>\n expression({ parts: Array.from(parts) }, values),\n} as const;\n\n/** Narrow a `.default()` argument to a `DefaultValue` expression/literal marker. */\nfunction isDefaultValue(value: unknown): value is DefaultValue {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"kind\" in value &&\n ((value as { kind: unknown }).kind === \"literal\" ||\n (value as { kind: unknown }).kind === \"expression\")\n );\n}\n\n/** True when an expression carries bound parameters (illegal in a DDL default). */\nfunction bindsParameters(value: DefaultValue): boolean {\n return (\n value.kind === \"expression\" &&\n typeof value.expression === \"object\" &&\n \"parts\" in value.expression\n );\n}\n\n/**\n * A referential action for a foreign key's `ON DELETE` / `ON UPDATE` clause.\n * Dialect-neutral tokens rendered uppercase at the DDL edge (mirrors\n * SQLAlchemy's `ForeignKey(ondelete=..., onupdate=...)`).\n */\nexport type FkAction = \"cascade\" | \"restrict\" | \"set null\" | \"set default\" | \"no action\";\n\n/**\n * A resolved foreign-key reference: the target `table.column` plus optional\n * referential actions. Produced by `Column.references(\"table.column\", ...)`.\n */\nexport interface ForeignKeyRef {\n readonly table: string;\n readonly column: string;\n readonly onDelete?: FkAction | undefined;\n readonly onUpdate?: FkAction | undefined;\n}\n\n/** Options for a foreign-key reference (referential actions). */\nexport interface ForeignKeyOptions {\n readonly onDelete?: FkAction | undefined;\n readonly onUpdate?: FkAction | undefined;\n}\n\n/** Parse a `\"table.column\"` reference string into a {@link ForeignKeyRef}. */\nfunction parseReference(ref: string, options?: ForeignKeyOptions): ForeignKeyRef {\n const dot = ref.lastIndexOf(\".\");\n if (dot <= 0 || dot === ref.length - 1) {\n throw new Error(`Invalid foreign key reference \"${ref}\"; expected \"table.column\".`);\n }\n return {\n table: ref.slice(0, dot),\n column: ref.slice(dot + 1),\n onDelete: options?.onDelete,\n onUpdate: options?.onUpdate,\n };\n}\n\n/**\n * A typed column builder. Holds runtime metadata (structured `type`, `flags`,\n * `default`, `onUpdate`, foreign-key `reference`) and a phantom static type `T`\n * used purely for inference.\n */\nclass Column<T, F extends ColumnFlags = ColumnFlags> {\n /** Phantom: never read at runtime, only inspected by the type system. */\n declare readonly [TYPE]: T;\n\n constructor(\n readonly type: ColumnType,\n readonly flags: F,\n /** The default applied on insert, or `null` for none. */\n readonly defaultValue: DefaultValue | null = null,\n /** The value re-applied on update (e.g. `updated_at`), or `null`. */\n readonly onUpdateValue: DefaultValue | null = null,\n /** The foreign-key reference this column points to, or `null` for none. */\n readonly reference: ForeignKeyRef | null = null,\n /** An explicit database column name overriding the property name, or `null`. */\n readonly dbName: string | null = null,\n /** Conversion to and from the stored representation, or `null` for none. */\n readonly codec: ColumnCodec | null = null,\n ) {}\n\n /** Clone this column with one facet replaced, carrying every other over. */\n private derive<F2 extends ColumnFlags>(patch: {\n flags?: F2;\n defaultValue?: DefaultValue | null;\n onUpdateValue?: DefaultValue | null;\n reference?: ForeignKeyRef | null;\n dbName?: string | null;\n codec?: ColumnCodec | null;\n }): Column<T, F2> {\n return new Column<T, F2>(\n this.type,\n (patch.flags ?? this.flags) as F2,\n patch.defaultValue !== undefined ? patch.defaultValue : this.defaultValue,\n patch.onUpdateValue !== undefined ? patch.onUpdateValue : this.onUpdateValue,\n patch.reference !== undefined ? patch.reference : this.reference,\n patch.dbName !== undefined ? patch.dbName : this.dbName,\n patch.codec !== undefined ? patch.codec : this.codec,\n );\n }\n\n primaryKey(): Column<T, F & { primaryKey: true; hasDefault: true }> {\n return this.derive({ flags: { ...this.flags, primaryKey: true, hasDefault: true } });\n }\n\n notNull(): Column<T, F & { notNull: true }> {\n return this.derive({ flags: { ...this.flags, notNull: true } });\n }\n\n /**\n * Add a `UNIQUE` constraint to the column (mirrors SQLAlchemy's\n * `mapped_column(unique=True)`). DDL-only — does not change the inferred type.\n */\n unique(): Column<T, F & { unique: true }> {\n return this.derive({ flags: { ...this.flags, unique: true } });\n }\n\n /**\n * Map this property to a differently-named database column, à la SQLAlchemy's\n * `mapped_column(\"consumer_name\")` (Django's `db_column`, Prisma's `@map`).\n *\n * The override applies everywhere the name reaches SQL — select, insert,\n * update, delete, where, order by, group by, returning, conflict targets, the\n * migration IR and the drift check — while the TypeScript row keeps the\n * property name. Use it to keep a `snake_case` schema behind a `camelCase`\n * model; {@link Model.naming} does the same for a whole table at once.\n *\n * @param dbName The real column name in the database.\n * @returns A new column bound to that name.\n * @throws Error When `dbName` is empty.\n *\n * @example\n * ```ts\n * class ApiKey extends Model {\n * static tablename = \"api_keys\";\n * consumerName = column.text().name(\"consumer_name\").notNull();\n * }\n * ```\n */\n name(dbName: string): Column<T, F> {\n if (dbName.length === 0) {\n throw new Error(\"column.name() requires a non-empty database column name.\");\n }\n return this.derive({ dbName });\n }\n\n /**\n * Declare a foreign-key reference to another table's column, à la SQLAlchemy's\n * `mapped_column(ForeignKey(\"table.column\", ondelete=...))`. DDL-only — does\n * not change the inferred type.\n *\n * @param ref The target as `\"table.column\"` (e.g. `\"users.id\"`).\n * @param options Optional `onDelete` / `onUpdate` referential actions.\n * @returns A new column carrying the reference.\n * @throws Error When `ref` is not a valid `\"table.column\"` string.\n */\n references(ref: string, options?: ForeignKeyOptions): Column<T, F> {\n return this.derive({ reference: parseReference(ref, options) });\n }\n\n /**\n * Set the insert-time default: a constant value of type `T`, or a portable\n * server-side expression from {@link sql} (e.g. `sql.now()`, `sql.uuidv4()`).\n *\n * @param value The literal default, or a {@link sql} expression.\n * @returns A new column carrying the default.\n * @throws Error When given a `sql.expr` fragment — a `DEFAULT` clause has\n * nowhere to bind parameters; use `sql.raw()` for a verbatim expression.\n */\n default(value: T | DefaultValue): Column<T, F & { hasDefault: true }> {\n const resolved: DefaultValue = isDefaultValue(value)\n ? value\n : { kind: \"literal\", value };\n if (bindsParameters(resolved)) {\n throw new Error(\n \"sql.expr`...` binds parameters and cannot be a column default — use sql.raw() for a verbatim DEFAULT expression.\",\n );\n }\n return this.derive({\n flags: { ...this.flags, hasDefault: true },\n defaultValue: resolved,\n });\n }\n\n /**\n * Re-apply a value whenever the row is updated (e.g. an `updated_at` column\n * with `sql.now()`). Mirrors SQLAlchemy's `onupdate`.\n *\n * @param value The literal value, or a {@link sql} expression.\n * @returns A new column carrying the on-update value.\n * @throws Error When given a `sql.expr` fragment (see {@link Column.default}).\n */\n onUpdate(value: T | DefaultValue): Column<T, F> {\n const resolved: DefaultValue = isDefaultValue(value)\n ? value\n : { kind: \"literal\", value };\n if (bindsParameters(resolved)) {\n throw new Error(\n \"sql.expr`...` binds parameters and cannot be an onUpdate default — use sql.raw() for a verbatim expression.\",\n );\n }\n return this.derive({ onUpdateValue: resolved });\n }\n}\n\n/**\n * Conversion between a domain value and what the database stores.\n *\n * The pair is applied on **both** paths — writes and reads — plus on a `where`\n * operand, so a custom-typed column cannot be compared against the wrong shape by\n * accident.\n */\nexport interface ColumnCodec {\n /** Domain value → stored value. */\n readonly toDb: (value: unknown) => unknown;\n /** Stored value → domain value. */\n readonly fromDb: (value: unknown) => unknown;\n}\n\n/**\n * Declare a column type of your own, over one this package already has.\n *\n * Money as integer cents, a `Temporal.Instant`, a branded id, a value object —\n * the conversion belongs to the column, not to every call site that forgets it.\n * The DDL and the migration IR keep using the **base** type, so a custom type is\n * invisible to the schema and cannot cause drift.\n *\n * @param spec `base` is a factory for the underlying column; `toDb`/`fromDb`\n * convert. `base` is a factory, not a column, because each declaration needs\n * its own instance.\n * @returns A factory producing columns of the custom type.\n *\n * @example\n * ```ts\n * const money = customType<Money, bigint>({\n * base: () => column.bigInteger(),\n * toDb: (m) => m.cents,\n * fromDb: (cents) => Money.fromCents(cents),\n * });\n *\n * class Order extends Model {\n * total = money().notNull();\n * }\n * ```\n */\nexport function customType<Domain, Stored>(spec: {\n base: () => Column<Stored, ColumnFlags>;\n toDb: (value: Domain) => Stored;\n fromDb: (value: Stored) => Domain;\n}): () => Column<Domain, ColumnFlags> {\n const codec: ColumnCodec = {\n toDb: (value) =>\n value === null || value === undefined ? value : spec.toDb(value as Domain),\n fromDb: (value) =>\n value === null || value === undefined ? value : spec.fromDb(value as Stored),\n };\n return () => {\n const base = spec.base();\n return new Column<Domain, ColumnFlags>(\n base.type,\n base.flags,\n base.defaultValue,\n base.onUpdateValue,\n base.reference,\n base.dbName,\n codec,\n );\n };\n}\n\n/** The per-column codecs of a model, keyed by property name, or `null` if none. */\nconst codecCache = new WeakMap<ModelClass, Record<string, ColumnCodec> | null>();\n\n/**\n * The codecs a model declares, by property name.\n *\n * `null` when the model has no custom type, which is the common case — the write\n * and read paths skip the whole conversion step on that answer.\n *\n * @param model The model class.\n * @returns The codec map, or `null`.\n */\nexport function codecsOf(model: ModelClass): Record<string, ColumnCodec> | null {\n const cached = codecCache.get(model);\n if (cached !== undefined) return cached;\n const codecs: Record<string, ColumnCodec> = {};\n let found = false;\n for (const [prop, col] of Object.entries(columnsOf(model))) {\n if (col.codec) {\n codecs[prop] = col.codec;\n found = true;\n }\n }\n const result = found ? codecs : null;\n codecCache.set(model, result);\n return result;\n}\n\n/** Build a `Column` of static type `T` from a kind + optional meta. */\nfunction makeColumn<T>(\n kind: ColumnTypeKind,\n meta: ColumnTypeMeta = {},\n): Column<T, ColumnFlags> {\n return new Column<T, ColumnFlags>({ kind, meta }, DEFAULT_FLAGS);\n}\n\n/**\n * Column factory mirroring SQLAlchemy's typed column constructors. Each entry\n * pairs a distinct SQL type with the TypeScript type it maps to.\n *\n * Notable mappings:\n * - `varchar(n)` (`VARCHAR(n)`) is distinct from `text` (`TEXT`).\n * - `bigInteger` maps to `bigint` (not `number`) to keep 64-bit precision.\n * - `numeric`/`decimal` map to `string` — JavaScript has no exact decimal, and\n * stringifying preserves precision instead of losing it to a float.\n * - `json<T>()` carries the parsed value type; `jsonb` is the PostgreSQL variant.\n * - `enum(...)` infers a string-literal union from its values.\n */\nexport const column = {\n /** `SMALLINT` → `number`. */\n smallInteger: (): Column<number, ColumnFlags> => makeColumn<number>(\"smallint\"),\n /** `INTEGER` → `number`. */\n integer: (): Column<number, ColumnFlags> => makeColumn<number>(\"integer\"),\n /** `BIGINT` → `bigint` (64-bit precision preserved). */\n bigInteger: (): Column<bigint, ColumnFlags> => makeColumn<bigint>(\"bigint\"),\n /** `NUMERIC(precision, scale)` → `string` (exact decimal, no float loss). */\n numeric: (precision?: number, scale?: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"numeric\", { precision, scale }),\n /** Alias of {@link column.numeric}. */\n decimal: (precision?: number, scale?: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"numeric\", { precision, scale }),\n /** `REAL` → `number`. */\n real: (): Column<number, ColumnFlags> => makeColumn<number>(\"real\"),\n /** `DOUBLE PRECISION` → `number`. */\n double: (): Column<number, ColumnFlags> => makeColumn<number>(\"double\"),\n /** `VARCHAR(length)` → `string`. Distinct from {@link column.text}. */\n varchar: (length: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"varchar\", { length }),\n /** Alias of {@link column.varchar} (SQLAlchemy's `String`). */\n string: (length: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"varchar\", { length }),\n /** `CHAR(length)` → `string` (fixed-width). */\n char: (length: number): Column<string, ColumnFlags> =>\n makeColumn<string>(\"char\", { length }),\n /** `TEXT` → `string` (unbounded). Distinct from {@link column.varchar}. */\n text: (): Column<string, ColumnFlags> => makeColumn<string>(\"text\"),\n /** `BOOLEAN` → `boolean`. */\n boolean: (): Column<boolean, ColumnFlags> => makeColumn<boolean>(\"boolean\"),\n /** `DATE` → `Date`. */\n date: (): Column<Date, ColumnFlags> => makeColumn<Date>(\"date\"),\n /** `TIME` → `string`. Pass `{ timezone: true }` for `WITH TIME ZONE`. */\n time: (options?: { timezone?: boolean }): Column<string, ColumnFlags> =>\n makeColumn<string>(\"time\", { withTimezone: options?.timezone }),\n /**\n * `DATETIME`/`TIMESTAMP` → `Date` (SQLAlchemy's generic `DateTime`). Pass\n * `{ timezone: true }` for `WITH TIME ZONE`. Pair with `.default(sql.now())`\n * and `.onUpdate(sql.now())` for managed `created_at`/`updated_at` columns.\n */\n datetime: (options?: { timezone?: boolean }): Column<Date, ColumnFlags> =>\n makeColumn<Date>(\"datetime\", { withTimezone: options?.timezone }),\n /** `TIMESTAMP` → `Date` (SQL-specific). Pass `{ timezone: true }`. */\n timestamp: (options?: { timezone?: boolean }): Column<Date, ColumnFlags> =>\n makeColumn<Date>(\"timestamp\", { withTimezone: options?.timezone }),\n /** `BLOB`/`BYTEA` → `Uint8Array`. */\n blob: (): Column<Uint8Array, ColumnFlags> => makeColumn<Uint8Array>(\"blob\"),\n /** `JSON` → the given parsed value type `T` (defaults to `unknown`). */\n json: <T = unknown>(): Column<T, ColumnFlags> => makeColumn<T>(\"json\"),\n /** `JSONB` (PostgreSQL) → the given parsed value type `T`. */\n jsonb: <T = unknown>(): Column<T, ColumnFlags> =>\n makeColumn<T>(\"json\", { jsonb: true }),\n /** `UUID` → `string`. */\n uuid: (): Column<string, ColumnFlags> => makeColumn<string>(\"uuid\"),\n /** `ENUM(...values)` → a string-literal union of the given values. */\n enum: <const E extends string>(...values: E[]): Column<E, ColumnFlags> =>\n makeColumn<E>(\"enum\", { values }),\n /**\n * A PostgreSQL array column (`text[]`, `integer[]`) → `T[]`.\n *\n * PostgreSQL only: SQLite and MySQL have no native array type, and rendering\n * one as JSON there would give the same model different semantics per dialect\n * (`@>` and `&&` work on one and not the other), so the DDL renderer throws\n * for those dialects instead of falling back silently.\n *\n * @param element The element column (its type, not its flags, is what is used).\n * @returns A column whose inferred type is an array of the element's type.\n *\n * @example\n * ```ts\n * class ApiKey extends Model {\n * static tablename = \"api_keys\";\n * scopes = column.array(column.text()).notNull().default([\"send\"]);\n * }\n * ```\n */\n array: <T>(element: Column<T, ColumnFlags>): Column<T[], ColumnFlags> =>\n makeColumn<T[]>(\"array\", { element: element.type }),\n} as const;\n\n/**\n * A table-level constraint declared via a model's `static tableArgs`. Mirrors\n * SQLAlchemy's `__table_args__` entries (`UniqueConstraint`, `ForeignKeyConstraint`).\n * Use the {@link unique} and {@link foreignKey} helpers to build these.\n */\nexport type TableConstraint =\n | {\n readonly kind: \"unique\";\n readonly name?: string | undefined;\n readonly columns: readonly string[];\n }\n | {\n readonly kind: \"check\";\n readonly name?: string | undefined;\n /** The invariant, in the same condition language `where` uses. */\n readonly expression: CondNode;\n /** Columns the expression mentions, for the generated name. */\n readonly columns: readonly string[];\n }\n | {\n readonly kind: \"index\";\n readonly name?: string | undefined;\n readonly columns: readonly string[];\n /** A unique index rather than a plain one. */\n readonly unique?: boolean | undefined;\n /** The predicate of a **partial** index, or `undefined` for a full one. */\n readonly where?: CondNode | undefined;\n }\n | {\n readonly kind: \"foreignKey\";\n readonly name?: string | undefined;\n readonly columns: readonly string[];\n readonly refTable: string;\n readonly refColumns: readonly string[];\n readonly onDelete?: FkAction | undefined;\n readonly onUpdate?: FkAction | undefined;\n };\n\n/**\n * Declare a (possibly composite) `UNIQUE` table constraint over the given\n * columns. Mirrors SQLAlchemy's `UniqueConstraint(\"a\", \"b\")`.\n *\n * @param columns The column names covered by the constraint.\n * @returns A unique {@link TableConstraint}.\n * @throws Error When no columns are given.\n */\nexport function unique(...columns: string[]): TableConstraint {\n if (columns.length === 0) {\n throw new Error(\"unique() requires at least one column.\");\n }\n return { kind: \"unique\", columns };\n}\n\n/**\n * Declare a (possibly composite) foreign-key table constraint. Mirrors\n * SQLAlchemy's `ForeignKeyConstraint([...], [...], ondelete=...)`.\n *\n * @param columns The local column names.\n * @param refTable The referenced table name.\n * @param refColumns The referenced column names (same length as `columns`).\n * @param options Optional constraint `name` and referential actions.\n * @returns A foreign-key {@link TableConstraint}.\n * @throws Error When the column arrays are empty or mismatched in length.\n */\n/**\n * Declare a `CHECK` constraint — an invariant the **database** enforces.\n *\n * The expression uses the same condition language as `where`, not a raw string:\n * a string would have to be compared textually to decide whether the schema\n * drifted, and two spellings of the same rule would read as a change.\n *\n * @param expression The invariant, e.g. `col(\"total\").gte(0)`.\n * @param options `name` to pin the constraint's name; `columns` to name the\n * generated one after something other than the expression's own columns.\n * @returns A check {@link TableConstraint}.\n *\n * @example\n * ```ts\n * class Order extends Model {\n * static override tableArgs = () => [check(col(\"total\").gte(0))];\n * }\n * ```\n */\nexport function check(\n expression: Condition | Record<string, unknown>,\n options?: { name?: string; columns?: readonly string[] },\n): TableConstraint {\n const node = toCondNode(expression);\n return {\n kind: \"check\",\n name: options?.name,\n expression: node,\n columns: options?.columns ?? conditionColumns(node),\n };\n}\n\n/**\n * Declare an index.\n *\n * An index the model does not declare is invisible to migrations: it never gets\n * created, and a table rebuild on SQLite drops it. Declaring it puts it in the\n * same place as the columns it covers.\n *\n * @param columns The indexed columns, in order.\n * @param options `unique` for a unique index, `where` for a **partial** one, and\n * `name` to pin the name.\n * @returns An index {@link TableConstraint}.\n * @throws Error When no column is given.\n *\n * @example\n * ```ts\n * static override tableArgs = () => [\n * index([\"customerId\", \"createdAt\"]),\n * index([\"email\"], { unique: true, where: { deletedAt: { isNull: true } } }),\n * ];\n * ```\n */\nexport function index(\n columns: readonly string[],\n options?: {\n name?: string;\n unique?: boolean;\n where?: Condition | Record<string, unknown>;\n },\n): TableConstraint {\n if (columns.length === 0) {\n throw new Error(\"index() requires at least one column.\");\n }\n return {\n kind: \"index\",\n name: options?.name,\n columns: [...columns],\n unique: options?.unique,\n where: options?.where === undefined ? undefined : toCondNode(options.where),\n };\n}\n\n/**\n * The columns a condition mentions, in first-seen order.\n *\n * Used to name a generated `CHECK` after what it constrains.\n *\n * @param node The condition.\n * @returns The column names.\n */\nfunction conditionColumns(node: CondNode): string[] {\n const found: string[] = [];\n const visitExpr = (expr: ExprNode): void => {\n if (expr.kind === \"column\") {\n if (!found.includes(expr.name)) found.push(expr.name);\n return;\n }\n if (expr.kind === \"fn\") for (const arg of expr.args) visitExpr(arg);\n if (expr.kind === \"cast\") visitExpr(expr.operand);\n };\n const visit = (current: CondNode): void => {\n switch (current.kind) {\n case \"fields\":\n for (const key of Object.keys(current.fields)) {\n if (!found.includes(key)) found.push(key);\n }\n return;\n case \"and\":\n case \"or\":\n for (const part of current.parts) visit(part);\n return;\n case \"not\":\n visit(current.part);\n return;\n case \"compare\":\n visitExpr(current.left);\n visitExpr(current.right);\n return;\n default:\n return;\n }\n };\n visit(node);\n return found;\n}\n\nexport function foreignKey(\n columns: string[],\n refTable: string,\n refColumns: string[],\n options?: { name?: string; onDelete?: FkAction; onUpdate?: FkAction },\n): TableConstraint {\n if (columns.length === 0 || columns.length !== refColumns.length) {\n throw new Error(\n \"foreignKey() requires matching, non-empty local and referenced column lists.\",\n );\n }\n return {\n kind: \"foreignKey\",\n name: options?.name,\n columns,\n refTable,\n refColumns,\n onDelete: options?.onDelete,\n onUpdate: options?.onUpdate,\n };\n}\n\n/**\n * How property names map to database column names when a column declares no\n * explicit {@link Column.name}.\n *\n * - `\"preserve\"` (default) — the column name is the property name, verbatim.\n * - `\"snake_case\"` — `consumerName` becomes `consumer_name`.\n */\nexport type NamingStrategy = \"preserve\" | \"snake_case\";\n\n/** Convert a `camelCase` / `PascalCase` identifier to `snake_case`. */\nexport function toSnakeCase(name: string): string {\n return name\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1_$2\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .toLowerCase();\n}\n\n/** Base class every model extends, SQLAlchemy-declarative style. */\n// biome-ignore lint/complexity/noStaticOnlyClass: declarative base users subclass; column fields live on instances.\nexport abstract class Model {\n static tablename: string;\n /**\n * Optional table-level constraints (composite unique / foreign keys), returned\n * by a thunk so forward references resolve lazily. Mirrors SQLAlchemy's\n * `__table_args__`.\n */\n static tableArgs?: () => readonly TableConstraint[];\n /**\n * How to derive column names from property names (default `\"preserve\"`). Set\n * `\"snake_case\"` to keep a `snake_case` schema behind a `camelCase` model\n * without annotating every column; {@link Column.name} overrides it per column.\n */\n static naming?: NamingStrategy;\n}\n\n/** Memoized column maps, keyed by model class (identity is stable per class). */\nconst columnsCache = new WeakMap<ModelClass, Record<string, Column<unknown>>>();\n\n/**\n * Reflect a model class into its column map at runtime, keyed by column name.\n *\n * Instantiates the class once and collects every field that is a `Column`. Used\n * by the serialization layer and (Phase 6) the migration schema reflector.\n *\n * The result is **memoized per class** — a model's columns never change at\n * runtime, and this is called once per row on hot read paths (coercion, joins),\n * so re-instantiating the class every time would dominate large result sets.\n *\n * @param model The model class (subclass of `Model`).\n * @returns A record of column name → `Column` instance (do not mutate).\n */\nexport function columnsOf(model: ModelClass): Record<string, Column<unknown>> {\n const cached = columnsCache.get(model);\n if (cached) return cached;\n const instance = new (model as new () => Model)();\n const out: Record<string, Column<unknown>> = {};\n for (const [key, value] of Object.entries(instance)) {\n if (value instanceof Column) {\n out[key] = value as Column<unknown>;\n }\n }\n columnsCache.set(model, out);\n return out;\n}\n\n/** A mapping between property names and database column names. */\nexport type NameMap = Readonly<Record<string, string>>;\n\n/** Memoized property → column maps (`null` when every name is the identity). */\nconst nameMapCache = new WeakMap<ModelClass, NameMap | null>();\n\n/** Memoized column → property maps (`null` when every name is the identity). */\nconst propMapCache = new WeakMap<ModelClass, NameMap | null>();\n\n/**\n * The property → database-column map for a model, or `null` when every column\n * keeps its property name.\n *\n * `null` is the common case and the fast path: builders and the row coercer skip\n * translation entirely, so a model that renames nothing costs nothing. The map\n * is memoized per class, like {@link columnsOf}.\n *\n * @param model The model class.\n * @returns The name map, or `null` when no column is renamed.\n * @throws Error When two properties resolve to the same column name.\n */\nexport function columnNamesOf(model: ModelClass): NameMap | null {\n const cached = nameMapCache.get(model);\n if (cached !== undefined) return cached;\n const strategy: NamingStrategy = model.naming ?? \"preserve\";\n const map: Record<string, string> = {};\n const seen = new Map<string, string>();\n let renamed = false;\n for (const [prop, col] of Object.entries(columnsOf(model))) {\n const dbName = col.dbName ?? (strategy === \"snake_case\" ? toSnakeCase(prop) : prop);\n const collision = seen.get(dbName);\n if (collision !== undefined) {\n throw new Error(\n `${model.tablename}: properties \"${collision}\" and \"${prop}\" both map to column \"${dbName}\".`,\n );\n }\n seen.set(dbName, prop);\n map[prop] = dbName;\n if (dbName !== prop) renamed = true;\n }\n const result = renamed ? (map as NameMap) : null;\n nameMapCache.set(model, result);\n return result;\n}\n\n/**\n * The database-column → property map for a model, or `null` when every column\n * keeps its property name. The inverse of {@link columnNamesOf}, used to map\n * driver rows back into property space.\n *\n * @param model The model class.\n * @returns The inverse name map, or `null` when no column is renamed.\n */\nexport function columnPropsOf(model: ModelClass): NameMap | null {\n const cached = propMapCache.get(model);\n if (cached !== undefined) return cached;\n const forward = columnNamesOf(model);\n let result: NameMap | null = null;\n if (forward) {\n const inverse: Record<string, string> = {};\n for (const [prop, dbName] of Object.entries(forward)) inverse[dbName] = prop;\n result = inverse as NameMap;\n }\n propMapCache.set(model, result);\n return result;\n}\n\n/** Resolve one property name to its database column name. */\nexport function dbColumn(names: NameMap | null | undefined, prop: string): string {\n return names?.[prop] ?? prop;\n}\n\n/**\n * Every primary-key column of a model, in declaration order.\n *\n * A composite key is a list of more than one name — which is why this returns an\n * array and not a single name. Reading only the first entry is how a repository\n * ends up filtering half a key and touching the wrong row.\n *\n * @param model The model class.\n * @returns The primary-key column names (property names, not database names).\n * @throws Error When the model declares no primary key.\n */\nexport function primaryKeysOf(model: ModelClass): string[] {\n const keys: string[] = [];\n for (const [name, col] of Object.entries(columnsOf(model))) {\n if (col.flags.primaryKey) keys.push(name);\n }\n if (keys.length === 0) throw new Error(`${model.tablename} has no primary key`);\n return keys;\n}\n\n/**\n * Turn a primary-key argument into the filter that identifies exactly one row.\n *\n * A single-column key takes the bare value (or an object carrying it); a\n * composite key **requires** the object, because a scalar cannot say which of the\n * key columns it is. Passing a scalar for a composite key throws instead of\n * silently matching on one column.\n *\n * @param model The model class.\n * @param id The key: a scalar, or an object with every key column.\n * @returns A filter object covering the whole key.\n * @throws Error When the key is incomplete, or a scalar was given for a composite key.\n */\nexport function primaryKeyFilter(\n model: ModelClass,\n id: unknown,\n): Record<string, unknown> {\n const keys = primaryKeysOf(model);\n const asObject =\n typeof id === \"object\" && id !== null && !Array.isArray(id) && !(id instanceof Date)\n ? (id as Record<string, unknown>)\n : null;\n const first = keys[0] as string;\n if (keys.length === 1) {\n return { [first]: asObject && first in asObject ? asObject[first] : id };\n }\n if (asObject === null) {\n throw new Error(\n `${model.tablename} has a composite primary key (${keys.join(\", \")}); pass an object like { ${keys.join(\", \")} } instead of a scalar.`,\n );\n }\n const filter: Record<string, unknown> = {};\n for (const key of keys) {\n if (!(key in asObject)) {\n throw new Error(\n `${model.tablename} has a composite primary key (${keys.join(\", \")}); the key is missing ${JSON.stringify(key)}.`,\n );\n }\n filter[key] = asObject[key];\n }\n return filter;\n}\n\n/** Pull the static type out of a Column. */\ntype ColType<C> = C extends Column<infer T, infer _F> ? T : never;\n\n/** Keys of the model instance whose values are Columns. */\ntype ColumnKeys<M> = {\n [K in keyof M]: M[K] extends Column<unknown, ColumnFlags> ? K : never;\n}[keyof M];\n\n/** Constructor type for a Model subclass. */\ntype ModelClass = (new () => Model) & {\n tablename: string;\n tableArgs?: () => readonly TableConstraint[];\n naming?: NamingStrategy;\n};\n\n/** Flatten an intersection into a single object literal for clean inference. */\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\n/** The nullability-aware value a column contributes to a row. */\ntype ColValue<Col> = Col extends Column<infer T, infer F>\n ? F extends { notNull: true } | { primaryKey: true }\n ? T\n : T | null\n : never;\n\n/** True when a column has a default (or is a PK) — i.e. optional on insert. */\ntype HasDefault<Col> = Col extends Column<unknown, infer F>\n ? F extends { hasDefault: true }\n ? true\n : false\n : false;\n\n/** True when a column accepts NULL — neither `notNull` nor a primary key. */\ntype IsNullable<Col> = Col extends Column<unknown, infer F>\n ? F extends { notNull: true } | { primaryKey: true }\n ? false\n : true\n : false;\n\n/**\n * Keys of the model whose columns may be omitted on insert.\n *\n * A column is optional when it has a default **or** when it accepts NULL: SQL\n * applies `NULL` to an omitted column that declares no other default, so\n * requiring the caller to write `note: null` adds noise that reads like a\n * deliberate decision to blank the column. Passing `null` explicitly still works.\n */\ntype OptionalInsertKeys<I> = {\n [K in ColumnKeys<I>]: HasDefault<I[K]> extends true\n ? K\n : IsNullable<I[K]> extends true\n ? K\n : never;\n}[ColumnKeys<I>];\n\n/**\n * Infer the SELECT row shape from a model class: every column field becomes its\n * mapped static type. Columns marked notNull/primaryKey are non-nullable; others\n * are `T | null` (SQL semantics — an unconstrained column can be NULL).\n */\nexport type InferModel<C extends ModelClass> = {\n [K in ColumnKeys<InstanceType<C>>]: ColValue<InstanceType<C>[K]>;\n};\n\n/**\n * Infer the INSERT shape: a column is optional when it has a default (or is a PK)\n * **or** when it is nullable — matching SQL, where an omitted column with no\n * `DEFAULT` clause is written as `NULL`. Only `notNull` columns without a default\n * are required. Nullability is preserved on both sides.\n */\nexport type InferInsert<C extends ModelClass> = Simplify<\n {\n [K in OptionalInsertKeys<InstanceType<C>>]?: ColValue<InstanceType<C>[K]>;\n } & {\n [K in Exclude<\n ColumnKeys<InstanceType<C>>,\n OptionalInsertKeys<InstanceType<C>>\n >]: ColValue<InstanceType<C>[K]>;\n }\n>;\n\nexport { Column, type ColType, type ColumnFlags, type ModelClass };\n\nexport {\n and,\n caseWhen,\n cast,\n type CastType,\n col,\n type CondNode,\n type Condition,\n Expression,\n type ExprNode,\n fn,\n isCondition,\n isExpression,\n not,\n or,\n toCondNode,\n val,\n type WhereArg,\n} from \"./conditions.js\";\n\nexport {\n denseRank,\n firstValue,\n lag,\n lastValue,\n lead,\n over,\n percentRank,\n rank,\n rowNumber,\n type WindowFn,\n type WindowSpec,\n} from \"./window.js\";\n\nexport {\n Agg,\n type AggregateTerm,\n avg,\n count,\n type LockClause,\n type LockOptions,\n max,\n min,\n exists,\n isSubquery,\n notExists,\n scalar,\n type SubqueryLike,\n type Operator,\n type OperatorsFor,\n OPERATORS,\n type OrderTerm,\n type SelectNode,\n SelectBuilder,\n select,\n type SortDirection,\n type Subquery,\n sum,\n type WhereInput,\n} from \"./query.js\";\n\nexport {\n DeleteBuilder,\n type DeleteNode,\n del,\n InsertBuilder,\n type InsertNode,\n insert,\n type OnConflict,\n type OnConflictOptions,\n type OnConflictUpdateOptions,\n type Returning,\n type WritePatch,\n type WriteValues,\n UpdateBuilder,\n type UpdateNode,\n update,\n} from \"./mutations.js\";\n\nexport {\n type Dialect,\n detectDialect,\n InvalidDatabaseUrl,\n type ParsedDatabaseUrl,\n parseDatabaseUrl,\n} from \"./url.js\";\n\nexport {\n decodeValue as decodeColumnValue,\n encodeValue as encodeColumnValue,\n fromDict,\n parse,\n stringify,\n toDict,\n toJSON,\n ValidationError,\n} from \"./serialize.js\";\n\nexport {\n BaseDialect,\n type CompiledQuery,\n getDialect,\n MysqlDialect,\n Params,\n PostgresDialect,\n type QueryNode,\n SqliteDialect,\n} from \"./dialect.js\";\n\nexport {\n type ColRef,\n join,\n JoinBuilder,\n type JoinClause,\n type JoinNode,\n type JoinOn,\n type JoinSelection,\n type JoinWhereInput,\n type Sources,\n} from \"./join.js\";\n\nexport {\n type ModelBase,\n notDeleted,\n onlyDeleted,\n withAudit,\n withSoftDelete,\n withTimestamps,\n} from \"./mixins.js\";\n\nexport {\n type IntegrityFailure,\n type IntegrityViolation,\n parseIntegrityError,\n} from \"./integrity.js\";\n\nexport {\n type ContainsOptions,\n contains,\n escapeLike,\n fullText,\n fullTextRank,\n type TextSearchLanguage,\n type TextSearchOptions,\n tokenize,\n} from \"./search.js\";\n\nexport {\n clearSignals,\n emitSignal,\n hasHandlers,\n onSignal,\n type RepositorySignal,\n type SignalHandler,\n type SignalPayload,\n} from \"./signals.js\";\n\nexport {\n except,\n intersect,\n SetBuilder,\n type SetNode,\n type SetOperator,\n union,\n unionAll,\n} from \"./setops.js\";\n\nexport {\n type ClaimOptions,\n type FailOptions,\n type OutboxEventInput,\n OutboxRepository,\n type OutboxStatus,\n outboxModel,\n} from \"./outbox.js\";\n\nexport {\n type ExplainOptions,\n type ExplainReport,\n isReadOnlyStatement,\n type QueryPlan,\n summarizePlan,\n} from \"./explain.js\";\n\nexport { type TenantScope, TenantScopedRepository } from \"./tenant.js\";\n\nexport {\n type AuditAction,\n type AuditDiff,\n type AuditEntry,\n type AuditOptions,\n auditLogModel,\n diffSnapshots,\n enableAudit,\n snapshot,\n} from \"./audit.js\";\n\nexport {\n type BackupOptions,\n type BackupResult,\n BackupToolMissing,\n backupDatabase,\n backupFormat,\n restoreDatabase,\n toolUrl,\n UnsupportedBackupBackend,\n} from \"./backup.js\";\n\nexport {\n attach as attachCte,\n Cte,\n type CteBody,\n type CteNode,\n type CteOptions,\n cte,\n cteRecursive,\n} from \"./cte.js\";\n\nexport { aliasOf, aliased } from \"./aliased.js\";\n\nexport { type FlushResult, type Tracked, UnitOfWork } from \"./unit-of-work.js\";\n\nexport {\n BaseRepository,\n type BulkUpsertOptions,\n type ChangesPage,\n type ChangesSinceFilter,\n type CursorPage,\n type CursorPaginationFilter,\n InvalidCursor,\n type PaginationFilter,\n type PaginationResult,\n RecordNotFound,\n} from \"./repository.js\";\n\nexport {\n ActiveRecord,\n type ActiveRecordManager,\n activeRecord,\n} from \"./active-record.js\";\n\nexport {\n type BelongsTo,\n belongsTo,\n type HasMany,\n hasMany,\n loadRelations,\n type Relation,\n type RelationValue,\n type WithRelations,\n} from \"./relations.js\";\n\nexport {\n AsyncEngine,\n AsyncResult,\n AsyncSession,\n type AsyncDriver,\n BetterSqliteDriver,\n createEngine,\n createSyncEngine,\n type DriverResult,\n type EngineOptions,\n type IsolationLevel,\n type Executable,\n NoResultError,\n NodeSqliteDriver,\n type NoticeLogger,\n type PoolOptions,\n QueryExecutionError,\n type QueryEndEvent,\n type QueryEndLogger,\n type QueryHooks,\n type QueryLogger,\n type ReservedAsyncDriver,\n type SqliteJournalMode,\n type SqliteOptions,\n type SqliteSynchronous,\n type RowOf,\n type SyncDriver,\n SyncEngine,\n SyncResult,\n SyncSession,\n toAsyncDriver,\n type TransactionOptions,\n} from \"./engine.js\";\n","/**\n * tempest-db-js — Phase 4a: dialect SQL compilation.\n *\n * Turns the dialect-neutral AST (`SelectNode`, `InsertNode`, `UpdateNode`,\n * `DeleteNode` from Phases 1-2) into `{ sql, params }`. This is the ONLY place\n * SQL is produced — always parameterized (`?` for SQLite, `$1` for PostgreSQL),\n * never string interpolation, so it is injection-safe by construction.\n *\n * It does NOT touch a database — execution is Phase 4b (`session.execute`).\n */\n\nimport {\n type CastType,\n type CondNode,\n type ExprNode,\n isExpression,\n} from \"./conditions.js\";\nimport type { CteNode } from \"./cte.js\";\nimport type { TransactionOptions } from \"./engine.js\";\nimport { renderExcluded, renderPortableToken } from \"./expressions.js\";\nimport {\n type ColumnCodec,\n type NameMap,\n type SqlExpression,\n isSqlExpression,\n} from \"./index.js\";\nimport type { JoinNode } from \"./join.js\";\nimport type { DeleteNode, InsertNode, UpdateNode } from \"./mutations.js\";\nimport {\n type AggregateTerm,\n type LockClause,\n OPERATORS,\n type SelectNode,\n isSubquery,\n} from \"./query.js\";\nimport { escapeLike } from \"./search.js\";\nimport type { SetNode, SetOperator } from \"./setops.js\";\nimport type { Dialect } from \"./url.js\";\n\n/** A compiled, parameterized statement ready to hand to a driver. */\nexport interface CompiledQuery {\n readonly sql: string;\n readonly params: readonly unknown[];\n}\n\n/** Any compilable AST node. */\nexport type QueryNode =\n | SelectNode\n | InsertNode\n | UpdateNode\n | DeleteNode\n | JoinNode\n | SetNode;\n\nconst OPERATOR_SET: ReadonlySet<string> = new Set(OPERATORS);\n\n/** Operators whose operand is a list or a tuple rather than a single value. */\nconst MULTI_VALUE_OPERATORS: ReadonlySet<string> = new Set([\"in\", \"notIn\", \"between\"]);\n\n/**\n * Convert an operator's operand into the stored representation.\n *\n * `isNull` takes a boolean that is not a column value, and `in`/`notIn`/`between`\n * take collections whose **elements** are the values — converting the collection\n * itself would corrupt them.\n *\n * @param op The operator.\n * @param operand The operand as written.\n * @param encode The column's conversion.\n * @returns The operand in stored representation.\n */\nfunction encodeOperand(\n op: string,\n operand: unknown,\n encode: (value: unknown) => unknown,\n): unknown {\n if (op === \"isNull\") return operand;\n if (MULTI_VALUE_OPERATORS.has(op)) {\n return Array.isArray(operand) ? operand.map(encode) : operand;\n }\n return encode(operand);\n}\n\n/**\n * Build the operand converter for a node's custom-typed columns.\n *\n * @param codecs The node's codecs, if any.\n * @returns A function converting a value for a column, identity when there are none.\n */\nfunction codecEncoder(\n codecs: Readonly<Record<string, ColumnCodec>> | undefined,\n): (key: string, value: unknown) => unknown {\n if (!codecs) return (_key, value) => value;\n return (key, value) => {\n const codec = codecs[key];\n return codec ? codec.toDb(value) : value;\n };\n}\n\n/** True when a where-value is an operator object rather than a bare value. */\nfunction isOperatorObject(value: unknown): value is Record<string, unknown> {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n value instanceof Date ||\n value instanceof Uint8Array\n ) {\n return false;\n }\n const keys = Object.keys(value);\n return keys.length > 0 && keys.every((k) => OPERATOR_SET.has(k));\n}\n\n/**\n * Collects bound parameters and renders placeholders in dialect style. Exposed\n * because dialect subclasses receive it when overriding clause rendering.\n */\nexport class Params {\n readonly values: unknown[] = [];\n\n constructor(private readonly placeholder: (index: number) => string) {}\n\n bind(value: unknown): string {\n this.values.push(value);\n return this.placeholder(this.values.length);\n }\n}\n\n/**\n * A {@link Params} that inlines values instead of binding them.\n *\n * Schema SQL — a `CHECK` clause, a partial index's predicate — has nowhere to\n * bind a parameter, so the value has to be written into the statement. Quoting\n * follows the same rules a literal `DEFAULT` uses.\n */\nexport class LiteralParams extends Params {\n constructor() {\n super(() => \"\");\n }\n\n override bind(value: unknown): string {\n if (value === null || value === undefined) return \"NULL\";\n if (typeof value === \"boolean\") return value ? \"TRUE\" : \"FALSE\";\n if (typeof value === \"number\" || typeof value === \"bigint\") return String(value);\n if (value instanceof Date) return `'${value.toISOString()}'`;\n return `'${String(value).replace(/'/g, \"''\")}'`;\n }\n}\n\n/**\n * The column list of an INSERT: the union of every row's keys, in first-seen\n * order.\n *\n * Taking only the first row's keys silently drops a value that a later row\n * supplies — the column is never named, so the value has nowhere to go. That was\n * unreachable while every row had to carry every key, and became reachable the\n * moment nullable columns turned optional on insert.\n *\n * @param rows The rows being inserted.\n * @returns Every column named by at least one row.\n */\nfunction insertColumns(rows: readonly Record<string, unknown>[]): string[] {\n const columns: string[] = [];\n const seen = new Set<string>();\n for (const row of rows) {\n for (const key of Object.keys(row)) {\n if (seen.has(key)) continue;\n seen.add(key);\n columns.push(key);\n }\n }\n return columns;\n}\n\n/** True when any value written by an INSERT is a SQL expression, not a literal. */\nfunction insertHasExpression(node: InsertNode): boolean {\n for (const row of node.values) {\n for (const value of Object.values(row)) {\n if (isSqlExpression(value)) return true;\n }\n }\n const update = node.onConflict?.update;\n if (update && update !== \"nothing\") {\n for (const value of Object.values(update)) {\n if (isSqlExpression(value)) return true;\n }\n }\n return false;\n}\n\n/**\n * Base SQL compiler shared by every dialect. Subclasses customize only what\n * actually differs between databases (placeholder syntax, `ILIKE` support).\n */\nexport abstract class BaseDialect {\n abstract readonly name: Dialect;\n\n /**\n * INSERT SQL templates keyed by structure (dialect|table|columns|rowCount|\n * returning). Shared across dialect instances — the key namespaces by dialect\n * name, and the placeholder text is dialect-specific but structure-determined.\n */\n private static readonly insertTemplates = new Map<string, string>();\n\n /** Quoted-identifier cache (see {@link quoteId}). Shared across dialects. */\n private static readonly quotedIds = new Map<string, string>();\n\n /** Render the n-th (1-based) placeholder. */\n protected abstract placeholder(index: number): string;\n\n /** Render a case-insensitive LIKE for the active dialect. */\n protected abstract ilike(column: string, param: string): string;\n\n /**\n * Render a case-insensitive LIKE whose pattern carries escaped wildcards.\n *\n * The `ESCAPE` clause is not decoration: PostgreSQL treats `\\` as the escape\n * character by default, **SQLite has none at all** until one is declared, so\n * without this the escaping done on our side would be meaningless there.\n *\n * @param column The rendered column.\n * @param param The bound pattern.\n * @returns The rendered comparison.\n */\n protected ilikeEscaped(column: string, param: string): string {\n return `${this.ilike(column, param)} ESCAPE '\\\\'`;\n }\n\n /**\n * Validate a subquery operand before it is rendered, for dialects that restrict\n * what an `IN (SELECT ...)` may contain. The default accepts everything.\n *\n * @param _node The subquery's AST.\n * @throws Error When the dialect cannot execute this subquery.\n */\n protected checkSubquery(_node: SelectNode): void {}\n\n /**\n * The SQL operator for an array containment/overlap test.\n *\n * Only PostgreSQL has native arrays; the other dialects throw rather than\n * emitting an operator that means something else there.\n *\n * @param op The array operator name.\n * @returns The SQL operator text.\n * @throws Error On a dialect without native array support.\n */\n protected arrayOperator(op: \"contains\" | \"containedBy\" | \"overlaps\"): string {\n throw new Error(\n `The \"${op}\" operator needs native array support, which ${this.name} does not have.`,\n );\n }\n\n /**\n * Quote an identifier (column/table) for the active dialect.\n *\n * Memoized: identifiers form a small, stable set (column/table names), but this\n * runs for every identifier on every compile. Caching the quoted form removes a\n * regex-replace + string allocation from the hot path. The standard double-quote\n * form is identical across both dialects, so one shared cache is correct.\n */\n protected quoteId(name: string): string {\n const cached = BaseDialect.quotedIds.get(name);\n if (cached !== undefined) return cached;\n const quoted = `\"${name.replace(/\"/g, '\"\"')}\"`;\n BaseDialect.quotedIds.set(name, quoted);\n return quoted;\n }\n\n /** Compile any node to `{ sql, params }`. */\n compile(node: QueryNode): CompiledQuery {\n const params = new Params((i) => this.placeholder(i));\n let sql: string;\n switch (node.kind) {\n case \"select\":\n sql = this.compileSelect(node, params);\n break;\n case \"insert\":\n sql = this.compileInsert(node, params);\n break;\n case \"update\":\n sql = this.compileUpdate(node, params);\n break;\n case \"delete\":\n sql = this.compileDelete(node, params);\n break;\n case \"join_select\":\n sql = this.compileJoin(node, params);\n break;\n case \"set_op\":\n sql = this.compileSetOp(node, params);\n break;\n }\n return { sql, params: params.values };\n }\n\n /**\n * Render a condition as schema SQL, with values inlined.\n *\n * Same compiler as a `WHERE`, different parameter strategy — so a `CHECK` and\n * the query language cannot drift apart in what they mean.\n *\n * @param node The condition.\n * @param params A {@link LiteralParams}.\n * @returns The rendered predicate.\n */\n renderConditionLiteral(node: CondNode, params: Params): string {\n return this.compileCondition(node, params, (key) => this.columnId(key, undefined));\n }\n\n /**\n * Render the `WITH` clause of a statement.\n *\n * `RECURSIVE` is a property of the **clause**, not of an entry: one recursive\n * entry makes the whole `WITH` recursive, which is what the SQL standard says\n * and what PostgreSQL and SQLite both implement.\n *\n * @param entries The `WITH` entries, if any.\n * @param params The parameter collector.\n * @returns The clause with a trailing space, or an empty string.\n */\n protected compileWith(entries: readonly CteNode[] | undefined, params: Params): string {\n if (!entries || entries.length === 0) return \"\";\n const recursive = entries.some((entry) => entry.recursive) ? \"RECURSIVE \" : \"\";\n const rendered = entries.map((entry) => {\n const body =\n entry.body.kind === \"set_op\"\n ? this.compileSetOp(entry.body, params)\n : this.compileSelect(entry.body, params);\n const hint =\n entry.materialized === null\n ? \"\"\n : entry.materialized\n ? \" MATERIALIZED\"\n : \" NOT MATERIALIZED\";\n return `${this.quoteId(entry.name)} AS${hint} (${body})`;\n });\n return `WITH ${recursive}${rendered.join(\", \")} `;\n }\n\n /**\n * The `EXPLAIN` prefix for this dialect.\n *\n * @param analyze Whether to measure by actually running the statement.\n * @returns The prefix to put in front of the statement.\n * @throws Error When the dialect cannot do what was asked.\n */\n explainPrefix(analyze: boolean): string {\n return analyze ? \"EXPLAIN (FORMAT JSON, ANALYZE)\" : \"EXPLAIN (FORMAT JSON)\";\n }\n\n /**\n * The SQL keyword for a set operation.\n *\n * @param op The operator.\n * @returns The keyword.\n * @throws Error On a dialect that does not implement it.\n */\n protected setOperator(op: SetOperator): string {\n switch (op) {\n case \"union\":\n return \"UNION\";\n case \"unionAll\":\n return \"UNION ALL\";\n case \"intersect\":\n return \"INTERSECT\";\n case \"except\":\n return \"EXCEPT\";\n }\n }\n\n /**\n * Compile a set operation.\n *\n * A branch carrying its own `ORDER BY`/`LIMIT` is parenthesized: without the\n * parentheses those clauses bind to the **combined** result, which is a\n * different query and a classic source of silently wrong output.\n *\n * @param node The set-operation node.\n * @param params The parameter collector.\n * @returns The rendered statement.\n */\n protected compileSetOp(node: SetNode, params: Params): string {\n const keyword = ` ${this.setOperator(node.op)} `;\n const branches = node.branches.map((branch) => {\n const sql =\n branch.kind === \"join_select\"\n ? this.compileJoin(branch, params)\n : this.compileSelect(branch, params);\n const scoped = branch.orderBy.length > 0 || branch.limit !== undefined;\n return scoped ? `(${sql})` : sql;\n });\n let sql = branches.join(keyword);\n if (node.orderBy.length > 0) {\n const terms = node.orderBy\n .map((t) => {\n const id =\n typeof t.column === \"string\"\n ? this.quoteId(t.column)\n : this.renderExpr(t.column, params, (k) => this.quoteId(k));\n return `${id} ${t.direction === \"desc\" ? \"DESC\" : \"ASC\"}`;\n })\n .join(\", \");\n sql += ` ORDER BY ${terms}`;\n }\n if (node.limit !== undefined) sql += ` LIMIT ${params.bind(node.limit)}`;\n if (node.offset !== undefined) sql += ` OFFSET ${params.bind(node.offset)}`;\n return sql;\n }\n\n /**\n * Render a qualified `alias.column` ref as `\"alias\".\"column\"`, translating the\n * property name to the real column name for that alias's model.\n *\n * @param ref The `alias.property` reference (a bare name is left unqualified).\n * @param names The node's per-alias name maps, if any source renames columns.\n * @returns The quoted, qualified identifier.\n */\n private qualify(\n ref: string,\n names?: Readonly<Record<string, NameMap>> | undefined,\n ): string {\n const dot = ref.indexOf(\".\");\n if (dot === -1) return this.quoteId(ref);\n const alias = ref.slice(0, dot);\n const prop = ref.slice(dot + 1);\n return `${this.quoteId(alias)}.${this.columnId(prop, names?.[alias])}`;\n }\n\n /**\n * Quote a column identifier, translating the model property name to the real\n * database column name first.\n *\n * `names` is `undefined` for a model that renames nothing — the overwhelmingly\n * common case — so this stays a single lookup plus the memoized quote.\n *\n * @param prop The model property name as written in the builder.\n * @param names The node's property → column map, if any.\n * @returns The quoted database identifier.\n */\n protected columnId(prop: string, names: NameMap | undefined): string {\n const mapped = names?.[prop];\n if (mapped !== undefined) return this.quoteId(mapped);\n const dot = prop.indexOf(\".\");\n // A dotted reference is a correlated one — `col(\"users.id\")` inside a\n // subquery points at the outer query's table, and quoting it whole would\n // produce the identifier \"users.id\" instead of \"users\".\"id\".\n if (dot > 0 && dot < prop.length - 1) {\n return `${this.quoteId(prop.slice(0, dot))}.${this.quoteId(prop.slice(dot + 1))}`;\n }\n return this.quoteId(prop);\n }\n\n /**\n * Render a {@link SqlExpression} inline, binding the parameters it carries.\n *\n * This is what keeps `set({ attempts: sql.raw(\"attempts + 1\") })` an expression\n * instead of a bound object: the fragment goes into the statement text, and\n * only a `sql.expr` template's interpolations become parameters.\n *\n * @param expr The branded expression.\n * @param params The parameter collector for the statement being compiled.\n * @returns The SQL text of the expression.\n */\n protected renderExpression(expr: SqlExpression, params: Params): string {\n const token = expr.expression;\n if (typeof token === \"string\") return renderPortableToken(token, this.name);\n if (\"raw\" in token) return token.raw;\n if (\"excluded\" in token) {\n return renderExcluded(this.quoteId(token.excluded), token.excluded, this.name);\n }\n const parts = token.parts;\n let sql = parts[0] ?? \"\";\n for (let i = 1; i < parts.length; i++) {\n sql += `${params.bind(expr.params[i - 1])}${parts[i]}`;\n }\n return sql;\n }\n\n /** Render one write value: a SQL expression inline, anything else as a parameter. */\n protected renderValue(value: unknown, params: Params): string {\n if (isSqlExpression(value)) return this.renderExpression(value, params);\n // A column reference written into a SET: `UPDATE ... SET tier = c.tier`.\n if (isExpression(value)) {\n return this.renderExpr(value.node, params, (k) => this.columnId(k, undefined));\n }\n return params.bind(value);\n }\n\n /**\n * The statements that open a transaction with the requested characteristics.\n *\n * Returned as a list because the dialects disagree on shape: PostgreSQL takes\n * everything on the `BEGIN` itself, MySQL needs a separate `SET TRANSACTION`\n * before it, and SQLite has no syntax at all.\n *\n * @param options The requested isolation level and read-only flag.\n * @returns The statements to run, in order.\n * @throws Error When the dialect cannot honor what was asked.\n */\n beginStatements(options?: TransactionOptions): string[] {\n const parts = [\"BEGIN\"];\n if (options?.isolation)\n parts.push(`ISOLATION LEVEL ${options.isolation.toUpperCase()}`);\n if (options?.readOnly) parts.push(\"READ ONLY\");\n return [parts.join(\" \")];\n }\n\n /**\n * Render a row-level locking clause (`FOR UPDATE ...`).\n *\n * Standard on PostgreSQL and MySQL 8.0+; SQLite overrides it to throw.\n *\n * @param lock The locking clause from the node.\n * @returns The SQL text, leading space included.\n */\n protected renderLock(lock: LockClause): string {\n const strength = lock.strength === \"update\" ? \"FOR UPDATE\" : \"FOR SHARE\";\n const of =\n lock.of.length > 0 ? ` OF ${lock.of.map((t) => this.quoteId(t)).join(\", \")}` : \"\";\n const wait =\n lock.wait === \"skipLocked\"\n ? \" SKIP LOCKED\"\n : lock.wait === \"noWait\"\n ? \" NOWAIT\"\n : \"\";\n return ` ${strength}${of}${wait}`;\n }\n\n // ---- statements -------------------------------------------------------\n\n /**\n * Compile a SELECT.\n *\n * Two alias rules differ between clauses and are handled here: PostgreSQL does\n * NOT accept a `SELECT` alias in `HAVING`, so an aggregate key is re-emitted as\n * its expression (`COUNT(*) > $1`), a form every dialect accepts; `ORDER BY`,\n * by contrast, accepts the output alias everywhere, so it is emitted as\n * written.\n *\n * @param node The select AST.\n * @param params The parameter collector.\n * @returns The SQL text.\n */\n private compileSelect(node: SelectNode, params: Params): string {\n const names = node.names;\n let cols: string;\n if (node.aggregates.length > 0) {\n // Grouped/aggregate query: SELECT group cols + `FN(col) AS \"alias\"`.\n const groupSel = node.groupBy.map((c) => this.columnId(c, names));\n const aggSel = node.aggregates.map((a) => {\n const inner = this.aggregateOperand(a, params, names);\n return `${a.fn.toUpperCase()}(${inner}) AS ${this.quoteId(a.alias)}`;\n });\n cols = [...groupSel, ...aggSel].join(\", \");\n } else {\n cols =\n node.columns === \"*\"\n ? \"*\"\n : node.columns.map((c) => this.columnId(c, names)).join(\", \");\n }\n const computed = Object.entries(node.computed ?? {}).map(\n ([alias, expr]) =>\n `${this.renderExpr(expr, params, (k) => this.columnId(k, names))} AS ${this.quoteId(alias)}`,\n );\n if (computed.length > 0) cols = [cols, ...computed].join(\", \");\n const from = node.alias\n ? `${this.quoteId(node.table)} AS ${this.quoteId(node.alias)}`\n : this.quoteId(node.table);\n let sql = `${this.compileWith(node.with, params)}SELECT ${node.distinct ? \"DISTINCT \" : \"\"}${cols} FROM ${from}`;\n\n const where = this.compileCondition(\n node.where,\n params,\n (k) => this.columnId(k, names),\n codecEncoder(node.codecs),\n );\n if (where) sql += ` WHERE ${where}`;\n\n if (node.groupBy.length > 0) {\n sql += ` GROUP BY ${node.groupBy.map((c) => this.columnId(c, names)).join(\", \")}`;\n }\n\n const aggByAlias = new Map(node.aggregates.map((a) => [a.alias, a]));\n\n if (node.having) {\n const having = this.compileCondition(node.having, params, (key) => {\n const agg = aggByAlias.get(key);\n if (!agg) return this.columnId(key, names);\n const inner = this.aggregateOperand(agg, params, names);\n return `${agg.fn.toUpperCase()}(${inner})`;\n });\n if (having) sql += ` HAVING ${having}`;\n }\n\n if (node.orderBy.length > 0) {\n const terms = node.orderBy\n .map((t) => {\n const id =\n typeof t.column !== \"string\"\n ? this.renderExpr(t.column, params, (k) => this.columnId(k, names))\n : aggByAlias.has(t.column)\n ? this.quoteId(t.column)\n : this.columnId(t.column, names);\n return `${id} ${t.direction === \"desc\" ? \"DESC\" : \"ASC\"}`;\n })\n .join(\", \");\n sql += ` ORDER BY ${terms}`;\n }\n if (node.limit !== undefined) sql += ` LIMIT ${params.bind(node.limit)}`;\n if (node.offset !== undefined) sql += ` OFFSET ${params.bind(node.offset)}`;\n if (node.lock) {\n if (node.distinct || node.groupBy.length > 0 || node.aggregates.length > 0) {\n throw new Error(\n \"FOR UPDATE / FOR SHARE cannot be combined with DISTINCT or an aggregate query — lock the underlying rows in a separate SELECT.\",\n );\n }\n sql += this.renderLock(node.lock);\n }\n return sql;\n }\n\n /**\n * Compile an INSERT.\n *\n * Takes the cached fast path only when the statement text is a pure function of\n * its structure. A SQL expression among the values, or a conflict predicate,\n * makes the text depend on the values themselves — those compile uncached, in\n * SQL order, so placeholder positions stay correct.\n */\n private compileInsert(node: InsertNode, params: Params): string {\n if (node.fromSelect) {\n const target = node.fromSelect.columns\n .map((c) => this.columnId(c, node.names))\n .join(\", \");\n const source = node.fromSelect.select as SelectNode | JoinNode | SetNode;\n const query =\n source.kind === \"join_select\"\n ? this.compileJoin(source, params)\n : source.kind === \"set_op\"\n ? this.compileSetOp(source, params)\n : this.compileSelect(source, params);\n const returning = this.compileReturning(node.returning, node.names);\n return `INSERT INTO ${this.quoteId(node.table)} (${target}) ${query}${returning}`;\n }\n const columns = insertColumns(node.values);\n const conflict = node.onConflict;\n const cacheable =\n conflict?.targetWhere === undefined &&\n conflict?.updateWhere === undefined &&\n !insertHasExpression(node);\n if (!cacheable) return this.compileInsertDirect(node, columns, params);\n\n // Bind every value in row-major, column order. The SQL text is independent of\n // the values (a null becomes a placeholder like any other), so it depends only\n // on the structure — which lets us cache the template below.\n for (const row of node.values) {\n for (const c of columns) params.bind((row as Record<string, unknown>)[c] ?? null);\n }\n // ON CONFLICT DO UPDATE binds its SET values after the row values, in key order.\n const conflictCols =\n conflict && conflict.update !== \"nothing\" ? Object.keys(conflict.update) : [];\n for (const c of conflictCols) {\n params.bind((conflict?.update as Record<string, unknown>)[c]);\n }\n return this.insertTemplate(node, columns, conflictCols, params);\n }\n\n /**\n * Compile an INSERT without the template cache, rendering clauses in statement\n * order so every parameter is bound at the position it appears.\n *\n * @param node The insert node.\n * @param columns The column keys shared by every row.\n * @param params The parameter collector.\n * @returns The SQL text.\n */\n private compileInsertDirect(\n node: InsertNode,\n columns: readonly string[],\n params: Params,\n ): string {\n const names = node.names;\n const colSql = columns.map((c) => this.columnId(c, names)).join(\", \");\n const rowsSql = node.values\n .map((row) => {\n const cells = columns.map((c) =>\n this.renderValue((row as Record<string, unknown>)[c] ?? null, params),\n );\n return `(${cells.join(\", \")})`;\n })\n .join(\", \");\n let sql = `INSERT INTO ${this.quoteId(node.table)} (${colSql}) VALUES ${rowsSql}`;\n if (node.onConflict) {\n const update = node.onConflict.update;\n const conflictCols = update === \"nothing\" ? [] : Object.keys(update);\n let cursor = 0;\n sql += this.renderConflict(\n node.onConflict,\n conflictCols,\n () => {\n const key = conflictCols[cursor++] as string;\n return this.renderValue((update as Record<string, unknown>)[key], params);\n },\n names,\n params,\n );\n }\n sql += this.compileReturning(node.returning, names);\n return sql;\n }\n\n /**\n * The INSERT SQL template for a given structure, cached across calls.\n *\n * The text depends only on (dialect, table, columns, row count, returning,\n * conflict shape) — never on the bound values — and placeholder positions are\n * deterministic from the counts (a fresh statement always starts binding at 1).\n * So a per-row insert loop compiles the string once and reuses it every row.\n */\n private insertTemplate(\n node: InsertNode,\n columns: readonly string[],\n conflictCols: readonly string[],\n params: Params,\n ): string {\n const returningKey =\n node.returning === null\n ? \"\"\n : node.returning === \"*\"\n ? \"*\"\n : node.returning.join(\",\");\n const conflictKey = node.onConflict\n ? `${node.onConflict.target.join(\",\")}>${node.onConflict.update === \"nothing\" ? \"nothing\" : conflictCols.join(\",\")}`\n : \"\";\n const key = `${this.name}|${node.table}|${columns.join(\",\")}|${node.values.length}|${returningKey}|${conflictKey}`;\n const cached = BaseDialect.insertTemplates.get(key);\n if (cached !== undefined) return cached;\n\n const names = node.names;\n const colSql = columns.map((c) => this.columnId(c, names)).join(\", \");\n let position = 0;\n const rowsSql = node.values\n .map(() => `(${columns.map(() => this.placeholder(++position)).join(\", \")})`)\n .join(\", \");\n let sql = `INSERT INTO ${this.quoteId(node.table)} (${colSql}) VALUES ${rowsSql}`;\n if (node.onConflict) {\n sql += this.renderConflict(\n node.onConflict,\n conflictCols,\n () => this.placeholder(++position),\n names,\n params,\n );\n }\n sql += this.compileReturning(node.returning, names);\n BaseDialect.insertTemplates.set(key, sql);\n return sql;\n }\n\n /**\n * Render the conflict-handling clause. Standard SQL (SQLite/PostgreSQL) uses\n * `ON CONFLICT (...) [WHERE predicate] DO NOTHING | DO UPDATE SET ... [WHERE ...]`;\n * MySQL overrides this.\n *\n * The index predicate is rendered before the `DO UPDATE` assignments because\n * that is where it sits in the statement, so its parameters bind first.\n *\n * @param onConflict The conflict clause from the node.\n * @param conflictCols The columns to overwrite on `DO UPDATE` (empty for nothing).\n * @param nextValue Yields the SQL for the next `DO UPDATE` assignment value.\n * @param names The node's property → column map, if any.\n * @param params The parameter collector, for the predicates.\n * @returns The SQL text, leading space included.\n */\n protected renderConflict(\n onConflict: NonNullable<InsertNode[\"onConflict\"]>,\n conflictCols: readonly string[],\n nextValue: () => string,\n names: NameMap | undefined,\n params: Params,\n ): string {\n const idFor = (key: string): string => this.columnId(key, names);\n const target = onConflict.target.map(idFor).join(\", \");\n const indexWhere = this.compileCondition(onConflict.targetWhere, params, idFor);\n const targetSql = indexWhere ? `(${target}) WHERE ${indexWhere}` : `(${target})`;\n if (onConflict.update === \"nothing\") return ` ON CONFLICT ${targetSql} DO NOTHING`;\n const assignments = conflictCols\n .map((c) => `${idFor(c)} = ${nextValue()}`)\n .join(\", \");\n let sql = ` ON CONFLICT ${targetSql} DO UPDATE SET ${assignments}`;\n const updateWhere = this.compileCondition(onConflict.updateWhere, params, idFor);\n if (updateWhere) sql += ` WHERE ${updateWhere}`;\n return sql;\n }\n\n private compileUpdate(node: UpdateNode, params: Params): string {\n const names = node.names;\n const sets = Object.entries(node.set)\n .map(\n ([col, value]) =>\n `${this.columnId(col, names)} = ${this.renderValue(value, params)}`,\n )\n .join(\", \");\n let sql = `UPDATE ${this.quoteId(node.table)} SET ${sets}`;\n sql += this.compileExtraSources(\"FROM\", node.from);\n const where = this.compileCondition(\n node.where,\n params,\n (k) => this.columnId(k, names),\n codecEncoder(node.codecs),\n );\n if (where) sql += ` WHERE ${where}`;\n sql += this.compileReturning(node.returning, names);\n return sql;\n }\n\n private compileDelete(node: DeleteNode, params: Params): string {\n const names = node.names;\n let sql = `DELETE FROM ${this.quoteId(node.table)}`;\n sql += this.compileExtraSources(\"USING\", node.using);\n const where = this.compileCondition(\n node.where,\n params,\n (k) => this.columnId(k, names),\n codecEncoder(node.codecs),\n );\n if (where) sql += ` WHERE ${where}`;\n sql += this.compileReturning(node.returning, names);\n return sql;\n }\n\n protected compileJoin(node: JoinNode, params: Params): string {\n const names = node.names;\n const cols = node.selections\n .map((s) => {\n const ref = `${s.alias}.${s.column}`;\n // `pick` projects one source flat, so the labels are the bare column\n // names a single-table shape needs, not the \"alias.column\" a composite\n // row is split by.\n const label = node.pick ? s.column : ref;\n return `${this.qualify(ref, names)} AS ${this.quoteId(label)}`;\n })\n .join(\", \");\n let sql = `${this.compileWith(node.with, params)}SELECT ${cols} FROM ${this.quoteId(node.base.table)} AS ${this.quoteId(node.base.alias)}`;\n for (const j of node.joins) {\n const kw = j.kind === \"left\" ? \"LEFT JOIN\" : \"INNER JOIN\";\n const on = j.on\n .map(([l, r]) => `${this.qualify(l, names)} = ${this.qualify(r, names)}`)\n .join(\" AND \");\n sql += ` ${kw} ${this.quoteId(j.table)} AS ${this.quoteId(j.alias)} ON ${on}`;\n }\n const where = this.compileCondition(node.where, params, (k) =>\n this.qualify(k, names),\n );\n if (where) sql += ` WHERE ${where}`;\n if (node.orderBy.length > 0) {\n const terms = node.orderBy\n .map(\n (t) =>\n `${this.qualify(t.ref, names)} ${t.direction === \"desc\" ? \"DESC\" : \"ASC\"}`,\n )\n .join(\", \");\n sql += ` ORDER BY ${terms}`;\n }\n if (node.limit !== undefined) sql += ` LIMIT ${params.bind(node.limit)}`;\n if (node.offset !== undefined) sql += ` OFFSET ${params.bind(node.offset)}`;\n return sql;\n }\n\n // ---- clauses ----------------------------------------------------------\n\n /**\n * Render the extra sources of an `UPDATE ... FROM` / `DELETE ... USING`.\n *\n * The dialects that do not have the clause override this and throw: emitting it\n * anyway would produce a statement the server rejects, and quietly dropping it\n * would change which rows are written.\n *\n * @param keyword `FROM` or `USING`.\n * @param sources The extra tables, if any.\n * @returns The clause with a leading space, or an empty string.\n */\n protected compileExtraSources(\n keyword: \"FROM\" | \"USING\",\n sources: readonly { readonly table: string; readonly alias: string }[] | undefined,\n ): string {\n if (!sources || sources.length === 0) return \"\";\n const list = sources\n .map((s) => `${this.quoteId(s.table)} AS ${this.quoteId(s.alias)}`)\n .join(\", \");\n return ` ${keyword} ${list}`;\n }\n\n protected compileReturning(\n returning: readonly string[] | \"*\" | null,\n names?: NameMap | undefined,\n ): string {\n if (returning === null) return \"\";\n if (returning === \"*\") return \" RETURNING *\";\n return ` RETURNING ${returning.map((c) => this.columnId(c, names)).join(\", \")}`;\n }\n\n /**\n * Compile a condition tree (fields / and / or / not) to SQL. `idFor` renders a\n * key to a quoted identifier — `quoteId` for single-table, `qualify` for joins —\n * so select/update/delete/join all share this one compiler.\n */\n protected compileCondition(\n node: CondNode | undefined,\n params: Params,\n idFor: (key: string) => string,\n encode: (key: string, value: unknown) => unknown = (_key, value) => value,\n ): string {\n if (!node) return \"\";\n switch (node.kind) {\n case \"fields\": {\n const conditions: string[] = [];\n for (const [key, value] of Object.entries(node.fields)) {\n const id = idFor(key);\n if (isExpression(value)) {\n // `where({ userId: col(\"users.id\") })` — the value is another column,\n // not a parameter. Binding it would compare the column against the\n // string \"users.id\".\n conditions.push(\n this.compileExprOperator(\n id,\n \"eq\",\n this.renderExpr(value.node, params, idFor),\n ),\n );\n } else if (isOperatorObject(value)) {\n for (const [op, operand] of Object.entries(value)) {\n conditions.push(\n isExpression(operand)\n ? this.compileExprOperator(\n id,\n op,\n this.renderExpr(operand.node, params, idFor),\n )\n : this.compileOperator(\n id,\n op,\n encodeOperand(op, operand, (v) => encode(key, v)),\n params,\n ),\n );\n }\n } else {\n // bare value → equality (null → IS NULL)\n const operand = encode(key, value);\n conditions.push(\n operand === null ? `${id} IS NULL` : `${id} = ${params.bind(operand)}`,\n );\n }\n }\n return conditions.join(\" AND \");\n }\n case \"and\":\n case \"or\": {\n const parts = node.parts\n .map((p) => this.compileCondition(p, params, idFor, encode))\n .filter((s) => s.length > 0);\n if (parts.length === 0) return \"\";\n const sep = node.kind === \"and\" ? \" AND \" : \" OR \";\n return parts.map((p) => `(${p})`).join(sep);\n }\n case \"not\": {\n const inner = this.compileCondition(node.part, params, idFor, encode);\n return inner ? `NOT (${inner})` : \"\";\n }\n case \"exists\": {\n const select = node.select as SelectNode;\n this.checkSubquery(select);\n const keyword = node.negate ? \"NOT EXISTS\" : \"EXISTS\";\n return `${keyword} (${this.compileSelect(select, params)})`;\n }\n case \"fullText\":\n return this.compileFullText(node, params, idFor);\n case \"compare\": {\n const left = this.renderExpr(node.left, params, idFor);\n if (node.right.kind === \"value\") {\n return this.compileOperator(left, node.op, node.right.value, params);\n }\n return this.compileExprOperator(\n left,\n node.op,\n this.renderExpr(node.right, params, idFor),\n );\n }\n }\n }\n\n /**\n * Compile a full-text condition.\n *\n * PostgreSQL gets the real thing (`@@ websearch_to_tsquery`); the dialects with\n * no text-search engine override this and compile the node's prebuilt substring\n * fallback instead, so the query still returns the right rows.\n *\n * @param node The full-text condition node.\n * @param params The parameter collector.\n * @param idFor Column-name resolver.\n * @returns The rendered condition.\n */\n protected compileFullText(\n node: Extract<CondNode, { kind: \"fullText\" }>,\n params: Params,\n idFor: (key: string) => string,\n ): string {\n const config = params.bind(node.language);\n return `${this.tsVector(node.columns, config, idFor)} @@ websearch_to_tsquery(${config}::regconfig, ${params.bind(node.term)})`;\n }\n\n /**\n * Render one side of a comparison.\n *\n * A column reference goes through `idFor`, so an explicit `.name()` mapping and\n * join qualification apply here exactly as they do in the object form of\n * `where` — `col()` is not a way around them. Only a `value` node binds.\n *\n * @param node The expression AST.\n * @param params The parameter collector.\n * @param idFor The identifier resolver for the enclosing statement.\n * @returns The SQL text of the expression.\n */\n /**\n * Render what an aggregate is applied to: `*`, a column, or an expression.\n *\n * An expression operand is what makes a conditional aggregate\n * (`SUM(CASE WHEN ... END)`) expressible — one pass over the table instead of a\n * query per bucket.\n *\n * @param agg The aggregate term.\n * @param params The parameter collector.\n * @param names The node's column-name map.\n * @returns The rendered operand.\n */\n private aggregateOperand(\n agg: AggregateTerm,\n params: Params,\n names: NameMap | undefined,\n ): string {\n if (agg.column === \"*\") return \"*\";\n if (typeof agg.column === \"string\") return this.columnId(agg.column, names);\n return this.renderExpr(agg.column, params, (k) => this.columnId(k, names));\n }\n\n private renderExpr(\n node: ExprNode,\n params: Params,\n idFor: (key: string) => string,\n ): string {\n switch (node.kind) {\n case \"column\":\n return idFor(node.name);\n case \"value\":\n return params.bind(node.value);\n case \"fn\": {\n const args = node.args.map((a) => this.renderExpr(a, params, idFor)).join(\", \");\n return `${node.name}(${args})`;\n }\n case \"case\": {\n const branches = node.branches\n .map(\n (b) =>\n `WHEN ${this.compileCondition(b.when, params, idFor)} THEN ${this.renderExpr(b.result, params, idFor)}`,\n )\n .join(\" \");\n const fallback =\n node.fallback === null\n ? \"\"\n : ` ELSE ${this.renderExpr(node.fallback, params, idFor)}`;\n return `CASE ${branches}${fallback} END`;\n }\n case \"cast\":\n return `CAST(${this.renderExpr(node.operand, params, idFor)} AS ${this.castTypeName(node.to)})`;\n case \"scalar\": {\n const select = node.select as SelectNode;\n this.checkSubquery(select);\n return `(${this.compileSelect(select, params)})`;\n }\n case \"rank\":\n return this.renderRank(node.columns, node.term, node.language, params, idFor);\n case \"star\":\n return \"*\";\n case \"window\": {\n const call = this.renderExpr(node.fn, params, idFor);\n const parts: string[] = [];\n if (node.partitionBy.length > 0) {\n parts.push(`PARTITION BY ${node.partitionBy.map(idFor).join(\", \")}`);\n }\n if (node.orderBy.length > 0) {\n const terms = node.orderBy\n .map((t) => `${idFor(t.column)} ${t.direction === \"desc\" ? \"DESC\" : \"ASC\"}`)\n .join(\", \");\n parts.push(`ORDER BY ${terms}`);\n }\n if (node.frame) parts.push(node.frame);\n return `${call} OVER (${parts.join(\" \")})`;\n }\n }\n }\n\n /**\n * Render a full-text relevance score.\n *\n * PostgreSQL has `ts_rank`; the others have nothing equivalent, and they\n * override this to a constant so that ordering by it is a no-op rather than a\n * compile error — the fallback keeps returning the right rows, only unranked.\n *\n * @param columns The columns making up the document.\n * @param term The search term.\n * @param language The text-search configuration.\n * @param params The parameter collector.\n * @param idFor Column-name resolver.\n * @returns The rendered score expression.\n */\n protected renderRank(\n columns: readonly string[],\n term: string,\n language: string,\n params: Params,\n idFor: (key: string) => string,\n ): string {\n const config = params.bind(language);\n return `ts_rank(${this.tsVector(columns, config, idFor)}, websearch_to_tsquery(${config}::regconfig, ${params.bind(term)}))`;\n }\n\n /**\n * Build the `to_tsvector(...)` document out of the searched columns.\n *\n * `coalesce(col, '')` matters: in SQL a `NULL` anywhere in a concatenation makes\n * the whole document `NULL`, so one empty column would silently exclude the row.\n *\n * @param columns The columns making up the document.\n * @param config The already-bound placeholder for the text-search config.\n * @param idFor Column-name resolver.\n * @returns The rendered `to_tsvector(...)` call.\n */\n protected tsVector(\n columns: readonly string[],\n config: string,\n idFor: (key: string) => string,\n ): string {\n const document = columns.map((c) => `coalesce(${idFor(c)}, '')`).join(\" || ' ' || \");\n return `to_tsvector(${config}::regconfig, ${document})`;\n }\n\n /**\n * The SQL type name this dialect accepts in a `CAST`.\n *\n * The base mapping is the standard one PostgreSQL takes; SQLite and MySQL\n * override it, because the names genuinely differ (MySQL's `CAST(x AS SIGNED)`\n * is not `INTEGER`, and SQLite only has five storage classes to aim at).\n *\n * @param to The portable cast target.\n * @returns The dialect's own type name.\n */\n protected castTypeName(to: CastType): string {\n switch (to) {\n case \"integer\":\n return \"INTEGER\";\n case \"bigint\":\n return \"BIGINT\";\n case \"real\":\n return \"DOUBLE PRECISION\";\n case \"numeric\":\n return \"NUMERIC\";\n case \"text\":\n return \"TEXT\";\n case \"boolean\":\n return \"BOOLEAN\";\n case \"date\":\n return \"DATE\";\n case \"datetime\":\n case \"timestamp\":\n return \"TIMESTAMP\";\n case \"uuid\":\n return \"UUID\";\n case \"json\":\n return \"JSON\";\n case \"jsonb\":\n return \"JSONB\";\n case \"blob\":\n return \"BYTEA\";\n }\n }\n\n /**\n * Compile a comparison whose right-hand side is another expression rather than\n * a bound value (`total > paid`, `lower(a) = lower(b)`).\n *\n * The list and null operators are excluded: `IN`, `BETWEEN` and `IS NULL` take\n * a value operand, and accepting an expression there would silently compile to\n * something else.\n *\n * @param left The rendered left-hand side.\n * @param op The operator name.\n * @param right The rendered right-hand side.\n * @returns The SQL text of the predicate.\n * @throws Error When the operator needs a value operand.\n */\n private compileExprOperator(left: string, op: string, right: string): string {\n switch (op) {\n case \"eq\":\n return `${left} = ${right}`;\n case \"ne\":\n return `${left} <> ${right}`;\n case \"gt\":\n return `${left} > ${right}`;\n case \"gte\":\n return `${left} >= ${right}`;\n case \"lt\":\n return `${left} < ${right}`;\n case \"lte\":\n return `${left} <= ${right}`;\n case \"like\":\n return `${left} LIKE ${right}`;\n case \"ilike\":\n return this.ilike(left, right);\n case \"ieq\":\n return `lower(${left}) = lower(${right})`;\n case \"iContains\":\n throw new Error(\n 'The \"iContains\" operator matches a literal, so it takes a value, not an expression.',\n );\n case \"contains\":\n case \"containedBy\":\n case \"overlaps\":\n return `${left} ${this.arrayOperator(op)} ${right}`;\n default:\n throw new Error(`The \"${op}\" operator takes a value operand, not an expression.`);\n }\n }\n\n private compileOperator(\n id: string,\n op: string,\n operand: unknown,\n params: Params,\n ): string {\n switch (op) {\n case \"eq\":\n return operand === null ? `${id} IS NULL` : `${id} = ${params.bind(operand)}`;\n case \"ne\":\n return operand === null\n ? `${id} IS NOT NULL`\n : `${id} <> ${params.bind(operand)}`;\n case \"gt\":\n return `${id} > ${params.bind(operand)}`;\n case \"gte\":\n return `${id} >= ${params.bind(operand)}`;\n case \"lt\":\n return `${id} < ${params.bind(operand)}`;\n case \"lte\":\n return `${id} <= ${params.bind(operand)}`;\n case \"like\":\n return `${id} LIKE ${params.bind(operand)}`;\n case \"ilike\":\n return this.ilike(id, params.bind(operand));\n case \"ieq\":\n return operand === null\n ? `${id} IS NULL`\n : `lower(${id}) = lower(${params.bind(operand)})`;\n case \"iContains\":\n return this.ilikeEscaped(id, params.bind(`%${escapeLike(String(operand))}%`));\n case \"contains\":\n return `${id} ${this.arrayOperator(\"contains\")} ${params.bind(operand)}`;\n case \"containedBy\":\n return `${id} ${this.arrayOperator(\"containedBy\")} ${params.bind(operand)}`;\n case \"overlaps\":\n return `${id} ${this.arrayOperator(\"overlaps\")} ${params.bind(operand)}`;\n case \"in\":\n return this.compileIn(id, operand, params, false);\n case \"notIn\":\n return this.compileIn(id, operand, params, true);\n case \"between\": {\n const [lo, hi] = operand as readonly [unknown, unknown];\n return `${id} BETWEEN ${params.bind(lo)} AND ${params.bind(hi)}`;\n }\n case \"isNull\":\n return operand ? `${id} IS NULL` : `${id} IS NOT NULL`;\n default:\n throw new Error(`Unknown operator ${JSON.stringify(op)}`);\n }\n }\n\n /**\n * Compile `IN` / `NOT IN`, whose operand is either a value list or a\n * single-column subquery.\n *\n * The subquery is rendered at the position it appears in the outer statement\n * and shares the same parameter collector, so its own placeholders land in the\n * right order — and it keeps its own `names` map, since the inner model may use\n * a different naming convention than the outer one.\n *\n * @param id The quoted column identifier being tested.\n * @param operand A list of values, or a {@link Subquery}.\n * @param params The parameter collector for the statement being compiled.\n * @param negate True for `NOT IN`.\n * @returns The SQL text of the predicate.\n */\n private compileIn(\n id: string,\n operand: unknown,\n params: Params,\n negate: boolean,\n ): string {\n const keyword = negate ? \"NOT IN\" : \"IN\";\n if (isSubquery(operand)) {\n this.checkSubquery(operand.node);\n return `${id} ${keyword} (${this.compileSelect(operand.node, params)})`;\n }\n const values = operand as readonly unknown[];\n if (values.length === 0) {\n // empty IN matches nothing; empty NOT IN matches everything\n return negate ? \"1 = 1\" : \"1 = 0\";\n }\n const list = values.map((v) => params.bind(v)).join(\", \");\n return `${id} ${keyword} (${list})`;\n }\n}\n\n/** SQLite dialect: `?` placeholders; `ILIKE` falls back to `LIKE` (ASCII-insensitive). */\nexport class SqliteDialect extends BaseDialect {\n readonly name = \"sqlite\" as const;\n\n /**\n * SQLite explains with `EXPLAIN QUERY PLAN`, and has no `ANALYZE` — the plain\n * `EXPLAIN` there dumps bytecode, which answers a different question.\n */\n override explainPrefix(analyze: boolean): string {\n if (analyze) {\n throw new Error(\n \"SQLite has no EXPLAIN ANALYZE; use EXPLAIN QUERY PLAN (analyze: false).\",\n );\n }\n return \"EXPLAIN QUERY PLAN\";\n }\n\n /**\n * SQLite has `UPDATE ... FROM` (3.33+) but no `DELETE ... USING`.\n *\n * The portable shape there is a subquery — `where({ id: { in: … } })` — so this\n * throws and says so, rather than emitting a clause SQLite does not parse.\n */\n protected override compileExtraSources(\n keyword: \"FROM\" | \"USING\",\n sources: readonly { readonly table: string; readonly alias: string }[] | undefined,\n ): string {\n if (keyword === \"USING\" && sources && sources.length > 0) {\n throw new Error(\n 'SQLite has no DELETE ... USING; filter with a subquery instead: where({ id: { in: select(Other, [\"id\"]).asSubquery(\"id\") } }).',\n );\n }\n return super.compileExtraSources(keyword, sources);\n }\n\n /**\n * SQLite has no text-search engine, so the prebuilt substring fallback is\n * compiled instead. The rows are right; the ranking is what is missing.\n */\n protected override compileFullText(\n node: Extract<CondNode, { kind: \"fullText\" }>,\n params: Params,\n idFor: (key: string) => string,\n ): string {\n return this.compileCondition(node.fallback, params, idFor);\n }\n\n /** No text-search engine means no score: a constant, so ordering by it is inert. */\n protected override renderRank(): string {\n return \"0\";\n }\n\n /**\n * SQLite has five storage classes, so most targets collapse onto `TEXT` or\n * `INTEGER`. Naming a type it does not know would not fail — SQLite applies the\n * closest affinity — but it would make the cast mean something different here\n * than on the other databases, which is what this mapping avoids.\n */\n protected override castTypeName(to: CastType): string {\n switch (to) {\n case \"integer\":\n case \"bigint\":\n case \"boolean\":\n return \"INTEGER\";\n case \"real\":\n return \"REAL\";\n case \"numeric\":\n return \"NUMERIC\";\n case \"blob\":\n return \"BLOB\";\n default:\n return \"TEXT\";\n }\n }\n\n protected placeholder(): string {\n return \"?\";\n }\n\n protected ilike(column: string, param: string): string {\n return `${column} LIKE ${param}`;\n }\n\n /**\n * SQLite runs one writer at a time, so its only isolation level **is**\n * serializable — there is no syntax to ask for another, and no weaker level to\n * fall back to. Asking for one is an error rather than a silent no-op, since a\n * caller who wrote `repeatable read` was reasoning about a guarantee.\n *\n * `readOnly` likewise has no per-transaction form here (`PRAGMA query_only` is\n * per connection), so it is refused instead of quietly ignored.\n */\n override beginStatements(options?: TransactionOptions): string[] {\n if (options?.isolation && options.isolation !== \"serializable\") {\n throw new Error(\n `SQLite only implements the \"serializable\" isolation level; ${JSON.stringify(options.isolation)} has no equivalent here.`,\n );\n }\n if (options?.readOnly) {\n throw new Error(\n \"SQLite has no read-only transaction; open the engine with { sqlite: { ... } } on a read-only connection instead.\",\n );\n }\n return [\"BEGIN\"];\n }\n\n /**\n * SQLite has no row-level locking, so a lock request is an error rather than a\n * silently unlocked `SELECT` — a lock that does not exist only shows up as\n * duplicated work under production concurrency.\n */\n protected override renderLock(): string {\n throw new Error(\n \"SQLite has no row-level locking — FOR UPDATE / FOR SHARE is unsupported. Serialize the claim inside a transaction instead.\",\n );\n }\n}\n\n/** PostgreSQL dialect: `$1` placeholders; native `ILIKE`; native array operators. */\nexport class PostgresDialect extends BaseDialect {\n readonly name = \"postgresql\" as const;\n\n protected placeholder(index: number): string {\n return `$${index}`;\n }\n\n protected ilike(column: string, param: string): string {\n return `${column} ILIKE ${param}`;\n }\n\n protected override arrayOperator(op: \"contains\" | \"containedBy\" | \"overlaps\"): string {\n if (op === \"contains\") return \"@>\";\n if (op === \"containedBy\") return \"<@\";\n return \"&&\";\n }\n}\n\n/** Backtick-quoted identifier cache for MySQL (its quoting differs from the base). */\nconst mysqlQuotedIds = new Map<string, string>();\n\n/**\n * MySQL dialect: `?` placeholders, backtick identifiers, `ON DUPLICATE KEY\n * UPDATE` for upsert, and case-insensitive `LIKE` (default collation). MySQL has\n * no `RETURNING`, so requesting it throws.\n */\nexport class MysqlDialect extends BaseDialect {\n readonly name = \"mysql\" as const;\n\n protected placeholder(): string {\n return \"?\";\n }\n\n protected ilike(column: string, param: string): string {\n return `${column} LIKE ${param}`; // MySQL LIKE is case-insensitive by default\n }\n\n /** MySQL's `EXPLAIN FORMAT=JSON` spells the option differently. */\n override explainPrefix(analyze: boolean): string {\n return analyze ? \"EXPLAIN ANALYZE\" : \"EXPLAIN FORMAT=JSON\";\n }\n\n /**\n * MySQL only gained `INTERSECT`/`EXCEPT` in 8.0.31, and this project does not\n * invest in MySQL beyond what already works — so they are refused here rather\n * than emitted against a server that may reject them.\n */\n protected override setOperator(op: SetOperator): string {\n if (op === \"intersect\" || op === \"except\") {\n throw new Error(\n `MySQL support for ${op.toUpperCase()} is out of scope for tempest-db-js; express it with a join or NOT EXISTS.`,\n );\n }\n return super.setOperator(op);\n }\n\n /**\n * MySQL writes multi-table updates as `UPDATE a JOIN b`, and has no\n * `DELETE ... USING` in this shape. Both are out of the project's active scope,\n * so they are refused rather than emitted against a server that rejects them.\n */\n protected override compileExtraSources(\n keyword: \"FROM\" | \"USING\",\n sources: readonly { readonly table: string; readonly alias: string }[] | undefined,\n ): string {\n if (sources && sources.length > 0) {\n throw new Error(\n `MySQL does not take ${keyword} on a write in this form; it spells multi-table writes as UPDATE a JOIN b, which is out of scope for tempest-db-js.`,\n );\n }\n return \"\";\n }\n\n /**\n * MySQL's full-text search needs a `FULLTEXT` index and different syntax, and it\n * is outside this project's active scope — the substring fallback is compiled,\n * like on SQLite.\n */\n protected override compileFullText(\n node: Extract<CondNode, { kind: \"fullText\" }>,\n params: Params,\n idFor: (key: string) => string,\n ): string {\n return this.compileCondition(node.fallback, params, idFor);\n }\n\n /** No `ts_rank` equivalent in scope: a constant, so ordering by it is inert. */\n protected override renderRank(): string {\n return \"0\";\n }\n\n /**\n * MySQL sets the level with a statement **before** the transaction opens, and\n * spells the read-only flag on `START TRANSACTION` rather than on `BEGIN`.\n */\n override beginStatements(options?: TransactionOptions): string[] {\n const statements: string[] = [];\n if (options?.isolation) {\n statements.push(\n `SET TRANSACTION ISOLATION LEVEL ${options.isolation.toUpperCase()}`,\n );\n }\n statements.push(options?.readOnly ? \"START TRANSACTION READ ONLY\" : \"BEGIN\");\n return statements;\n }\n\n /**\n * MySQL's `CAST` takes its own vocabulary — `SIGNED`, not `INTEGER`; `CHAR`,\n * not `TEXT` — and rejects the standard names outright.\n */\n protected override castTypeName(to: CastType): string {\n switch (to) {\n case \"integer\":\n case \"bigint\":\n case \"boolean\":\n return \"SIGNED\";\n case \"real\":\n case \"numeric\":\n return \"DECIMAL\";\n case \"text\":\n case \"uuid\":\n return \"CHAR\";\n case \"date\":\n return \"DATE\";\n case \"datetime\":\n case \"timestamp\":\n return \"DATETIME\";\n case \"json\":\n case \"jsonb\":\n return \"JSON\";\n case \"blob\":\n return \"BINARY\";\n }\n }\n\n protected override quoteId(name: string): string {\n const cached = mysqlQuotedIds.get(name);\n if (cached !== undefined) return cached;\n const quoted = `\\`${name.replace(/`/g, \"``\")}\\``;\n mysqlQuotedIds.set(name, quoted);\n return quoted;\n }\n\n /**\n * MySQL rejects `LIMIT` inside an `IN` subquery with\n * `ER_NOT_SUPPORTED_YET: This version of MySQL doesn't yet support\n * 'LIMIT & IN/ALL/ANY/SOME subquery'`. Failing at compile time names the fix\n * instead of surfacing that error from the driver at runtime.\n */\n protected override checkSubquery(node: SelectNode): void {\n if (node.limit !== undefined || node.offset !== undefined) {\n throw new Error(\n \"MySQL does not support LIMIT/OFFSET inside an IN subquery. Select the ids first and pass them as a list, or wrap the subquery in a derived table.\",\n );\n }\n }\n\n protected override renderConflict(\n onConflict: NonNullable<InsertNode[\"onConflict\"]>,\n conflictCols: readonly string[],\n nextValue: () => string,\n names: NameMap | undefined,\n ): string {\n if (onConflict.targetWhere || onConflict.updateWhere) {\n throw new Error(\n \"MySQL's ON DUPLICATE KEY UPDATE has no conflict-target predicate — a partial unique index is PostgreSQL/SQLite only.\",\n );\n }\n if (onConflict.update === \"nothing\") {\n // MySQL has no DO NOTHING; a no-op self-assignment on a target column is\n // the idiomatic equivalent (keeps the existing row untouched).\n const col = this.columnId(onConflict.target[0] ?? \"id\", names);\n return ` ON DUPLICATE KEY UPDATE ${col} = ${col}`;\n }\n const assignments = conflictCols\n .map((c) => `${this.columnId(c, names)} = ${nextValue()}`)\n .join(\", \");\n return ` ON DUPLICATE KEY UPDATE ${assignments}`;\n }\n\n /**\n * MySQL has no `RETURNING`, so it cannot be compiled into a statement.\n *\n * `session.execute()` still honors `.returning()` on a **single-row INSERT** by\n * running the insert and reading the row back by key on the same connection —\n * that is execution, not compilation, so it never reaches here. Compiling a\n * node with `returning` directly is an error, rather than SQL that silently\n * returns nothing.\n */\n protected override compileReturning(returning: readonly string[] | \"*\" | null): string {\n if (returning === null) return \"\";\n throw new Error(\n \"RETURNING cannot be compiled for MySQL. session.execute() reads a single-row INSERT back by key (LAST_INSERT_ID()); UPDATE/DELETE have no equivalent — run a SELECT yourself.\",\n );\n }\n}\n\n/** Get a dialect instance by name. */\nexport function getDialect(name: Dialect): BaseDialect {\n switch (name) {\n case \"sqlite\":\n return new SqliteDialect();\n case \"postgresql\":\n return new PostgresDialect();\n case \"mysql\":\n return new MysqlDialect();\n }\n}\n","/**\n * tempest-db-js — Phase 4b: engine, session, real execution.\n *\n * Async by default (`createEngine`), with an optional sync engine for SQLite\n * (`createSyncEngine`). The database is identified by its URL (Phase 4a's\n * `parseDatabaseUrl`); the dialect compiles the builder AST to `{ sql, params }`\n * (Phase 4a's `getDialect`); a driver runs it; rows are coerced back to native\n * types via `coerceRow` (the serialization layer).\n *\n * SQLite execution is real and tested here through Node's built-in `node:sqlite`.\n * `better-sqlite3` and `postgres` (postgres.js) are lazy-loaded peer drivers.\n */\n\nimport { createRequire } from \"node:module\";\nimport { col, fn } from \"./conditions.js\";\nimport { type BaseDialect, getDialect } from \"./dialect.js\";\nimport {\n type ExplainOptions,\n type ExplainReport,\n type RecordedStatement,\n buildReport,\n} from \"./explain.js\";\nimport { type ModelClass, columnNamesOf, columnsOf } from \"./index.js\";\nimport type { JoinBuilder, JoinNode } from \"./join.js\";\nimport type { InsertBuilder, InsertNode, UpdateBuilder } from \"./mutations.js\";\nimport { type SelectBuilder, select } from \"./query.js\";\nimport { coerceRow } from \"./serialize.js\";\nimport type { SetBuilder } from \"./setops.js\";\nimport { UnitOfWork } from \"./unit-of-work.js\";\nimport { type Dialect, type ParsedDatabaseUrl, parseDatabaseUrl } from \"./url.js\";\n\n/** A synchronous `require`, usable from both ESM and CJS builds. */\nconst nodeRequire = createRequire(import.meta.url);\n\n// ---------------------------------------------------------------------------\n// driver layer\n// ---------------------------------------------------------------------------\n\n/** The outcome of running one statement. */\nexport interface DriverResult {\n /** Returned rows (SELECT or `RETURNING`); empty otherwise. */\n readonly rows: Record<string, unknown>[];\n /** Rows affected by an INSERT/UPDATE/DELETE. */\n readonly changes: number;\n}\n\n/** A synchronous driver (SQLite). */\nexport interface SyncDriver {\n execute(sql: string, params: readonly unknown[]): DriverResult;\n /** Lazily iterate rows (for `.stream()`), if the driver supports it. */\n iterate?(\n sql: string,\n params: readonly unknown[],\n ): IterableIterator<Record<string, unknown>>;\n close(): void;\n}\n\n/** An asynchronous driver (PostgreSQL, or an async-wrapped SQLite). */\nexport interface AsyncDriver {\n execute(sql: string, params: readonly unknown[]): Promise<DriverResult>;\n /** Lazily iterate rows (for `.stream()`), if the driver supports it. */\n iterate?(\n sql: string,\n params: readonly unknown[],\n ): AsyncIterableIterator<Record<string, unknown>>;\n /**\n * Reserve a single pinned connection for the duration of a transaction.\n * Pooled drivers (PostgreSQL) MUST implement this so `BEGIN`/`COMMIT` and the\n * statements between them all run on the same connection. Single-connection\n * drivers (SQLite) may omit it — `transaction` then runs on the shared handle.\n */\n reserve?(): Promise<ReservedAsyncDriver>;\n close(): Promise<void>;\n}\n\n/** An {@link AsyncDriver} pinned to one connection, used inside a transaction. */\nexport interface ReservedAsyncDriver extends AsyncDriver {\n /** Return the pinned connection to the pool. */\n release(): Promise<void>;\n}\n\n/** Encode a JS value into something a SQLite driver can bind. */\nfunction encodeSqliteParam(value: unknown): unknown {\n if (value === undefined || value === null) return null;\n if (typeof value === \"boolean\") return value ? 1 : 0;\n if (value instanceof Date) return value.toISOString();\n if (value instanceof Uint8Array) return value;\n if (typeof value === \"object\") return JSON.stringify(value);\n return value; // number, bigint, string\n}\n\n/** SQLite driver backed by Node's built-in `node:sqlite` (zero install). */\nexport class NodeSqliteDriver implements SyncDriver {\n // biome-ignore lint/suspicious/noExplicitAny: node:sqlite DatabaseSync has no shipped types here.\n private readonly db: any;\n /**\n * Prepared-statement cache keyed by SQL text. tempest-db-js always\n * parameterizes, so a query shape maps to one stable SQL string — reusing the\n * compiled statement avoids re-`prepare()` on every call (the dominant cost of\n * per-row inserts and point lookups).\n */\n // biome-ignore lint/suspicious/noExplicitAny: node:sqlite StatementSync has no shipped types here.\n private readonly statements = new Map<string, any>();\n\n // biome-ignore lint/suspicious/noExplicitAny: accept an already-open DatabaseSync handle.\n constructor(database: any) {\n this.db = database;\n }\n\n /**\n * Open a `node:sqlite` database at the given path (or `:memory:`).\n *\n * @param path The database file, or `\":memory:\"`.\n * @param options Passed straight to `DatabaseSync` (`readOnly`, `timeout`, …).\n * @returns A driver over the open handle.\n */\n static open(\n path: string,\n options?: Readonly<Record<string, unknown>>,\n ): NodeSqliteDriver {\n // Lazy require so importing tempest-db-js never forces the built-in module to load.\n const { DatabaseSync } = nodeRequire(\"node:sqlite\") as {\n DatabaseSync: new (path: string, options?: Record<string, unknown>) => unknown;\n };\n return new NodeSqliteDriver(\n options ? new DatabaseSync(path, { ...options }) : new DatabaseSync(path),\n );\n }\n\n /** Return the cached prepared statement for `sql`, preparing it on first use. */\n // biome-ignore lint/suspicious/noExplicitAny: statement type is unavailable here.\n private prepare(sql: string): any {\n const cached = this.statements.get(sql);\n if (cached) return cached;\n const stmt = this.db.prepare(sql);\n this.statements.set(sql, stmt);\n return stmt;\n }\n\n execute(sql: string, params: readonly unknown[]): DriverResult {\n const stmt = this.prepare(sql);\n const bound = params.map(encodeSqliteParam);\n if (returnsRows(sql)) {\n return { rows: stmt.all(...bound) as Record<string, unknown>[], changes: 0 };\n }\n const info = stmt.run(...bound);\n return { rows: [], changes: Number(info.changes ?? 0) };\n }\n\n *iterate(\n sql: string,\n params: readonly unknown[],\n ): IterableIterator<Record<string, unknown>> {\n const stmt = this.prepare(sql);\n const bound = params.map(encodeSqliteParam);\n yield* stmt.iterate(...bound) as IterableIterator<Record<string, unknown>>;\n }\n\n close(): void {\n this.statements.clear();\n this.db.close();\n }\n}\n\n/**\n * SQLite driver backed by the `better-sqlite3` peer dependency.\n *\n * Selected with `{ driver: \"better-sqlite3\" }` or the URL suffix\n * `sqlite+better-sqlite3://…`; the built-in `node:sqlite` stays the default, so\n * nothing has to be installed to use SQLite. Pick this one when the service\n * already runs on better-sqlite3, or needs what it exposes and `node:sqlite`\n * does not — `pragma()`, loadable extensions, its own WAL helpers.\n *\n * Row shape matches {@link NodeSqliteDriver}: plain objects, BLOBs as `Buffer`\n * (a `Uint8Array` subclass), which is what `coerceRow` already expects.\n */\nexport class BetterSqliteDriver implements SyncDriver {\n // biome-ignore lint/suspicious/noExplicitAny: the peer dep's types are optional here.\n private readonly db: any;\n /** Prepared-statement cache keyed by SQL text — see {@link NodeSqliteDriver}. */\n // biome-ignore lint/suspicious/noExplicitAny: see above.\n private readonly statements = new Map<string, any>();\n\n // biome-ignore lint/suspicious/noExplicitAny: accept an already-open Database handle.\n constructor(database: any) {\n this.db = database;\n }\n\n /**\n * Open a `better-sqlite3` database at the given path (or `\":memory:\"`).\n *\n * @param path The database file, or `\":memory:\"`.\n * @param options Passed straight to `new Database()` (`readonly`, `timeout`, …).\n * @returns A driver over the open handle.\n * @throws If `better-sqlite3` is not installed — it is an optional peer\n * dependency, so the error names the package to install.\n */\n static open(\n path: string,\n options?: Readonly<Record<string, unknown>>,\n ): BetterSqliteDriver {\n let Database: new (path: string, options?: Record<string, unknown>) => unknown;\n try {\n const mod = nodeRequire(\"better-sqlite3\") as\n | { default?: typeof Database }\n | typeof Database;\n Database = ((mod as { default?: typeof Database }).default ??\n mod) as typeof Database;\n } catch (cause) {\n throw new Error(\n 'The \"better-sqlite3\" driver requires the better-sqlite3 package: npm install better-sqlite3',\n { cause },\n );\n }\n return new BetterSqliteDriver(\n options ? new Database(path, { ...options }) : new Database(path),\n );\n }\n\n /** Return the cached prepared statement for `sql`, preparing it on first use. */\n // biome-ignore lint/suspicious/noExplicitAny: statement type is optional here.\n private prepare(sql: string): any {\n const cached = this.statements.get(sql);\n if (cached) return cached;\n const stmt = this.db.prepare(sql);\n this.statements.set(sql, stmt);\n return stmt;\n }\n\n execute(sql: string, params: readonly unknown[]): DriverResult {\n const stmt = this.prepare(sql);\n const bound = params.map(encodeSqliteParam);\n // better-sqlite3 throws when all()/run() is called on the wrong statement\n // kind, and it already knows which is which — ask it instead of guessing.\n if (stmt.reader) {\n return { rows: stmt.all(...bound) as Record<string, unknown>[], changes: 0 };\n }\n const info = stmt.run(...bound);\n return { rows: [], changes: Number(info.changes ?? 0) };\n }\n\n *iterate(\n sql: string,\n params: readonly unknown[],\n ): IterableIterator<Record<string, unknown>> {\n const stmt = this.prepare(sql);\n const bound = params.map(encodeSqliteParam);\n yield* stmt.iterate(...bound) as IterableIterator<Record<string, unknown>>;\n }\n\n close(): void {\n this.statements.clear();\n this.db.close();\n }\n}\n\n/**\n * True when a statement yields rows.\n *\n * `node:sqlite` needs this decided up front (`all()` vs `run()`), and getting it\n * wrong is silent: a statement that returns rows, run through `run()`, reports\n * zero rows instead of failing. So the list covers every row-producing form —\n * `WITH` (a CTE query), `EXPLAIN`, `VALUES` and `TABLE`, not only `SELECT`.\n */\nfunction returnsRows(sql: string): boolean {\n return (\n /^\\s*(select|with|values|table|pragma|explain)\\b/i.test(sql) ||\n /\\breturning\\b/i.test(sql)\n );\n}\n\n// ---------------------------------------------------------------------------\n// executable builders & row extraction\n// ---------------------------------------------------------------------------\n\n/* biome-ignore lint/suspicious/noExplicitAny: builder generics are irrelevant to execution dispatch. */\ntype AnySelect = SelectBuilder<any, any, any>;\n/* biome-ignore lint/suspicious/noExplicitAny: see above. */\ntype AnyInsert = InsertBuilder<any, any, any>;\n/* biome-ignore lint/suspicious/noExplicitAny: only the guarded flag matters. */\ntype GuardedUpdate = UpdateBuilder<any, true, any>;\n/* biome-ignore lint/suspicious/noExplicitAny: only the guarded flag matters. */\ntype GuardedDelete = import(\"./mutations.js\").DeleteBuilder<any, true, any>;\n/* biome-ignore lint/suspicious/noExplicitAny: join sources are irrelevant to dispatch. */\ntype AnyJoin = JoinBuilder<any>;\n/* biome-ignore lint/suspicious/noExplicitAny: the row type is irrelevant to dispatch. */\ntype AnySet = SetBuilder<any>;\n\n/**\n * A builder that is safe to execute. UPDATE/DELETE are accepted only once\n * guarded (after `.where()` or `.unguarded()`) — an unguarded full-table write\n * is a compile error at the execution boundary.\n */\nexport type Executable =\n | AnySelect\n | AnyInsert\n | GuardedUpdate\n | GuardedDelete\n | AnyJoin\n | AnySet;\n\n/** The element type a builder yields on execution. */\nexport type RowOf<B> = B extends { readonly __row: infer R } ? R : never;\n\n/** Internals shared between single-table builders, read structurally at runtime. */\ninterface SingleBuilder {\n readonly node: Parameters<BaseDialect[\"compile\"]>[0];\n readonly source: ModelClass;\n}\n\n/** Internals of a join builder, read structurally at runtime. */\ninterface JoinRunnable {\n readonly node: JoinNode;\n readonly sources: Readonly<Record<string, ModelClass>>;\n}\n\n/** Split one flat `alias.column` row into a coerced composite `{ alias: {...} }`. */\nfunction splitJoinRow(\n node: JoinNode,\n sources: Readonly<Record<string, ModelClass>>,\n raw: Record<string, unknown>,\n): Record<string, unknown> {\n const leftAliases = new Set(\n node.joins.filter((j) => j.kind === \"left\").map((j) => j.alias),\n );\n const out: Record<string, unknown> = {};\n for (const [alias, model] of Object.entries(sources)) {\n const sub: Record<string, unknown> = {};\n const names = columnNamesOf(model);\n let allNull = true;\n for (const colName of Object.keys(columnsOf(model))) {\n const value = raw[`${alias}.${colName}`];\n if (value !== null && value !== undefined) allNull = false;\n sub[names?.[colName] ?? colName] = value;\n }\n out[alias] = leftAliases.has(alias) && allNull ? null : coerceRow(model, sub);\n }\n return out;\n}\n\n/** Coerce one raw driver row into the builder's native row shape. */\nfunction coerceOne(builder: unknown, raw: Record<string, unknown>): unknown {\n const node = (builder as { node: { kind: string; pick?: string } }).node;\n if (node.kind === \"join_select\") {\n const b = builder as unknown as JoinRunnable;\n // `pick` asked for one source, flat: coerce it like a single-table row\n // instead of splitting the composite.\n if (node.pick) {\n const model = b.sources[node.pick];\n if (model) return coerceRow(model, raw);\n }\n return splitJoinRow(b.node, b.sources, raw);\n }\n const b = builder as unknown as SingleBuilder;\n return coerceRow(b.source, raw);\n}\n\n/** Coerce raw driver rows into the builder's native row shape. */\nfunction mapRows(builder: unknown, raw: Record<string, unknown>[]): unknown[] {\n return raw.map((r) => coerceOne(builder, r));\n}\n\n// ---------------------------------------------------------------------------\n// results\n// ---------------------------------------------------------------------------\n\n/** Raised by `.one()` when the row count is not exactly one. */\nexport class NoResultError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NoResultError\";\n }\n}\n\n/** A short, safe preview of a bound parameter for an error message. */\nfunction previewParam(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (value instanceof Uint8Array) return `<${value.length} bytes>`;\n const text = typeof value === \"string\" ? value : String(value);\n return text.length > 64 ? `${text.slice(0, 61)}...` : text;\n}\n\n/**\n * Raised when the driver rejects a statement. Wraps the original driver error\n * and attaches the offending SQL and its bound parameters, so a failure points\n * at the exact query instead of an opaque driver message.\n */\nexport class QueryExecutionError extends Error {\n constructor(\n /** The original error thrown by the driver. */\n override readonly cause: unknown,\n /** The SQL that failed. */\n readonly sql: string,\n /** The bound parameters, in order. */\n readonly params: readonly unknown[],\n ) {\n const reason = cause instanceof Error ? cause.message : String(cause);\n super(\n `Query failed: ${reason}\\n SQL: ${sql}\\n params: [${params\n .map(previewParam)\n .join(\", \")}]`,\n );\n this.name = \"QueryExecutionError\";\n }\n}\n\n/**\n * A hook invoked for every statement a session runs (query logging / tracing).\n * Errors thrown by the logger are ignored so logging never breaks execution.\n */\nexport type QueryLogger = (event: {\n readonly sql: string;\n readonly params: readonly unknown[];\n}) => void;\n\n/**\n * What a statement did, reported **after** it ran.\n *\n * `onQuery` fires before execution, so it cannot time anything; this is the other\n * half. It fires on the failure path too, with `error` set — a slow statement that\n * then fails is exactly the one worth seeing.\n */\nexport interface QueryEndEvent {\n /** The statement text. */\n readonly sql: string;\n /** The bound parameters, in placeholder order. */\n readonly params: readonly unknown[];\n /** Wall-clock time the driver took, in milliseconds. */\n readonly durationMs: number;\n /** Rows returned (a SELECT or `RETURNING`), or rows affected by a write. */\n readonly rowCount: number;\n /** The driver's error, when the statement failed. */\n readonly error?: unknown;\n}\n\n/**\n * Called after every statement, with its duration.\n *\n * Errors thrown by the hook are ignored, like {@link QueryLogger}.\n */\nexport type QueryEndLogger = (event: QueryEndEvent) => void;\n\n/** The per-statement hooks a session carries. */\nexport interface QueryHooks {\n /** Called before a statement runs. */\n readonly onQuery?: QueryLogger | undefined;\n /** Called after a statement runs, with its duration. */\n readonly onQueryEnd?: QueryEndLogger | undefined;\n /** When set, `onQueryEnd` fires only for statements at least this slow (ms). */\n readonly slowQueryMs?: number | undefined;\n}\n\n/** Invoke a query logger, swallowing any error it throws. */\nfunction emitLog(\n hooks: QueryHooks | undefined,\n sql: string,\n params: readonly unknown[],\n): void {\n const logger = hooks?.onQuery;\n if (!logger) return;\n try {\n logger({ sql, params });\n } catch {\n // logging must never break execution\n }\n}\n\n/** Read a monotonic clock, in milliseconds. */\nfunction now(): number {\n return performance.now();\n}\n\n/**\n * Invoke the end-of-statement hook, swallowing any error it throws.\n *\n * @param hooks The session's hooks.\n * @param event What the statement did.\n */\nfunction emitQueryEnd(hooks: QueryHooks | undefined, event: QueryEndEvent): void {\n const logger = hooks?.onQueryEnd;\n if (!logger) return;\n const threshold = hooks?.slowQueryMs;\n if (threshold !== undefined && event.durationMs < threshold) return;\n try {\n logger(event);\n } catch {\n // logging must never break execution\n }\n}\n\n/** Rows a driver result reports — returned rows, or rows affected by a write. */\nfunction resultRowCount(result: DriverResult): number {\n return result.rows.length > 0 ? result.rows.length : result.changes;\n}\n\nfunction firstScalar(row: Record<string, unknown> | undefined): unknown {\n if (!row) return null;\n const keys = Object.keys(row);\n return keys.length > 0 ? row[keys[0] as string] : null;\n}\n\n/** Synchronous result view over already-fetched rows. */\nexport class SyncResult<Row> {\n constructor(\n private readonly rows: Row[],\n private readonly changes: number,\n ) {}\n\n all(): Row[] {\n return this.rows;\n }\n first(): Row | null {\n return this.rows[0] ?? null;\n }\n one(): Row {\n if (this.rows.length !== 1) {\n throw new NoResultError(`expected exactly one row, got ${this.rows.length}`);\n }\n return this.rows[0] as Row;\n }\n oneOrNull(): Row | null {\n if (this.rows.length > 1) {\n throw new NoResultError(`expected at most one row, got ${this.rows.length}`);\n }\n return this.rows[0] ?? null;\n }\n scalar(): unknown {\n return firstScalar(this.rows[0] as Record<string, unknown> | undefined);\n }\n scalars(): unknown[] {\n return this.rows.map((r) => firstScalar(r as Record<string, unknown>));\n }\n rowsAffected(): number {\n return this.changes;\n }\n}\n\n/** Asynchronous result view (terminals return Promises). */\nexport class AsyncResult<Row> {\n constructor(private readonly inner: Promise<SyncResult<Row>>) {}\n\n async all(): Promise<Row[]> {\n return (await this.inner).all();\n }\n async first(): Promise<Row | null> {\n return (await this.inner).first();\n }\n async one(): Promise<Row> {\n return (await this.inner).one();\n }\n async oneOrNull(): Promise<Row | null> {\n return (await this.inner).oneOrNull();\n }\n async scalar(): Promise<unknown> {\n return (await this.inner).scalar();\n }\n async scalars(): Promise<unknown[]> {\n return (await this.inner).scalars();\n }\n async rowsAffected(): Promise<number> {\n return (await this.inner).rowsAffected();\n }\n}\n\n// ---------------------------------------------------------------------------\n// sessions\n// ---------------------------------------------------------------------------\n\nlet savepointCounter = 0;\n\n/**\n * True when a builder asks for `RETURNING` on a dialect that has none, so the\n * session must insert and read the row back instead of compiling one statement.\n */\nfunction needsInsertReadBack(\n dialect: BaseDialect,\n node: Parameters<BaseDialect[\"compile\"]>[0],\n): node is InsertNode {\n return dialect.name === \"mysql\" && node.kind === \"insert\" && node.returning !== null;\n}\n\n/** The model's single primary-key property name, for the insert read-back. */\nfunction singlePrimaryKey(model: ModelClass): string {\n const keys = Object.entries(columnsOf(model))\n .filter(([, column]) => column.flags.primaryKey)\n .map(([name]) => name);\n if (keys.length !== 1) {\n throw new Error(\n `${model.tablename} needs exactly one primary key to read an insert back on a dialect without RETURNING; found ${keys.length}.`,\n );\n }\n return keys[0] as string;\n}\n\n/** Reject a `raw()` call whose parameters are not an array. */\nfunction assertRawParams(params: readonly unknown[]): void {\n if (!Array.isArray(params)) {\n throw new TypeError(\n \"session.raw(sql, params) takes an array of bound parameters — never interpolate values into the SQL string.\",\n );\n }\n}\n\n/**\n * A transaction isolation level, in the SQL standard's names.\n *\n * The database's default is what you get without asking: `read committed` on\n * PostgreSQL and MySQL's `repeatable read`. SQLite has only `serializable`.\n */\nexport type IsolationLevel =\n | \"read uncommitted\"\n | \"read committed\"\n | \"repeatable read\"\n | \"serializable\";\n\n/** Characteristics for one transaction block. */\nexport interface TransactionOptions {\n /**\n * The isolation level for this block.\n *\n * Raising it is how the queue and outbox patterns get their invariants: under\n * `read committed` two workers can both pass the same check before either\n * commits. Asking for a level a dialect does not implement throws.\n */\n readonly isolation?: IsolationLevel;\n /**\n * Open the block read-only, so the database itself rejects a write in it.\n * PostgreSQL and MySQL only; SQLite throws.\n */\n readonly readOnly?: boolean;\n}\n\n/**\n * Refuse transaction characteristics on a block that is only joining an outer one.\n *\n * Isolation is fixed when the transaction opens; asking for it on a nested block\n * cannot take effect, and silently ignoring the request would leave the caller\n * believing they got a guarantee they do not have.\n *\n * @param options The options passed to the nested call.\n * @throws Error When any characteristic was requested.\n */\nfunction assertNoNestedOptions(options?: TransactionOptions): void {\n if (options?.isolation || options?.readOnly) {\n throw new Error(\n \"Transaction characteristics can only be set on the outermost transaction() — a nested block joins the one already open.\",\n );\n }\n}\n\n/** A synchronous unit of work (SQLite). */\nexport class SyncSession {\n constructor(\n private readonly driver: SyncDriver,\n private readonly dialect: BaseDialect,\n /** Optional per-statement hooks (query tracing and timing). */\n private readonly hooks?: QueryHooks,\n ) {}\n\n /** Open `transaction()` blocks on this session; only the outermost commits. */\n private depth = 0;\n\n /** Log, run, time, and error-wrap one raw statement. */\n private exec(sql: string, params: readonly unknown[]): DriverResult {\n emitLog(this.hooks, sql, params);\n const startedAt = now();\n try {\n const result = this.driver.execute(sql, params);\n emitQueryEnd(this.hooks, {\n sql,\n params,\n durationMs: now() - startedAt,\n rowCount: resultRowCount(result),\n });\n return result;\n } catch (error) {\n emitQueryEnd(this.hooks, {\n sql,\n params,\n durationMs: now() - startedAt,\n rowCount: 0,\n error,\n });\n throw new QueryExecutionError(error, sql, params);\n }\n }\n\n /**\n * Run a raw, parameterized SQL statement (synchronous) — the runtime counterpart of the\n * migrations' `Op.execute`.\n *\n * A query builder never covers all of SQL, and without an escape hatch a single\n * unsupported query forces a whole second database stack alongside this one. Use\n * it for what the builder cannot yet express, and keep everything else typed.\n *\n * The statement goes through the same path as a compiled one: it is logged via\n * `onQuery`, wrapped in {@link QueryExecutionError} on failure, and runs on the\n * reserved connection inside `transaction()`.\n *\n * @param sql The statement text. Placeholders only (`$1` / `?` per dialect) —\n * never interpolate a value into this string.\n * @param params The bound parameters, in placeholder order.\n * @param options Pass `as` to coerce the returned rows with a model's column\n * types (and its column-name mapping).\n * @returns The result view over the returned rows.\n * @throws Error When `params` is not an array — the guard against calling this\n * with an interpolated string and no parameters by mistake.\n *\n * @example\n * ```ts\n * const claimed = await session.raw<OutboundRow>(\n * `UPDATE outbound_messages SET status = 'sending'\n * WHERE id = ANY($1) RETURNING *`,\n * [ids],\n * { as: Outbound },\n * ).all();\n * ```\n */\n raw<Row = Record<string, unknown>>(\n sql: string,\n params: readonly unknown[] = [],\n options?: { readonly as?: ModelClass },\n ): SyncResult<Row> {\n assertRawParams(params);\n const result = this.exec(sql, params);\n const model = options?.as;\n const rows = (\n model ? result.rows.map((row) => coerceRow(model, row)) : result.rows\n ) as Row[];\n return new SyncResult<Row>(rows, result.changes);\n }\n\n /** Compile, run, and coerce a builder into a result. */\n execute<B extends Executable>(builder: B): SyncResult<RowOf<B>> {\n const node = (builder as unknown as { node: Parameters<BaseDialect[\"compile\"]>[0] })\n .node;\n const { sql, params } = this.dialect.compile(node);\n const result = this.exec(sql, params);\n const rows = mapRows(builder, result.rows) as RowOf<B>[];\n return new SyncResult<RowOf<B>>(rows, result.changes);\n }\n\n /** Run `fn` inside a transaction: commit on success, rollback on throw. */\n /**\n * How many `transaction()` blocks are open on this session.\n *\n * The counter is what makes a service that orchestrates two repositories work:\n * both hold the same session, so an inner block **joins** the outer one instead\n * of emitting a second `BEGIN`, and only the outermost exit commits.\n */\n get transactionDepth(): number {\n return this.depth;\n }\n\n /** Whether a `transaction()` block is currently open on this session. */\n get inTransaction(): boolean {\n return this.depth > 0;\n }\n\n /**\n * Run `fn` inside a transaction, committing on a clean exit and rolling back on\n * a throw.\n *\n * **Re-entrant:** a nested call joins the block already open on this session —\n * one `BEGIN`, one `COMMIT`, and an inner failure rolls the whole thing back.\n * To recover from an inner failure without discarding the outer work, use\n * {@link beginNested}, which is a real savepoint.\n *\n * @param fn The body; receives the session to work through.\n * @returns Whatever `fn` returned.\n */\n transaction<T>(fn: (tx: SyncSession) => T, options?: TransactionOptions): T {\n if (this.depth > 0) {\n assertNoNestedOptions(options);\n this.depth += 1;\n try {\n return fn(this);\n } finally {\n this.depth -= 1;\n }\n }\n for (const stmt of this.dialect.beginStatements(options)) this.exec(stmt, []);\n this.depth = 1;\n try {\n const out = fn(this);\n this.exec(\"COMMIT\", []);\n return out;\n } catch (error) {\n this.exec(\"ROLLBACK\", []);\n throw error;\n } finally {\n this.depth = 0;\n }\n }\n\n /** Run `fn` inside a SAVEPOINT (nested transaction). */\n beginNested<T>(fn: (sp: SyncSession) => T): T {\n savepointCounter += 1;\n const name = `qsp_${savepointCounter}`;\n this.exec(`SAVEPOINT ${name}`, []);\n try {\n const out = fn(this);\n this.exec(`RELEASE ${name}`, []);\n return out;\n } catch (error) {\n this.exec(`ROLLBACK TO ${name}`, []);\n throw error;\n }\n }\n\n /**\n * Lazily iterate result rows without materializing them all. Falls back to a\n * buffered fetch when the driver has no native iteration.\n */\n *stream<B extends Executable>(builder: B): IterableIterator<RowOf<B>> {\n const node = (builder as unknown as { node: Parameters<BaseDialect[\"compile\"]>[0] })\n .node;\n const { sql, params } = this.dialect.compile(node);\n emitLog(this.hooks, sql, params);\n if (this.driver.iterate) {\n const startedAt = now();\n let rowCount = 0;\n try {\n for (const raw of this.driver.iterate(sql, params)) {\n rowCount++;\n yield coerceOne(builder, raw) as RowOf<B>;\n }\n } catch (error) {\n emitQueryEnd(this.hooks, {\n sql,\n params,\n durationMs: now() - startedAt,\n rowCount,\n error,\n });\n throw new QueryExecutionError(error, sql, params);\n }\n emitQueryEnd(this.hooks, {\n sql,\n params,\n durationMs: now() - startedAt,\n rowCount,\n });\n return;\n }\n for (const raw of this.exec(sql, params).rows) {\n yield coerceOne(builder, raw) as RowOf<B>;\n }\n }\n\n close(): void {\n this.driver.close();\n }\n\n /** `using session = ...` closes the driver when the scope exits. */\n [Symbol.dispose](): void {\n this.close();\n }\n}\n\n/** An asynchronous unit of work. */\nexport class AsyncSession {\n constructor(\n private readonly driver: AsyncDriver,\n private readonly dialect: BaseDialect,\n /** Optional per-statement hooks (query tracing and timing). */\n private readonly hooks?: QueryHooks,\n ) {}\n\n /** Open `transaction()` blocks on this session; only the outermost commits. */\n private depth = 0;\n\n /** Log, run, time, and error-wrap one raw statement. */\n private async exec(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n emitLog(this.hooks, sql, params);\n const startedAt = now();\n try {\n const result = await this.driver.execute(sql, params);\n emitQueryEnd(this.hooks, {\n sql,\n params,\n durationMs: now() - startedAt,\n rowCount: resultRowCount(result),\n });\n return result;\n } catch (error) {\n emitQueryEnd(this.hooks, {\n sql,\n params,\n durationMs: now() - startedAt,\n rowCount: 0,\n error,\n });\n throw new QueryExecutionError(error, sql, params);\n }\n }\n\n /**\n * Run a raw, parameterized SQL statement — the runtime counterpart of the\n * migrations' `Op.execute`.\n *\n * A query builder never covers all of SQL, and without an escape hatch a single\n * unsupported query forces a whole second database stack alongside this one. Use\n * it for what the builder cannot yet express, and keep everything else typed.\n *\n * The statement goes through the same path as a compiled one: it is logged via\n * `onQuery`, wrapped in {@link QueryExecutionError} on failure, and runs on the\n * reserved connection inside `transaction()`.\n *\n * @param sql The statement text. Placeholders only (`$1` / `?` per dialect) —\n * never interpolate a value into this string.\n * @param params The bound parameters, in placeholder order.\n * @param options Pass `as` to coerce the returned rows with a model's column\n * types (and its column-name mapping).\n * @returns The result view over the returned rows.\n * @throws Error When `params` is not an array — the guard against calling this\n * with an interpolated string and no parameters by mistake.\n *\n * @example\n * ```ts\n * const claimed = await session.raw<OutboundRow>(\n * `UPDATE outbound_messages SET status = 'sending'\n * WHERE id = ANY($1) RETURNING *`,\n * [ids],\n * { as: Outbound },\n * ).all();\n * ```\n */\n raw<Row = Record<string, unknown>>(\n sql: string,\n params: readonly unknown[] = [],\n options?: { readonly as?: ModelClass },\n ): AsyncResult<Row> {\n assertRawParams(params);\n const model = options?.as;\n const inner = this.exec(sql, params).then((result) => {\n const rows = (\n model ? result.rows.map((row) => coerceRow(model, row)) : result.rows\n ) as Row[];\n return new SyncResult<Row>(rows, result.changes);\n });\n return new AsyncResult<Row>(inner);\n }\n\n execute<B extends Executable>(builder: B): AsyncResult<RowOf<B>> {\n const node = (builder as unknown as { node: Parameters<BaseDialect[\"compile\"]>[0] })\n .node;\n if (needsInsertReadBack(this.dialect, node)) {\n return new AsyncResult<RowOf<B>>(\n this.insertAndReadBack(builder as unknown as SingleBuilder, node),\n );\n }\n const { sql, params } = this.dialect.compile(node);\n const inner = this.exec(sql, params).then((result) => {\n const rows = mapRows(builder, result.rows) as RowOf<B>[];\n return new SyncResult<RowOf<B>>(rows, result.changes);\n });\n return new AsyncResult<RowOf<B>>(inner);\n }\n\n /**\n * Honor `.returning()` on a dialect without `RETURNING`, by inserting and then\n * reading the row back by key.\n *\n * Both statements must run on **one** connection, because `LAST_INSERT_ID()` is\n * per-connection: outside a transaction the pooled driver is reserved for the\n * pair; inside one, the session already holds a pinned connection (a reserved\n * driver exposes no `reserve`), so it runs there directly.\n *\n * @param builder The insert builder, for its source model.\n * @param node The insert AST, whose `returning` drives the read-back.\n * @returns The result view over the read-back row.\n * @throws Error When the insert writes more than one row — `LAST_INSERT_ID()`\n * identifies only the first, and the rest are consecutive only under some\n * auto-increment lock modes.\n */\n private async insertAndReadBack<Row>(\n builder: SingleBuilder,\n node: InsertNode,\n ): Promise<SyncResult<Row>> {\n if (node.values.length !== 1) {\n throw new Error(\n `${this.dialect.name} has no RETURNING, and reading back a multi-row insert is not reliable — insert one row at a time, or drop .returning().`,\n );\n }\n const model = builder.source;\n const pk = singlePrimaryKey(model);\n const supplied = (node.values[0] as Record<string, unknown>)[pk];\n const readBack = select(model).where(\n supplied === undefined || supplied === null\n ? col(pk).eq(fn.call(\"LAST_INSERT_ID\"))\n : { [pk]: supplied },\n );\n const insertSql = this.dialect.compile({ ...node, returning: null });\n const selectSql = this.dialect.compile(\n node.returning === \"*\" || node.returning === null\n ? readBack.node\n : { ...readBack.node, columns: node.returning },\n );\n const run = async (driver: AsyncDriver): Promise<SyncResult<Row>> => {\n const scoped = new AsyncSession(driver, this.dialect, this.hooks);\n const written = await scoped.exec(insertSql.sql, insertSql.params);\n const read = await scoped.exec(selectSql.sql, selectSql.params);\n const rows = read.rows.map((row) => coerceRow(model, row)) as Row[];\n return new SyncResult<Row>(rows, written.changes);\n };\n if (!this.driver.reserve) return run(this.driver);\n const reserved = await this.driver.reserve();\n try {\n return await run(reserved);\n } finally {\n await reserved.release();\n }\n }\n\n /** Lazily iterate result rows. Uses driver streaming when available. */\n async *stream<B extends Executable>(builder: B): AsyncIterableIterator<RowOf<B>> {\n const node = (builder as unknown as { node: Parameters<BaseDialect[\"compile\"]>[0] })\n .node;\n const { sql, params } = this.dialect.compile(node);\n emitLog(this.hooks, sql, params);\n if (this.driver.iterate) {\n const startedAt = now();\n let rowCount = 0;\n try {\n for await (const raw of this.driver.iterate(sql, params)) {\n rowCount++;\n yield coerceOne(builder, raw) as RowOf<B>;\n }\n } catch (error) {\n emitQueryEnd(this.hooks, {\n sql,\n params,\n durationMs: now() - startedAt,\n rowCount,\n error,\n });\n throw new QueryExecutionError(error, sql, params);\n }\n emitQueryEnd(this.hooks, {\n sql,\n params,\n durationMs: now() - startedAt,\n rowCount,\n });\n return;\n }\n const result = await this.exec(sql, params);\n for (const raw of result.rows) {\n yield coerceOne(builder, raw) as RowOf<B>;\n }\n }\n\n /**\n * How many `transaction()` blocks are open on this session.\n *\n * The counter is what makes a service that orchestrates two repositories work:\n * both hold the same session, so an inner block **joins** the outer one instead\n * of emitting a second `BEGIN`, and only the outermost exit commits.\n */\n get transactionDepth(): number {\n return this.depth;\n }\n\n /** Whether a `transaction()` block is currently open on this session. */\n get inTransaction(): boolean {\n return this.depth > 0;\n }\n\n /**\n * Run `fn` inside a transaction, committing on a clean exit and rolling back on\n * a throw.\n *\n * **Re-entrant:** a nested call joins the block already open on this session,\n * so a service orchestrating several repositories bound to the same session\n * gets one `BEGIN` and one `COMMIT`, not two of each. An inner failure rolls the\n * whole block back; use {@link beginNested} for a savepoint that can be\n * recovered from.\n *\n * Pooled drivers (PostgreSQL) pin one connection for the block: `BEGIN`/`COMMIT`\n * and every statement between them have to run on the same connection, or\n * postgres.js rejects the raw transaction. Single-connection drivers (SQLite)\n * skip the reservation.\n *\n * @param fn The body; receives the session to work through (the pinned one, on a\n * pooled driver).\n * @returns Whatever `fn` returned.\n */\n async transaction<T>(\n fn: (tx: AsyncSession) => Promise<T>,\n options?: TransactionOptions,\n ): Promise<T> {\n if (this.depth > 0) {\n assertNoNestedOptions(options);\n this.depth += 1;\n try {\n return await fn(this);\n } finally {\n this.depth -= 1;\n }\n }\n const begin = this.dialect.beginStatements(options);\n if (this.driver.reserve) {\n const reserved = await this.driver.reserve();\n const scoped = new AsyncSession(reserved, this.dialect, this.hooks);\n try {\n for (const stmt of begin) await scoped.exec(stmt, []);\n scoped.depth = 1;\n const out = await fn(scoped);\n await scoped.exec(\"COMMIT\", []);\n return out;\n } catch (error) {\n await scoped.exec(\"ROLLBACK\", []);\n throw error;\n } finally {\n scoped.depth = 0;\n await reserved.release();\n }\n }\n for (const stmt of begin) await this.exec(stmt, []);\n this.depth = 1;\n try {\n const out = await fn(this);\n await this.exec(\"COMMIT\", []);\n return out;\n } catch (error) {\n await this.exec(\"ROLLBACK\", []);\n throw error;\n } finally {\n this.depth = 0;\n }\n }\n\n /**\n * Run `fn` inside a `SAVEPOINT` (a nested transaction that can be rolled back on\n * its own).\n *\n * This is the difference from a nested {@link transaction}: a savepoint that\n * fails discards **only** its own work, so the enclosing block can catch the\n * error and carry on. A nested `transaction()` joins the outer block, and its\n * failure takes the whole block down.\n *\n * Must run inside an open transaction — PostgreSQL rejects a savepoint outside a\n * transaction block.\n *\n * @param fn The body; receives the same session.\n * @returns Whatever `fn` returned.\n */\n async beginNested<T>(fn: (sp: AsyncSession) => Promise<T>): Promise<T> {\n savepointCounter += 1;\n const name = `qsp_${savepointCounter}`;\n await this.exec(`SAVEPOINT ${name}`, []);\n try {\n const out = await fn(this);\n await this.exec(`RELEASE ${name}`, []);\n return out;\n } catch (error) {\n await this.exec(`ROLLBACK TO ${name}`, []);\n throw error;\n }\n }\n\n /**\n * Open an opt-in {@link UnitOfWork} over this session.\n *\n * The default stays a plain object written when you ask; this is the other\n * model, for code that prefers to mutate and flush once.\n *\n * @returns A new, empty unit of work.\n */\n unitOfWork(): UnitOfWork {\n return new UnitOfWork(this);\n }\n\n async close(): Promise<void> {\n await this.driver.close();\n }\n\n /** `await using session = ...` closes the driver when the scope exits. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// engines\n// ---------------------------------------------------------------------------\n\n/** Connection-pool tuning (PostgreSQL; ignored by SQLite). */\nexport interface PoolOptions {\n /** Max connections in the pool. */\n readonly size?: number;\n /** Close a connection after it sits idle this long (ms). */\n readonly idleTimeoutMs?: number;\n /** Give up acquiring a connection after this long (ms). */\n readonly connectTimeoutMs?: number;\n /**\n * Validate a connection before pinning it for a transaction.\n *\n * A pooled connection can die without the pool noticing — a failover, a\n * pgbouncer restart, a firewall dropping an idle socket. The damage lands on\n * whoever picks it up next, and it lands worst on a transaction: `BEGIN`\n * succeeds, a statement mid-block fails, and the block dies halfway.\n *\n * With this on, `transaction()` runs `SELECT 1` on the reserved connection\n * first and reserves another one if that fails. It costs a round trip per\n * transaction, which is why it is opt-in.\n *\n * PostgreSQL only — MySQL throws, and SQLite has no pool.\n */\n readonly prePing?: boolean;\n /**\n * Close and reopen a connection older than this (ms), regardless of activity.\n *\n * The blunt companion to {@link prePing}: it bounds how long a connection can\n * have been alive, which is what keeps a slow leak (a server-side timeout, a\n * load balancer's idle cap) from becoming a mystery error hours later.\n *\n * PostgreSQL only — MySQL throws, and SQLite has no pool.\n */\n readonly recycleMs?: number;\n}\n\n/**\n * A server-side notice (a PostgreSQL `NOTICE`). The shape is the driver's own —\n * passed through untouched rather than normalized, since what is useful in it\n * differs per database.\n */\nexport type NoticeLogger = (notice: Record<string, unknown>) => void;\n\n/**\n * SQLite journal modes accepted by `PRAGMA journal_mode`.\n *\n * `\"wal\"` is the one worth reaching for on a server: readers stop blocking the\n * writer. It needs a real file — an in-memory database refuses it and stays on\n * `\"memory\"`, which this layer reports as an error rather than a silent no-op.\n */\nexport type SqliteJournalMode =\n | \"delete\"\n | \"truncate\"\n | \"persist\"\n | \"memory\"\n | \"wal\"\n | \"off\";\n\n/** Durability levels accepted by `PRAGMA synchronous`. */\nexport type SqliteSynchronous = \"off\" | \"normal\" | \"full\" | \"extra\";\n\n/**\n * Per-connection SQLite settings, applied right after the handle opens.\n *\n * Pragmas are **per connection**, not per database file, so they belong to the\n * engine rather than to a migration. Only `foreignKeys` has a default that\n * changes behavior; every other field is emitted only when given, so an existing\n * database keeps whatever it was configured with.\n */\nexport interface SqliteOptions {\n /**\n * Enforce `FOREIGN KEY` constraints. **Defaults to `true`.**\n *\n * SQLite ships with enforcement `OFF`, per connection, so a declared foreign\n * key is decorative until someone turns it on: an orphan `INSERT` is accepted\n * and `ON DELETE CASCADE` never fires. tempest-db-js turns it on, which makes\n * the same model behave the same on all three databases.\n *\n * Set it to `false` only for the case it exists for — loading a dump whose\n * insert order does not respect the graph.\n */\n readonly foreignKeys?: boolean;\n /** `PRAGMA journal_mode`. Omitted: the database keeps its current mode. */\n readonly journalMode?: SqliteJournalMode;\n /** `PRAGMA busy_timeout`, in milliseconds. How long a writer waits on a lock. */\n readonly busyTimeoutMs?: number;\n /** `PRAGMA synchronous`. Durability vs write throughput. */\n readonly synchronous?: SqliteSynchronous;\n}\n\n/** Options shared by both engine flavors. */\nexport interface EngineOptions {\n /**\n * Override the driver detected from the URL.\n *\n * SQLite ships two: `\"node:sqlite\"` (the built-in, default — nothing to\n * install) and `\"better-sqlite3\"` (the optional peer dependency). PostgreSQL\n * runs on `\"postgres\"` (postgres.js) and MySQL on `\"mysql2\"`; naming those is\n * a no-op today, kept so the option means the same thing everywhere.\n *\n * A name this dialect does not have throws — passing `{ driver: \"sqlite3\" }`\n * is a decision that would otherwise be silently ignored.\n *\n * The `+suffix` in the URL (`sqlite+better-sqlite3:///app.db`) selects the same\n * way, with one difference: a suffix naming a driver from another ecosystem\n * (`sqlite+aiosqlite`, `postgresql+asyncpg`) is ignored rather than rejected,\n * so a URL copied from a Python service still connects.\n */\n readonly driver?: string;\n /** Connection-pool tuning (PostgreSQL only). */\n readonly pool?: PoolOptions;\n /**\n * Called for every statement a session runs — SQL + bound params. Use for\n * query logging/tracing. Thrown errors are swallowed so it never breaks a query.\n */\n readonly onQuery?: QueryLogger;\n /**\n * Called for every server-side notice (`CREATE TABLE IF NOT EXISTS` on an\n * existing table, `DROP ... IF EXISTS` on a missing one, and so on).\n *\n * **Without this, notices are silenced.** postgres.js defaults to printing them\n * with `console.log`, which drops a nine-line object into the host service's\n * stdout in the middle of its structured log — on every boot, since a migration\n * runner is usually the first thing to run. Writing to the host's stdout is the\n * application's decision, not a library's, so the default is to say nothing and\n * let you route them:\n *\n * ```ts\n * createEngine(url, { onNotice: (n) => logger.debug({ pg: n }, \"postgres notice\") });\n * ```\n *\n * Thrown errors are swallowed, like `onQuery`.\n */\n readonly onNotice?: NoticeLogger;\n /**\n * Options passed straight to the underlying driver, applied **last** so they\n * win over everything this layer derives (`pool`, `onNotice`).\n *\n * The escape hatch for what the typed surface does not model and is not going\n * to — postgres.js `connection`/`types`/`transform`/`ssl`, mysql2's own\n * settings, `node:sqlite`'s `readOnly` — so a gap need not become a feature\n * request.\n */\n readonly driverOptions?: Readonly<Record<string, unknown>>;\n /**\n * Per-connection SQLite pragmas (`foreign_keys`, `journal_mode`, …), applied\n * as soon as the handle opens. Passing it to a PostgreSQL or MySQL engine\n * throws — the settings have no meaning there, and silently ignoring them is\n * how a durability choice gets lost.\n */\n readonly sqlite?: SqliteOptions;\n /**\n * Called **after** every statement, with how long the driver took.\n *\n * `onQuery` fires before execution, so it cannot time anything; this is the\n * other half, and it fires on the failure path too (with `error` set). Use it\n * for latency metrics, tracing spans, and finding the query dragging p99.\n *\n * Errors thrown by the hook are swallowed, like `onQuery`.\n */\n readonly onQueryEnd?: QueryEndLogger;\n /**\n * Only report statements at least this slow (milliseconds) to `onQueryEnd`.\n *\n * The cheapest slow-query log there is: set a threshold, log what crosses it.\n * Without it every statement is reported.\n */\n readonly slowQueryMs?: number;\n}\n\n/**\n * Collect the per-statement hooks out of the engine options.\n *\n * @param options The engine options, if any.\n * @returns The hook bundle a session carries, or `undefined` when none is set.\n */\nfunction queryHooks(options?: EngineOptions): QueryHooks | undefined {\n if (!options?.onQuery && !options?.onQueryEnd) return undefined;\n return {\n onQuery: options.onQuery,\n onQueryEnd: options.onQueryEnd,\n slowQueryMs: options.slowQueryMs,\n };\n}\n\n/** Invoke a notice logger, swallowing any error it throws. */\nfunction emitNotice(logger: NoticeLogger | undefined, notice: unknown): void {\n if (!logger) return;\n try {\n logger(notice as Record<string, unknown>);\n } catch {\n // logging must never break a connection\n }\n}\n\n/** A synchronous engine (SQLite only). */\nexport class SyncEngine {\n readonly dialect: Dialect = \"sqlite\";\n\n constructor(\n private readonly driver: SyncDriver,\n private readonly hooks?: QueryHooks,\n ) {}\n\n session(): SyncSession {\n return new SyncSession(this.driver, getDialect(\"sqlite\"), this.hooks);\n }\n\n transaction<T>(fn: (tx: SyncSession) => T, options?: TransactionOptions): T {\n return this.session().transaction(fn, options);\n }\n\n close(): void {\n this.driver.close();\n }\n\n /** `using engine = createSyncEngine(...)` closes the pool when the scope exits. */\n [Symbol.dispose](): void {\n this.close();\n }\n}\n\n/** An asynchronous engine. */\nexport class AsyncEngine {\n constructor(\n private readonly driver: AsyncDriver,\n readonly dialect: Dialect,\n private readonly hooks?: QueryHooks,\n ) {}\n\n session(): AsyncSession {\n return new AsyncSession(this.driver, getDialect(this.dialect), this.hooks);\n }\n\n transaction<T>(\n fn: (tx: AsyncSession) => Promise<T>,\n options?: TransactionOptions,\n ): Promise<T> {\n return this.session().transaction(fn, options);\n }\n\n /**\n * Run `fn` and return the query plan of every statement it ran.\n *\n * The block gets its own session over a **recording** driver, so the plans are\n * built from the statements and the parameters the code really used — not from\n * SQL copied out of a log by hand. A development tool: it runs the block once\n * and then one `EXPLAIN` per statement, so keep it out of the hot path.\n *\n * @param fn The code to observe; receives the recording session.\n * @param options `analyze: true` to measure (refused for writes), `filter` to\n * explain only some statements.\n * @returns The report, one plan per statement in execution order.\n * @throws Error When `analyze` is requested for a statement that writes, or on\n * a dialect that has no `EXPLAIN ANALYZE`.\n *\n * @example\n * ```ts\n * const report = await engine.explain(async (session) => {\n * await new BaseRepository(Order, session).paginate({ page: 3 });\n * });\n * console.log(report.summary());\n * ```\n */\n async explain(\n fn: (session: AsyncSession) => Promise<unknown>,\n options?: ExplainOptions,\n ): Promise<ExplainReport> {\n const statements: RecordedStatement[] = [];\n const recorder: AsyncDriver = {\n execute: async (sql, params) => {\n statements.push({ sql, params });\n return this.driver.execute(sql, params);\n },\n close: () => Promise.resolve(),\n ...(this.driver.iterate\n ? {\n iterate: (sql: string, params: readonly unknown[]) => {\n statements.push({ sql, params });\n return (this.driver.iterate as NonNullable<AsyncDriver[\"iterate\"]>)(\n sql,\n params,\n );\n },\n }\n : {}),\n };\n await fn(new AsyncSession(recorder, getDialect(this.dialect), this.hooks));\n return buildReport(\n this.session(),\n statements,\n (analyze) => getDialect(this.dialect).explainPrefix(analyze),\n options,\n );\n }\n\n async close(): Promise<void> {\n await this.driver.close();\n }\n\n /** `await using engine = createEngine(...)` closes the pool when the scope exits. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n\n/**\n * Adapt a sync **or** async driver to the async interface.\n *\n * `await` normalizes both: a sync driver returns a plain value, an async one a\n * promise, and awaiting either yields the result. That is what lets the migration\n * CLI take one code path instead of branching on a difference it cannot detect\n * from the object's shape.\n *\n * @param driver Either driver flavor.\n * @returns An async driver delegating to it.\n */\nexport function toAsyncDriver(driver: SyncDriver | AsyncDriver): AsyncDriver {\n return {\n async execute(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n return await driver.execute(sql, params);\n },\n async close(): Promise<void> {\n await driver.close();\n },\n };\n}\n\n/** Wrap a sync driver so it satisfies the async interface (SQLite async path). */\nfunction asAsync(driver: SyncDriver): AsyncDriver {\n const syncIterate = driver.iterate?.bind(driver);\n return {\n execute: (sql, params) => Promise.resolve(driver.execute(sql, params)),\n close: () => Promise.resolve(driver.close()),\n ...(syncIterate\n ? {\n iterate: async function* (sql: string, params: readonly unknown[]) {\n yield* syncIterate(sql, params);\n },\n }\n : {}),\n };\n}\n\n/** The SQLite drivers this package can open. */\ntype SqliteDriverName = \"node:sqlite\" | \"better-sqlite3\";\n\n/** Accepted spellings of each SQLite driver, lowercased. */\nconst SQLITE_DRIVER_ALIASES: Readonly<Record<string, SqliteDriverName>> = {\n \"node:sqlite\": \"node:sqlite\",\n \"node-sqlite\": \"node:sqlite\",\n node: \"node:sqlite\",\n \"better-sqlite3\": \"better-sqlite3\",\n better_sqlite3: \"better-sqlite3\",\n bettersqlite3: \"better-sqlite3\",\n};\n\n/** Accepted spellings of the one driver each server dialect runs on. */\nconst SERVER_DRIVER_ALIASES: Readonly<Record<string, readonly string[]>> = {\n postgresql: [\"postgres\", \"postgres.js\", \"postgresjs\", \"pg\"],\n mysql: [\"mysql\", \"mysql2\"],\n};\n\n/**\n * Validate an explicit `options.driver` against a server dialect.\n *\n * PostgreSQL and MySQL each have exactly one driver here, so the option can only\n * confirm it. Confirming is allowed; naming something else is the error the\n * silent no-op used to hide.\n *\n * @param dialect The dialect parsed from the URL.\n * @param driver The explicit override, if any.\n * @throws If `driver` is not a spelling of that dialect's driver.\n */\nfunction checkServerDriver(dialect: Dialect, driver: string | undefined): void {\n if (!driver) return;\n const accepted = SERVER_DRIVER_ALIASES[dialect] ?? [];\n if (accepted.includes(driver.toLowerCase())) return;\n throw new Error(\n `Unknown ${dialect} driver ${JSON.stringify(driver)}; tempest-db-js runs ${dialect} on ${JSON.stringify(accepted[0])}.`,\n );\n}\n\n/**\n * Decide which SQLite driver to open: the explicit option first, then the URL\n * suffix, then the built-in.\n *\n * @param parsed The parsed URL, for its `+suffix`.\n * @param options Engine options, for an explicit `driver`.\n * @returns The driver to open.\n * @throws If `options.driver` names a driver this package does not ship. An\n * unrecognized URL suffix does not throw — `sqlite+aiosqlite:///app.db` comes\n * from a Python service and means \"SQLite\", so it falls through to the default.\n */\nfunction resolveSqliteDriver(\n parsed: ParsedDatabaseUrl,\n options?: EngineOptions,\n): SqliteDriverName {\n const explicit = options?.driver;\n if (explicit) {\n const resolved = SQLITE_DRIVER_ALIASES[explicit.toLowerCase()];\n if (!resolved) {\n throw new Error(\n `Unknown SQLite driver ${JSON.stringify(explicit)}; supported: \"node:sqlite\" (built-in, default) and \"better-sqlite3\".`,\n );\n }\n return resolved;\n }\n const fromUrl = parsed.driver\n ? SQLITE_DRIVER_ALIASES[parsed.driver.toLowerCase()]\n : undefined;\n return fromUrl ?? \"node:sqlite\";\n}\n\n/** `PRAGMA synchronous` names, in the numeric order SQLite reports them back. */\nconst SQLITE_SYNCHRONOUS_LEVELS: readonly SqliteSynchronous[] = [\n \"off\",\n \"normal\",\n \"full\",\n \"extra\",\n];\n\n/**\n * Read the single value a query-form pragma returns.\n *\n * @param driver The open SQLite driver.\n * @param name The pragma to read.\n * @returns Its value, or `null` when the pragma reported nothing.\n */\nfunction readPragma(driver: SyncDriver, name: string): unknown {\n const { rows } = driver.execute(`PRAGMA ${name}`, []);\n const first = rows[0];\n if (!first) return null;\n return Object.values(first)[0] ?? null;\n}\n\n/**\n * Apply the configured pragmas to a freshly opened SQLite connection.\n *\n * Every pragma is **verified by reading it back**. SQLite answers a setting it\n * cannot honor by keeping the old value and saying nothing — `journal_mode=wal`\n * on an in-memory database is the common case — so writing the pragma and moving\n * on would report success for a setting that never took.\n *\n * @param driver The open driver.\n * @param options The requested settings; `foreignKeys` defaults to `true`.\n * @param path The database path, used only to explain a refused setting.\n * @throws Error When a value is out of range, or when SQLite refused a setting.\n */\nfunction applySqlitePragmas(\n driver: SyncDriver,\n options: SqliteOptions | undefined,\n path: string,\n): void {\n const foreignKeys = options?.foreignKeys ?? true;\n driver.execute(`PRAGMA foreign_keys = ${foreignKeys ? \"ON\" : \"OFF\"}`, []);\n if (Number(readPragma(driver, \"foreign_keys\")) !== (foreignKeys ? 1 : 0)) {\n throw new Error(\n `SQLite refused PRAGMA foreign_keys = ${foreignKeys ? \"ON\" : \"OFF\"} — the build may lack foreign-key support.`,\n );\n }\n\n const journalMode = options?.journalMode;\n if (journalMode) {\n driver.execute(`PRAGMA journal_mode = ${journalMode}`, []);\n const actual = String(readPragma(driver, \"journal_mode\") ?? \"\").toLowerCase();\n if (actual !== journalMode) {\n const hint =\n journalMode === \"wal\" && actual === \"memory\"\n ? \" — an in-memory database cannot use WAL.\"\n : \".\";\n throw new Error(\n `SQLite refused PRAGMA journal_mode = ${journalMode} for ${JSON.stringify(path)} and stayed on ${JSON.stringify(actual)}${hint}`,\n );\n }\n }\n\n const busyTimeoutMs = options?.busyTimeoutMs;\n if (busyTimeoutMs !== undefined) {\n if (!Number.isInteger(busyTimeoutMs) || busyTimeoutMs < 0) {\n throw new Error(\n `busyTimeoutMs must be a non-negative integer, got ${JSON.stringify(busyTimeoutMs)}.`,\n );\n }\n driver.execute(`PRAGMA busy_timeout = ${busyTimeoutMs}`, []);\n if (Number(readPragma(driver, \"busy_timeout\")) !== busyTimeoutMs) {\n throw new Error(`SQLite refused PRAGMA busy_timeout = ${busyTimeoutMs}.`);\n }\n }\n\n const synchronous = options?.synchronous;\n if (synchronous) {\n driver.execute(`PRAGMA synchronous = ${synchronous}`, []);\n const actual = SQLITE_SYNCHRONOUS_LEVELS[Number(readPragma(driver, \"synchronous\"))];\n if (actual !== synchronous) {\n throw new Error(\n `SQLite refused PRAGMA synchronous = ${synchronous} and stayed on ${JSON.stringify(actual ?? \"unknown\")}.`,\n );\n }\n }\n}\n\n/**\n * Reject SQLite-only settings on a dialect that has no such thing.\n *\n * @param dialect The dialect parsed from the URL.\n * @param options The engine options.\n * @throws Error When `sqlite` options are given for a server dialect.\n */\nfunction checkSqliteOptions(dialect: Dialect, options?: EngineOptions): void {\n if (!options?.sqlite) return;\n throw new Error(\n `The \"sqlite\" engine options are SQLite-only; ${dialect} has no per-connection pragmas.`,\n );\n}\n\n/** Open a SQLite sync driver from a parsed URL, passing driver options through. */\nfunction openSqliteDriver(\n parsed: ParsedDatabaseUrl,\n options?: EngineOptions,\n): SyncDriver {\n const path = parsed.database ?? \":memory:\";\n const driver =\n resolveSqliteDriver(parsed, options) === \"better-sqlite3\"\n ? BetterSqliteDriver.open(path, options?.driverOptions)\n : NodeSqliteDriver.open(path, options?.driverOptions);\n try {\n applySqlitePragmas(driver, options?.sqlite, path);\n } catch (error) {\n driver.close();\n throw error;\n }\n return driver;\n}\n\n/**\n * Create a **synchronous** engine from a database URL. SQLite only — PostgreSQL\n * has no sane synchronous driver in Node, so a Postgres URL throws, pointing at\n * the async `createEngine`.\n *\n * @param url A SQLite URL, e.g. `\"sqlite:///app.db\"` or `\"sqlite://:memory:\"`.\n * @param options Engine options.\n * @returns A `SyncEngine`.\n */\nexport function createSyncEngine(url: string, options?: EngineOptions): SyncEngine {\n const parsed = parseDatabaseUrl(url);\n if (parsed.dialect !== \"sqlite\") {\n throw new Error(\n `createSyncEngine supports only SQLite; ${parsed.dialect} is async-only — use createEngine.`,\n );\n }\n return new SyncEngine(openSqliteDriver(parsed, options), queryHooks(options));\n}\n\n/**\n * Create an **asynchronous** engine from a database URL (the default). Works for\n * both SQLite (sync driver wrapped as async) and PostgreSQL (postgres.js,\n * lazy-loaded).\n *\n * @param url A database URL, e.g. `\"postgresql://app@localhost/app\"` or\n * `\"sqlite:///app.db\"`.\n * @param options Engine options.\n * @returns An `AsyncEngine`.\n */\nexport function createEngine(url: string, options?: EngineOptions): AsyncEngine {\n const parsed = parseDatabaseUrl(url);\n if (parsed.dialect === \"sqlite\") {\n return new AsyncEngine(\n asAsync(openSqliteDriver(parsed, options)),\n \"sqlite\",\n queryHooks(options),\n );\n }\n if (parsed.dialect === \"mysql\") {\n checkServerDriver(\"mysql\", options?.driver);\n checkSqliteOptions(\"mysql\", options);\n // MySQL: mysql2 is lazy-loaded the first time a query runs.\n return new AsyncEngine(\n createMysqlDriver(parsed.raw, options),\n \"mysql\",\n queryHooks(options),\n );\n }\n checkServerDriver(\"postgresql\", options?.driver);\n checkSqliteOptions(\"postgresql\", options);\n // PostgreSQL: postgres.js is lazy-loaded the first time a query runs.\n return new AsyncEngine(\n createPostgresDriver(parsed.raw, options),\n \"postgresql\",\n queryHooks(options),\n );\n}\n\n/** Encode a JS value into something the MySQL driver (mysql2) can bind. */\nfunction encodeMysqlParam(value: unknown): unknown {\n if (value === undefined || value === null) return null;\n if (typeof value === \"boolean\") return value ? 1 : 0;\n if (value instanceof Uint8Array) return value;\n if (value instanceof Date) return value;\n if (typeof value === \"object\") return JSON.stringify(value);\n return value; // number, bigint, string\n}\n\n/** Shape a mysql2 result into our `DriverResult`. */\nfunction toMysqlResult(rows: unknown): DriverResult {\n if (Array.isArray(rows)) {\n return { rows: rows as Record<string, unknown>[], changes: 0 };\n }\n // A ResultSetHeader (INSERT/UPDATE/DELETE): no rows, affectedRows is the count.\n const header = rows as { affectedRows?: number };\n return { rows: [], changes: header.affectedRows ?? 0 };\n}\n\n/**\n * MySQL driver backed by mysql2/promise (lazy-loaded peer dependency).\n *\n * Transactions reserve a single pooled connection via {@link AsyncDriver.reserve}\n * so `BEGIN`/`COMMIT` and the statements between them run on one connection.\n * MySQL has no `RETURNING`; the dialect throws if it is requested.\n */\nfunction createMysqlDriver(url: string, options?: EngineOptions): AsyncDriver {\n const pool = options?.pool;\n // biome-ignore lint/suspicious/noExplicitAny: mysql2 pool typed at call site.\n let poolHandle: any;\n const ensure = async (): Promise<void> => {\n if (poolHandle) return;\n const moduleName = \"mysql2/promise\";\n // biome-ignore lint/suspicious/noExplicitAny: dynamic import of the peer dep.\n const mod = (await import(/* @vite-ignore */ moduleName)) as any;\n const opts: Record<string, unknown> = { uri: url };\n if (pool?.prePing || pool?.recycleMs !== undefined) {\n throw new Error(\n \"pool.prePing and pool.recycleMs are PostgreSQL-only; mysql2 has no equivalent knob.\",\n );\n }\n if (pool?.size !== undefined) opts.connectionLimit = pool.size;\n if (pool?.idleTimeoutMs !== undefined) opts.idleTimeout = pool.idleTimeoutMs;\n if (pool?.connectTimeoutMs !== undefined) opts.connectTimeout = pool.connectTimeoutMs;\n Object.assign(opts, options?.driverOptions ?? {});\n poolHandle = mod.createPool(opts);\n };\n const runOn = async (\n // biome-ignore lint/suspicious/noExplicitAny: mysql2 queryable (pool or connection).\n queryable: any,\n sql: string,\n params: readonly unknown[],\n ): Promise<DriverResult> => {\n const [rows] = await queryable.query(sql, params.map(encodeMysqlParam));\n return toMysqlResult(rows);\n };\n return {\n async execute(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n await ensure();\n return runOn(poolHandle, sql, params);\n },\n async reserve(): Promise<ReservedAsyncDriver> {\n await ensure();\n // biome-ignore lint/suspicious/noExplicitAny: reserved connection from mysql2.\n const conn: any = await poolHandle.getConnection();\n return {\n execute: (sql, params) => runOn(conn, sql, params),\n async release(): Promise<void> {\n conn.release();\n },\n async close(): Promise<void> {\n conn.release();\n },\n };\n },\n async close(): Promise<void> {\n if (poolHandle) await poolHandle.end();\n },\n };\n}\n\n/** Shape a postgres.js result array into our `DriverResult`. */\nfunction toPostgresResult(rows: unknown): DriverResult {\n const arr = rows as Record<string, unknown>[] & { count?: number };\n return { rows: Array.from(arr), changes: arr.count ?? arr.length };\n}\n\n/**\n * PostgreSQL driver backed by postgres.js (lazy-loaded peer dependency).\n *\n * Transactions reserve a single connection via {@link AsyncDriver.reserve} —\n * postgres.js pools connections, so a raw `BEGIN` on the shared client would run\n * on a different connection than the statements that follow (and is rejected with\n * `UNSAFE_TRANSACTION`). The reserved connection runs `BEGIN`/`COMMIT`/`ROLLBACK`\n * and every statement between them on one socket, then is released back.\n */\nfunction createPostgresDriver(url: string, options?: EngineOptions): AsyncDriver {\n const pool = options?.pool;\n // biome-ignore lint/suspicious/noExplicitAny: postgres.js client typed at call site.\n let client: any;\n const ensure = async (): Promise<void> => {\n if (client) return;\n // Non-literal specifier so the optional peer dep is not type-resolved at build.\n const moduleName = \"postgres\";\n // biome-ignore lint/suspicious/noExplicitAny: dynamic import of the peer dep.\n const mod = (await import(/* @vite-ignore */ moduleName)) as any;\n // Map our PoolOptions onto postgres.js's option names (seconds, not ms).\n const opts: Record<string, unknown> = {};\n if (pool?.size !== undefined) opts.max = pool.size;\n if (pool?.idleTimeoutMs !== undefined)\n opts.idle_timeout = Math.ceil(pool.idleTimeoutMs / 1000);\n if (pool?.connectTimeoutMs !== undefined) {\n opts.connect_timeout = Math.ceil(pool.connectTimeoutMs / 1000);\n }\n if (pool?.recycleMs !== undefined) {\n opts.max_lifetime = Math.ceil(pool.recycleMs / 1000);\n }\n opts.onnotice = (notice: unknown): void => emitNotice(options?.onNotice, notice);\n Object.assign(opts, options?.driverOptions ?? {});\n client = (mod.default ?? mod)(url, opts);\n };\n return {\n async execute(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n await ensure();\n // postgres.js `unsafe` runs a parameterized string with positional params.\n return toPostgresResult(await client.unsafe(sql, params as unknown[]));\n },\n async reserve(): Promise<ReservedAsyncDriver> {\n await ensure();\n // biome-ignore lint/suspicious/noExplicitAny: reserved connection from postgres.js.\n let conn: any = await client.reserve();\n if (pool?.prePing) {\n try {\n await conn.unsafe(\"SELECT 1\", []);\n } catch {\n // The connection died while it sat in the pool. Drop it and take\n // another one — the pool opens a fresh one when none is idle.\n conn.release();\n conn = await client.reserve();\n await conn.unsafe(\"SELECT 1\", []);\n }\n }\n return {\n async execute(sql: string, params: readonly unknown[]): Promise<DriverResult> {\n return toPostgresResult(await conn.unsafe(sql, params as unknown[]));\n },\n async release(): Promise<void> {\n conn.release();\n },\n async close(): Promise<void> {\n conn.release();\n },\n };\n },\n async close(): Promise<void> {\n if (client) await client.end();\n },\n };\n}\n","/**\n * tempest-db-js — backup and restore, driven from the CLI.\n *\n * The step every runbook asks for before a migration, wrapped so it is the same\n * command against both databases in scope. It shells out to the canonical tooling\n * rather than reimplementing a dump format: `pg_dump`/`pg_restore`/`psql` on\n * PostgreSQL, and SQLite's own `VACUUM INTO` — which, unlike copying the file, is\n * consistent while the database is being written to.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { copyFile } from \"node:fs/promises\";\nimport { promisify } from \"node:util\";\nimport { NodeSqliteDriver } from \"./engine.js\";\nimport { parseDatabaseUrl } from \"./url.js\";\n\nconst run = promisify(execFile);\n\n/** Raised when the tool a dialect needs is not on the PATH. */\nexport class BackupToolMissing extends Error {\n constructor(tool: string) {\n super(`${tool} is not on the PATH; install the PostgreSQL client tools to back up.`);\n this.name = \"BackupToolMissing\";\n }\n}\n\n/** Raised for a dialect that has no backup path here. */\nexport class UnsupportedBackupBackend extends Error {\n constructor(dialect: string) {\n super(\n `Backups are implemented for PostgreSQL and SQLite; ${dialect} is not covered.`,\n );\n this.name = \"UnsupportedBackupBackend\";\n }\n}\n\n/** Options shared by backup and restore. */\nexport interface BackupOptions {\n /** Overwrite the target if it already exists (restore only). */\n readonly force?: boolean;\n /** Extra arguments appended to the underlying tool's command line. */\n readonly extraArgs?: readonly string[];\n}\n\n/** What a backup or restore did. */\nexport interface BackupResult {\n /** The file written (backup) or read (restore). */\n readonly file: string;\n /** The dialect it was taken from. */\n readonly dialect: string;\n /** The tool used, or `\"VACUUM INTO\"` / `\"copy\"` for SQLite. */\n readonly via: string;\n}\n\n/**\n * The dump format implied by a file's extension.\n *\n * `.dump` is `pg_dump`'s custom format, which `pg_restore` reads selectively and\n * in parallel; `.sql` is plain text, restored by piping it through `psql`. The\n * extension decides so the two commands cannot disagree about the file.\n *\n * @param file The backup file's path.\n * @returns Which format it is.\n */\nexport function backupFormat(file: string): \"custom\" | \"plain\" {\n return file.endsWith(\".sql\") ? \"plain\" : \"custom\";\n}\n\n/**\n * The environment a PostgreSQL tool runs with.\n *\n * The password goes in `PGPASSWORD`, never in `argv`: every process on the\n * machine can read another's command line.\n *\n * @param password The password from the URL, if any.\n * @returns The environment to spawn with.\n */\nfunction postgresEnv(password: string | null): NodeJS.ProcessEnv {\n return password ? { ...process.env, PGPASSWORD: password } : { ...process.env };\n}\n\n/**\n * The connection URL with the driver suffix removed.\n *\n * `postgresql+asyncpg://…` is a URL a Python service wrote; `pg_dump` does not\n * know that scheme.\n *\n * @param url The URL as configured.\n * @returns The URL a client tool accepts.\n */\nexport function toolUrl(url: string): string {\n return url.replace(/^([a-z0-9]+)\\+[a-z0-9_-]+:/i, \"$1:\");\n}\n\n/**\n * Run a tool, turning \"not found\" into a named error.\n *\n * @param tool The executable.\n * @param args Its arguments.\n * @param env The environment.\n * @throws BackupToolMissing When the executable is not on the PATH.\n */\nasync function spawn(\n tool: string,\n args: readonly string[],\n env: NodeJS.ProcessEnv,\n): Promise<void> {\n try {\n await run(tool, [...args], { env, maxBuffer: 1024 * 1024 * 64 });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new BackupToolMissing(tool);\n }\n throw error;\n }\n}\n\n/**\n * Write a backup of the database to a file.\n *\n * @param url The database URL.\n * @param file Where to write. On PostgreSQL the extension picks the format\n * (`.sql` plain, anything else custom).\n * @param options Extra arguments for the underlying tool.\n * @returns What was done.\n * @throws BackupToolMissing When PostgreSQL's client tools are absent.\n * @throws UnsupportedBackupBackend On a dialect without a backup path.\n */\nexport async function backupDatabase(\n url: string,\n file: string,\n options?: BackupOptions,\n): Promise<BackupResult> {\n const parsed = parseDatabaseUrl(url);\n if (parsed.dialect === \"sqlite\") {\n const source = parsed.database ?? \":memory:\";\n // VACUUM INTO, not a file copy: it is consistent even while another\n // connection is writing, and it works with WAL, where the .db file alone is\n // not the whole database.\n const driver = NodeSqliteDriver.open(source);\n try {\n driver.execute(\"VACUUM INTO ?\", [file]);\n } finally {\n driver.close();\n }\n return { file, dialect: \"sqlite\", via: \"VACUUM INTO\" };\n }\n if (parsed.dialect !== \"postgresql\") {\n throw new UnsupportedBackupBackend(parsed.dialect);\n }\n const format = backupFormat(file);\n await spawn(\n \"pg_dump\",\n [\n \"--dbname\",\n toolUrl(url),\n ...(format === \"custom\" ? [\"--format=custom\"] : []),\n \"--file\",\n file,\n ...(options?.extraArgs ?? []),\n ],\n postgresEnv(parsed.password),\n );\n return { file, dialect: \"postgresql\", via: \"pg_dump\" };\n}\n\n/**\n * Restore a database from a backup file.\n *\n * @param url The database URL to restore **into**.\n * @param file The backup file.\n * @param options `force` to overwrite an existing SQLite file; extra tool args.\n * @returns What was done.\n * @throws Error When restoring SQLite over an existing file without `force`.\n * @throws BackupToolMissing When PostgreSQL's client tools are absent.\n * @throws UnsupportedBackupBackend On a dialect without a restore path.\n */\nexport async function restoreDatabase(\n url: string,\n file: string,\n options?: BackupOptions,\n): Promise<BackupResult> {\n const parsed = parseDatabaseUrl(url);\n if (parsed.dialect === \"sqlite\") {\n const target = parsed.database ?? \":memory:\";\n await copyFile(file, target);\n return { file, dialect: \"sqlite\", via: \"copy\" };\n }\n if (parsed.dialect !== \"postgresql\") {\n throw new UnsupportedBackupBackend(parsed.dialect);\n }\n const env = postgresEnv(parsed.password);\n if (backupFormat(file) === \"plain\") {\n await spawn(\n \"psql\",\n [\"--dbname\", toolUrl(url), \"--file\", file, ...(options?.extraArgs ?? [])],\n env,\n );\n return { file, dialect: \"postgresql\", via: \"psql\" };\n }\n await spawn(\n \"pg_restore\",\n [\n \"--dbname\",\n toolUrl(url),\n ...(options?.force ? [\"--clean\", \"--if-exists\"] : []),\n file,\n ...(options?.extraArgs ?? []),\n ],\n env,\n );\n return { file, dialect: \"postgresql\", via: \"pg_restore\" };\n}\n","/**\n * tempest-db-js — Phase 6: typed migration operations.\n *\n * Every schema change is a typed `Operation` with a known inverse. This is what\n * gives autogenerated, reversible `down()` and dialect-rendered DDL — never a\n * hand-written `.sql` blob (the anti-Drizzle core).\n */\n\nimport type { ColumnIR, IndexIR, NamedConstraint, TableIR } from \"./ir.js\";\n\n/** A single, reversible schema operation. */\nexport type Operation =\n | { readonly kind: \"create_table\"; readonly table: TableIR }\n | { readonly kind: \"drop_table\"; readonly table: TableIR }\n | { readonly kind: \"rename_table\"; readonly from: string; readonly to: string }\n | { readonly kind: \"add_column\"; readonly table: string; readonly column: ColumnIR }\n | { readonly kind: \"drop_column\"; readonly table: string; readonly column: ColumnIR }\n | {\n readonly kind: \"alter_column\";\n readonly table: string;\n readonly name: string;\n readonly from: ColumnIR;\n readonly to: ColumnIR;\n }\n | {\n readonly kind: \"rename_column\";\n readonly table: string;\n readonly from: string;\n readonly to: string;\n }\n | {\n // Rebuild a table from `from` to `to`. On SQLite this is the batch /\n // table-rebuild path (SQLite cannot ALTER COLUMN); on PostgreSQL it is\n // realized as per-column ALTER/ADD/DROP.\n readonly kind: \"recreate_table\";\n readonly from: TableIR;\n readonly to: TableIR;\n }\n | {\n // Add a table-level unique / foreign-key constraint. On SQLite this needs\n // a table-rebuild (recreate_table); PostgreSQL / MySQL use ALTER TABLE ADD.\n readonly kind: \"add_constraint\";\n readonly table: string;\n readonly constraint: NamedConstraint;\n }\n | {\n readonly kind: \"drop_constraint\";\n readonly table: string;\n readonly constraint: NamedConstraint;\n }\n | { readonly kind: \"create_index\"; readonly table: string; readonly index: IndexIR }\n | { readonly kind: \"drop_index\"; readonly table: string; readonly index: IndexIR }\n | { readonly kind: \"execute\"; readonly up: string; readonly down: string | null };\n\n/** Raised when an operation has no safe inverse (e.g. a one-way `execute`). */\nexport class IrreversibleMigration extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"IrreversibleMigration\";\n }\n}\n\n/**\n * Compute the inverse of an operation, for autogenerated `down()`.\n *\n * @param op The forward operation.\n * @returns The operation that undoes it.\n * @throws IrreversibleMigration When `op` cannot be safely reversed.\n */\nexport function invert(op: Operation): Operation {\n switch (op.kind) {\n case \"create_table\":\n return { kind: \"drop_table\", table: op.table };\n case \"drop_table\":\n return { kind: \"create_table\", table: op.table };\n case \"rename_table\":\n return { kind: \"rename_table\", from: op.to, to: op.from };\n case \"add_column\":\n return { kind: \"drop_column\", table: op.table, column: op.column };\n case \"drop_column\":\n return { kind: \"add_column\", table: op.table, column: op.column };\n case \"alter_column\":\n return {\n kind: \"alter_column\",\n table: op.table,\n name: op.name,\n from: op.to,\n to: op.from,\n };\n case \"rename_column\":\n return { kind: \"rename_column\", table: op.table, from: op.to, to: op.from };\n case \"recreate_table\":\n return { kind: \"recreate_table\", from: op.to, to: op.from };\n case \"add_constraint\":\n return { kind: \"drop_constraint\", table: op.table, constraint: op.constraint };\n case \"create_index\":\n return { kind: \"drop_index\", table: op.table, index: op.index };\n case \"drop_index\":\n return { kind: \"create_index\", table: op.table, index: op.index };\n case \"drop_constraint\":\n return { kind: \"add_constraint\", table: op.table, constraint: op.constraint };\n case \"execute\":\n if (op.down === null) {\n throw new IrreversibleMigration(\"execute() operation has no down SQL\");\n }\n return { kind: \"execute\", up: op.down, down: op.up };\n }\n}\n\n/** Invert a list of operations: reverse order, each inverted. */\nexport function invertAll(ops: readonly Operation[]): Operation[] {\n return [...ops].reverse().map(invert);\n}\n","/**\n * tempest-db-js — Phase 6: migration autogeneration.\n *\n * Turns a diff's `Operation[]` into an editable TypeScript migration file with\n * `up()` and an autogenerated, inverted `down()`. Operations are embedded as\n * plain-data literals (they are JSON-serializable), so the file stays readable\n * and hand-editable — never an opaque `.sql` blob.\n */\n\nimport { type Operation, invertAll } from \"./operations.js\";\n\n/** Inputs for one generated migration file. */\nexport interface MigrationDraft {\n readonly revision: string;\n readonly downRevision: readonly string[];\n readonly label: string;\n readonly operations: readonly Operation[];\n}\n\n/** Serialize operations as an indented array literal for the generated file. */\nfunction renderOps(ops: readonly Operation[]): string {\n if (ops.length === 0) return \"[]\";\n const body = ops.map((op) => ` ${JSON.stringify(op)},`).join(\"\\n\");\n return `[\\n${body}\\n ]`;\n}\n\n/**\n * Render a migration file body as TypeScript source.\n *\n * The generated `down()` inverts `up()`; if any operation is irreversible, the\n * generation still succeeds but `down()` throws at run time with a clear message\n * (so reversibility is never silently broken).\n *\n * @param draft The revision id, parents, label, and forward operations.\n * @returns The migration file source.\n */\nexport function generateMigration(draft: MigrationDraft): string {\n let down: string;\n try {\n down = renderOps(invertAll(draft.operations));\n } catch (error) {\n down = `(() => { throw new Error(${JSON.stringify(\n `irreversible migration: ${(error as Error).message}`,\n )}); })()`;\n }\n\n return `import type { Migration, Op } from \"tempest-db-js/migrations\";\n\nexport const revision = ${JSON.stringify(draft.revision)};\nexport const downRevision: string[] = ${JSON.stringify(draft.downRevision)};\nexport const label = ${JSON.stringify(draft.label)};\n\nconst upOps = ${renderOps(draft.operations)};\n\nconst downOps = ${down};\n\nexport const up = (op: Op): void => {\n for (const operation of upOps) op.run(operation);\n};\n\nexport const down = (op: Op): void => {\n for (const operation of downOps) op.run(operation);\n};\n\nexport default { revision, downRevision, label, up, down } satisfies Migration;\n`;\n}\n\n/** Build a short, stable revision id from a label + parent set. */\nexport function makeRevisionId(label: string, parents: readonly string[]): string {\n // Deterministic non-crypto hash (FNV-1a) — no Date/Math.random (build-stable).\n let hash = 0x811c9dc5;\n for (const ch of `${label}|${[...parents].sort().join(\",\")}`) {\n hash ^= ch.charCodeAt(0);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","/**\n * tempest-db-js — Phase 6/9: DDL rendering.\n *\n * Renders the dialect-neutral IR + operations to concrete SQL per dialect. This\n * is the ONLY place migration SQL is produced — the same operation yields the\n * right DDL for SQLite, PostgreSQL or MySQL.\n */\n\nimport type { CondNode } from \"../conditions.js\";\nimport { LiteralParams, getDialect } from \"../dialect.js\";\nimport { renderPortableToken } from \"../expressions.js\";\nimport type { ColumnType, DefaultValue, FkAction } from \"../index.js\";\nimport type { Dialect } from \"../url.js\";\nimport type {\n CheckIR,\n ColumnIR,\n ForeignKeyIR,\n IndexIR,\n NamedConstraint,\n TableIR,\n UniqueConstraintIR,\n} from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\n\n/** Quote an identifier for the dialect (backticks on MySQL, double-quotes else). */\nfunction quoteId(name: string, dialect: Dialect): string {\n return dialect === \"mysql\"\n ? `\\`${name.replace(/`/g, \"``\")}\\``\n : `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction quoteLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\n/** Map a column type to its SQL type string for the dialect. */\nexport function renderColumnType(type: ColumnType, dialect: Dialect): string {\n const { kind, meta } = type;\n if (dialect === \"sqlite\") {\n switch (kind) {\n case \"smallint\":\n case \"integer\":\n case \"bigint\":\n case \"boolean\":\n return \"INTEGER\";\n case \"real\":\n case \"double\":\n return \"REAL\";\n case \"numeric\":\n return \"NUMERIC\";\n case \"blob\":\n return \"BLOB\";\n case \"array\":\n throw new Error(unsupportedArray(\"sqlite\"));\n default:\n return \"TEXT\"; // varchar/char/text/uuid/enum/json/date/time/datetime/timestamp\n }\n }\n if (dialect === \"mysql\") {\n switch (kind) {\n case \"smallint\":\n return \"SMALLINT\";\n case \"integer\":\n return \"INT\";\n case \"bigint\":\n return \"BIGINT\";\n case \"numeric\":\n return meta.precision !== undefined\n ? `DECIMAL(${meta.precision}${meta.scale !== undefined ? `, ${meta.scale}` : \"\"})`\n : \"DECIMAL\";\n case \"real\":\n return \"FLOAT\";\n case \"double\":\n return \"DOUBLE\";\n case \"varchar\":\n return `VARCHAR(${meta.length ?? 255})`;\n case \"char\":\n return `CHAR(${meta.length ?? 255})`;\n case \"text\":\n return \"TEXT\";\n case \"boolean\":\n return \"TINYINT(1)\";\n case \"date\":\n return \"DATE\";\n case \"time\":\n return \"TIME\";\n case \"datetime\":\n case \"timestamp\":\n return \"DATETIME\";\n case \"blob\":\n return \"BLOB\";\n case \"json\":\n return \"JSON\";\n case \"uuid\":\n return \"CHAR(36)\";\n case \"enum\":\n return `ENUM(${(meta.values ?? []).map(quoteLiteral).join(\", \")})`;\n case \"array\":\n throw new Error(unsupportedArray(\"mysql\"));\n }\n }\n // PostgreSQL\n switch (kind) {\n case \"smallint\":\n return \"SMALLINT\";\n case \"integer\":\n return \"INTEGER\";\n case \"bigint\":\n return \"BIGINT\";\n case \"numeric\":\n return meta.precision !== undefined\n ? `NUMERIC(${meta.precision}${meta.scale !== undefined ? `, ${meta.scale}` : \"\"})`\n : \"NUMERIC\";\n case \"real\":\n return \"REAL\";\n case \"double\":\n return \"DOUBLE PRECISION\";\n case \"varchar\":\n return meta.length !== undefined ? `VARCHAR(${meta.length})` : \"VARCHAR\";\n case \"char\":\n return meta.length !== undefined ? `CHAR(${meta.length})` : \"CHAR\";\n case \"text\":\n return \"TEXT\";\n case \"boolean\":\n return \"BOOLEAN\";\n case \"date\":\n return \"DATE\";\n case \"time\":\n return meta.withTimezone ? \"TIME WITH TIME ZONE\" : \"TIME\";\n case \"datetime\":\n case \"timestamp\":\n return meta.withTimezone ? \"TIMESTAMP WITH TIME ZONE\" : \"TIMESTAMP\";\n case \"blob\":\n return \"BYTEA\";\n case \"json\":\n return meta.jsonb ? \"JSONB\" : \"JSON\";\n case \"uuid\":\n return \"UUID\";\n case \"enum\":\n // Named PG enum types are handled in renderCreateTable; fall back to TEXT.\n return \"TEXT\";\n case \"array\":\n return `${renderColumnType(arrayElement(meta.element), dialect)}[]`;\n }\n}\n\n/** The message for an array column on a dialect without native arrays. */\nfunction unsupportedArray(dialect: Dialect): string {\n return `column.array() is PostgreSQL-only — ${dialect} has no native array type. Model the column as JSON there, accepting that array operators will not work.`;\n}\n\n/** The element type of an array column, or a hard error when it is missing. */\nfunction arrayElement(element: ColumnType | undefined): ColumnType {\n if (!element) {\n throw new Error(\n \"An array column has no element type — build it with column.array().\",\n );\n }\n return element;\n}\n\n/** Render a default value into a SQL `DEFAULT` expression for the dialect. */\nexport function renderDefault(\n def: DefaultValue,\n dialect: Dialect,\n type?: ColumnType,\n): string {\n if (def.kind === \"expression\") {\n const expr = def.expression;\n if (typeof expr === \"object\") {\n if (\"raw\" in expr) return expr.raw;\n throw new Error(\n \"sql.expr`...` binds parameters and cannot be rendered as a DEFAULT — use sql.raw().\",\n );\n }\n const rendered = renderPortableToken(expr, dialect);\n // SQLite only accepts a function call in a DEFAULT clause when it is\n // parenthesized; a bare keyword like CURRENT_TIMESTAMP must not be.\n return dialect === \"sqlite\" && rendered.includes(\"(\") ? `(${rendered})` : rendered;\n }\n const value = def.value;\n if (value === null) return \"NULL\";\n if (Array.isArray(value) && type?.kind === \"array\") {\n const elementType = renderColumnType(arrayElement(type.meta.element), dialect);\n const items = value.map((v) => renderDefault({ kind: \"literal\", value: v }, dialect));\n return `ARRAY[${items.join(\", \")}]::${elementType}[]`;\n }\n if (typeof value === \"boolean\") {\n return dialect === \"postgresql\" ? (value ? \"TRUE\" : \"FALSE\") : value ? \"1\" : \"0\";\n }\n if (typeof value === \"number\" || typeof value === \"bigint\") return String(value);\n if (value instanceof Date) return quoteLiteral(value.toISOString());\n if (typeof value === \"object\") return quoteLiteral(JSON.stringify(value));\n return quoteLiteral(String(value));\n}\n\n/** Render a referential action for an `ON DELETE` / `ON UPDATE` clause. */\nfunction renderFkAction(action: FkAction): string {\n return action.toUpperCase();\n}\n\n/** Render the `[ON DELETE ..] [ON UPDATE ..]` tail shared by inline + table FKs. */\nfunction renderFkActions(fk: {\n onDelete?: FkAction | undefined;\n onUpdate?: FkAction | undefined;\n}): string {\n let sql = \"\";\n if (fk.onDelete) sql += ` ON DELETE ${renderFkAction(fk.onDelete)}`;\n if (fk.onUpdate) sql += ` ON UPDATE ${renderFkAction(fk.onUpdate)}`;\n return sql;\n}\n\n/**\n * The column-level constraint suffix: ` UNIQUE` and/or an inline\n * ` REFERENCES \"table\" (\"column\") [ON DELETE ..] [ON UPDATE ..]`. Appended to\n * every rendered column definition (including the enum/serial branches).\n */\nfunction columnConstraintSuffix(col: ColumnIR, dialect: Dialect): string {\n let sql = \"\";\n if (col.unique) sql += \" UNIQUE\";\n if (col.references) {\n const ref = col.references;\n sql += ` REFERENCES ${quoteId(ref.table, dialect)} (${quoteId(ref.column, dialect)})`;\n sql += renderFkActions(ref);\n }\n return sql;\n}\n\n/** Render a table-level `CONSTRAINT \"name\" UNIQUE (...)` clause. */\nfunction renderUniqueConstraint(uc: UniqueConstraintIR, dialect: Dialect): string {\n const cols = uc.columns.map((c) => quoteId(c, dialect)).join(\", \");\n return `CONSTRAINT ${quoteId(uc.name, dialect)} UNIQUE (${cols})`;\n}\n\n/** Render a table-level `CONSTRAINT \"name\" FOREIGN KEY (...) REFERENCES ...` clause. */\nfunction renderForeignKeyConstraint(fk: ForeignKeyIR, dialect: Dialect): string {\n const cols = fk.columns.map((c) => quoteId(c, dialect)).join(\", \");\n const refCols = fk.refColumns.map((c) => quoteId(c, dialect)).join(\", \");\n return (\n `CONSTRAINT ${quoteId(fk.name, dialect)} FOREIGN KEY (${cols}) ` +\n `REFERENCES ${quoteId(fk.refTable, dialect)} (${refCols})${renderFkActions(fk)}`\n );\n}\n\n/** The table-level constraint clauses (unique + foreign key) for a table. */\nfunction tableConstraintClauses(table: TableIR, dialect: Dialect): string[] {\n return [\n ...table.uniqueConstraints.map((uc) => renderUniqueConstraint(uc, dialect)),\n ...table.foreignKeys.map((fk) => renderForeignKeyConstraint(fk, dialect)),\n ...table.checks.map((ck) => renderCheckConstraint(ck, dialect)),\n ];\n}\n\n/**\n * Render a condition as **literal** SQL, with no placeholders.\n *\n * A `CHECK` clause and a partial index's predicate live in the schema, where\n * there is nothing to bind a parameter to — so the values are inlined, quoted by\n * the same rules a default literal uses.\n *\n * @param node The condition.\n * @param dialect The target dialect.\n * @returns The rendered predicate.\n */\nexport function renderPredicate(node: CondNode, dialect: Dialect): string {\n const literals = new LiteralParams();\n return getDialect(dialect).renderConditionLiteral(node, literals);\n}\n\n/** Render `CONSTRAINT \"name\" CHECK (...)`. */\nfunction renderCheckConstraint(ck: CheckIR, dialect: Dialect): string {\n return `CONSTRAINT ${quoteId(ck.name, dialect)} CHECK (${renderPredicate(ck.expression, dialect)})`;\n}\n\n/**\n * Render `CREATE [UNIQUE] INDEX ... [WHERE ...]`.\n *\n * @param table The table the index is on.\n * @param ix The index.\n * @param dialect The target dialect.\n * @returns The statement.\n * @throws Error For a partial index on MySQL, which has no such thing.\n */\nexport function renderCreateIndex(table: string, ix: IndexIR, dialect: Dialect): string {\n if (ix.where && dialect === \"mysql\") {\n throw new Error(\n `MySQL has no partial index; ${ix.name} on ${table} declares a WHERE predicate.`,\n );\n }\n const unique = ix.unique ? \"UNIQUE \" : \"\";\n const cols = ix.columns.map((c) => quoteId(c, dialect)).join(\", \");\n const where = ix.where ? ` WHERE ${renderPredicate(ix.where, dialect)}` : \"\";\n return `CREATE ${unique}INDEX ${quoteId(ix.name, dialect)} ON ${quoteId(table, dialect)} (${cols})${where}`;\n}\n\n/**\n * Render `DROP INDEX`.\n *\n * MySQL needs the table (`DROP INDEX x ON t`); PostgreSQL and SQLite do not.\n *\n * @param table The table the index is on.\n * @param ix The index.\n * @param dialect The target dialect.\n * @returns The statement.\n */\nexport function renderDropIndex(table: string, ix: IndexIR, dialect: Dialect): string {\n return dialect === \"mysql\"\n ? `DROP INDEX ${quoteId(ix.name, dialect)} ON ${quoteId(table, dialect)}`\n : `DROP INDEX ${quoteId(ix.name, dialect)}`;\n}\n\n/**\n * Render one column definition: `\"name\" TYPE [NOT NULL] [DEFAULT x] [UNIQUE]\n * [REFERENCES ...]`.\n */\nexport function renderColumnDef(col: ColumnIR, dialect: Dialect): string {\n let sql = `${quoteId(col.name, dialect)} ${renderColumnType(col.type, dialect)}`;\n if (col.notNull) sql += \" NOT NULL\";\n if (col.default !== null) {\n sql += ` DEFAULT ${renderDefault(col.default, dialect, col.type)}`;\n }\n sql += columnConstraintSuffix(col, dialect);\n return sql;\n}\n\n/** The PostgreSQL named-enum type for a column (`<table>_<column>`). */\nfunction enumTypeName(table: string, column: string): string {\n return `${table}_${column}`;\n}\n\n/** True when a column is the sole integer-family PK with no explicit default. */\nfunction isAutoIncrementPk(table: TableIR, col: ColumnIR): boolean {\n return (\n table.primaryKey.length === 1 &&\n table.primaryKey[0] === col.name &&\n col.default === null &&\n (col.type.kind === \"smallint\" ||\n col.type.kind === \"integer\" ||\n col.type.kind === \"bigint\")\n );\n}\n\n/** The PostgreSQL auto-incrementing serial type for an integer-family kind. */\nfunction postgresSerialType(kind: ColumnType[\"kind\"]): string {\n if (kind === \"bigint\") return \"BIGSERIAL\";\n if (kind === \"smallint\") return \"SMALLSERIAL\";\n return \"SERIAL\";\n}\n\n/**\n * Render a CREATE TABLE (plus, on PostgreSQL, any `CREATE TYPE ... AS ENUM` for\n * enum columns, which must precede the table). Returns the statement list.\n *\n * Auto-increment for a lone integer-family primary key (SQLAlchemy semantics):\n * - SQLite: free via `INTEGER PRIMARY KEY` (rowid alias).\n * - PostgreSQL: `SERIAL`/`BIGSERIAL`.\n * - MySQL: `AUTO_INCREMENT` on the column (which must also be a key).\n */\nfunction renderCreateTable(table: TableIR, dialect: Dialect): string[] {\n const typeStmts: string[] = [];\n const cols = Object.values(table.columns).map((c) => {\n if (dialect === \"postgresql\" && c.type.kind === \"enum\") {\n const typeName = enumTypeName(table.name, c.name);\n const values = (c.type.meta.values ?? []).map(quoteLiteral).join(\", \");\n typeStmts.push(`CREATE TYPE ${quoteId(typeName, dialect)} AS ENUM (${values})`);\n let def = `${quoteId(c.name, dialect)} ${quoteId(typeName, dialect)}`;\n if (c.notNull) def += \" NOT NULL\";\n if (c.default !== null) {\n def += ` DEFAULT ${renderDefault(c.default, dialect, c.type)}`;\n }\n return def + columnConstraintSuffix(c, dialect);\n }\n if (dialect === \"postgresql\" && isAutoIncrementPk(table, c)) {\n return `${quoteId(c.name, dialect)} ${postgresSerialType(c.type.kind)}${columnConstraintSuffix(c, dialect)}`;\n }\n if (dialect === \"mysql\" && isAutoIncrementPk(table, c)) {\n return `${quoteId(c.name, dialect)} ${renderColumnType(c.type, dialect)} NOT NULL AUTO_INCREMENT${columnConstraintSuffix(c, dialect)}`;\n }\n return renderColumnDef(c, dialect);\n });\n if (table.primaryKey.length > 0) {\n cols.push(\n `PRIMARY KEY (${table.primaryKey.map((c) => quoteId(c, dialect)).join(\", \")})`,\n );\n }\n cols.push(...tableConstraintClauses(table, dialect));\n return [\n ...typeStmts,\n `CREATE TABLE ${quoteId(table.name, dialect)} (\\n ${cols.join(\",\\n \")}\\n)`,\n // Indexes are separate statements, not table clauses — which is also why a\n // SQLite table rebuild has to recreate them.\n ...table.indexes.map((ix) => renderCreateIndex(table.name, ix, dialect)),\n ];\n}\n\n/**\n * Render an operation to one or more SQL statements for the dialect.\n *\n * @param op The operation.\n * @param dialect The target dialect.\n * @returns The SQL statements (usually one).\n * @throws Error When the operation is unsupported on the dialect (e.g. SQLite\n * `alter_column`, which needs the table-rebuild path).\n */\nexport function renderOperation(op: Operation, dialect: Dialect): string[] {\n switch (op.kind) {\n case \"create_table\":\n return renderCreateTable(op.table, dialect);\n case \"drop_table\":\n return [`DROP TABLE ${quoteId(op.table.name, dialect)}`];\n case \"rename_table\":\n return dialect === \"mysql\"\n ? [`RENAME TABLE ${quoteId(op.from, dialect)} TO ${quoteId(op.to, dialect)}`]\n : [\n `ALTER TABLE ${quoteId(op.from, dialect)} RENAME TO ${quoteId(op.to, dialect)}`,\n ];\n case \"add_column\":\n return [\n `ALTER TABLE ${quoteId(op.table, dialect)} ADD COLUMN ${renderColumnDef(op.column, dialect)}`,\n ];\n case \"drop_column\":\n return [\n `ALTER TABLE ${quoteId(op.table, dialect)} DROP COLUMN ${quoteId(op.column.name, dialect)}`,\n ];\n case \"rename_column\":\n return [\n `ALTER TABLE ${quoteId(op.table, dialect)} RENAME COLUMN ${quoteId(op.from, dialect)} TO ${quoteId(op.to, dialect)}`,\n ];\n case \"alter_column\":\n return renderAlterColumn(op.table, op.to, dialect);\n case \"recreate_table\":\n return dialect === \"sqlite\"\n ? renderSqliteRebuild(op.from, op.to)\n : renderTableDiff(op.from, op.to, dialect);\n case \"add_constraint\":\n return renderAddConstraint(op.table, op.constraint, dialect);\n case \"drop_constraint\":\n return renderDropConstraint(op.table, op.constraint, dialect);\n case \"create_index\":\n return [renderCreateIndex(op.table, op.index, dialect)];\n case \"drop_index\":\n return [renderDropIndex(op.table, op.index, dialect)];\n case \"execute\":\n return [op.up];\n }\n}\n\n/**\n * Render an `ALTER TABLE ... ADD CONSTRAINT`. SQLite cannot add constraints in\n * place — it needs a table-rebuild (`recreate_table`), so this throws there.\n */\nfunction renderAddConstraint(\n table: string,\n constraint: NamedConstraint,\n dialect: Dialect,\n): string[] {\n if (dialect === \"sqlite\") {\n throw new Error(\n `add_constraint on SQLite needs a table-rebuild (recreate_table); constraint ${constraint.constraint.name} on ${table}`,\n );\n }\n const clause =\n constraint.type === \"unique\"\n ? renderUniqueConstraint(constraint.constraint, dialect)\n : constraint.type === \"check\"\n ? renderCheckConstraint(constraint.constraint, dialect)\n : renderForeignKeyConstraint(constraint.constraint, dialect);\n return [`ALTER TABLE ${quoteId(table, dialect)} ADD ${clause}`];\n}\n\n/**\n * Render an `ALTER TABLE ... DROP CONSTRAINT`. PostgreSQL uses the generic\n * `DROP CONSTRAINT`; MySQL uses `DROP INDEX` (unique) / `DROP FOREIGN KEY` (fk).\n * SQLite needs a table-rebuild, so this throws there.\n */\nfunction renderDropConstraint(\n table: string,\n constraint: NamedConstraint,\n dialect: Dialect,\n): string[] {\n if (dialect === \"sqlite\") {\n throw new Error(\n `drop_constraint on SQLite needs a table-rebuild (recreate_table); constraint ${constraint.constraint.name} on ${table}`,\n );\n }\n const t = quoteId(table, dialect);\n const name = quoteId(constraint.constraint.name, dialect);\n if (dialect === \"mysql\") {\n return [\n constraint.type === \"unique\"\n ? `ALTER TABLE ${t} DROP INDEX ${name}`\n : `ALTER TABLE ${t} DROP FOREIGN KEY ${name}`,\n ];\n }\n return [`ALTER TABLE ${t} DROP CONSTRAINT ${name}`];\n}\n\n/**\n * SQLite batch / table-rebuild: create a new table with the target schema, copy\n * the columns common to both, swap names. This is how SQLite realizes column\n * changes it cannot `ALTER` (drop/alter type/constraint changes).\n */\nfunction renderSqliteRebuild(from: TableIR, to: TableIR): string[] {\n const tmp = `__new_${to.name}`;\n const common = Object.keys(to.columns).filter((c) => c in from.columns);\n const cols = Object.values(to.columns).map((c) => renderColumnDef(c, \"sqlite\"));\n if (to.primaryKey.length > 0) {\n cols.push(\n `PRIMARY KEY (${to.primaryKey.map((c) => quoteId(c, \"sqlite\")).join(\", \")})`,\n );\n }\n cols.push(...tableConstraintClauses(to, \"sqlite\"));\n const commonSql = common.map((c) => quoteId(c, \"sqlite\")).join(\", \");\n return [\n \"PRAGMA foreign_keys=off\",\n `CREATE TABLE ${quoteId(tmp, \"sqlite\")} (\\n ${cols.join(\",\\n \")}\\n)`,\n common.length > 0\n ? `INSERT INTO ${quoteId(tmp, \"sqlite\")} (${commonSql}) SELECT ${commonSql} FROM ${quoteId(from.name, \"sqlite\")}`\n : `-- no common columns to copy from ${from.name}`,\n `DROP TABLE ${quoteId(from.name, \"sqlite\")}`,\n `ALTER TABLE ${quoteId(tmp, \"sqlite\")} RENAME TO ${quoteId(to.name, \"sqlite\")}`,\n // The rebuild dropped the old table, and its indexes with it: SQLite ties an\n // index to the table it was created on. Recreating them is part of the\n // rebuild, not a follow-up somebody has to remember.\n ...to.indexes.map((ix) => renderCreateIndex(to.name, ix, \"sqlite\")),\n \"PRAGMA foreign_keys=on\",\n ];\n}\n\n/** PostgreSQL/MySQL realize a table recreate as per-column ADD/DROP/ALTER. */\nfunction renderTableDiff(from: TableIR, to: TableIR, dialect: Dialect): string[] {\n const stmts: string[] = [];\n for (const [name, col] of Object.entries(to.columns)) {\n if (!(name in from.columns)) {\n stmts.push(\n `ALTER TABLE ${quoteId(to.name, dialect)} ADD COLUMN ${renderColumnDef(col, dialect)}`,\n );\n } else {\n stmts.push(...renderAlterColumn(to.name, col, dialect));\n }\n }\n for (const name of Object.keys(from.columns)) {\n if (!(name in to.columns)) {\n stmts.push(\n `ALTER TABLE ${quoteId(to.name, dialect)} DROP COLUMN ${quoteId(name, dialect)}`,\n );\n }\n }\n return stmts;\n}\n\n/**\n * Render an ALTER COLUMN. SQLite needs table-rebuild (unsupported here); MySQL\n * uses a single `MODIFY COLUMN` (type + NOT NULL + DEFAULT together); PostgreSQL\n * uses separate `ALTER COLUMN ... TYPE / SET|DROP NOT NULL / SET|DROP DEFAULT`.\n */\nfunction renderAlterColumn(table: string, to: ColumnIR, dialect: Dialect): string[] {\n if (dialect === \"sqlite\") {\n throw new Error(\n `alter_column on SQLite needs a table-rebuild (recreate_table); column ${table}.${to.name}`,\n );\n }\n if (dialect === \"mysql\") {\n return [\n `ALTER TABLE ${quoteId(table, dialect)} MODIFY COLUMN ${renderColumnDef(to, dialect)}`,\n ];\n }\n const t = quoteId(table, dialect);\n const c = quoteId(to.name, dialect);\n const stmts = [\n `ALTER TABLE ${t} ALTER COLUMN ${c} TYPE ${renderColumnType(to.type, dialect)}`,\n ];\n stmts.push(\n to.notNull\n ? `ALTER TABLE ${t} ALTER COLUMN ${c} SET NOT NULL`\n : `ALTER TABLE ${t} ALTER COLUMN ${c} DROP NOT NULL`,\n );\n stmts.push(\n to.default !== null\n ? `ALTER TABLE ${t} ALTER COLUMN ${c} SET DEFAULT ${renderDefault(to.default, dialect, to.type)}`\n : `ALTER TABLE ${t} ALTER COLUMN ${c} DROP DEFAULT`,\n );\n return stmts;\n}\n","/**\n * tempest-db-js — Phase 6: the schema differ.\n *\n * Compares two `SchemaIR`s (current vs target) and emits the typed `Operation[]`\n * that turns one into the other. Purely structural — no SQL, no DB.\n */\n\nimport type {\n CheckIR,\n ColumnIR,\n ForeignKeyIR,\n IndexIR,\n NamedConstraint,\n SchemaIR,\n TableIR,\n UniqueConstraintIR,\n} from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\n\n/** Stable structural identity of a column, for change detection. */\nfunction columnSignature(col: ColumnIR): string {\n return JSON.stringify({\n type: col.type,\n notNull: col.notNull,\n primaryKey: col.primaryKey,\n default: col.default,\n unique: col.unique,\n references: col.references,\n });\n}\n\n/** Stable structural identity of a table-level constraint (name excluded). */\nfunction uniqueSignature(uc: UniqueConstraintIR): string {\n return JSON.stringify({ columns: uc.columns });\n}\n\nfunction foreignKeySignature(fk: ForeignKeyIR): string {\n return JSON.stringify({\n columns: fk.columns,\n refTable: fk.refTable,\n refColumns: fk.refColumns,\n onDelete: fk.onDelete ?? null,\n onUpdate: fk.onUpdate ?? null,\n });\n}\n\n/**\n * Diff the table-level constraints of an existing table, keyed by name. Emits\n * `drop_constraint` for removed/changed and `add_constraint` for added/changed.\n */\nfunction diffConstraints(current: TableIR, target: TableIR): Operation[] {\n const ops: Operation[] = [];\n const table = target.name;\n\n const currentUq = new Map(current.uniqueConstraints.map((u) => [u.name, u]));\n const targetUq = new Map(target.uniqueConstraints.map((u) => [u.name, u]));\n for (const [name, cur] of currentUq) {\n const tgt = targetUq.get(name);\n if (!tgt || uniqueSignature(cur) !== uniqueSignature(tgt)) {\n ops.push(dropUnique(table, cur));\n }\n }\n for (const [name, tgt] of targetUq) {\n const cur = currentUq.get(name);\n if (!cur || uniqueSignature(cur) !== uniqueSignature(tgt)) {\n ops.push(addUnique(table, tgt));\n }\n }\n\n const currentFk = new Map(current.foreignKeys.map((f) => [f.name, f]));\n const targetFk = new Map(target.foreignKeys.map((f) => [f.name, f]));\n for (const [name, cur] of currentFk) {\n const tgt = targetFk.get(name);\n if (!tgt || foreignKeySignature(cur) !== foreignKeySignature(tgt)) {\n ops.push(dropForeignKey(table, cur));\n }\n }\n for (const [name, tgt] of targetFk) {\n const cur = currentFk.get(name);\n if (!cur || foreignKeySignature(cur) !== foreignKeySignature(tgt)) {\n ops.push(addForeignKey(table, tgt));\n }\n }\n\n const currentCk = new Map(current.checks.map((c) => [c.name, c]));\n const targetCk = new Map(target.checks.map((c) => [c.name, c]));\n for (const [name, cur] of currentCk) {\n const tgt = targetCk.get(name);\n if (!tgt || checkSignature(cur) !== checkSignature(tgt)) {\n ops.push({ kind: \"drop_constraint\", table, constraint: checkNamed(cur) });\n }\n }\n for (const [name, tgt] of targetCk) {\n const cur = currentCk.get(name);\n if (!cur || checkSignature(cur) !== checkSignature(tgt)) {\n ops.push({ kind: \"add_constraint\", table, constraint: checkNamed(tgt) });\n }\n }\n\n const currentIx = new Map(current.indexes.map((i) => [i.name, i]));\n const targetIx = new Map(target.indexes.map((i) => [i.name, i]));\n for (const [name, cur] of currentIx) {\n const tgt = targetIx.get(name);\n if (!tgt || indexSignature(cur) !== indexSignature(tgt)) {\n ops.push({ kind: \"drop_index\", table, index: cur });\n }\n }\n for (const [name, tgt] of targetIx) {\n const cur = currentIx.get(name);\n if (!cur || indexSignature(cur) !== indexSignature(tgt)) {\n ops.push({ kind: \"create_index\", table, index: tgt });\n }\n }\n\n return ops;\n}\n\n/**\n * The structural identity of a `CHECK`.\n *\n * The expression is compared as the condition **tree**, not as SQL text: two\n * spellings of the same rule would otherwise read as a change on every diff.\n */\nfunction checkSignature(ck: CheckIR): string {\n return JSON.stringify(ck.expression);\n}\n\n/** The structural identity of an index (name excluded — it is the key). */\nfunction indexSignature(ix: IndexIR): string {\n return JSON.stringify({\n columns: ix.columns,\n unique: ix.unique,\n where: ix.where,\n });\n}\n\nfunction checkNamed(ck: CheckIR): NamedConstraint {\n return { type: \"check\", constraint: ck };\n}\n\nfunction uniqueNamed(uc: UniqueConstraintIR): NamedConstraint {\n return { type: \"unique\", constraint: uc };\n}\nfunction foreignKeyNamed(fk: ForeignKeyIR): NamedConstraint {\n return { type: \"foreignKey\", constraint: fk };\n}\nfunction addUnique(table: string, uc: UniqueConstraintIR): Operation {\n return { kind: \"add_constraint\", table, constraint: uniqueNamed(uc) };\n}\nfunction dropUnique(table: string, uc: UniqueConstraintIR): Operation {\n return { kind: \"drop_constraint\", table, constraint: uniqueNamed(uc) };\n}\nfunction addForeignKey(table: string, fk: ForeignKeyIR): Operation {\n return { kind: \"add_constraint\", table, constraint: foreignKeyNamed(fk) };\n}\nfunction dropForeignKey(table: string, fk: ForeignKeyIR): Operation {\n return { kind: \"drop_constraint\", table, constraint: foreignKeyNamed(fk) };\n}\n\n/**\n * Diff `current` → `target`, returning the operations to migrate forward.\n *\n * Order: create new tables, then per-table column adds/alters/drops, then drop\n * removed tables last (so nothing depends on a table being dropped first).\n *\n * @param current The current schema (e.g. from migration replay).\n * @param target The desired schema (e.g. from model reflection).\n * @returns The forward operations.\n */\nexport function diffSchema(current: SchemaIR, target: SchemaIR): Operation[] {\n const ops: Operation[] = [];\n const drops: Operation[] = [];\n\n for (const [name, targetTable] of Object.entries(target.tables)) {\n const currentTable = current.tables[name];\n if (!currentTable) {\n ops.push({ kind: \"create_table\", table: targetTable });\n continue;\n }\n // existing table → diff columns\n for (const [colName, targetCol] of Object.entries(targetTable.columns)) {\n const currentCol = currentTable.columns[colName];\n if (!currentCol) {\n ops.push({ kind: \"add_column\", table: name, column: targetCol });\n } else if (columnSignature(currentCol) !== columnSignature(targetCol)) {\n ops.push({\n kind: \"alter_column\",\n table: name,\n name: colName,\n from: currentCol,\n to: targetCol,\n });\n }\n }\n for (const [colName, currentCol] of Object.entries(currentTable.columns)) {\n if (!targetTable.columns[colName]) {\n ops.push({ kind: \"drop_column\", table: name, column: currentCol });\n }\n }\n ops.push(...diffConstraints(currentTable, targetTable));\n }\n\n for (const [name, currentTable] of Object.entries(current.tables)) {\n if (!target.tables[name]) {\n drops.push({ kind: \"drop_table\", table: currentTable });\n }\n }\n\n return [...ops, ...drops];\n}\n","/**\n * tempest-db-js — Phase 6: the revision DAG.\n *\n * Migrations form a directed acyclic graph via `downRevision` (a list of parents,\n * so branches and merges are first-class). This module orders them for applying\n * (topological, deterministic) and finds heads.\n */\n\n/** The minimal graph shape a migration must expose. */\nexport interface RevisionNode {\n readonly revision: string;\n readonly downRevision: readonly string[];\n}\n\n/** Raised when the revision graph contains a cycle. */\nexport class CyclicMigrationGraph extends Error {\n constructor(remaining: readonly string[]) {\n super(`migration graph has a cycle among: ${remaining.join(\", \")}`);\n this.name = \"CyclicMigrationGraph\";\n }\n}\n\n/** Raised when a `downRevision` points at a revision that does not exist. */\nexport class UnknownRevision extends Error {\n constructor(revision: string, parent: string) {\n super(`revision ${revision} references unknown parent ${parent}`);\n this.name = \"UnknownRevision\";\n }\n}\n\n/**\n * Topologically order migrations so every parent precedes its children. Ties are\n * broken by revision id for reproducible builds. Throws on cycles or dangling\n * parents.\n *\n * @param migrations The migrations to order.\n * @returns The migrations in apply order.\n */\nexport function topoOrder<T extends RevisionNode>(migrations: readonly T[]): T[] {\n const byId = new Map<string, T>();\n for (const m of migrations) byId.set(m.revision, m);\n\n const indegree = new Map<string, number>();\n const children = new Map<string, string[]>();\n for (const m of migrations) {\n indegree.set(m.revision, m.downRevision.length);\n for (const parent of m.downRevision) {\n if (!byId.has(parent)) throw new UnknownRevision(m.revision, parent);\n const list = children.get(parent) ?? [];\n list.push(m.revision);\n children.set(parent, list);\n }\n }\n\n // roots: indegree 0, sorted for determinism\n const ready = migrations\n .filter((m) => (indegree.get(m.revision) ?? 0) === 0)\n .map((m) => m.revision)\n .sort();\n\n const ordered: T[] = [];\n while (ready.length > 0) {\n const id = ready.shift() as string;\n ordered.push(byId.get(id) as T);\n const next = (children.get(id) ?? []).sort();\n for (const child of next) {\n const deg = (indegree.get(child) ?? 0) - 1;\n indegree.set(child, deg);\n if (deg === 0) {\n ready.push(child);\n ready.sort();\n }\n }\n }\n\n if (ordered.length !== migrations.length) {\n const remaining = migrations\n .map((m) => m.revision)\n .filter((r) => !ordered.some((o) => o.revision === r));\n throw new CyclicMigrationGraph(remaining);\n }\n return ordered;\n}\n\n/** Revisions that are nobody's parent — the current head(s) of the graph. */\nexport function heads<T extends RevisionNode>(migrations: readonly T[]): string[] {\n const parents = new Set<string>();\n for (const m of migrations) for (const p of m.downRevision) parents.add(p);\n return migrations\n .map((m) => m.revision)\n .filter((r) => !parents.has(r))\n .sort();\n}\n","/**\n * tempest-db-js — Phase 6: the Schema IR (intermediate representation).\n *\n * A canonical, dialect-neutral description of a database schema. Every source of\n * truth — model reflection (here), migration replay, or DB introspection —\n * produces the SAME `SchemaIR`, so the differ compares like with like and SQL is\n * only ever emitted at the dialect edge (the anti-\"SQL-stitching\" core).\n */\n\nimport type { CondNode, ExprNode } from \"../conditions.js\";\nimport {\n type ColumnType,\n type DefaultValue,\n type FkAction,\n type ForeignKeyRef,\n type ModelClass,\n columnNamesOf,\n columnsOf,\n} from \"../index.js\";\n\n/** A column's default in the IR. */\nexport type DefaultIR = DefaultValue | null;\n\n/** One column. */\nexport interface ColumnIR {\n readonly name: string;\n readonly type: ColumnType;\n readonly notNull: boolean;\n readonly primaryKey: boolean;\n readonly default: DefaultIR;\n /** A column-level `UNIQUE` constraint. */\n readonly unique: boolean;\n /** A column-level foreign-key reference, or `null` for none. */\n readonly references: ForeignKeyRef | null;\n}\n\n/** A (composite) `UNIQUE` table constraint in the IR. */\nexport interface UniqueConstraintIR {\n readonly name: string;\n readonly columns: readonly string[];\n}\n\n/** A `CHECK` constraint in the IR. */\nexport interface CheckIR {\n readonly name: string;\n /** The invariant, in the condition language — comparable without parsing SQL. */\n readonly expression: CondNode;\n}\n\n/** An index in the IR. */\nexport interface IndexIR {\n readonly name: string;\n readonly columns: readonly string[];\n readonly unique: boolean;\n /** The predicate of a partial index, or `null` for a full one. */\n readonly where: CondNode | null;\n}\n\n/** A (composite) foreign-key table constraint in the IR. */\nexport interface ForeignKeyIR {\n readonly name: string;\n readonly columns: readonly string[];\n readonly refTable: string;\n readonly refColumns: readonly string[];\n readonly onDelete?: FkAction | undefined;\n readonly onUpdate?: FkAction | undefined;\n}\n\n/**\n * A named table-level constraint, tagged by kind. Carried whole by the\n * `add_constraint` / `drop_constraint` operations so each is reversible.\n */\nexport type NamedConstraint =\n | { readonly type: \"unique\"; readonly constraint: UniqueConstraintIR }\n | { readonly type: \"foreignKey\"; readonly constraint: ForeignKeyIR }\n | { readonly type: \"check\"; readonly constraint: CheckIR };\n\n/** One table. */\nexport interface TableIR {\n readonly name: string;\n readonly columns: Record<string, ColumnIR>;\n /** Primary-key column names (composite = more than one). */\n readonly primaryKey: readonly string[];\n /** Table-level unique constraints (from `tableArgs`). */\n readonly uniqueConstraints: readonly UniqueConstraintIR[];\n /** Table-level foreign-key constraints (from `tableArgs`). */\n readonly foreignKeys: readonly ForeignKeyIR[];\n /** `CHECK` constraints (from `tableArgs`). */\n readonly checks: readonly CheckIR[];\n /** Indexes (from `tableArgs`). Not constraints: they live in their own DDL. */\n readonly indexes: readonly IndexIR[];\n}\n\n/** A whole schema, keyed by table name. */\nexport interface SchemaIR {\n readonly tables: Record<string, TableIR>;\n}\n\n/** Deterministic constraint name when the user did not supply one. */\nfunction constraintName(\n prefix: \"uq\" | \"fk\" | \"ck\" | \"ix\",\n table: string,\n columns: readonly string[],\n): string {\n return `${prefix}_${table}_${columns.join(\"_\")}`;\n}\n\n/**\n * Rewrite a condition's column references from property names to column names.\n *\n * The IR lives in **database**-name space, so a `CHECK` written against\n * `idempotencyKey` has to come out as `idempotency_key` — otherwise the drift\n * check would compare a model-space expression against a database-space one and\n * report a difference that is not there.\n *\n * @param node The condition as written.\n * @param toColumn The property → column mapping.\n * @returns The same condition in database-name space.\n */\nexport function renameConditionColumns(\n node: CondNode,\n toColumn: (prop: string) => string,\n): CondNode {\n const expr = (current: ExprNode): ExprNode => {\n switch (current.kind) {\n case \"column\":\n return { kind: \"column\", name: toColumn(current.name) };\n case \"fn\":\n return { ...current, args: current.args.map(expr) };\n case \"cast\":\n return { ...current, operand: expr(current.operand) };\n default:\n return current;\n }\n };\n switch (node.kind) {\n case \"fields\": {\n const fields: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node.fields)) {\n fields[toColumn(key)] = value;\n }\n return { kind: \"fields\", fields };\n }\n case \"and\":\n case \"or\":\n return {\n ...node,\n parts: node.parts.map((part) => renameConditionColumns(part, toColumn)),\n };\n case \"not\":\n return { kind: \"not\", part: renameConditionColumns(node.part, toColumn) };\n case \"compare\":\n return { ...node, left: expr(node.left), right: expr(node.right) };\n default:\n return node;\n }\n}\n\n/**\n * Reflect one model class into a `TableIR`.\n *\n * The IR is keyed by **database** column names, so a model that maps\n * `consumerName` to `consumer_name` produces the same IR that introspecting the\n * live database does — otherwise the drift check would report every renamed\n * column as missing.\n *\n * @param model The model class.\n * @returns The table IR in database-name space.\n */\nexport function reflectTable(model: ModelClass): TableIR {\n const names = columnNamesOf(model);\n const toColumn = (prop: string): string => names?.[prop] ?? prop;\n const columns: Record<string, ColumnIR> = {};\n const primaryKey: string[] = [];\n for (const [prop, col] of Object.entries(columnsOf(model))) {\n const isPk = col.flags.primaryKey;\n const name = toColumn(prop);\n columns[name] = {\n name,\n type: col.type,\n notNull: col.flags.notNull || isPk,\n primaryKey: isPk,\n default: col.defaultValue,\n unique: col.flags.unique,\n references: col.reference,\n };\n if (isPk) primaryKey.push(name);\n }\n\n const uniqueConstraints: UniqueConstraintIR[] = [];\n const foreignKeys: ForeignKeyIR[] = [];\n const checks: CheckIR[] = [];\n const indexes: IndexIR[] = [];\n for (const c of model.tableArgs?.() ?? []) {\n const cols = c.columns.map(toColumn);\n if (c.kind === \"unique\") {\n uniqueConstraints.push({\n name: c.name ?? constraintName(\"uq\", model.tablename, cols),\n columns: cols,\n });\n } else if (c.kind === \"check\") {\n checks.push({\n name: c.name ?? constraintName(\"ck\", model.tablename, cols),\n expression: renameConditionColumns(c.expression, toColumn),\n });\n } else if (c.kind === \"index\") {\n indexes.push({\n name: c.name ?? constraintName(\"ix\", model.tablename, cols),\n columns: cols,\n unique: c.unique === true,\n where: c.where ? renameConditionColumns(c.where, toColumn) : null,\n });\n } else {\n foreignKeys.push({\n name: c.name ?? constraintName(\"fk\", model.tablename, cols),\n columns: cols,\n refTable: c.refTable,\n refColumns: c.refColumns,\n onDelete: c.onDelete,\n onUpdate: c.onUpdate,\n });\n }\n }\n\n return {\n name: model.tablename,\n columns,\n primaryKey,\n uniqueConstraints,\n foreignKeys,\n checks,\n indexes,\n };\n}\n\n/**\n * Reflect a set of model classes into a `SchemaIR`. This is the **target** state\n * the differ compares the current (replayed) schema against.\n *\n * @param models The model classes that make up the schema.\n * @returns The reflected schema IR.\n */\nexport function reflectSchema(models: readonly ModelClass[]): SchemaIR {\n const tables: Record<string, TableIR> = {};\n for (const model of models) {\n const table = reflectTable(model);\n tables[table.name] = table;\n }\n return { tables };\n}\n\n/** An empty schema (the baseline before any migration). */\nexport function emptySchema(): SchemaIR {\n return { tables: {} };\n}\n","/**\n * tempest-db-js — Phase 6d: SQLite introspection + drift detection.\n *\n * Reads the live schema from a SQLite database (via `PRAGMA table_info`) into a\n * `SchemaIR`, and compares it against the models to detect **drift** — the DB\n * diverging from what the migrations/models say it should be. Comparison is done\n * at SQLite's storage-affinity level, so coarse SQLite typing (every string is\n * `TEXT`) does not produce false positives.\n */\n\nimport type { AsyncDriver, SyncDriver } from \"../engine.js\";\nimport type { ColumnType } from \"../index.js\";\nimport type { ModelClass } from \"../index.js\";\nimport type { Dialect } from \"../url.js\";\nimport { renderColumnType } from \"./ddl.js\";\nimport {\n type ColumnIR,\n type ForeignKeyIR,\n type IndexIR,\n type SchemaIR,\n type TableIR,\n type UniqueConstraintIR,\n reflectSchema,\n} from \"./ir.js\";\n\n/** SQLite's five storage classes / affinities. */\nexport type SqliteAffinity = \"INTEGER\" | \"TEXT\" | \"REAL\" | \"BLOB\" | \"NUMERIC\";\n\n/** Apply SQLite's affinity rules to a declared type string. */\nexport function sqliteAffinity(declared: string): SqliteAffinity {\n const t = declared.toUpperCase();\n if (t.includes(\"INT\")) return \"INTEGER\";\n if (t.includes(\"CHAR\") || t.includes(\"CLOB\") || t.includes(\"TEXT\")) return \"TEXT\";\n if (t.includes(\"BLOB\") || t === \"\") return \"BLOB\";\n if (t.includes(\"REAL\") || t.includes(\"FLOA\") || t.includes(\"DOUB\")) return \"REAL\";\n return \"NUMERIC\";\n}\n\n/** Map a SQLite affinity back to the closest IR column kind. */\nfunction affinityToKind(affinity: SqliteAffinity): ColumnType[\"kind\"] {\n switch (affinity) {\n case \"INTEGER\":\n return \"integer\";\n case \"REAL\":\n return \"real\";\n case \"BLOB\":\n return \"blob\";\n case \"NUMERIC\":\n return \"numeric\";\n default:\n return \"text\";\n }\n}\n\ninterface PragmaColumn {\n name: string;\n type: string;\n notnull: number;\n pk: number;\n}\n\ninterface PragmaForeignKey {\n id: number;\n seq: number;\n table: string;\n from: string;\n to: string;\n on_update: string;\n on_delete: string;\n}\n\ninterface PragmaIndex {\n seq: number;\n name: string;\n unique: number;\n origin: string;\n /** 1 when the index has a `WHERE` predicate. */\n partial?: number;\n}\n\ninterface PragmaIndexColumn {\n seqno: number;\n cid: number;\n name: string;\n}\n\n/** Read a table's foreign keys via `PRAGMA foreign_key_list`, grouped by id. */\nfunction sqliteForeignKeys(driver: SyncDriver, table: string): ForeignKeyIR[] {\n const rows = driver.execute(`PRAGMA foreign_key_list(${JSON.stringify(table)})`, [])\n .rows as unknown as PragmaForeignKey[];\n return sqliteForeignKeysFromPragma(table, rows);\n}\n\n/** Read a table's unique constraints via `PRAGMA index_list`/`index_info`. */\nfunction sqliteUniques(driver: SyncDriver, table: string): UniqueConstraintIR[] {\n const indexes = driver.execute(`PRAGMA index_list(${JSON.stringify(table)})`, [])\n .rows as unknown as PragmaIndex[];\n const uniques: UniqueConstraintIR[] = [];\n for (const idx of indexes) {\n if (!isUniqueIndex(idx)) continue;\n const cols = driver.execute(`PRAGMA index_info(${JSON.stringify(idx.name)})`, [])\n .rows as unknown as PragmaIndexColumn[];\n const unique = sqliteUniqueFromPragma(table, cols);\n if (unique) uniques.push(unique);\n }\n return uniques;\n}\n\n/**\n * Read the current SQLite schema into a `SchemaIR`. Lossy by nature (SQLite\n * collapses types into affinities), so types come back as the affinity's kind.\n *\n * @param driver A sync SQLite driver.\n * @returns The introspected schema.\n */\nexport function introspectSqlite(driver: SyncDriver): SchemaIR {\n const tablesRows = driver.execute(SQLITE_TABLES_SQL, []).rows;\n const tables: Record<string, TableIR> = {};\n for (const row of tablesRows) {\n const tableName = String(row.name);\n const info = driver.execute(`PRAGMA table_info(${JSON.stringify(tableName)})`, [])\n .rows as unknown as PragmaColumn[];\n const { columns, primaryKey } = sqliteColumnsFromPragma(info);\n tables[tableName] = {\n name: tableName,\n columns,\n primaryKey,\n uniqueConstraints: sqliteUniques(driver, tableName),\n checks: [],\n indexes: sqliteIndexes(driver, tableName),\n foreignKeys: sqliteForeignKeys(driver, tableName),\n };\n }\n return { tables };\n}\n\n/**\n * Compare the live SQLite schema against the models and report drift. Comparison\n * is at the affinity level (so `varchar` vs `TEXT` is not flagged), plus\n * nullability, primary-key, and presence of tables/columns.\n *\n * @param driver A sync SQLite driver.\n * @param models The model classes that define the intended schema.\n * @returns A list of human-readable drift messages — empty means no drift.\n */\n/**\n * Normalize a table's constraints into comparable key sets, merging the\n * column-level (`.unique()` / `.references()`) and table-level (`tableArgs`)\n * forms so drift comparison is agnostic to how a constraint was declared.\n */\nfunction constraintKeys(table: TableIR): { fks: Set<string>; uniques: Set<string> } {\n const fks = new Set<string>();\n const uniques = new Set<string>();\n for (const col of Object.values(table.columns)) {\n if (col.unique) uniques.add(col.name);\n if (col.references) {\n fks.add(`${col.name}=>${col.references.table}(${col.references.column})`);\n }\n }\n for (const uc of table.uniqueConstraints) {\n uniques.add([...uc.columns].sort().join(\",\"));\n }\n for (const fk of table.foreignKeys) {\n fks.add(`${fk.columns.join(\",\")}=>${fk.refTable}(${fk.refColumns.join(\",\")})`);\n }\n return { fks, uniques };\n}\n\nexport function checkDrift(driver: SyncDriver, models: readonly ModelClass[]): string[] {\n return compareSqliteSchemas(introspectSqlite(driver), reflectSchema(models));\n}\n\n/**\n * Compare an introspected SQLite schema against the reflected models.\n *\n * Split out from {@link checkDrift} so the sync and async drivers share one\n * comparison — a second copy would drift from this one the first time a rule\n * changes.\n *\n * @param actual The schema read from the database.\n * @param expected The schema reflected from the models.\n * @returns A list of human-readable drift messages — empty means no drift.\n */\nexport function compareSqliteSchemas(actual: SchemaIR, expected: SchemaIR): string[] {\n const issues: string[] = [];\n\n for (const [tableName, expectedTable] of Object.entries(expected.tables)) {\n const actualTable = actual.tables[tableName];\n if (!actualTable) {\n issues.push(`table \"${tableName}\" is missing from the database`);\n continue;\n }\n for (const [colName, expectedCol] of Object.entries(expectedTable.columns)) {\n const actualCol = actualTable.columns[colName];\n if (!actualCol) {\n issues.push(`column \"${tableName}.${colName}\" is missing from the database`);\n continue;\n }\n const expAff = sqliteAffinity(renderColumnType(expectedCol.type, \"sqlite\"));\n const actAff = sqliteAffinity(renderColumnType(actualCol.type, \"sqlite\"));\n if (expAff !== actAff) {\n issues.push(\n `column \"${tableName}.${colName}\" affinity differs: model ${expAff}, db ${actAff}`,\n );\n }\n if (expectedCol.notNull !== actualCol.notNull) {\n issues.push(`column \"${tableName}.${colName}\" nullability differs`);\n }\n if (expectedCol.primaryKey !== actualCol.primaryKey) {\n issues.push(`column \"${tableName}.${colName}\" primary-key flag differs`);\n }\n }\n for (const colName of Object.keys(actualTable.columns)) {\n if (!expectedTable.columns[colName]) {\n issues.push(\n `column \"${tableName}.${colName}\" exists in the database but not in the model`,\n );\n }\n }\n\n const expectedKeys = constraintKeys(expectedTable);\n const actualKeys = constraintKeys(actualTable);\n for (const fk of expectedKeys.fks) {\n if (!actualKeys.fks.has(fk)) {\n issues.push(`foreign key \"${tableName}: ${fk}\" is missing from the database`);\n }\n }\n for (const fk of actualKeys.fks) {\n if (!expectedKeys.fks.has(fk)) {\n issues.push(\n `foreign key \"${tableName}: ${fk}\" exists in the database but not in the model`,\n );\n }\n }\n for (const uq of expectedKeys.uniques) {\n if (!actualKeys.uniques.has(uq)) {\n issues.push(\n `unique constraint \"${tableName}: (${uq})\" is missing from the database`,\n );\n }\n }\n for (const uq of actualKeys.uniques) {\n if (!expectedKeys.uniques.has(uq)) {\n issues.push(\n `unique constraint \"${tableName}: (${uq})\" exists in the database but not in the model`,\n );\n }\n }\n\n issues.push(...indexDrift(tableName, actualTable, expectedTable));\n }\n\n for (const tableName of Object.keys(actual.tables)) {\n if (!expected.tables[tableName]) {\n issues.push(`table \"${tableName}\" exists in the database but not in the models`);\n }\n }\n\n return issues;\n}\n\n/** Build a table's column map + primary key from `PRAGMA table_info` rows. */\nfunction sqliteColumnsFromPragma(info: readonly PragmaColumn[]): {\n columns: Record<string, ColumnIR>;\n primaryKey: string[];\n} {\n const columns: Record<string, ColumnIR> = {};\n const primaryKey: string[] = [];\n for (const col of info) {\n const isPk = Number(col.pk) > 0;\n columns[col.name] = {\n name: col.name,\n type: { kind: affinityToKind(sqliteAffinity(col.type)), meta: {} },\n notNull: Number(col.notnull) === 1 || isPk,\n primaryKey: isPk,\n default: null,\n unique: false,\n references: null,\n };\n if (isPk) primaryKey.push(col.name);\n }\n return { columns, primaryKey };\n}\n\n/** Assemble foreign keys from `PRAGMA foreign_key_list` rows. */\nfunction sqliteForeignKeysFromPragma(\n table: string,\n rows: readonly PragmaForeignKey[],\n): ForeignKeyIR[] {\n const byId = new Map<number, PragmaForeignKey[]>();\n for (const row of rows) {\n const group = byId.get(row.id) ?? [];\n group.push(row);\n byId.set(row.id, group);\n }\n const fks: ForeignKeyIR[] = [];\n for (const group of byId.values()) {\n const ordered = [...group].sort((a, b) => a.seq - b.seq);\n fks.push({\n name: `fk_${table}_${ordered.map((r) => r.from).join(\"_\")}`,\n columns: ordered.map((r) => r.from),\n refTable: ordered[0]?.table ?? \"\",\n refColumns: ordered.map((r) => r.to),\n });\n }\n return fks;\n}\n\n/** Assemble one unique constraint from `PRAGMA index_info` rows. */\nfunction sqliteUniqueFromPragma(\n table: string,\n rows: readonly PragmaIndexColumn[],\n): UniqueConstraintIR | null {\n const cols = [...rows].sort((a, b) => a.seqno - b.seqno).map((c) => c.name);\n if (cols.length === 0) return null;\n return { name: `uq_${table}_${cols.join(\"_\")}`, columns: cols };\n}\n\n/**\n * The indexes a `CREATE INDEX` made — origin `\"c\"` — with their columns.\n *\n * `origin` is what separates the three kinds `index_list` mixes: `\"pk\"` backs the\n * primary key, `\"u\"` backs a `UNIQUE` constraint (reported as a constraint, not\n * an index), and `\"c\"` is an index somebody created. Only the last one belongs\n * here, or every unique constraint would also read as a missing index.\n */\nfunction indexesFromPragma(\n rows: readonly PragmaIndex[],\n columnsOfIndex: (name: string) => readonly PragmaIndexColumn[],\n): IndexIR[] {\n const indexes: IndexIR[] = [];\n for (const idx of rows) {\n if (idx.origin !== \"c\") continue;\n if (idx.partial === 1) continue;\n const cols = [...columnsOfIndex(idx.name)]\n .sort((a, b) => a.seqno - b.seqno)\n .map((c) => c.name);\n if (cols.length === 0) continue;\n indexes.push({\n name: idx.name,\n columns: cols,\n unique: Number(idx.unique) === 1,\n where: null,\n });\n }\n return indexes;\n}\n\n/** Read a table's explicit indexes (sync driver). */\nfunction sqliteIndexes(driver: SyncDriver, table: string): IndexIR[] {\n const rows = driver.execute(`PRAGMA index_list(${JSON.stringify(table)})`, [])\n .rows as unknown as PragmaIndex[];\n return indexesFromPragma(\n rows,\n (name) =>\n driver.execute(`PRAGMA index_info(${JSON.stringify(name)})`, [])\n .rows as unknown as PragmaIndexColumn[],\n );\n}\n\n/** True when a `PRAGMA index_list` row describes a real UNIQUE constraint. */\nfunction isUniqueIndex(idx: PragmaIndex): boolean {\n return Number(idx.unique) === 1 && idx.origin !== \"pk\";\n}\n\n/**\n * Compare the indexes of one table.\n *\n * Only **explicit** indexes are compared — the ones a `CREATE INDEX` made. The\n * ones backing a primary key or a unique constraint are reported as constraints,\n * and counting them here as well would flag every unique constraint as a missing\n * index.\n *\n * `CHECK` constraints are deliberately **not** compared: a database reports them\n * as SQL text, and comparing text against the condition tree would report a\n * difference for every difference in spelling. They are still created and dropped\n * by migrations; they are just invisible to drift.\n *\n * @param tableName The table.\n * @param actual The introspected table.\n * @param expected The reflected table.\n * @returns Drift messages, empty when the indexes agree.\n */\nfunction indexDrift(tableName: string, actual: TableIR, expected: TableIR): string[] {\n const issues: string[] = [];\n const signature = (ix: { columns: readonly string[]; unique: boolean }): string =>\n `${ix.columns.join(\",\")}${ix.unique ? \" unique\" : \"\"}`;\n const actualByName = new Map(actual.indexes.map((ix) => [ix.name, ix]));\n const expectedByName = new Map(expected.indexes.map((ix) => [ix.name, ix]));\n for (const [name, exp] of expectedByName) {\n const act = actualByName.get(name);\n if (!act) {\n issues.push(`index \"${tableName}.${name}\" is missing from the database`);\n continue;\n }\n if (signature(act) !== signature(exp)) {\n issues.push(\n `index \"${tableName}.${name}\" differs: model (${signature(exp)}), db (${signature(act)})`,\n );\n }\n }\n for (const name of actualByName.keys()) {\n if (!expectedByName.has(name)) {\n issues.push(\n `index \"${tableName}.${name}\" exists in the database but not in the model`,\n );\n }\n }\n return issues;\n}\n\n/** The `sqlite_master` query listing user tables (excluding the version table). */\nconst SQLITE_TABLES_SQL =\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name != 'tempest_db_js_migrations'\";\n\n/**\n * Read the current SQLite schema into a `SchemaIR` over an **async** driver.\n *\n * The sequencing differs from {@link introspectSqlite} — each `PRAGMA` depends on\n * the previous result, so it cannot be one awaited batch — but every row → IR\n * mapping is the shared code above.\n *\n * @param driver An async SQLite driver.\n * @returns The introspected schema.\n */\nexport async function introspectSqliteAsync(driver: AsyncDriver): Promise<SchemaIR> {\n const tablesRows = (await driver.execute(SQLITE_TABLES_SQL, [])).rows;\n const tables: Record<string, TableIR> = {};\n for (const row of tablesRows) {\n const tableName = String(row.name);\n const info = (\n await driver.execute(`PRAGMA table_info(${JSON.stringify(tableName)})`, [])\n ).rows as unknown as PragmaColumn[];\n const { columns, primaryKey } = sqliteColumnsFromPragma(info);\n\n const fkRows = (\n await driver.execute(`PRAGMA foreign_key_list(${JSON.stringify(tableName)})`, [])\n ).rows as unknown as PragmaForeignKey[];\n\n const indexes = (\n await driver.execute(`PRAGMA index_list(${JSON.stringify(tableName)})`, [])\n ).rows as unknown as PragmaIndex[];\n const uniqueConstraints: UniqueConstraintIR[] = [];\n for (const idx of indexes) {\n if (!isUniqueIndex(idx)) continue;\n const cols = (\n await driver.execute(`PRAGMA index_info(${JSON.stringify(idx.name)})`, [])\n ).rows as unknown as PragmaIndexColumn[];\n const unique = sqliteUniqueFromPragma(tableName, cols);\n if (unique) uniqueConstraints.push(unique);\n }\n const explicitIndexes: IndexIR[] = [];\n for (const idx of indexes) {\n if (idx.origin !== \"c\" || idx.partial === 1) continue;\n const cols = (\n await driver.execute(`PRAGMA index_info(${JSON.stringify(idx.name)})`, [])\n ).rows as unknown as PragmaIndexColumn[];\n const sorted = [...cols].sort((a, b) => a.seqno - b.seqno).map((c) => c.name);\n if (sorted.length === 0) continue;\n explicitIndexes.push({\n name: idx.name,\n columns: sorted,\n unique: Number(idx.unique) === 1,\n where: null,\n });\n }\n\n tables[tableName] = {\n name: tableName,\n columns,\n primaryKey,\n uniqueConstraints,\n foreignKeys: sqliteForeignKeysFromPragma(tableName, fkRows),\n checks: [],\n indexes: explicitIndexes,\n };\n }\n return { tables };\n}\n\n/**\n * Drift check over an **async** driver, routed by dialect. This is what\n * `tempest-db check` runs, so the CLI reaches the same comparison for every\n * supported database instead of only SQLite.\n *\n * @param driver An async driver for the live database.\n * @param dialect The dialect the driver speaks.\n * @param models The model classes that define the intended schema.\n * @returns A list of drift messages — empty means no drift.\n */\nexport async function checkDriftAsync(\n driver: AsyncDriver,\n dialect: Dialect,\n models: readonly ModelClass[],\n): Promise<string[]> {\n if (dialect === \"postgresql\") return checkDriftPostgres(driver, models);\n if (dialect === \"sqlite\") {\n return compareSqliteSchemas(\n await introspectSqliteAsync(driver),\n reflectSchema(models),\n );\n }\n return [\n \"drift checking is not implemented for MySQL — its information_schema introspection is still missing\",\n ];\n}\n\n/**\n * Map a PostgreSQL `information_schema` row to the closest IR column type.\n *\n * An array column reports `data_type = \"ARRAY\"` with the element type hidden in\n * `udt_name` as `_text` / `_int4`, so it is unpacked here into a nested element\n * type — otherwise every `text[]` column would read back as plain text and the\n * drift check would fire forever.\n *\n * @param dataType The `information_schema.columns.data_type` value.\n * @param udtName The `information_schema.columns.udt_name` value.\n * @returns The IR column type.\n */\nfunction pgTypeToColumnType(dataType: string, udtName: string): ColumnType {\n if (dataType.toLowerCase() === \"array\") {\n return {\n kind: \"array\",\n meta: { element: { kind: pgUdtToKind(udtName.replace(/^_/, \"\")), meta: {} } },\n };\n }\n return { kind: pgTypeToKind(dataType, udtName), meta: {} };\n}\n\n/** Map a PostgreSQL internal type name (`text`, `int4`) to the closest IR kind. */\nfunction pgUdtToKind(udtName: string): ColumnType[\"kind\"] {\n switch (udtName) {\n case \"int2\":\n return \"smallint\";\n case \"int4\":\n return \"integer\";\n case \"int8\":\n return \"bigint\";\n case \"float4\":\n return \"real\";\n case \"float8\":\n return \"double\";\n case \"numeric\":\n return \"numeric\";\n case \"varchar\":\n return \"varchar\";\n case \"bpchar\":\n return \"char\";\n case \"bool\":\n return \"boolean\";\n case \"date\":\n return \"date\";\n case \"time\":\n case \"timetz\":\n return \"time\";\n case \"timestamp\":\n case \"timestamptz\":\n return \"timestamp\";\n case \"bytea\":\n return \"blob\";\n case \"json\":\n case \"jsonb\":\n return \"json\";\n case \"uuid\":\n return \"uuid\";\n default:\n return \"text\";\n }\n}\n\n/** Map a PostgreSQL `information_schema` type name to the closest IR kind. */\nfunction pgTypeToKind(dataType: string, udtName: string): ColumnType[\"kind\"] {\n const t = dataType.toLowerCase();\n if (t === \"user-defined\") return \"enum\"; // a named enum type\n if (t === \"smallint\") return \"smallint\";\n if (t === \"integer\") return \"integer\";\n if (t === \"bigint\") return \"bigint\";\n if (t === \"numeric\") return \"numeric\";\n if (t === \"real\") return \"real\";\n if (t === \"double precision\") return \"double\";\n if (t === \"character varying\") return \"varchar\";\n if (t === \"character\") return \"char\";\n if (t === \"text\") return \"text\";\n if (t === \"boolean\") return \"boolean\";\n if (t === \"date\") return \"date\";\n if (t.startsWith(\"time\")) return t.startsWith(\"timestamp\") ? \"timestamp\" : \"time\";\n if (t === \"bytea\") return \"blob\";\n if (t === \"json\") return \"json\";\n if (t === \"jsonb\") return \"json\";\n if (t === \"uuid\") return \"uuid\";\n return udtName === \"jsonb\" ? \"json\" : \"text\";\n}\n\n/**\n * Read the current PostgreSQL schema into a `SchemaIR` from `information_schema`.\n *\n * Not exercised by the in-repo test suite (no PostgreSQL in CI); mirrors\n * {@link introspectSqlite} for the async driver.\n *\n * @param driver An async PostgreSQL driver.\n * @returns The introspected schema.\n */\nexport async function introspectPostgres(driver: AsyncDriver): Promise<SchemaIR> {\n const tablesResult = await driver.execute(\n \"SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE' AND table_name != 'tempest_db_js_migrations'\",\n [],\n );\n const tables: Record<string, TableIR> = {};\n for (const row of tablesResult.rows) {\n const tableName = String(row.table_name);\n const colsResult = await driver.execute(\n \"SELECT column_name, data_type, udt_name, is_nullable FROM information_schema.columns WHERE table_name = $1\",\n [tableName],\n );\n const pkResult = await driver.execute(\n `SELECT a.attname AS name FROM pg_index i\n JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n WHERE i.indrelid = $1::regclass AND i.indisprimary`,\n [tableName],\n );\n const pkSet = new Set(pkResult.rows.map((r) => String(r.name)));\n const columns: Record<string, ColumnIR> = {};\n const primaryKey: string[] = [];\n for (const col of colsResult.rows) {\n const name = String(col.column_name);\n const isPk = pkSet.has(name);\n columns[name] = {\n name,\n type: pgTypeToColumnType(String(col.data_type), String(col.udt_name)),\n notNull: col.is_nullable === \"NO\" || isPk,\n primaryKey: isPk,\n default: null,\n unique: false,\n references: null,\n };\n if (isPk) primaryKey.push(name);\n }\n tables[tableName] = {\n name: tableName,\n columns,\n primaryKey,\n uniqueConstraints: await postgresUniques(driver, tableName),\n checks: [],\n indexes: await postgresIndexes(driver, tableName),\n foreignKeys: await postgresForeignKeys(driver, tableName),\n };\n }\n return { tables };\n}\n\n/** Read a table's foreign keys from `pg_constraint` (best-effort, no CI). */\nasync function postgresForeignKeys(\n driver: AsyncDriver,\n table: string,\n): Promise<ForeignKeyIR[]> {\n const result = await driver.execute(\n `SELECT c.conname AS name,\n (SELECT array_agg(a.attname ORDER BY k.ord)\n FROM unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord)\n JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.attnum) AS cols,\n cf.relname AS ref_table,\n (SELECT array_agg(a.attname ORDER BY k.ord)\n FROM unnest(c.confkey) WITH ORDINALITY AS k(attnum, ord)\n JOIN pg_attribute a ON a.attrelid = c.confrelid AND a.attnum = k.attnum) AS ref_cols\n FROM pg_constraint c\n JOIN pg_class cf ON cf.oid = c.confrelid\n WHERE c.contype = 'f' AND c.conrelid = $1::regclass`,\n [table],\n );\n return result.rows.map((r) => ({\n name: String(r.name),\n columns: (r.cols as string[]) ?? [],\n refTable: String(r.ref_table),\n refColumns: (r.ref_cols as string[]) ?? [],\n }));\n}\n\n/** Read a table's unique constraints from `pg_constraint` (best-effort, no CI). */\nasync function postgresUniques(\n driver: AsyncDriver,\n table: string,\n): Promise<UniqueConstraintIR[]> {\n const result = await driver.execute(\n `SELECT c.conname AS name,\n (SELECT array_agg(a.attname ORDER BY k.ord)\n FROM unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord)\n JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.attnum) AS cols\n FROM pg_constraint c\n WHERE c.contype = 'u' AND c.conrelid = $1::regclass`,\n [table],\n );\n return result.rows.map((r) => ({\n name: String(r.name),\n columns: (r.cols as string[]) ?? [],\n }));\n}\n\n/** The comparable name of a column type — `text[]` for arrays, the kind otherwise. */\n/**\n * Read a table's explicit indexes from `pg_indexes`.\n *\n * Indexes backing a constraint (primary key, unique) are excluded through\n * `pg_constraint`: they are reported as constraints, and counting them twice\n * would make every unique constraint read as a missing index.\n *\n * Partial indexes are skipped for now — their predicate comes back as SQL text,\n * and comparing text against the IR's condition tree would report a difference\n * for every difference in spelling.\n *\n * @param driver The async driver.\n * @param table The table.\n * @returns The indexes.\n */\nasync function postgresIndexes(driver: AsyncDriver, table: string): Promise<IndexIR[]> {\n const { rows } = await driver.execute(\n `SELECT i.relname AS name,\n ix.indisunique AS is_unique,\n ix.indpred IS NOT NULL AS is_partial,\n array_to_string(array_agg(a.attname ORDER BY k.ord), ',') AS columns\n FROM pg_index ix\n JOIN pg_class i ON i.oid = ix.indexrelid\n JOIN pg_class t ON t.oid = ix.indrelid\n JOIN LATERAL unnest(ix.indkey) WITH ORDINALITY AS k(attnum, ord) ON true\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum\n WHERE t.relname = $1\n AND NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conindid = ix.indexrelid)\n GROUP BY i.relname, ix.indisunique, ix.indpred`,\n [table],\n );\n return (\n rows as { name: string; is_unique: boolean; is_partial: boolean; columns: string }[]\n )\n .filter((row) => !row.is_partial)\n .map((row) => ({\n name: row.name,\n columns: row.columns.split(\",\"),\n unique: row.is_unique === true,\n where: null,\n }));\n}\n\nfunction describeKind(type: ColumnType): string {\n if (type.kind !== \"array\") return type.kind;\n return `${type.meta.element ? describeKind(type.meta.element) : \"unknown\"}[]`;\n}\n\n/**\n * Drift check for PostgreSQL: compares the live schema (introspected) against the\n * models by column kind, nullability, primary-key, and presence. Structural —\n * not exercised in CI (no PostgreSQL).\n *\n * @param driver An async PostgreSQL driver.\n * @param models The model classes that define the intended schema.\n * @returns A list of drift messages — empty means no drift.\n */\nexport async function checkDriftPostgres(\n driver: AsyncDriver,\n models: readonly ModelClass[],\n): Promise<string[]> {\n const actual = await introspectPostgres(driver);\n const expected = reflectSchema(models);\n const issues: string[] = [];\n for (const [tableName, expectedTable] of Object.entries(expected.tables)) {\n const actualTable = actual.tables[tableName];\n if (!actualTable) {\n issues.push(`table \"${tableName}\" is missing from the database`);\n continue;\n }\n for (const [colName, expectedCol] of Object.entries(expectedTable.columns)) {\n const actualCol = actualTable.columns[colName];\n if (!actualCol) {\n issues.push(`column \"${tableName}.${colName}\" is missing from the database`);\n continue;\n }\n if (describeKind(expectedCol.type) !== describeKind(actualCol.type)) {\n issues.push(\n `column \"${tableName}.${colName}\" type differs: model ${describeKind(expectedCol.type)}, db ${describeKind(actualCol.type)}`,\n );\n }\n if (expectedCol.notNull !== actualCol.notNull) {\n issues.push(`column \"${tableName}.${colName}\" nullability differs`);\n }\n }\n for (const colName of Object.keys(actualTable.columns)) {\n if (!expectedTable.columns[colName]) {\n issues.push(\n `column \"${tableName}.${colName}\" exists in the database but not in the model`,\n );\n }\n }\n\n const expectedKeys = constraintKeys(expectedTable);\n const actualKeys = constraintKeys(actualTable);\n for (const fk of expectedKeys.fks) {\n if (!actualKeys.fks.has(fk)) {\n issues.push(`foreign key \"${tableName}: ${fk}\" is missing from the database`);\n }\n }\n for (const uq of expectedKeys.uniques) {\n if (!actualKeys.uniques.has(uq)) {\n issues.push(\n `unique constraint \"${tableName}: (${uq})\" is missing from the database`,\n );\n }\n }\n\n issues.push(...indexDrift(tableName, actualTable, expectedTable));\n }\n for (const tableName of Object.keys(actual.tables)) {\n if (!expected.tables[tableName]) {\n issues.push(`table \"${tableName}\" exists in the database but not in the models`);\n }\n }\n return issues;\n}\n","/**\n * tempest-db-js — Phase 6: rename detection.\n *\n * The differ ({@link diffSchema}) is deliberately conservative: a renamed column\n * looks like a drop + add, and a renamed table like a drop + create. That is the\n * *safe* default (never guesses), but it loses data. This module turns those\n * add/drop pairs into rename *candidates* the CLI can confirm — interactively at\n * a TTY, or explicitly via flags — and folds confirmed ones back into a single\n * `rename_table` / `rename_column` operation.\n *\n * Everything here is pure and structural (no SQL, no DB, no I/O), so the\n * detection and folding are fully testable; the actual prompting lives in the\n * `tempest-db` bin.\n */\n\nimport type { ColumnIR } from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\n\n/** A possible rename the differ emitted as a drop + add/create pair. */\nexport type RenameCandidate =\n | { readonly kind: \"table\"; readonly from: string; readonly to: string }\n | {\n readonly kind: \"column\";\n readonly table: string;\n readonly from: string;\n readonly to: string;\n };\n\n/** Structural identity of a column, ignoring its name. */\nfunction columnShape(col: ColumnIR): string {\n return JSON.stringify({\n type: col.type,\n notNull: col.notNull,\n primaryKey: col.primaryKey,\n default: col.default,\n unique: col.unique,\n references: col.references,\n });\n}\n\n/** Structural identity of a table's columns, ignoring the table name. */\nfunction tableShape(columns: Readonly<Record<string, ColumnIR>>): string {\n return Object.entries(columns)\n .map(([name, col]) => `${name}:${columnShape(col)}`)\n .sort()\n .join(\"|\");\n}\n\n/**\n * Detect rename candidates in a forward operation list.\n *\n * A table rename is a `create_table` + `drop_table` whose column shapes match\n * exactly. A column rename is an `add_column` + `drop_column` on the same table\n * whose column shapes match exactly. Only unambiguous 1:1 shape matches are\n * reported — if two dropped columns share a shape, neither is offered (the\n * mapping would be a guess).\n *\n * @param ops The forward operations from {@link diffSchema}.\n * @returns The rename candidates found (never mutates `ops`).\n */\nexport function detectRenames(ops: readonly Operation[]): RenameCandidate[] {\n const candidates: RenameCandidate[] = [];\n\n // --- table renames ---\n const creates = ops.filter((o) => o.kind === \"create_table\");\n const tableDrops = ops.filter((o) => o.kind === \"drop_table\");\n const takenCreate = new Set<string>();\n const takenDrop = new Set<string>();\n for (const create of creates) {\n const createShape = tableShape(create.table.columns);\n const matches = tableDrops.filter(\n (d) => !takenDrop.has(d.table.name) && tableShape(d.table.columns) === createShape,\n );\n // Only a unique match is a safe rename; ambiguity → leave as drop + create.\n const uniqueCreate =\n creates.filter(\n (c) =>\n !takenCreate.has(c.table.name) && tableShape(c.table.columns) === createShape,\n ).length === 1;\n if (matches.length === 1 && uniqueCreate) {\n const drop = matches[0] as Extract<Operation, { kind: \"drop_table\" }>;\n if (drop.table.name !== create.table.name) {\n candidates.push({ kind: \"table\", from: drop.table.name, to: create.table.name });\n takenCreate.add(create.table.name);\n takenDrop.add(drop.table.name);\n }\n }\n }\n\n // --- column renames (per table) ---\n const adds = ops.filter((o) => o.kind === \"add_column\");\n const colDrops = ops.filter((o) => o.kind === \"drop_column\");\n const tables = new Set([...adds.map((o) => o.table), ...colDrops.map((o) => o.table)]);\n for (const table of tables) {\n const tableAdds = adds.filter((o) => o.table === table);\n const tableColDrops = colDrops.filter((o) => o.table === table);\n const takenAdd = new Set<string>();\n const takenColDrop = new Set<string>();\n for (const add of tableAdds) {\n const shape = columnShape(add.column);\n const dropMatches = tableColDrops.filter(\n (d) => !takenColDrop.has(d.column.name) && columnShape(d.column) === shape,\n );\n const addMatches = tableAdds.filter(\n (a) => !takenAdd.has(a.column.name) && columnShape(a.column) === shape,\n );\n if (dropMatches.length === 1 && addMatches.length === 1) {\n const drop = dropMatches[0] as Extract<Operation, { kind: \"drop_column\" }>;\n candidates.push({\n kind: \"column\",\n table,\n from: drop.column.name,\n to: add.column.name,\n });\n takenAdd.add(add.column.name);\n takenColDrop.add(drop.column.name);\n }\n }\n }\n\n return candidates;\n}\n\n/** Match a table-rename candidate against an op pair. */\nfunction isTableRename(\n op: Operation,\n r: Extract<RenameCandidate, { kind: \"table\" }>,\n): boolean {\n return (\n (op.kind === \"create_table\" && op.table.name === r.to) ||\n (op.kind === \"drop_table\" && op.table.name === r.from)\n );\n}\n\n/** Match a column-rename candidate against an op pair. */\nfunction isColumnRename(\n op: Operation,\n r: Extract<RenameCandidate, { kind: \"column\" }>,\n): boolean {\n return (\n (op.kind === \"add_column\" && op.table === r.table && op.column.name === r.to) ||\n (op.kind === \"drop_column\" && op.table === r.table && op.column.name === r.from)\n );\n}\n\n/**\n * Fold confirmed renames into an operation list: each confirmed candidate's\n * drop + add/create pair is removed and replaced by a single rename operation,\n * inserted at the position of the first op it replaces (preserving order).\n *\n * @param ops The forward operations from {@link diffSchema}.\n * @param confirmed The rename candidates the user accepted.\n * @returns A new operation list with renames applied.\n */\nexport function applyRenames(\n ops: readonly Operation[],\n confirmed: readonly RenameCandidate[],\n): Operation[] {\n const out: Operation[] = [];\n const emitted = new Set<RenameCandidate>();\n\n for (const op of ops) {\n const match = confirmed.find((r) =>\n r.kind === \"table\" ? isTableRename(op, r) : isColumnRename(op, r),\n );\n if (!match) {\n out.push(op);\n continue;\n }\n // Emit the rename once (at the first op of the pair); skip both members.\n if (!emitted.has(match)) {\n emitted.add(match);\n out.push(\n match.kind === \"table\"\n ? { kind: \"rename_table\", from: match.from, to: match.to }\n : { kind: \"rename_column\", table: match.table, from: match.from, to: match.to },\n );\n }\n }\n return out;\n}\n","/**\n * tempest-db-js — Phase 6: the migration runner.\n *\n * The `Op` facade records operations; the `MigrationRunner` renders them to SQL\n * (per dialect) and runs them through a sync driver, tracking applied revisions\n * in a `tempest_db_js_migrations` table. Upgrades/downgrades respect the revision DAG.\n *\n * SQLite execution is real (via `node:sqlite`); the same code path serves any\n * sync driver.\n */\n\nimport type { AsyncDriver, SyncDriver } from \"../engine.js\";\nimport type { Dialect } from \"../url.js\";\nimport { renderOperation } from \"./ddl.js\";\nimport { topoOrder } from \"./graph.js\";\nimport type { ColumnIR, NamedConstraint, TableIR } from \"./ir.js\";\nimport { type Operation, invertAll } from \"./operations.js\";\n\n/**\n * The facade injected into `up()`/`down()`. Each method records an operation;\n * the runner renders and executes them after the function returns.\n */\nexport class Op {\n readonly operations: Operation[] = [];\n\n /** Record a raw operation (used by autogenerated migrations). */\n run(operation: Operation): void {\n this.operations.push(operation);\n }\n\n createTable(table: TableIR): void {\n this.run({ kind: \"create_table\", table });\n }\n dropTable(table: TableIR): void {\n this.run({ kind: \"drop_table\", table });\n }\n renameTable(from: string, to: string): void {\n this.run({ kind: \"rename_table\", from, to });\n }\n addColumn(table: string, column: ColumnIR): void {\n this.run({ kind: \"add_column\", table, column });\n }\n dropColumn(table: string, column: ColumnIR): void {\n this.run({ kind: \"drop_column\", table, column });\n }\n alterColumn(table: string, name: string, from: ColumnIR, to: ColumnIR): void {\n this.run({ kind: \"alter_column\", table, name, from, to });\n }\n renameColumn(table: string, from: string, to: string): void {\n this.run({ kind: \"rename_column\", table, from, to });\n }\n /** Rebuild a table (SQLite batch-mode / PostgreSQL per-column alters). */\n recreateTable(from: TableIR, to: TableIR): void {\n this.run({ kind: \"recreate_table\", from, to });\n }\n /** Add a table-level unique / foreign-key constraint. */\n addConstraint(table: string, constraint: NamedConstraint): void {\n this.run({ kind: \"add_constraint\", table, constraint });\n }\n /** Drop a table-level unique / foreign-key constraint. */\n dropConstraint(table: string, constraint: NamedConstraint): void {\n this.run({ kind: \"drop_constraint\", table, constraint });\n }\n /** Raw SQL escape hatch (e.g. a data migration). `down` may be `null`. */\n execute(up: string, down: string | null = null): void {\n this.run({ kind: \"execute\", up, down });\n }\n}\n\n/** A migration file's shape. */\nexport interface Migration {\n readonly revision: string;\n readonly downRevision: readonly string[];\n readonly label?: string;\n up(op: Op): void;\n down(op: Op): void;\n}\n\nconst VERSION_TABLE = \"tempest_db_js_migrations\";\n\n/** Runs migrations against a sync driver, tracking applied revisions. */\nexport class MigrationRunner {\n constructor(\n private readonly driver: SyncDriver,\n private readonly dialect: Dialect,\n ) {}\n\n /** Create the version-tracking table if it does not exist. */\n ensureVersionTable(): void {\n this.driver.execute(\n `CREATE TABLE IF NOT EXISTS \"${VERSION_TABLE}\" (revision TEXT PRIMARY KEY, applied_at TEXT NOT NULL, down_revision TEXT NOT NULL)`,\n [],\n );\n }\n\n /** The set of applied revision ids. */\n applied(): Set<string> {\n this.ensureVersionTable();\n const { rows } = this.driver.execute(`SELECT revision FROM \"${VERSION_TABLE}\"`, []);\n return new Set(rows.map((r) => String(r.revision)));\n }\n\n private runOps(ops: readonly Operation[]): void {\n for (const op of ops) {\n for (const stmt of renderOperation(op, this.dialect)) {\n const trimmed = stmt.trim();\n if (trimmed.length === 0 || trimmed.startsWith(\"--\")) continue;\n this.driver.execute(stmt, []);\n }\n }\n }\n\n private record(migration: Migration, appliedAt: string): void {\n this.driver.execute(\n `INSERT INTO \"${VERSION_TABLE}\" (revision, applied_at, down_revision) VALUES (?, ?, ?)`,\n [migration.revision, appliedAt, migration.downRevision.join(\",\")],\n );\n }\n\n private forget(revision: string): void {\n this.driver.execute(`DELETE FROM \"${VERSION_TABLE}\" WHERE revision = ?`, [revision]);\n }\n\n /**\n * Apply all pending migrations up to the head(s), in DAG order.\n *\n * @param migrations All known migrations.\n * @param appliedAt Timestamp string to stamp (pass one in — the runtime has no\n * wall clock of its own here).\n * @returns The revision ids that were applied this run.\n */\n upgrade(migrations: readonly Migration[], appliedAt: string): string[] {\n const done = this.applied();\n const ordered = topoOrder(migrations);\n const ran: string[] = [];\n for (const migration of ordered) {\n if (done.has(migration.revision)) continue;\n const op = new Op();\n migration.up(op);\n this.runOps(op.operations);\n this.record(migration, appliedAt);\n ran.push(migration.revision);\n }\n return ran;\n }\n\n /**\n * Revert the last `steps` applied migrations (default 1), newest first.\n *\n * @param migrations All known migrations.\n * @param steps How many applied revisions to roll back.\n * @returns The revision ids that were reverted.\n */\n downgrade(migrations: readonly Migration[], steps = 1): string[] {\n const done = this.applied();\n const ordered = topoOrder(migrations).filter((m) => done.has(m.revision));\n const toRevert = ordered.slice(-steps).reverse();\n const reverted: string[] = [];\n for (const migration of toRevert) {\n const op = new Op();\n // Prefer the migration's own down(); fall back to inverting up().\n if (migration.down.length >= 0) {\n try {\n migration.down(op);\n } catch {\n op.operations.length = 0;\n }\n }\n if (op.operations.length === 0) {\n const upOp = new Op();\n migration.up(upOp);\n op.operations.push(...invertAll(upOp.operations));\n }\n this.runOps(op.operations);\n this.forget(migration.revision);\n reverted.push(migration.revision);\n }\n return reverted;\n }\n}\n\n// ---------------------------------------------------------------------------\n// async runner (PostgreSQL / any async driver)\n// ---------------------------------------------------------------------------\n\n/** Quote an identifier for the dialect (backticks on MySQL, double-quotes else). */\nfunction quoteIdent(name: string, dialect: Dialect): string {\n return dialect === \"mysql\"\n ? `\\`${name.replace(/`/g, \"``\")}\\``\n : `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\n/** The n-th (1-based) placeholder for the dialect (`$n` on PostgreSQL, `?` else). */\nfunction placeholder(index: number, dialect: Dialect): string {\n return dialect === \"postgresql\" ? `$${index}` : \"?\";\n}\n\n/**\n * Runs migrations against an **async** driver (PostgreSQL, or any async driver),\n * tracking applied revisions. Mirrors {@link MigrationRunner} but every statement\n * is awaited, and identifier quoting + placeholder style follow the dialect —\n * so the version table and its bookkeeping are portable across SQLite/PG/MySQL.\n */\nexport class AsyncMigrationRunner {\n private readonly vt: string;\n\n constructor(\n private readonly driver: AsyncDriver,\n private readonly dialect: Dialect,\n ) {\n this.vt = quoteIdent(VERSION_TABLE, dialect);\n }\n\n /** Create the version-tracking table if it does not exist. */\n async ensureVersionTable(): Promise<void> {\n await this.driver.execute(\n `CREATE TABLE IF NOT EXISTS ${this.vt} (revision ${this.textType()} PRIMARY KEY, applied_at ${this.textType()} NOT NULL, down_revision ${this.textType()} NOT NULL)`,\n [],\n );\n }\n\n /** A portable \"text\" column type for the version table. */\n private textType(): string {\n // MySQL cannot index an unbounded TEXT primary key; use VARCHAR there.\n return this.dialect === \"mysql\" ? \"VARCHAR(255)\" : \"TEXT\";\n }\n\n /** The set of applied revision ids. */\n async applied(): Promise<Set<string>> {\n await this.ensureVersionTable();\n const { rows } = await this.driver.execute(`SELECT revision FROM ${this.vt}`, []);\n return new Set(rows.map((r) => String(r.revision)));\n }\n\n private async runOps(ops: readonly Operation[]): Promise<void> {\n for (const op of ops) {\n for (const stmt of renderOperation(op, this.dialect)) {\n const trimmed = stmt.trim();\n if (trimmed.length === 0 || trimmed.startsWith(\"--\")) continue;\n await this.driver.execute(stmt, []);\n }\n }\n }\n\n private async record(migration: Migration, appliedAt: string): Promise<void> {\n const p = (i: number) => placeholder(i, this.dialect);\n await this.driver.execute(\n `INSERT INTO ${this.vt} (revision, applied_at, down_revision) VALUES (${p(1)}, ${p(2)}, ${p(3)})`,\n [migration.revision, appliedAt, migration.downRevision.join(\",\")],\n );\n }\n\n private async forget(revision: string): Promise<void> {\n await this.driver.execute(\n `DELETE FROM ${this.vt} WHERE revision = ${placeholder(1, this.dialect)}`,\n [revision],\n );\n }\n\n /**\n * Apply all pending migrations up to the head(s), in DAG order.\n *\n * @param migrations All known migrations.\n * @param appliedAt Timestamp string to stamp on each applied revision.\n * @returns The revision ids that were applied this run.\n */\n async upgrade(migrations: readonly Migration[], appliedAt: string): Promise<string[]> {\n const done = await this.applied();\n const ordered = topoOrder(migrations);\n const ran: string[] = [];\n for (const migration of ordered) {\n if (done.has(migration.revision)) continue;\n const op = new Op();\n migration.up(op);\n await this.runOps(op.operations);\n await this.record(migration, appliedAt);\n ran.push(migration.revision);\n }\n return ran;\n }\n\n /**\n * Revert the last `steps` applied migrations (default 1), newest first.\n *\n * @param migrations All known migrations.\n * @param steps How many applied revisions to roll back.\n * @returns The revision ids that were reverted.\n */\n async downgrade(migrations: readonly Migration[], steps = 1): Promise<string[]> {\n const done = await this.applied();\n const ordered = topoOrder(migrations).filter((m) => done.has(m.revision));\n const toRevert = ordered.slice(-steps).reverse();\n const reverted: string[] = [];\n for (const migration of toRevert) {\n const op = new Op();\n try {\n migration.down(op);\n } catch {\n op.operations.length = 0;\n }\n if (op.operations.length === 0) {\n const upOp = new Op();\n migration.up(upOp);\n op.operations.push(...invertAll(upOp.operations));\n }\n await this.runOps(op.operations);\n await this.forget(migration.revision);\n reverted.push(migration.revision);\n }\n return reverted;\n }\n}\n","/**\n * tempest-db-js — Phase 6: migration replay → virtual schema IR.\n *\n * Applies a migration's operations to an in-memory `SchemaIR`, building the\n * \"current\" schema without touching a database. This is the hybrid source of\n * truth for autogenerate: diff the replayed schema against the reflected models.\n */\n\nimport { topoOrder } from \"./graph.js\";\nimport { type SchemaIR, type TableIR, emptySchema } from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\nimport { type Migration, Op } from \"./runner.js\";\n\n/** Apply one operation to a schema, returning the updated schema. */\nexport function applyOperation(schema: SchemaIR, op: Operation): SchemaIR {\n const tables: Record<string, TableIR> = { ...schema.tables };\n switch (op.kind) {\n case \"create_table\":\n tables[op.table.name] = op.table;\n break;\n case \"drop_table\":\n delete tables[op.table.name];\n break;\n case \"rename_table\": {\n const t = tables[op.from];\n if (t) {\n delete tables[op.from];\n tables[op.to] = { ...t, name: op.to };\n }\n break;\n }\n case \"recreate_table\":\n delete tables[op.from.name];\n tables[op.to.name] = op.to;\n break;\n case \"add_column\": {\n const t = tables[op.table];\n if (t) {\n tables[op.table] = {\n ...t,\n columns: { ...t.columns, [op.column.name]: op.column },\n };\n }\n break;\n }\n case \"drop_column\": {\n const t = tables[op.table];\n if (t) {\n const columns = { ...t.columns };\n delete columns[op.column.name];\n tables[op.table] = { ...t, columns };\n }\n break;\n }\n case \"alter_column\": {\n const t = tables[op.table];\n if (t) {\n tables[op.table] = {\n ...t,\n columns: { ...t.columns, [op.name]: op.to },\n };\n }\n break;\n }\n case \"rename_column\": {\n const t = tables[op.table];\n const col = t?.columns[op.from];\n if (t && col) {\n const columns = { ...t.columns };\n delete columns[op.from];\n columns[op.to] = { ...col, name: op.to };\n tables[op.table] = { ...t, columns };\n }\n break;\n }\n case \"add_constraint\": {\n const t = tables[op.table];\n if (t) {\n tables[op.table] =\n op.constraint.type === \"unique\"\n ? {\n ...t,\n uniqueConstraints: [...t.uniqueConstraints, op.constraint.constraint],\n }\n : op.constraint.type === \"check\"\n ? { ...t, checks: [...t.checks, op.constraint.constraint] }\n : { ...t, foreignKeys: [...t.foreignKeys, op.constraint.constraint] };\n }\n break;\n }\n case \"create_index\": {\n const t = tables[op.table];\n if (t) tables[op.table] = { ...t, indexes: [...t.indexes, op.index] };\n break;\n }\n case \"drop_index\": {\n const t = tables[op.table];\n if (t) {\n tables[op.table] = {\n ...t,\n indexes: t.indexes.filter((i) => i.name !== op.index.name),\n };\n }\n break;\n }\n case \"drop_constraint\": {\n const t = tables[op.table];\n if (t) {\n const dropName = op.constraint.constraint.name;\n tables[op.table] =\n op.constraint.type === \"unique\"\n ? {\n ...t,\n uniqueConstraints: t.uniqueConstraints.filter((u) => u.name !== dropName),\n }\n : op.constraint.type === \"check\"\n ? { ...t, checks: t.checks.filter((c) => c.name !== dropName) }\n : {\n ...t,\n foreignKeys: t.foreignKeys.filter((f) => f.name !== dropName),\n };\n }\n break;\n }\n case \"execute\":\n // raw SQL is opaque to the IR\n break;\n }\n return { tables };\n}\n\n/**\n * Replay migrations (in DAG order) into a virtual `SchemaIR` — the \"current\"\n * schema, computed without a database.\n *\n * @param migrations All known migrations.\n * @returns The schema after applying every migration's `up()`.\n */\nexport function replaySchema(migrations: readonly Migration[]): SchemaIR {\n let schema = emptySchema();\n for (const migration of topoOrder(migrations)) {\n const op = new Op();\n migration.up(op);\n for (const operation of op.operations) {\n schema = applyOperation(schema, operation);\n }\n }\n return schema;\n}\n","/**\n * tempest-db-js — migration CLI (programmatic core).\n *\n * `runMigrationCli(argv, config)` dispatches Alembic-style commands against a\n * driver + a set of migrations + (optionally) the models. It returns lines and\n * an exit code rather than touching `process`, so it is fully testable; a thin\n * `bin` wrapper just maps `process.argv`/`process.exit` onto it.\n */\n\nimport { type AsyncDriver, type SyncDriver, toAsyncDriver } from \"../engine.js\";\nimport type { ModelClass } from \"../index.js\";\nimport type { Dialect } from \"../url.js\";\nimport { generateMigration, makeRevisionId } from \"./codegen.js\";\nimport { renderOperation } from \"./ddl.js\";\nimport { diffSchema } from \"./diff.js\";\nimport { heads as graphHeads, topoOrder } from \"./graph.js\";\nimport { checkDriftAsync } from \"./introspect.js\";\nimport { reflectSchema } from \"./ir.js\";\nimport type { Operation } from \"./operations.js\";\nimport { type RenameCandidate, applyRenames, detectRenames } from \"./renames.js\";\nimport { replaySchema } from \"./replay.js\";\nimport { AsyncMigrationRunner, type Migration, Op } from \"./runner.js\";\n\n/** Configuration the CLI operates against. */\nexport interface CliConfig {\n /**\n * The driver for the live database — sync (SQLite) or async (PostgreSQL,\n * MySQL). Both are accepted: the CLI adapts either to the async runner, so a\n * Postgres migration runs through the same commands as a SQLite one.\n */\n readonly driver: SyncDriver | AsyncDriver;\n readonly dialect: Dialect;\n readonly migrations: readonly Migration[];\n readonly models?: readonly ModelClass[];\n /** Timestamp string stamped on applied revisions (no wall clock here). */\n readonly appliedAt?: string;\n}\n\n/** The result of a CLI run. */\nexport interface CliResult {\n readonly code: number;\n readonly lines: string[];\n}\n\n/**\n * Identity helper for authoring a typed migration config file. Gives editor\n * autocompletion and type-checking on the object the `tempest-db` bin loads.\n *\n * @example\n * ```ts\n * // tempest-db.config.mjs\n * import { defineMigrationConfig } from \"tempest-db-js/migrations\";\n * import { NodeSqliteDriver } from \"tempest-db-js\";\n * import { migrations } from \"./migrations/index.js\";\n * import { User } from \"./models.js\";\n *\n * export default defineMigrationConfig({\n * driver: NodeSqliteDriver.open(\"app.db\"),\n * dialect: \"sqlite\",\n * migrations,\n * models: [User],\n * });\n * ```\n *\n * @param config The migration config to pass through unchanged.\n * @returns The same config, typed as `CliConfig`.\n */\nexport function defineMigrationConfig(config: CliConfig): CliConfig {\n return config;\n}\n\nfunction ok(lines: string[]): CliResult {\n return { code: 0, lines };\n}\nfunction fail(lines: string[]): CliResult {\n return { code: 1, lines };\n}\n\n/**\n * Parse rename flags into explicit rename candidates.\n *\n * `--rename-table <from>:<to>` and `--rename-column <table>.<from>:<to>` may each\n * be repeated. Malformed specs are ignored (the safe drop + add stays).\n *\n * @param rest The command arguments.\n * @returns The explicitly requested renames.\n */\nfunction parseRenameFlags(rest: readonly string[]): RenameCandidate[] {\n const out: RenameCandidate[] = [];\n for (let i = 0; i < rest.length; i += 1) {\n const arg = rest[i];\n if (arg === \"--rename-table\") {\n const [from, to] = (rest[i + 1] ?? \"\").split(\":\");\n i += 1;\n if (from && to) out.push({ kind: \"table\", from, to });\n } else if (arg === \"--rename-column\") {\n const [left, to] = (rest[i + 1] ?? \"\").split(\":\");\n i += 1;\n const dot = left?.lastIndexOf(\".\") ?? -1;\n if (left && to && dot > 0) {\n out.push({\n kind: \"column\",\n table: left.slice(0, dot),\n from: left.slice(dot + 1),\n to,\n });\n }\n }\n }\n return out;\n}\n\n/** Pending migrations (DAG order) not yet applied. */\nasync function pending(\n config: CliConfig,\n runner: AsyncMigrationRunner,\n): Promise<Migration[]> {\n const done = await runner.applied();\n return topoOrder(config.migrations).filter((m) => !done.has(m.revision));\n}\n\n/**\n * Run one CLI command.\n *\n * Commands: `current`, `history`, `heads`, `upgrade [--sql]`, `downgrade [N]`,\n * `check`, `revision -m <msg> [--autogenerate]`.\n *\n * Async for every dialect: the config's driver is adapted with\n * {@link toAsyncDriver}, so SQLite and PostgreSQL take the same path and the CLI\n * is not silently SQLite-only.\n *\n * @param argv The command and its arguments (without the program name).\n * @param config The driver, migrations, and models to operate on.\n * @returns Output lines and an exit code.\n */\nexport async function runMigrationCli(\n argv: readonly string[],\n config: CliConfig,\n): Promise<CliResult> {\n const [command, ...rest] = argv;\n const driver = toAsyncDriver(config.driver);\n const runner = new AsyncMigrationRunner(driver, config.dialect);\n const appliedAt = config.appliedAt ?? \"1970-01-01T00:00:00.000Z\";\n\n switch (command) {\n case \"current\": {\n const applied = [...(await runner.applied())].sort();\n return ok(applied.length > 0 ? applied : [\"(no migrations applied)\"]);\n }\n\n case \"heads\":\n return ok(graphHeads(config.migrations));\n\n case \"history\": {\n const done = await runner.applied();\n return ok(\n topoOrder(config.migrations).map(\n (m) =>\n `${done.has(m.revision) ? \"✓\" : \"·\"} ${m.revision}${m.label ? ` — ${m.label}` : \"\"}`,\n ),\n );\n }\n\n case \"upgrade\": {\n if (rest.includes(\"--sql\")) {\n const lines: string[] = [];\n for (const migration of await pending(config, runner)) {\n const op = new Op();\n migration.up(op);\n lines.push(`-- ${migration.revision}`);\n for (const operation of op.operations) {\n for (const stmt of renderOperation(operation, config.dialect))\n lines.push(`${stmt};`);\n }\n }\n return ok(lines.length > 0 ? lines : [\"-- nothing to upgrade\"]);\n }\n const ran = await runner.upgrade(config.migrations, appliedAt);\n return ok(ran.length > 0 ? ran.map((r) => `applied ${r}`) : [\"nothing to upgrade\"]);\n }\n\n case \"downgrade\": {\n const steps = rest[0] ? Number(rest[0]) : 1;\n const reverted = await runner.downgrade(config.migrations, steps);\n return ok(\n reverted.length > 0\n ? reverted.map((r) => `reverted ${r}`)\n : [\"nothing to downgrade\"],\n );\n }\n\n case \"check\": {\n if (!config.models) return fail([\"check requires models in the config\"]);\n const drift = await checkDriftAsync(driver, config.dialect, config.models);\n // Pending model changes not yet captured by a migration.\n const undiffed = diffSchema(\n replaySchema(config.migrations),\n reflectSchema(config.models),\n );\n const issues = [\n ...drift.map((d) => `drift: ${d}`),\n ...undiffed.map((o) => `uncaptured: ${o.kind}`),\n ];\n return issues.length > 0 ? fail(issues) : ok([\"no drift; models match migrations\"]);\n }\n\n case \"revision\": {\n if (!config.models)\n return fail([\"revision --autogenerate requires models in the config\"]);\n const msgIndex = rest.indexOf(\"-m\");\n const label = msgIndex >= 0 ? (rest[msgIndex + 1] ?? \"revision\") : \"revision\";\n const parents = graphHeads(config.migrations);\n let ops: Operation[] = rest.includes(\"--autogenerate\")\n ? diffSchema(replaySchema(config.migrations), reflectSchema(config.models))\n : [];\n if (rest.includes(\"--autogenerate\")) {\n // Fold add/drop pairs into renames: `--autorename` accepts every\n // detected candidate; otherwise only the explicit `--rename-*` flags.\n const confirmed = rest.includes(\"--autorename\")\n ? detectRenames(ops)\n : parseRenameFlags(rest);\n if (confirmed.length > 0) ops = applyRenames(ops, confirmed);\n }\n const source = generateMigration({\n revision: makeRevisionId(label, parents),\n downRevision: parents,\n label,\n operations: ops,\n });\n return ok(source.split(\"\\n\"));\n }\n\n default:\n return fail([\n `unknown command ${JSON.stringify(command)}`,\n \"commands: current | history | heads | upgrade [--sql] | downgrade [N] | check | revision -m <msg> [--autogenerate]\",\n ]);\n }\n}\n","#!/usr/bin/env node\n/**\n * tempest-db-js — `tempest-db` executable.\n *\n * A thin wrapper around {@link runMigrationCli}: it discovers a config module,\n * loads it, injects a real timestamp, dispatches the command, prints the output\n * lines, and maps the result code onto `process.exit`. All the migration logic\n * lives in the (fully testable) programmatic core — this file only touches\n * `process`, the filesystem, and the wall clock.\n *\n * @example\n * ```bash\n * tempest-db upgrade\n * tempest-db revision -m \"add users\" --autogenerate\n * tempest-db --config db/tempest.config.mjs current\n * ```\n */\n\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport { pathToFileURL } from \"node:url\";\nimport { backupDatabase, restoreDatabase } from \"./backup.js\";\nimport type { CliConfig } from \"./migrations/cli.js\";\nimport { runMigrationCli } from \"./migrations/cli.js\";\nimport { diffSchema } from \"./migrations/diff.js\";\nimport { reflectSchema } from \"./migrations/ir.js\";\nimport { type RenameCandidate, detectRenames } from \"./migrations/renames.js\";\nimport { replaySchema } from \"./migrations/replay.js\";\n\n/** Config file names looked up in the current directory, in order. */\nconst DEFAULT_CONFIG_NAMES: readonly string[] = [\n \"tempest-db.config.mjs\",\n \"tempest-db.config.js\",\n \"tempest-db.config.cjs\",\n];\n\n/**\n * Pull the `--config <path>` flag out of the argv, returning the path (if any)\n * and the remaining arguments for the CLI command itself.\n *\n * @param argv The process arguments (without node + script).\n * @returns The explicit config path (or `null`) and the leftover argv.\n */\nfunction extractConfigFlag(argv: readonly string[]): {\n configPath: string | null;\n rest: string[];\n} {\n const rest: string[] = [];\n let configPath: string | null = null;\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n if (arg === \"--config\" || arg === \"-c\") {\n configPath = argv[i + 1] ?? null;\n i += 1;\n } else if (arg?.startsWith(\"--config=\")) {\n configPath = arg.slice(\"--config=\".length);\n } else if (arg !== undefined) {\n rest.push(arg);\n }\n }\n return { configPath, rest };\n}\n\n/**\n * Resolve the config file path: the explicit `--config` value, or the first of\n * the default names that exists in the current directory.\n *\n * @param explicit The `--config` value, or `null` to search defaults.\n * @returns The absolute config path, or `null` if none was found.\n */\nfunction resolveConfigPath(explicit: string | null): string | null {\n if (explicit) return resolve(process.cwd(), explicit);\n for (const name of DEFAULT_CONFIG_NAMES) {\n const candidate = resolve(process.cwd(), name);\n if (existsSync(candidate)) return candidate;\n }\n return null;\n}\n\n/**\n * Dynamically import a config module and extract the `CliConfig` from its\n * `default` export (or a named `config` export as a fallback).\n *\n * @param path The absolute path to the config module.\n * @returns The loaded migration config.\n * @throws If the module has neither a default nor a `config` export.\n */\nasync function loadConfig(path: string): Promise<CliConfig> {\n const mod = (await import(pathToFileURL(path).href)) as {\n default?: CliConfig;\n config?: CliConfig;\n };\n const config = mod.default ?? mod.config;\n if (!config) {\n throw new Error(\n `config at ${path} must default-export (or export \\`config\\`) a CliConfig`,\n );\n }\n return config;\n}\n\n/** Turn a confirmed candidate into the `--rename-*` flag args the CLI parses. */\nfunction renameToFlags(r: RenameCandidate): string[] {\n return r.kind === \"table\"\n ? [\"--rename-table\", `${r.from}:${r.to}`]\n : [\"--rename-column\", `${r.table}.${r.from}:${r.to}`];\n}\n\n/**\n * When running `revision --autogenerate` at an interactive TTY, detect rename\n * candidates and ask the user to confirm each; return the `--rename-*` flags for\n * the accepted ones. No-op when not autogenerating, when `--autorename` or\n * explicit `--rename-*` flags are already present, when there are no models, or\n * when stdin is not a TTY (CI, pipes).\n *\n * @param config The loaded migration config.\n * @param rest The CLI command arguments.\n * @returns Extra `--rename-*` args to append before dispatching.\n */\nasync function promptRenames(\n config: CliConfig,\n rest: readonly string[],\n): Promise<string[]> {\n const decided =\n rest.includes(\"--autorename\") ||\n rest.includes(\"--rename-table\") ||\n rest.includes(\"--rename-column\");\n if (\n rest[0] !== \"revision\" ||\n !rest.includes(\"--autogenerate\") ||\n decided ||\n !config.models ||\n !process.stdin.isTTY\n ) {\n return [];\n }\n\n const ops = diffSchema(replaySchema(config.migrations), reflectSchema(config.models));\n const candidates = detectRenames(ops);\n if (candidates.length === 0) return [];\n\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const flags: string[] = [];\n try {\n for (const c of candidates) {\n const what =\n c.kind === \"table\"\n ? `table \"${c.from}\" → \"${c.to}\"`\n : `column \"${c.table}.${c.from}\" → \"${c.table}.${c.to}\"`;\n const answer = (await rl.question(`Rename ${what}? [y/N] `)).trim().toLowerCase();\n if (answer === \"y\" || answer === \"yes\") flags.push(...renameToFlags(c));\n }\n } finally {\n rl.close();\n }\n return flags;\n}\n\n/**\n * Handle `backup` / `restore`, which need only a URL — not the migration config.\n *\n * Kept ahead of the config lookup on purpose: a database that cannot be migrated\n * (no config yet, or a config that fails to load) is exactly the one somebody\n * needs a dump of.\n *\n * @param argv The command and its arguments.\n * @returns True when the command was handled here.\n */\nasync function runBackupCommand(argv: readonly string[]): Promise<boolean> {\n const [command, file, ...rest] = argv;\n if (command !== \"backup\" && command !== \"restore\") return false;\n\n const urlFlag = rest.indexOf(\"--url\");\n const url =\n (urlFlag >= 0 ? rest[urlFlag + 1] : undefined) ??\n rest.find((arg) => arg.startsWith(\"--url=\"))?.slice(\"--url=\".length) ??\n process.env.DATABASE_URL;\n\n if (!file || !url) {\n process.stderr.write(\n `tempest-db: usage: tempest-db ${command} <file> --url <database-url>\\n (or set DATABASE_URL)\\n`,\n );\n process.exitCode = 1;\n return true;\n }\n\n const force = rest.includes(\"--force\");\n try {\n const result =\n command === \"backup\"\n ? await backupDatabase(url, file, { force })\n : await restoreDatabase(url, file, { force });\n process.stdout.write(\n `${command === \"backup\" ? \"backed up\" : \"restored\"} ${result.dialect} via ${result.via}: ${result.file}\\n`,\n );\n } catch (error) {\n process.stderr.write(`tempest-db: ${(error as Error).message}\\n`);\n process.exitCode = 1;\n }\n return true;\n}\n\n/**\n * Run the `tempest-db` CLI end to end: discover + load the config, dispatch the\n * command, print output, and exit with the CLI's status code.\n *\n * @param argv The process arguments (without node + script).\n * @returns A promise resolving once the command has printed and exit is set.\n */\nexport async function main(argv: readonly string[]): Promise<void> {\n const { configPath, rest } = extractConfigFlag(argv);\n if (await runBackupCommand(rest)) return;\n const resolved = resolveConfigPath(configPath);\n if (!resolved) {\n process.stderr.write(\n `tempest-db: no config found. Create one of ${DEFAULT_CONFIG_NAMES.join(\n \", \",\n )} or pass --config <path>.\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n let config: CliConfig;\n try {\n config = await loadConfig(resolved);\n } catch (error) {\n process.stderr.write(`tempest-db: ${(error as Error).message}\\n`);\n process.exitCode = 1;\n return;\n }\n\n const withClock: CliConfig = {\n ...config,\n appliedAt: config.appliedAt ?? new Date().toISOString(),\n };\n const renameFlags = await promptRenames(withClock, rest);\n const result = await runMigrationCli([...rest, ...renameFlags], withClock);\n const sink = result.code === 0 ? process.stdout : process.stderr;\n for (const line of result.lines) sink.write(`${line}\\n`);\n process.exitCode = result.code;\n}\n\n// Only auto-run when invoked as a program (not when imported by a test).\nif (import.meta.url === pathToFileURL(process.argv[1] ?? \"\").href) {\n void main(process.argv.slice(2));\n}\n"]}