tempest-db-js 0.6.0 → 0.7.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/** Keys of the model whose columns are optional on insert. */\ntype OptionalInsertKeys<I> = {\n [K in ColumnKeys<I>]: HasDefault<I[K]> extends true ? K : 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: columns with a default (or PK) are optional; the rest\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 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 /** Open a `node:sqlite` database at the given path (or `:memory:`). */\n static open(path: string): 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) => unknown;\n };\n return new NodeSqliteDriver(new DatabaseSync(path));\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/** 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\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. */\nfunction openSqliteDriver(path: string, _options?: EngineOptions): SyncDriver {\n return NodeSqliteDriver.open(path);\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?.pool),\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?.pool),\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, pool?: PoolOptions): AsyncDriver {\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 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, pool?: PoolOptions): AsyncDriver {\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, number> = {};\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 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/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"]}