@shapio/local 0.5.8 → 0.5.10

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"advisoryLocks-ajVNBhfa.js","names":["isPlainObject","encodeParameter","scopes","tableNameOf","encodeParameter","directionOf","tableNameOf","ROW_LOCKS","tableNameOf"],"sources":["../../../apps/api/src/helpers/appError.ts","../../../apps/api/src/db/mysql/codec.ts","../../../apps/api/src/db/sql/typed.ts","../../../apps/api/src/db/sql/time.ts","../../../apps/api/src/db/connectionScope.ts","../../../apps/api/src/db/mysql/tables.ts","../../../apps/api/src/db/mysql/conflicts.ts","../../../apps/api/src/db/mysql/errors.ts","../../../apps/api/src/db/mysql/planKeys.ts","../../../apps/api/src/db/mysql/insertPlan.ts","../../../apps/api/src/db/mysql/subqueries.ts","../../../apps/api/src/db/mysql/keyedWritePlans.ts","../../../apps/api/src/db/mysql/plans.ts","../../../apps/api/src/db/mysql/compiler.ts","../../../apps/api/src/db/notifyHub.ts","../../../apps/api/src/db/poolAcquire.ts","../../../apps/api/src/db/mysql/module.ts","../../../apps/api/src/db/mysql/parameters.ts","../../../apps/api/src/db/mysql/driver.ts","../../../apps/api/src/db/sql/markers.ts","../../../apps/api/src/db/mysql/insertValues.ts","../../../apps/api/src/db/mysql/nullOrdering.ts","../../../apps/api/src/db/mysql/resultDecoding.ts","../../../apps/api/src/db/mysql/plugin.ts","../../../apps/api/src/db/mysql/index.ts","../../../apps/api/src/db/sqlite/codec.ts","../../../apps/api/src/db/sqlite/errors.ts","../../../apps/api/src/db/sqlite/functions.ts","../../../apps/api/src/db/sqlite/connection.ts","../../../apps/api/src/db/sqlite/nullsNotDistinct.ts","../../../apps/api/src/db/sqlite/plugin.ts","../../../apps/api/src/db/sqlite/writeLock.ts","../../../apps/api/src/db/sqlite/driver.ts","../../../apps/api/src/db/sqlite/index.ts","../../../apps/api/src/db/advisoryLocks.ts"],"sourcesContent":["/**\n * An error with a stable machine-readable code, rendered by the central error handler as\n * `{ error: { code, message, details? } }`. Services throw these; they carry no HTTP objects.\n */\nexport class AppError extends Error {\n readonly statusCode: number;\n readonly code: string;\n readonly details: unknown;\n\n constructor(statusCode: number, code: string, message: string, details?: unknown, options?: ErrorOptions) {\n super(message, options);\n this.name = 'AppError';\n this.statusCode = statusCode;\n this.code = code;\n this.details = details;\n }\n}\n","import type { TypeCast } from 'mysql2';\n\n/**\n * The MySQL value codec (ADR 0001, \"MySQL\"). Shapio's PostgreSQL types map to MySQL like this, and rows\n * read back with the JavaScript shape `pg` gives them:\n *\n * | PostgreSQL | MySQL | read as |\n * | --------------- | --------------------------------------- | --------------------------- |\n * | uuid | CHAR(36) ascii, case-insensitive | string |\n * | text | VARCHAR(n) (keys) / LONGTEXT, 0900_bin | string |\n * | timestamptz | DATETIME(6), UTC | Date |\n * | date | DATE | `YYYY-MM-DD` string |\n * | jsonb / text[] | JSON | parsed value |\n * | boolean | TINYINT(1) | boolean |\n * | bigint | BIGINT | decimal string |\n * | integer / real | INT / FLOAT | number |\n *\n * Parameters: plain objects and arrays are bound as JSON text (mysql2 would otherwise expand an object into\n * `key = value` pairs and an array into a list), Dates as UTC `DATETIME` text, booleans as 1/0. `undefined`\n * is refused rather than written as NULL.\n */\n\n/** A parameter that cannot be bound; never silently written as NULL. */\nexport class MysqlBindError extends TypeError {\n constructor(index: number, value: unknown) {\n const kind = value === undefined ? 'undefined' : (value?.constructor?.name ?? typeof value);\n super(`Cannot bind ${kind} to MySQL parameter ${index + 1}`);\n this.name = 'MysqlBindError';\n }\n}\n\nconst pad = (value: number, width = 2) => String(value).padStart(width, '0');\n\n/** A Date as MySQL `DATETIME(6)` text in UTC (millisecond precision, the precision of a Date). */\nexport const formatDatetime = (date: Date): string =>\n `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())} ` +\n `${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}.${pad(date.getUTCMilliseconds(), 3)}`;\n\nconst ISO_UTC = /^(\\d{4}-\\d{2}-\\d{2})[T ](\\d{2}:\\d{2}:\\d{2})(?:\\.(\\d{1,6}))?(?:Z|\\+00:?00)$/;\n\n/**\n * A timestamp parameter as `DATETIME(6)` text. ISO-8601 UTC text keeps all its fractional digits (keyset\n * cursors carry microseconds); other text is parsed as a Date. Throws on an invalid time.\n */\nexport const toDatetimeText = (value: Date | string): string => {\n if (typeof value === 'string') {\n const match = ISO_UTC.exec(value);\n if (match) {\n return `${match[1]} ${match[2]}.${(match[3] ?? '').padEnd(6, '0')}`;\n }\n }\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) {\n throw new RangeError(`Invalid timestamp: ${String(value)}`);\n }\n return formatDatetime(date);\n};\n\nconst isPlainObject = (value: object): boolean => {\n const prototype = Object.getPrototypeOf(value) as unknown;\n return prototype === Object.prototype || prototype === null;\n};\n\n/** A JavaScript value as a mysql2 parameter (see the table above). */\nexport const encodeParameter = (value: unknown, index: number): unknown => {\n switch (typeof value) {\n case 'string':\n case 'number':\n case 'bigint':\n return value;\n case 'boolean':\n return value ? 1 : 0;\n case 'object':\n if (value === null || value instanceof Uint8Array) {\n return value;\n }\n if (value instanceof Date) {\n return formatDatetime(value);\n }\n if (Array.isArray(value) || isPlainObject(value)) {\n return JSON.stringify(value);\n }\n throw new MysqlBindError(index, value);\n default:\n throw new MysqlBindError(index, value);\n }\n};\n\n/**\n * Decodes result columns: `TINYINT(1)` as boolean (MySQL's boolean), `DATE` as `YYYY-MM-DD` text.\n * DATETIME (UTC Dates), JSON (parsed), BIGINT/DECIMAL (strings) are decoded by the pool options.\n */\nexport const typeCast: TypeCast = (field, next) => {\n if (field.type === 'TINY' && field.length === 1) {\n const text = field.string();\n return text === null ? null : text !== '0';\n }\n if (field.type === 'DATE') {\n return field.string();\n }\n return next();\n};\n","import { sql, type Expression, type OperationNode, type RawBuilder } from 'kysely';\nimport { isMysql, isSqlite } from '../dialect.js';\n\n/**\n * Result types for computed columns (dialect boundary, ADR 0001). PostgreSQL tells its driver the type of\n * every result column, so an aggregate or a `coalesce` over a timestamp comes back as a Date and a JSON\n * aggregate as an object. SQLite only knows the declared type of plain table columns; an expression's value\n * arrives as raw text or a number. Wrapping a selected expression in one of these markers tells the SQLite\n * driver how to decode it. MySQL types computed columns, but computes comparisons as integers, so its plugin\n * decodes a column marked `asBoolean` (and the others) too. PostgreSQL ignores them (the SQL is unchanged).\n *\n * Mark the outermost selected expression (`asJson(eb.fn.coalesce(…)).as('x')`), not an inner one. In tests\n * the SQLite driver fails on an unmarked computed column whose value looks like a stored timestamp or a JSON\n * document, so a missing marker is caught instead of returning the wrong type.\n */\nexport type ResultType = 'json' | 'timestamp' | 'boolean' | 'bigint' | 'text';\n\nconst MARKED = new WeakMap<OperationNode, ResultType>();\n\n/** The marker on a selection's expression node, if any (read by the SQLite plugin). */\nexport const markedResultType = (node: OperationNode): ResultType | undefined => MARKED.get(node);\n\nconst mark = <T>(expression: Expression<unknown>, type: ResultType): RawBuilder<T> => {\n const builder = sql<T>`${expression}`;\n if (isSqlite() || isMysql()) {\n MARKED.set(builder.toOperationNode(), type);\n }\n return builder;\n};\n\n/** A JSON document (an object or array once read; PostgreSQL json/jsonb). */\nexport const asJson = <T>(expression: Expression<unknown>): RawBuilder<T> => mark<T>(expression, 'json');\n\n/** A timestamp (a Date once read). */\nexport const asTimestamp = <T extends Date | null = Date>(expression: Expression<unknown>): RawBuilder<T> =>\n mark<T>(expression, 'timestamp');\n\n/** A boolean (`true`/`false` once read; SQLite computes 1/0). */\nexport const asBoolean = <T extends boolean | null = boolean>(\n expression: Expression<unknown>,\n): RawBuilder<T> => mark<T>(expression, 'boolean');\n\n/** A 64-bit integer (a decimal string once read, like PostgreSQL's bigint, count and sum). */\nexport const asBigint = <T extends string | null = string>(expression: Expression<unknown>): RawBuilder<T> =>\n mark<T>(expression, 'bigint');\n\n/** Text that must stay text even when it looks like a timestamp or JSON (e.g. a cursor). */\nexport const asText = <T extends string | null = string>(expression: Expression<unknown>): RawBuilder<T> =>\n mark<T>(expression, 'text');\n","import { sql, type Expression, type RawBuilder } from 'kysely';\nimport { isMysql, isSqlite } from '../dialect.js';\nimport { toDatetimeText } from '../mysql/codec.js';\nimport { asText, asTimestamp } from './typed.js';\n\n/**\n * Time primitives (dialect boundary, ADR 0001). Only SQL that creates, formats or casts a time value goes\n * through here. Comparing or sorting a timestamp column against a bound JavaScript `Date` stays plain Kysely:\n * it is portable as long as every dialect stores timestamps so that their order is time order.\n *\n * SQLite stores timestamps as fixed-width UTC ISO-8601 text with milliseconds (`toStoredTimestamp`), so text\n * order is time order. PostgreSQL keeps microseconds; SQLite's precision is the millisecond. MySQL stores\n * `DATETIME(6)` in UTC (the session time zone), microseconds like PostgreSQL.\n */\n\n/**\n * The text SQLite stores for an instant: `YYYY-MM-DDTHH:MM:SS.sssZ` (24 characters, UTC, milliseconds).\n * Every timestamp written on SQLite has exactly this form (the driver's codec, column defaults and\n * `currentTimestamp`), so comparisons between stored values and bound values are text comparisons.\n * Accepts a Date or any text `Date` parses (sub-millisecond digits are truncated). Throws on an invalid time.\n */\nexport const toStoredTimestamp = (value: Date | string): string => {\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) {\n throw new RangeError(`Invalid timestamp: ${String(value)}`);\n }\n return date.toISOString();\n};\n\n/**\n * The database server's current time.\n * PostgreSQL: `now()` (the transaction's start time). SQLite: `shapio_now()`, the transaction's start time\n * too (milliseconds). MySQL: `current_timestamp(6)`, pinned to the transaction's start by the driver.\n * Contract: a UTC instant from the database clock, constant within a transaction.\n */\nexport const currentTimestamp = (): RawBuilder<Date> => {\n if (isMysql()) {\n // The driver pins the session timestamp to the transaction's start (`SET timestamp`).\n return sql<Date>`current_timestamp(6)`;\n }\n return isSqlite() ? asTimestamp(sql`shapio_now()`) : sql<Date>`now()`;\n};\n\n/**\n * A bound value read as a timestamp (ISO-8601 text or a Date; null stays null).\n * PostgreSQL: `cast($1 as timestamptz)`. SQLite: the value normalised by `toStoredTimestamp` and bound.\n * MySQL: `cast($1 as datetime(6))` with UTC `DATETIME` text (ISO text keeps its microseconds).\n * Contract: compares and sorts against timestamp columns as an instant, at the precision the text carries\n * (microseconds from `timestampCursorText` on PostgreSQL, milliseconds on SQLite).\n */\nexport const timestampParam = (value: string | Date | null): RawBuilder<Date> => {\n if (isMysql()) {\n return sql<Date>`cast(${value === null ? null : toDatetimeText(value)} as datetime(6))`;\n }\n if (isSqlite()) {\n return sql<Date>`${value === null ? null : toStoredTimestamp(value)}`;\n }\n return sql<Date>`cast(${value} as timestamptz)`;\n};\n\n/**\n * A `YYYY-MM-DD` day as a SQL date (never a JS Date, whose time zone would shift it).\n * PostgreSQL: `$1::date`. SQLite: the bound text (dates are stored as `YYYY-MM-DD`). MySQL: `cast($1 as date)`.\n * Contract: compares against `date` columns by calendar day.\n */\nexport const dateParam = (day: string): RawBuilder<Date> => {\n if (isMysql()) {\n return sql<Date>`cast(${day} as date)`;\n }\n return isSqlite() ? sql<Date>`${day}` : sql<Date>`${day}::date`;\n};\n\n/**\n * A timestamp column as fixed-width UTC text with the full stored precision, for keyset cursors: a\n * JavaScript Date (milliseconds) would skip or repeat rows written within one PostgreSQL microsecond.\n * PostgreSQL: `to_char(col at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS.US\"Z\"')`. SQLite: the stored text\n * itself (milliseconds). Contract: the text round-trips exactly through `timestampParam`, and its order is\n * the column's order. Cursors are opaque and only valid on the instance that issued them. MySQL:\n * `date_format(col, '%Y-%m-%dT%H:%i:%s.%fZ')` (microseconds; the session is UTC).\n */\nexport const timestampCursorText = (column: string): RawBuilder<string> => {\n if (isMysql()) {\n return sql<string>`date_format(${sql.ref(column)}, '%Y-%m-%dT%H:%i:%s.%fZ')`;\n }\n return isSqlite()\n ? asText(sql`(${sql.ref(column)} || '')`)\n : sql<string>`to_char(${sql.ref(column)} at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS.US\"Z\"')`;\n};\n\n/**\n * SQLite's scalar `max` and MySQL's `greatest` return null when any argument is null: coalesce each with\n * the others first.\n */\nconst nullSkippingGreatest = <T>(fn: 'max' | 'greatest', values: readonly Expression<T>[]): RawBuilder<T> => {\n if (values.length === 1) {\n return sql<T>`${values[0]}`;\n }\n const terms = values.map(\n (value, index) => sql`coalesce(${sql.join([value, ...values.filter((_, other) => other !== index)])})`,\n );\n return sql<T>`${sql.raw(fn)}(${sql.join(terms)})`;\n};\n\n/**\n * The largest of its arguments (nulls ignored; null only when all are null).\n * PostgreSQL: `greatest(a, b, …)`. SQLite: `max(coalesce(a, b, …), coalesce(b, a, …), …)`; MySQL the same\n * with `greatest`.\n * Contract: the same null handling. Mark the result (`asTimestamp`) when it is selected.\n */\nexport const greatestOf = <T>(...values: Expression<T>[]): RawBuilder<T> => {\n if (isMysql()) {\n return nullSkippingGreatest('greatest', values);\n }\n return isSqlite() ? nullSkippingGreatest('max', values) : sql<T>`greatest(${sql.join(values)})`;\n};\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { TransactionBuilder } from 'kysely';\n\n/**\n * Nested pool acquisition (PostgreSQL and MySQL). Code inside a transaction that queries through the pool\n * (`db`) instead of the transaction (`trx`) holds one pooled connection while it waits for a second. When as\n * many requests as the pool has connections do that at once, each waits for the others forever. Strict mode\n * (tests) runs every transaction in a scope and fails such an acquisition at once with\n * `NestedPoolAcquireError`, the way SQLite fails a nested write (`db/sqlite/writeLock.ts`).\n */\ntype ConnectionScope = { acquired: boolean; parent: ConnectionScope | undefined };\n\nconst scopes = new AsyncLocalStorage<ConnectionScope>();\n\nexport class NestedPoolAcquireError extends Error {\n constructor() {\n super(\n 'A query inside an open transaction asked the pool for a second connection; under load every ' +\n 'connection waits for another. Run it on the transaction (trx) instead.',\n );\n this.name = 'NestedPoolAcquireError';\n }\n}\n\nconst holdsConnection = (scope: ConnectionScope | undefined): boolean => {\n for (let current = scope; current; current = current.parent) {\n if (current.acquired) {\n return true;\n }\n }\n return false;\n};\n\n/**\n * Called by a driver before it takes a pooled connection. The first acquisition of a scope is the\n * transaction's own connection; any later one, or one inside a scope that already holds a connection, is\n * nested.\n */\nexport const assertNotNested = (): void => {\n const scope = scopes.getStore();\n if (!scope) {\n return;\n }\n if (holdsConnection(scope)) {\n throw new NestedPoolAcquireError();\n }\n scope.acquired = true;\n};\n\n/**\n * Runs `fn` as if no transaction were open: for work that does not belong to the enclosing transaction and\n * that it never waits for (notifications published at commit, a test's independent request).\n */\nexport const outsideConnectionScope = <T>(fn: () => T): T => scopes.exit(fn);\n\n/** Runs every `execute` of a transaction builder (and of the builders it returns) in a connection scope. */\nexport const withConnectionScope = <DB>(builder: TransactionBuilder<DB>): TransactionBuilder<DB> =>\n new Proxy(builder, {\n get(target, property, receiver) {\n if (property === 'execute') {\n return <T>(callback: Parameters<TransactionBuilder<DB>['execute']>[0]) =>\n scopes.run(\n { acquired: false, parent: scopes.getStore() },\n () => target.execute(callback) as Promise<T>,\n );\n }\n if (property === 'setIsolationLevel' || property === 'setAccessMode') {\n return (value: never) => withConnectionScope(target[property](value));\n }\n return Reflect.get(target, property, receiver) as unknown;\n },\n });\n","/**\n * What the MySQL layer needs to know about Shapio's tables (ADR 0001, \"MySQL\"): primary keys, the columns\n * PostgreSQL fills by default that MySQL cannot (UUIDs are generated here, so an emulated `RETURNING` knows\n * the key; the change sequence has no column default), identity columns, unique keys by the columns a\n * conflict target names, and which columns may be NULL (for `ORDER BY` null placement).\n *\n * Generated from the migrated PostgreSQL catalog together with the MySQL baseline;\n * `test/mysqlBaseline.int.test.ts` checks it against the migrated MySQL schema.\n */\nexport type GeneratedValue = 'uuid' | 'entry_heads_change_seq';\n\nexport type UniqueKey = { name: string; columns: readonly string[] };\n\nexport type MysqlTableInfo = {\n primaryKey: readonly string[];\n /** An AUTO_INCREMENT column (PostgreSQL identity). */\n identity?: string;\n generated?: Readonly<Record<string, GeneratedValue>>;\n columns: readonly string[];\n nullable: readonly string[];\n /** `DATETIME(6)` columns (PostgreSQL timestamptz): text bound to them is normalised to UTC DATETIME text. */\n timestamps?: readonly string[];\n uniqueKeys: readonly UniqueKey[];\n};\n\nexport const MYSQL_TABLES: Readonly<Record<string, MysqlTableInfo>> = {\n admin_invitations: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'email',\n 'token_hash',\n 'invited_by',\n 'expires_at',\n 'accepted_at',\n 'revoked_at',\n 'created_at',\n 'updated_at',\n 'role_assignments',\n ],\n nullable: ['token_hash', 'invited_by', 'accepted_at', 'revoked_at'],\n timestamps: ['expires_at', 'accepted_at', 'revoked_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'admin_invitations_pkey', columns: ['id'] },\n { name: 'admin_invitations_token_hash_key', columns: ['token_hash'] },\n ],\n },\n admin_role_permissions: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'role_id', 'action', 'model_id', 'condition', 'field_ids', 'created_at', 'updated_at'],\n nullable: ['model_id', 'condition', 'field_ids'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'admin_role_permissions_grant_uq', columns: ['role_id', 'action', 'model_id'] },\n { name: 'admin_role_permissions_pkey', columns: ['id'] },\n ],\n },\n admin_roles: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'key', 'name', 'description', 'kind', 'is_system', 'version', 'created_at', 'updated_at'],\n nullable: [],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'admin_roles_key_key', columns: ['key'] },\n { name: 'admin_roles_pkey', columns: ['id'] },\n ],\n },\n admin_sessions: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'admin_user_id',\n 'token_hash',\n 'csrf_secret',\n 'ip',\n 'user_agent',\n 'last_seen_at',\n 'expires_at',\n 'revoked_at',\n 'rotation_required',\n 'created_at',\n 'updated_at',\n ],\n nullable: ['ip', 'user_agent', 'revoked_at'],\n timestamps: ['last_seen_at', 'expires_at', 'revoked_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'admin_sessions_pkey', columns: ['id'] },\n { name: 'admin_sessions_token_hash_key', columns: ['token_hash'] },\n ],\n },\n admin_user_roles: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['admin_user_id', 'role_id', 'created_at', 'updated_at', 'site_id', 'id'],\n nullable: ['site_id'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'admin_user_roles_assignment_uq', columns: ['admin_user_id', 'role_id', 'site_id'] },\n { name: 'admin_user_roles_pk', columns: ['id'] },\n ],\n },\n admin_users: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'email',\n 'name',\n 'password_hash',\n 'status',\n 'last_login_at',\n 'password_changed_at',\n 'created_at',\n 'updated_at',\n ],\n nullable: ['last_login_at'],\n timestamps: ['last_login_at', 'password_changed_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'admin_users_email_key', columns: ['email'] },\n { name: 'admin_users_pkey', columns: ['id'] },\n ],\n },\n api_tokens: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'name',\n 'token_hash',\n 'token_prefix',\n 'role_id',\n 'created_by',\n 'expires_at',\n 'last_used_at',\n 'revoked_at',\n 'created_at',\n 'updated_at',\n 'site_id',\n ],\n nullable: ['created_by', 'expires_at', 'last_used_at', 'revoked_at', 'site_id'],\n timestamps: ['expires_at', 'last_used_at', 'revoked_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'api_tokens_pkey', columns: ['id'] },\n { name: 'api_tokens_token_hash_key', columns: ['token_hash'] },\n ],\n },\n app_login_codes: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'app_user_id', 'code_hash', 'expires_at', 'used_at', 'created_at', 'code_challenge'],\n nullable: ['used_at'],\n timestamps: ['expires_at', 'used_at', 'created_at'],\n uniqueKeys: [\n { name: 'app_login_codes_code_hash_key', columns: ['code_hash'] },\n { name: 'app_login_codes_pkey', columns: ['id'] },\n ],\n },\n app_oauth_accounts: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'app_user_id',\n 'provider',\n 'provider_user_id',\n 'email',\n 'created_at',\n 'updated_at',\n 'site_id',\n ],\n nullable: ['email'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'app_oauth_accounts_identity_uq', columns: ['site_id', 'provider', 'provider_user_id'] },\n { name: 'app_oauth_accounts_pkey', columns: ['id'] },\n ],\n },\n app_password_resets: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'app_user_id',\n 'email',\n 'token_hash',\n 'expires_at',\n 'used_at',\n 'created_at',\n 'updated_at',\n ],\n nullable: ['token_hash', 'used_at'],\n timestamps: ['expires_at', 'used_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'app_password_resets_pkey', columns: ['id'] },\n { name: 'app_password_resets_token_hash_key', columns: ['token_hash'] },\n ],\n },\n app_refresh_tokens: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'app_user_id',\n 'family_id',\n 'token_hash',\n 'expires_at',\n 'used_at',\n 'reuse_grace_used_at',\n 'revoked_at',\n 'revoked_reason',\n 'ip',\n 'user_agent',\n 'created_at',\n ],\n nullable: ['used_at', 'reuse_grace_used_at', 'revoked_at', 'revoked_reason', 'ip', 'user_agent'],\n timestamps: ['expires_at', 'used_at', 'reuse_grace_used_at', 'revoked_at', 'created_at'],\n uniqueKeys: [\n { name: 'app_refresh_tokens_pkey', columns: ['id'] },\n { name: 'app_refresh_tokens_token_hash_key', columns: ['token_hash'] },\n ],\n },\n app_role_permissions: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'role_id', 'action', 'model_id', 'condition', 'field_ids', 'created_at', 'updated_at'],\n nullable: ['model_id', 'condition', 'field_ids'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'app_role_permissions_grant_uq', columns: ['role_id', 'action', 'model_id'] },\n { name: 'app_role_permissions_pkey', columns: ['id'] },\n ],\n },\n app_roles: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'key', 'name', 'description', 'is_system', 'version', 'created_at', 'updated_at'],\n nullable: [],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'app_roles_key_key', columns: ['key'] },\n { name: 'app_roles_pkey', columns: ['id'] },\n ],\n },\n app_user_roles: {\n primaryKey: ['app_user_id', 'role_id'],\n columns: ['app_user_id', 'role_id', 'created_at', 'site_id'],\n nullable: [],\n timestamps: ['created_at'],\n uniqueKeys: [{ name: 'app_user_roles_pk', columns: ['app_user_id', 'role_id'] }],\n },\n app_users: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'email',\n 'name',\n 'password_hash',\n 'confirmed_at',\n 'blocked_at',\n 'last_login_at',\n 'password_changed_at',\n 'deleted_at',\n 'created_at',\n 'updated_at',\n 'token_version',\n 'site_id',\n ],\n nullable: [\n 'password_hash',\n 'confirmed_at',\n 'blocked_at',\n 'last_login_at',\n 'password_changed_at',\n 'deleted_at',\n ],\n timestamps: [\n 'confirmed_at',\n 'blocked_at',\n 'last_login_at',\n 'password_changed_at',\n 'deleted_at',\n 'created_at',\n 'updated_at',\n ],\n uniqueKeys: [\n { name: 'app_users_email_uq', columns: ['site_id', 'email'] },\n { name: 'app_users_pkey', columns: ['id'] },\n ],\n },\n assist_runs: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'site_id',\n 'actor_type',\n 'actor_id',\n 'action',\n 'rule',\n 'provider',\n 'model',\n 'input_tokens',\n 'output_tokens',\n 'duration_ms',\n 'status',\n 'error_code',\n 'job_id',\n 'created_at',\n 'finished_at',\n ],\n nullable: ['rule', 'error_code', 'job_id', 'finished_at'],\n timestamps: ['created_at', 'finished_at'],\n uniqueKeys: [{ name: 'assist_runs_pkey', columns: ['id'] }],\n },\n audit_events: {\n primaryKey: ['id'],\n identity: 'seq',\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'occurred_at',\n 'actor_type',\n 'actor_id',\n 'action',\n 'target_type',\n 'target_id',\n 'outcome',\n 'request_id',\n 'ip',\n 'metadata',\n 'site_id',\n 'seq',\n ],\n nullable: ['actor_id', 'target_type', 'target_id', 'request_id', 'ip', 'site_id'],\n timestamps: ['occurred_at'],\n uniqueKeys: [\n { name: 'audit_events_pkey', columns: ['id'] },\n { name: 'audit_events_seq_key', columns: ['seq'] },\n ],\n },\n change_set_items: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'change_set_id',\n 'kind',\n 'position',\n 'entry_id',\n 'model_id',\n 'locale',\n 'action',\n 'source_revision_id',\n 'schema_draft_id',\n 'status',\n 'error',\n 'ship_state',\n 'created_at',\n 'site_id',\n ],\n nullable: [\n 'entry_id',\n 'model_id',\n 'locale',\n 'action',\n 'source_revision_id',\n 'schema_draft_id',\n 'error',\n 'ship_state',\n ],\n timestamps: ['created_at'],\n uniqueKeys: [\n { name: 'change_set_items_draft_uq', columns: ['schema_draft_id'] },\n { name: 'change_set_items_entry_uq', columns: ['change_set_id', 'entry_id', 'locale'] },\n { name: 'change_set_items_pkey', columns: ['id'] },\n ],\n },\n change_sets: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'title',\n 'description',\n 'status',\n 'ship_phase',\n 'source',\n 'restore_of_seq',\n 'scheduled_for',\n 'schedule_job_id',\n 'scheduled_by',\n 'scheduled_by_token',\n 'ship_job_id',\n 'ship_mode',\n 'ship_requested_by',\n 'ship_requested_by_token',\n 'acknowledge_breaking',\n 'acknowledge_destructive',\n 'deployment_connection_id',\n 'deployment_run_id',\n 'shipped_at',\n 'shipped_seq',\n 'schema_version_after',\n 'error',\n 'restore_report',\n 'created_by',\n 'created_by_token',\n 'version',\n 'created_at',\n 'updated_at',\n 'site_id',\n ],\n nullable: [\n 'ship_phase',\n 'restore_of_seq',\n 'scheduled_for',\n 'schedule_job_id',\n 'scheduled_by',\n 'scheduled_by_token',\n 'ship_job_id',\n 'ship_mode',\n 'ship_requested_by',\n 'ship_requested_by_token',\n 'deployment_connection_id',\n 'deployment_run_id',\n 'shipped_at',\n 'shipped_seq',\n 'schema_version_after',\n 'error',\n 'created_by',\n 'created_by_token',\n ],\n timestamps: ['scheduled_for', 'shipped_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'change_sets_id_site_uq', columns: ['id', 'site_id'] },\n { name: 'change_sets_pkey', columns: ['id'] },\n ],\n },\n content_health_findings: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'entry_id',\n 'model_id',\n 'locale',\n 'rule',\n 'subject',\n 'severity',\n 'path',\n 'details',\n 'first_seen_at',\n 'last_seen_at',\n 'resolved_at',\n 'site_id',\n ],\n nullable: ['path', 'resolved_at'],\n timestamps: ['first_seen_at', 'last_seen_at', 'resolved_at'],\n uniqueKeys: [\n {\n name: 'content_health_findings_entry_id_locale_rule_subject_key',\n columns: ['entry_id', 'locale', 'rule', 'subject'],\n },\n { name: 'content_health_findings_pkey', columns: ['id'] },\n ],\n },\n content_revisions: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'entry_id',\n 'locale',\n 'schema_revision_id',\n 'data',\n 'reason',\n 'author_type',\n 'author_id',\n 'parent_revision_id',\n 'created_at',\n ],\n nullable: ['author_id', 'parent_revision_id'],\n timestamps: ['created_at'],\n uniqueKeys: [{ name: 'content_revisions_pkey', columns: ['id'] }],\n },\n deployment_connections: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'name',\n 'provider',\n 'settings',\n 'secrets_encrypted',\n 'secret_env_refs',\n 'delivery_role_id',\n 'preview_url_template',\n 'trigger_policy',\n 'debounce_seconds',\n 'allow_private_network',\n 'enabled',\n 'version',\n 'created_by',\n 'created_at',\n 'updated_at',\n 'site_id',\n ],\n nullable: ['delivery_role_id', 'preview_url_template', 'created_by'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [{ name: 'deployment_connections_pkey', columns: ['id'] }],\n },\n deployment_runs: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'connection_id',\n 'status',\n 'status_rank',\n 'trigger',\n 'snapshot_seq',\n 'schema_version',\n 'retry_of',\n 'provider_ref',\n 'log_url',\n 'site_url',\n 'error',\n 'timeline',\n 'job_id',\n 'triggered_at',\n 'finished_at',\n 'created_by',\n 'created_at',\n 'updated_at',\n 'change_set_id',\n ],\n nullable: [\n 'snapshot_seq',\n 'schema_version',\n 'retry_of',\n 'provider_ref',\n 'log_url',\n 'site_url',\n 'error',\n 'job_id',\n 'triggered_at',\n 'finished_at',\n 'created_by',\n 'change_set_id',\n ],\n timestamps: ['triggered_at', 'finished_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'deployment_runs_pkey', columns: ['id'] },\n { name: 'deployment_runs_queued_uq', columns: ['connection_id'] },\n ],\n },\n editor_presence: {\n primaryKey: ['entry_id', 'admin_user_id', 'tab_id'],\n columns: ['entry_id', 'model_id', 'admin_user_id', 'tab_id', 'locale', 'started_at', 'last_seen_at'],\n nullable: ['locale'],\n timestamps: ['started_at', 'last_seen_at'],\n uniqueKeys: [{ name: 'editor_presence_pkey', columns: ['entry_id', 'admin_user_id', 'tab_id'] }],\n },\n email_confirmations: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'app_user_id',\n 'email',\n 'token_hash',\n 'expires_at',\n 'used_at',\n 'created_at',\n 'updated_at',\n ],\n nullable: ['token_hash', 'used_at'],\n timestamps: ['expires_at', 'used_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'email_confirmations_pkey', columns: ['id'] },\n { name: 'email_confirmations_token_hash_key', columns: ['token_hash'] },\n ],\n },\n entries: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'model_id',\n 'owner_app_user_id',\n 'created_by_admin_id',\n 'created_at',\n 'updated_at',\n 'deleted_at',\n 'site_id',\n ],\n nullable: ['owner_app_user_id', 'created_by_admin_id', 'deleted_at'],\n timestamps: ['created_at', 'updated_at', 'deleted_at'],\n uniqueKeys: [\n { name: 'entries_id_site_uq', columns: ['id', 'site_id'] },\n { name: 'entries_pkey', columns: ['id'] },\n ],\n },\n entry_heads: {\n primaryKey: ['entry_id', 'locale', 'state'],\n generated: { change_seq: 'entry_heads_change_seq' },\n columns: [\n 'entry_id',\n 'model_id',\n 'locale',\n 'state',\n 'revision_id',\n 'data',\n 'autosaved_at',\n 'version',\n 'change_seq',\n 'created_at',\n 'updated_at',\n 'site_id',\n 'entry_created_at',\n ],\n nullable: ['autosaved_at', 'entry_created_at'],\n timestamps: ['autosaved_at', 'created_at', 'updated_at', 'entry_created_at'],\n uniqueKeys: [{ name: 'entry_heads_pkey', columns: ['entry_id', 'locale', 'state'] }],\n },\n extension_hook_runs: {\n primaryKey: ['event_id', 'hook'],\n columns: ['event_id', 'hook', 'job_id', 'completed_at'],\n nullable: ['job_id'],\n timestamps: ['completed_at'],\n uniqueKeys: [{ name: 'extension_hook_runs_pkey', columns: ['event_id', 'hook'] }],\n },\n field_reads: {\n primaryKey: ['day', 'site_id', 'model_id', 'field_path', 'principal_key', 'selection'],\n columns: [\n 'day',\n 'model_id',\n 'field_path',\n 'principal_key',\n 'selection',\n 'reads',\n 'last_read_at',\n 'site_id',\n ],\n nullable: [],\n timestamps: ['last_read_at'],\n uniqueKeys: [\n {\n name: 'field_reads_pkey',\n columns: ['day', 'site_id', 'model_id', 'field_path', 'principal_key', 'selection'],\n },\n ],\n },\n jobs: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'type',\n 'payload',\n 'status',\n 'priority',\n 'run_at',\n 'attempts',\n 'max_attempts',\n 'idempotency_key',\n 'locked_by',\n 'locked_until',\n 'checkpoint',\n 'result',\n 'last_error',\n 'created_at',\n 'updated_at',\n 'finished_at',\n ],\n nullable: [\n 'idempotency_key',\n 'locked_by',\n 'locked_until',\n 'checkpoint',\n 'result',\n 'last_error',\n 'finished_at',\n ],\n timestamps: ['run_at', 'locked_until', 'created_at', 'updated_at', 'finished_at'],\n uniqueKeys: [\n { name: 'jobs_idempotency_key_uq', columns: ['idempotency_key'] },\n { name: 'jobs_pkey', columns: ['id'] },\n ],\n },\n locales: {\n primaryKey: ['code'],\n columns: ['code', 'label', 'is_default', 'fallbacks', 'created_at', 'updated_at'],\n nullable: [],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'locales_pkey', columns: ['code'] },\n { name: 'locales_single_default_uq', columns: ['is_default'] },\n ],\n },\n media_assets: {\n primaryKey: ['id'],\n columns: [\n 'id',\n 'folder_id',\n 'storage_driver',\n 'storage_key',\n 'original_filename',\n 'mime_type',\n 'size_bytes',\n 'width',\n 'height',\n 'checksum_sha256',\n 'alt',\n 'caption',\n 'focal_x',\n 'focal_y',\n 'visibility',\n 'status',\n 'processing_error',\n 'created_by',\n 'version',\n 'deleted_at',\n 'created_at',\n 'updated_at',\n 'site_id',\n ],\n nullable: [\n 'folder_id',\n 'width',\n 'height',\n 'checksum_sha256',\n 'focal_x',\n 'focal_y',\n 'processing_error',\n 'created_by',\n 'deleted_at',\n ],\n timestamps: ['deleted_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'media_assets_pkey', columns: ['id'] },\n { name: 'media_assets_storage_key_uq', columns: ['storage_key'] },\n ],\n },\n media_folders: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'parent_id', 'name', 'created_by', 'version', 'created_at', 'updated_at', 'site_id'],\n nullable: ['parent_id', 'created_by'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'media_folders_id_site_uq', columns: ['id', 'site_id'] },\n { name: 'media_folders_pkey', columns: ['id'] },\n { name: 'media_folders_sibling_name_uq', columns: ['site_id', 'parent_id', 'name'] },\n ],\n },\n media_references: {\n primaryKey: ['asset_id', 'entry_id', 'locale', 'state', 'field_id'],\n columns: ['asset_id', 'entry_id', 'model_id', 'field_id', 'locale', 'state', 'created_at'],\n nullable: [],\n timestamps: ['created_at'],\n uniqueKeys: [\n { name: 'media_references_pk', columns: ['asset_id', 'entry_id', 'locale', 'state', 'field_id'] },\n ],\n },\n media_upload_grants: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'asset_id',\n 'kind',\n 'storage_driver',\n 'storage_key',\n 'original_filename',\n 'declared_mime_type',\n 'max_size_bytes',\n 'folder_id',\n 'visibility',\n 'created_by',\n 'created_by_principal',\n 'status',\n 'expires_at',\n 'consumed_at',\n 'created_at',\n 'site_id',\n ],\n nullable: ['folder_id', 'created_by', 'consumed_at'],\n timestamps: ['expires_at', 'consumed_at', 'created_at'],\n uniqueKeys: [\n { name: 'media_upload_grants_pkey', columns: ['id'] },\n { name: 'media_upload_grants_storage_key_key', columns: ['storage_key'] },\n ],\n },\n media_variants: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'asset_id',\n 'name',\n 'width',\n 'height',\n 'format',\n 'mime_type',\n 'storage_key',\n 'size_bytes',\n 'checksum_sha256',\n 'status',\n 'error',\n 'created_at',\n 'updated_at',\n ],\n nullable: ['width', 'height', 'storage_key', 'size_bytes', 'checksum_sha256', 'error'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'media_variants_asset_name_uq', columns: ['asset_id', 'name'] },\n { name: 'media_variants_pkey', columns: ['id'] },\n { name: 'media_variants_storage_key_uq', columns: ['storage_key'] },\n ],\n },\n model_active_versions: {\n primaryKey: ['model_id'],\n columns: ['model_id', 'revision_id', 'version', 'schema_version', 'activated_at'],\n nullable: [],\n timestamps: ['activated_at'],\n uniqueKeys: [{ name: 'model_active_versions_pkey', columns: ['model_id'] }],\n },\n models: {\n primaryKey: ['id'],\n columns: ['id', 'kind', 'api_key', 'created_at', 'updated_at', 'deleted_at', 'site_id'],\n nullable: ['deleted_at', 'site_id'],\n timestamps: ['created_at', 'updated_at', 'deleted_at'],\n uniqueKeys: [\n { name: 'models_api_key_uq', columns: ['site_id', 'api_key'] },\n { name: 'models_pkey', columns: ['id'] },\n ],\n },\n outbox_events: {\n primaryKey: ['id'],\n identity: 'id',\n generated: { event_id: 'uuid' },\n columns: [\n 'id',\n 'event_id',\n 'type',\n 'aggregate_type',\n 'aggregate_id',\n 'payload',\n 'created_at',\n 'dispatched_at',\n 'dispatch_attempts',\n 'last_dispatch_error',\n 'site_id',\n ],\n nullable: ['dispatched_at', 'last_dispatch_error', 'site_id'],\n timestamps: ['created_at', 'dispatched_at'],\n uniqueKeys: [\n { name: 'outbox_events_event_id_key', columns: ['event_id'] },\n { name: 'outbox_events_pkey', columns: ['id'] },\n ],\n },\n password_resets: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'admin_user_id', 'token_hash', 'expires_at', 'used_at', 'created_at', 'updated_at'],\n nullable: ['token_hash', 'used_at'],\n timestamps: ['expires_at', 'used_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'password_resets_pkey', columns: ['id'] },\n { name: 'password_resets_token_hash_key', columns: ['token_hash'] },\n ],\n },\n preview_tokens: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'token_hash',\n 'token_prefix',\n 'model_id',\n 'entry_id',\n 'locale',\n 'connection_id',\n 'delivery_role_id',\n 'created_by',\n 'expires_at',\n 'revoked_at',\n 'last_used_at',\n 'created_at',\n 'site_id',\n ],\n nullable: ['locale', 'connection_id', 'delivery_role_id', 'revoked_at', 'last_used_at'],\n timestamps: ['expires_at', 'revoked_at', 'last_used_at', 'created_at'],\n uniqueKeys: [\n { name: 'preview_tokens_pkey', columns: ['id'] },\n { name: 'preview_tokens_token_hash_key', columns: ['token_hash'] },\n ],\n },\n publication_log: {\n primaryKey: ['id'],\n identity: 'id',\n columns: [\n 'id',\n 'entry_id',\n 'model_id',\n 'locale',\n 'revision_id',\n 'from_seq',\n 'to_seq',\n 'published_at',\n 'site_id',\n ],\n nullable: ['to_seq'],\n timestamps: ['published_at'],\n uniqueKeys: [\n { name: 'publication_log_open_uq', columns: ['entry_id', 'locale'] },\n { name: 'publication_log_pkey', columns: ['id'] },\n ],\n },\n publication_snapshots: {\n primaryKey: ['site_id', 'seq'],\n columns: [\n 'seq',\n 'schema_version',\n 'source',\n 'change_set_id',\n 'actor_type',\n 'actor_id',\n 'created_at',\n 'site_id',\n ],\n nullable: ['schema_version', 'change_set_id', 'actor_type', 'actor_id'],\n timestamps: ['created_at'],\n uniqueKeys: [{ name: 'publication_snapshots_pkey', columns: ['site_id', 'seq'] }],\n },\n publication_state: {\n primaryKey: ['site_id'],\n columns: ['last_seq', 'site_id'],\n nullable: [],\n uniqueKeys: [{ name: 'publication_state_pkey', columns: ['site_id'] }],\n },\n relation_edges: {\n primaryKey: ['source_entry_id', 'locale', 'state', 'field_id', 'position'],\n columns: ['source_entry_id', 'locale', 'state', 'field_id', 'position', 'target_entry_id'],\n nullable: [],\n uniqueKeys: [\n {\n name: 'relation_edges_pkey',\n columns: ['source_entry_id', 'locale', 'state', 'field_id', 'position'],\n },\n ],\n },\n scheduled_publications: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'entry_id',\n 'model_id',\n 'locale',\n 'action',\n 'run_at',\n 'status',\n 'created_by_token',\n 'job_id',\n 'snapshot_seq',\n 'error',\n 'executed_at',\n 'created_by',\n 'created_at',\n 'updated_at',\n 'site_id',\n ],\n nullable: ['created_by_token', 'job_id', 'snapshot_seq', 'error', 'executed_at', 'created_by'],\n timestamps: ['run_at', 'executed_at', 'created_at', 'updated_at'],\n uniqueKeys: [{ name: 'scheduled_publications_pkey', columns: ['id'] }],\n },\n schema_change_jobs: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'target_type',\n 'target_id',\n 'model_id',\n 'from_revision_id',\n 'to_revision_id',\n 'status',\n 'plan',\n 'job_id',\n 'error',\n 'requested_by_type',\n 'requested_by_id',\n 'created_at',\n 'updated_at',\n 'finished_at',\n 'change_set_id',\n ],\n nullable: [\n 'model_id',\n 'from_revision_id',\n 'to_revision_id',\n 'job_id',\n 'error',\n 'requested_by_id',\n 'finished_at',\n 'change_set_id',\n ],\n timestamps: ['created_at', 'updated_at', 'finished_at'],\n uniqueKeys: [\n { name: 'schema_change_jobs_in_flight_uq', columns: ['target_type', 'target_id'] },\n { name: 'schema_change_jobs_pkey', columns: ['id'] },\n ],\n },\n schema_drafts: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'change_set_id',\n 'definition_id',\n 'kind',\n 'api_key',\n 'base_version',\n 'definition',\n 'version',\n 'updated_by_type',\n 'updated_by_id',\n 'created_at',\n 'updated_at',\n 'shared',\n ],\n nullable: ['base_version', 'definition', 'updated_by_id'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'schema_drafts_pkey', columns: ['id'] },\n { name: 'schema_drafts_set_definition_uq', columns: ['change_set_id', 'definition_id'] },\n ],\n },\n schema_revisions: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'model_id',\n 'version',\n 'definition',\n 'hash',\n 'parent_revision_id',\n 'created_by_type',\n 'created_by_id',\n 'created_at',\n ],\n nullable: ['parent_revision_id', 'created_by_id'],\n timestamps: ['created_at'],\n uniqueKeys: [\n { name: 'schema_revisions_model_version_uq', columns: ['model_id', 'version'] },\n { name: 'schema_revisions_pkey', columns: ['id'] },\n ],\n },\n schema_settings: {\n primaryKey: ['id'],\n columns: ['id', 'read_only', 'read_only_reason', 'updated_by_type', 'updated_by_id', 'updated_at'],\n nullable: ['read_only_reason', 'updated_by_type', 'updated_by_id'],\n timestamps: ['updated_at'],\n uniqueKeys: [{ name: 'schema_settings_pkey', columns: ['id'] }],\n },\n setup_tokens: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'token_hash', 'used_at', 'superseded_at', 'created_at', 'updated_at'],\n nullable: ['used_at', 'superseded_at'],\n timestamps: ['used_at', 'superseded_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'setup_tokens_pkey', columns: ['id'] },\n { name: 'setup_tokens_token_hash_key', columns: ['token_hash'] },\n ],\n },\n site_app_roles: {\n primaryKey: ['site_id', 'audience', 'role_id'],\n columns: ['site_id', 'audience', 'role_id', 'created_at'],\n nullable: [],\n timestamps: ['created_at'],\n uniqueKeys: [{ name: 'site_app_roles_pkey', columns: ['site_id', 'audience', 'role_id'] }],\n },\n sites: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: ['id', 'key', 'name', 'is_primary', 'version', 'created_at', 'updated_at', 'seo_defaults'],\n nullable: ['seo_defaults'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'sites_key_key', columns: ['key'] },\n { name: 'sites_pkey', columns: ['id'] },\n { name: 'sites_single_primary_uq', columns: ['is_primary'] },\n ],\n },\n system_settings: {\n primaryKey: ['key'],\n columns: ['key', 'value', 'updated_at'],\n nullable: [],\n timestamps: ['updated_at'],\n uniqueKeys: [{ name: 'system_settings_pkey', columns: ['key'] }],\n },\n system_versions: {\n primaryKey: ['id'],\n columns: ['id', 'schema_version', 'permissions_version', 'updated_at', 'release'],\n nullable: ['release'],\n timestamps: ['updated_at'],\n uniqueKeys: [{ name: 'system_versions_pkey', columns: ['id'] }],\n },\n token_reads: {\n primaryKey: ['day', 'site_id', 'principal_key'],\n columns: ['day', 'principal_key', 'requests', 'last_snapshot', 'last_read_at', 'site_id'],\n nullable: ['last_snapshot'],\n timestamps: ['last_read_at'],\n uniqueKeys: [{ name: 'token_reads_pkey', columns: ['day', 'site_id', 'principal_key'] }],\n },\n unique_values: {\n primaryKey: ['site_id', 'field_id', 'locale', 'state', 'value_hash'],\n columns: ['field_id', 'locale', 'state', 'value_hash', 'entry_id', 'model_id', 'site_id'],\n nullable: [],\n uniqueKeys: [\n { name: 'unique_values_pkey', columns: ['site_id', 'field_id', 'locale', 'state', 'value_hash'] },\n ],\n },\n webhook_deliveries: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'webhook_id',\n 'event_id',\n 'event_type',\n 'payload',\n 'is_test',\n 'status',\n 'attempts',\n 'last_response_status',\n 'last_error',\n 'attempt_log',\n 'job_id',\n 'delivered_at',\n 'created_at',\n 'updated_at',\n ],\n nullable: ['event_id', 'last_response_status', 'last_error', 'job_id', 'delivered_at'],\n timestamps: ['delivered_at', 'created_at', 'updated_at'],\n uniqueKeys: [\n { name: 'webhook_deliveries_event_uq', columns: ['webhook_id', 'event_id'] },\n { name: 'webhook_deliveries_pkey', columns: ['id'] },\n ],\n },\n webhooks: {\n primaryKey: ['id'],\n generated: { id: 'uuid' },\n columns: [\n 'id',\n 'name',\n 'url',\n 'events',\n 'enabled',\n 'secret_encrypted',\n 'allow_private_network',\n 'max_attempts',\n 'version',\n 'created_by',\n 'created_at',\n 'updated_at',\n 'site_id',\n ],\n nullable: ['created_by', 'site_id'],\n timestamps: ['created_at', 'updated_at'],\n uniqueKeys: [{ name: 'webhooks_pkey', columns: ['id'] }],\n },\n advisory_locks: {\n primaryKey: ['namespace', 'lock_key'],\n columns: ['namespace', 'lock_key'],\n nullable: [],\n uniqueKeys: [{ name: 'advisory_locks_pkey', columns: ['namespace', 'lock_key'] }],\n },\n notifications: {\n primaryKey: ['id'],\n identity: 'id',\n columns: ['id', 'channel', 'payload', 'created_at'],\n nullable: [],\n timestamps: ['created_at'],\n uniqueKeys: [{ name: 'notifications_pkey', columns: ['id'] }],\n },\n sequence_entry_heads_change_seq: {\n primaryKey: ['value'],\n identity: 'value',\n columns: ['value'],\n nullable: [],\n uniqueKeys: [{ name: 'sequence_entry_heads_change_seq_pkey', columns: ['value'] }],\n },\n};\n\n/** The table's metadata, or undefined for a table Shapio does not own (tests' own tables). */\nexport const tableInfo = (table: string): MysqlTableInfo | undefined => MYSQL_TABLES[table];\n","import {\n ColumnNode,\n ColumnUpdateNode,\n OnDuplicateKeyNode,\n ReferenceNode,\n TableNode,\n ValuesNode,\n type InsertQueryNode,\n type OnConflictNode,\n} from 'kysely';\nimport { tableInfo } from './tables.js';\n\n/** The alias the compiler gives the inserted row in `ON DUPLICATE KEY UPDATE` (PostgreSQL's `excluded`). */\nexport const EXCLUDED_ALIAS = 'excluded';\n\nexport const sameColumns = (a: readonly string[], b: readonly string[]) =>\n a.length === b.length && a.every((column) => b.includes(column));\n\n/**\n * Whether `ON DUPLICATE KEY` (which fires on any unique key) behaves like `ON CONFLICT (target)` for this\n * insert: every other unique key of the table is made of columns generated for this insert (fresh UUIDs),\n * so it cannot collide. An untargeted conflict (`ON CONFLICT DO NOTHING`) matches any key, like MySQL.\n */\nexport const duplicateKeyMatchesTarget = (\n table: string,\n target: readonly string[] | undefined,\n supplied: readonly string[],\n): boolean => {\n const info = tableInfo(table);\n if (!info) {\n return false;\n }\n if (target === undefined) {\n return true;\n }\n const generated = info.generated ?? {};\n return info.uniqueKeys.every(\n (key) =>\n sameColumns(key.columns, target) ||\n key.columns.every((column) => generated[column] === 'uuid' && !supplied.includes(column)),\n );\n};\n\n/**\n * Tables whose rows a trigger keeps immutable (the baseline's `*_no_update` triggers): a no-op\n * `ON DUPLICATE KEY UPDATE` is still an UPDATE there, so their `DO NOTHING` goes through the plan.\n */\nconst REFUSES_UPDATES: ReadonlySet<string> = new Set(['content_revisions', 'schema_revisions']);\n\nconst targetOf = (conflict: OnConflictNode): readonly string[] | undefined =>\n conflict.columns?.map((column) => column.column.name);\n\n/**\n * `ON CONFLICT … DO UPDATE` as `ON DUPLICATE KEY UPDATE`, and `ON CONFLICT … DO NOTHING` without RETURNING\n * as `ON DUPLICATE KEY UPDATE <key> = <key>` (a no-op), when MySQL's any-key behaviour equals the target's\n * (`duplicateKeyMatchesTarget`). Any other conflict clause (another unique key could fire, a `WHERE` on the\n * update, RETURNING) is left for the compiler's plan: each row inserted under a savepoint, and a duplicate\n * on the target either skipped or turned into an UPDATE of the row it found.\n */\nexport const toOnDuplicateKey = (\n node: InsertQueryNode,\n conflict: OnConflictNode,\n table: string,\n): InsertQueryNode => {\n const target = targetOf(conflict);\n const supplied = node.columns?.map((column) => column.column.name) ?? [];\n const matches = duplicateKeyMatchesTarget(table, target, supplied);\n if (conflict.doNothing) {\n if (node.returning || !matches || REFUSES_UPDATES.has(table)) {\n return node;\n }\n const column = target?.[0] ?? tableInfo(table)!.primaryKey[0]!;\n // Qualified: the `excluded` row alias has the same column names.\n const self = ReferenceNode.create(ColumnNode.create(column), TableNode.create(table));\n return Object.freeze({\n ...node,\n onConflict: undefined,\n onDuplicateKey: OnDuplicateKeyNode.create([ColumnUpdateNode.create(ColumnNode.create(column), self)]),\n });\n }\n if (conflict.constraint || conflict.indexExpression) {\n throw new Error(`MySQL: ON CONFLICT on ${table} needs a column target`);\n }\n if (conflict.updateWhere || !matches || node.returning || !node.values || !ValuesNode.is(node.values)) {\n // The statement plan runs it row by row: insert, or update the row the target found (`plans.ts`).\n return node;\n }\n return Object.freeze({\n ...node,\n onConflict: undefined,\n onDuplicateKey: OnDuplicateKeyNode.create(conflict.updates ?? []),\n });\n};\n","/**\n * MySQL error details (ADR 0001, \"MySQL\"). mysql2 errors carry `code` (`ER_DUP_ENTRY`, …) and a message\n * that names the failed key; the connection adds `constraint` and `table` to the error, so\n * `db/sql/errors.ts` can match constraint names as it does on PostgreSQL.\n */\nexport const DUPLICATE_KEY = 'ER_DUP_ENTRY';\nexport const FOREIGN_KEY_CODES: ReadonlySet<string> = new Set([\n 'ER_ROW_IS_REFERENCED_2',\n 'ER_NO_REFERENCED_ROW_2',\n]);\n\ntype MysqlErrorFields = { code?: unknown; sqlMessage?: unknown; constraint?: unknown; table?: unknown };\n\nconst fieldsOf = (error: unknown): MysqlErrorFields | undefined =>\n typeof error === 'object' && error !== null ? error : undefined;\n\n/** `Duplicate entry '…' for key 'table.index'` → { table, index } (`PRIMARY` → `<table>_pkey`). */\nconst duplicateKeyOf = (message: string): { table: string | undefined; constraint: string } | undefined => {\n const match = /for key '(?:([^.']+)\\.)?([^']+)'$/.exec(message);\n if (!match) {\n return undefined;\n }\n const [, table, key] = match;\n return { table, constraint: key === 'PRIMARY' && table ? `${table}_pkey` : (key as string) };\n};\n\n/** `… (\\`db\\`.\\`table\\`, CONSTRAINT \\`name\\` FOREIGN KEY …` → { table, constraint }. */\nconst foreignKeyOf = (message: string): { table: string | undefined; constraint: string } | undefined => {\n const match = /\\(`[^`]+`\\.`([^`]+)`, CONSTRAINT `([^`]+)`/.exec(message);\n return match ? { table: match[1], constraint: match[2] as string } : undefined;\n};\n\n/** Adds `constraint` and `table` to a MySQL constraint error (mutates and returns it). */\nexport const annotateMysqlError = <T>(error: T): T => {\n const fields = fieldsOf(error);\n if (!fields || typeof fields.sqlMessage !== 'string') {\n return error;\n }\n const found =\n fields.code === DUPLICATE_KEY\n ? duplicateKeyOf(fields.sqlMessage)\n : FOREIGN_KEY_CODES.has(fields.code as string)\n ? foreignKeyOf(fields.sqlMessage)\n : undefined;\n if (found) {\n fields.constraint = found.constraint;\n fields.table = found.table;\n }\n return error;\n};\n\n/** Whether `error` is a duplicate key on one of `indexes` (any unique key when `indexes` is undefined). */\nexport const isDuplicateKeyOn = (error: unknown, indexes: ReadonlySet<string> | undefined): boolean => {\n const fields = fieldsOf(error);\n if (fields?.code !== DUPLICATE_KEY) {\n return false;\n }\n return indexes === undefined || indexes.has(fields.constraint as string);\n};\n\n/**\n * What the operator must change when MySQL refuses a migration statement for a server setting: with binary\n * logging on, creating the baseline's triggers needs SUPER (or SET_USER_ID) or\n * `log_bin_trust_function_creators = 1`. Undefined for any other error.\n */\nexport const mysqlMigrationHint = (error: unknown): string | undefined =>\n fieldsOf(error)?.code === 'ER_BINLOG_CREATE_ROUTINE_NEED_SUPER'\n ? 'MySQL refused to create a trigger because binary logging is on. Set log_bin_trust_function_creators = 1 ' +\n '(a parameter group setting on managed MySQL) or migrate as a user with SUPER, then retry; ' +\n 'see documentation/mysql.md.'\n : undefined;\n","import {\n AliasNode,\n AndNode,\n BinaryOperationNode,\n ColumnNode,\n IdentifierNode,\n OperatorNode,\n OrNode,\n ParensNode,\n PrimitiveValueListNode,\n ReferenceNode,\n SelectionNode,\n SelectQueryNode,\n TableNode,\n ValueNode,\n WhereNode,\n type OperationNode,\n type QueryResult,\n type ReturningNode,\n type UnknownRow,\n} from 'kysely';\nimport { tableInfo, type MysqlTableInfo } from './tables.js';\n\n/** Building blocks of statement plans (`plans.ts`): rows found again by their keys. */\n\nexport const ref = (column: string, table?: string): ReferenceNode =>\n ReferenceNode.create(ColumnNode.create(column), table === undefined ? undefined : TableNode.create(table));\n\nexport const equals = (left: OperationNode, right: OperationNode) =>\n BinaryOperationNode.create(left, OperatorNode.create('='), right);\n\nexport const valueNode = (value: unknown): OperationNode =>\n value !== null && typeof value === 'object' && 'kind' in value\n ? (value as OperationNode)\n : ValueNode.create(value);\n\n/** `(k1 = v1 and k2 = v2) or (…)` over rows of key values (values may be expressions). */\nexport const keyMatch = (columns: readonly string[], keys: readonly (readonly unknown[])[]): WhereNode => {\n if (columns.length === 1) {\n const [column] = columns as [string];\n const values = keys.map((key) => key[0]);\n if (values.every((value) => !(value !== null && typeof value === 'object' && 'kind' in value))) {\n return WhereNode.create(\n BinaryOperationNode.create(\n ref(column),\n OperatorNode.create('in'),\n PrimitiveValueListNode.create(values),\n ),\n );\n }\n }\n const rows = keys.map((key) =>\n ParensNode.create(\n columns\n .map((column, index) => equals(ref(column), valueNode(key[index])) as OperationNode)\n .reduce((left, right) => AndNode.create(left, right)),\n ),\n );\n return WhereNode.create(\n rows.slice(1).reduce<OperationNode>((left, right) => OrNode.create(left, right), rows[0]!),\n );\n};\n\nconst keyText = (values: readonly unknown[]) =>\n JSON.stringify(values.map((value) => String(value).toLowerCase()));\n\n/** Rows in the order of `keys`, without the key columns the plan selected (expression keys keep the database's order). */\nexport const inKeyOrder = (\n rows: readonly UnknownRow[],\n columns: readonly string[],\n keys: readonly (readonly unknown[])[],\n): UnknownRow[] => {\n const keyColumns = columns.map((_, index) => `__shapio_key_${index}`);\n const strip = (row: UnknownRow) =>\n Object.fromEntries(Object.entries(row).filter(([name]) => !keyColumns.includes(name)));\n if (keys.some((key) => key.some((value) => value !== null && typeof value === 'object'))) {\n return rows.map(strip);\n }\n const position = new Map(keys.map((key, index) => [keyText(key), index]));\n const positionOf = (row: UnknownRow) => position.get(keyText(keyColumns.map((column) => row[column]))) ?? 0;\n return [...rows].sort((a, b) => positionOf(a) - positionOf(b)).map(strip);\n};\n\n/** `select <returning>, <key columns as __shapio_key_i> from <table> where <keys>`. */\nexport const selectByKeys = (\n table: string,\n returning: ReturningNode,\n columns: readonly string[],\n keys: readonly (readonly unknown[])[],\n): SelectQueryNode =>\n Object.freeze({\n ...SelectQueryNode.createFrom([TableNode.create(table)]),\n selections: [\n ...returning.selections,\n ...columns.map((column, index) =>\n SelectionNode.create(\n AliasNode.create(ref(column, table), IdentifierNode.create(`__shapio_key_${index}`)),\n ),\n ),\n ],\n where: keyMatch(columns, keys),\n });\n\nexport const infoOf = (table: string): MysqlTableInfo => {\n const info = tableInfo(table);\n if (!info) {\n throw new Error(`MySQL: RETURNING and ON CONFLICT need a Shapio table; ${table} is not one`);\n }\n return info;\n};\n\nexport const tableOf = (node: OperationNode | undefined, statement: string): string => {\n const table = node && TableNode.is(node) ? node : undefined;\n if (!table) {\n throw new Error(`MySQL: ${statement} with RETURNING needs a single table without an alias`);\n }\n return table.table.identifier.name;\n};\n\nexport const resultOf = (rows: UnknownRow[], affected: number): QueryResult<UnknownRow> => ({\n rows,\n numAffectedRows: BigInt(affected),\n});\n\n/** The value a VALUES row gives `column` (a primitive or an expression node). */\nexport const rowValue = (row: OperationNode, index: number): unknown => {\n if (PrimitiveValueListNode.is(row)) {\n return row.values[index];\n }\n const value = (row as unknown as { values: readonly OperationNode[] }).values[index];\n return value && ValueNode.is(value) ? value.value : value;\n};\n","import {\n AndNode,\n ColumnNode,\n OperationNodeTransformer,\n ParensNode,\n TableNode,\n UpdateQueryNode,\n ValuesNode,\n WhereNode,\n type ColumnUpdateNode,\n type InsertQueryNode,\n type OnConflictNode,\n type OperationNode,\n type QueryResult,\n type ReferenceNode,\n type UnknownRow,\n} from 'kysely';\nimport { sameColumns } from './conflicts.js';\nimport { isDuplicateKeyOn } from './errors.js';\nimport {\n infoOf,\n inKeyOrder,\n keyMatch,\n resultOf,\n rowValue,\n selectByKeys,\n tableOf,\n valueNode,\n} from './planKeys.js';\nimport type { Compile, StatementPlan } from './planTypes.js';\n\n/**\n * INSERT … RETURNING and INSERT … ON CONFLICT on MySQL (`plans.ts`): the insert, then the returned rows by\n * key; with a conflict target, each row under a savepoint, a duplicate on the target skipped or turned into\n * an UPDATE of the row it found.\n */\n\n/** Replaces `excluded.<column>` references with the values one VALUES row gives those columns. */\nclass ExcludedRowValues extends OperationNodeTransformer {\n readonly #value: (column: string) => OperationNode;\n\n constructor(value: (column: string) => OperationNode) {\n super();\n this.#value = value;\n }\n\n protected override transformReference(node: ReferenceNode): ReferenceNode {\n if (node.table?.table.identifier.name === 'excluded' && ColumnNode.is(node.column)) {\n return this.#value(node.column.column.name) as ReferenceNode;\n }\n return node;\n }\n}\n\n/**\n * The UPDATE `ON CONFLICT (target) DO UPDATE SET … [WHERE …]` runs on the row the target found, with the\n * proposed row's values in place of `excluded.*`.\n */\nconst conflictUpdate = (\n table: string,\n conflict: OnConflictNode,\n target: readonly string[],\n value: (column: string) => OperationNode,\n): UpdateQueryNode => {\n const replace = new ExcludedRowValues(value);\n const match = keyMatch(target, [target.map((column) => value(column))]).where;\n const where = conflict.updateWhere\n ? AndNode.create(match, ParensNode.create(replace.transformNode(conflict.updateWhere.where)))\n : match;\n return Object.freeze({\n ...UpdateQueryNode.create([TableNode.create(table)]),\n updates: (conflict.updates ?? []).map((update) => replace.transformNode<ColumnUpdateNode>(update)),\n where: WhereNode.create(where),\n });\n};\n\nexport const insertPlan = (node: InsertQueryNode, compile: Compile): StatementPlan => {\n const table = tableOf(node.into, 'INSERT');\n const info = infoOf(table);\n if (!node.values || !ValuesNode.is(node.values) || !node.columns) {\n throw new Error(`MySQL: INSERT … SELECT into ${table} cannot use RETURNING or ON CONFLICT DO NOTHING`);\n }\n const columns = node.columns.map((column) => column.column.name);\n const rows = node.values.values;\n const conflict = node.onConflict;\n const target = conflict?.columns?.map((column) => column.column.name);\n const targetIndexes = target\n ? new Set(info.uniqueKeys.filter((key) => sameColumns(key.columns, target)).map((key) => key.name))\n : undefined;\n if (targetIndexes && targetIndexes.size === 0) {\n throw new Error(`MySQL: no unique key on ${table} (${target!.join(', ')}) for ON CONFLICT`);\n }\n const identityKey = info.identity !== undefined && !columns.includes(info.identity);\n const perRow = conflict !== undefined || (identityKey && node.returning !== undefined);\n const base = Object.freeze({ ...node, onConflict: undefined, returning: undefined });\n const statements = perRow\n ? rows.map((row) => compile(Object.freeze({ ...base, values: ValuesNode.create([row]) })))\n : [compile(base)];\n const updates = conflict !== undefined && !conflict.doNothing;\n if (updates && !target) {\n throw new Error(`MySQL: ON CONFLICT DO UPDATE on ${table} needs a conflict target`);\n }\n // An upsert may return a row it updated (another primary key): it is found by its target instead.\n const keyColumns = updates ? target! : identityKey ? [info.identity!] : info.primaryKey;\n const valueOf = (rowIndex: number) => (column: string) => {\n const index = columns.indexOf(column);\n if (index < 0) {\n throw new Error(`MySQL: ON CONFLICT on ${table} refers to ${column}, which the insert leaves out`);\n }\n return valueNode(rowValue(rows[rowIndex]!, index));\n };\n const keyOf = (rowIndex: number, insertId: bigint | undefined): unknown[] =>\n identityKey && !updates\n ? [String(insertId)]\n : keyColumns.map((column) => rowValue(rows[rowIndex]!, columns.indexOf(column)));\n\n return (context) =>\n context.atomically(async () => {\n const keys: unknown[][] = [];\n let affected = 0;\n for (const [index, statement] of statements.entries()) {\n let result: QueryResult<UnknownRow>;\n try {\n result = conflict\n ? await context.savepoint(() => context.run(statement))\n : await context.run(statement);\n } catch (error) {\n if (!conflict || !isDuplicateKeyOn(error, targetIndexes)) {\n throw error;\n }\n if (!updates) {\n continue;\n }\n result = await context.run(compile(conflictUpdate(table, conflict, target!, valueOf(index))));\n if (Number(result.numAffectedRows ?? 0n) === 0) {\n // The update's WHERE excluded the row: PostgreSQL returns nothing for it either.\n continue;\n }\n }\n affected += Number(result.numAffectedRows ?? 0n);\n if (perRow) {\n keys.push(keyOf(index, result.insertId));\n } else {\n keys.push(...rows.map((_, rowIndex) => keyOf(rowIndex, result.insertId)));\n }\n }\n if (!node.returning || keys.length === 0) {\n return resultOf([], affected);\n }\n const selected = await context.run(compile(selectByKeys(table, node.returning, keyColumns, keys)));\n return resultOf(inKeyOrder(selected.rows, keyColumns, keys), affected);\n });\n};\n","import {\n AliasNode,\n IdentifierNode,\n ListNode,\n OperationNodeTransformer,\n OperatorNode,\n SelectAllNode,\n SelectionNode,\n SelectQueryNode,\n TableNode,\n ValueListNode,\n ValuesNode,\n type BinaryOperationNode,\n type InsertQueryNode,\n type OperationNode,\n type QueryId,\n type UpdateQueryNode,\n type WhereNode,\n} from 'kysely';\n\n/**\n * Subquery shapes MySQL rejects, rewritten (ADR 0001, \"MySQL\"): `IN (… LIMIT n)` (error 1235) and a subquery\n * reading the table an UPDATE, DELETE or INSERT writes (error 1093) read a derived table instead, which MySQL\n * materialises first; PostgreSQL's `UPDATE … FROM` becomes a multi-table UPDATE.\n */\n\n/** The alias of a derived table wrapped around a subquery. */\nexport const DERIVED_ALIAS = 'shapio_derived';\n\nexport const tableNameOf = (node: OperationNode | undefined): string | undefined =>\n node && TableNode.is(node) ? node.table.identifier.name : undefined;\n\n/**\n * Whether an IN subquery must read a derived table: it has a LIMIT (MySQL rejects `IN (… LIMIT n)`), or it\n * reads `table`, the target of the enclosing UPDATE, DELETE or INSERT (error 1093).\n */\nconst needsDerivedTable = (node: SelectQueryNode, table: string | undefined): boolean =>\n node.limit !== undefined ||\n (table !== undefined &&\n ((node.from?.froms ?? []).some((item) => tableNameOf(AliasNode.is(item) ? item.node : item) === table) ||\n (node.joins ?? []).some(\n (join) => tableNameOf(AliasNode.is(join.table) ? join.table.node : join.table) === table,\n )));\n\n/** `(select * from (<subquery>) as shapio_derived)`: MySQL materialises it first. */\nconst derived = (node: SelectQueryNode): SelectQueryNode =>\n Object.freeze({\n ...SelectQueryNode.createFrom([AliasNode.create(node, IdentifierNode.create(DERIVED_ALIAS))]),\n selections: [SelectionNode.create(SelectAllNode.create())],\n });\n\nconst IN_OPERATORS = new Set(['in', 'not in']);\n\n/** Wraps the IN-subqueries of a WHERE tree that need it (see `needsDerivedTable`). */\nclass DerivedTableWrapper extends OperationNodeTransformer {\n readonly #table: string | undefined;\n\n constructor(table: string | undefined) {\n super();\n this.#table = table;\n }\n\n protected override transformBinaryOperation(node: BinaryOperationNode, queryId?: QueryId) {\n const transformed = super.transformBinaryOperation(node, queryId);\n const operator = OperatorNode.is(transformed.operator) ? transformed.operator.operator : '';\n const right = transformed.rightOperand;\n if (IN_OPERATORS.has(operator) && SelectQueryNode.is(right) && needsDerivedTable(right, this.#table)) {\n return Object.freeze({ ...transformed, rightOperand: derived(right) });\n }\n return transformed;\n }\n\n // Do not descend into subqueries' own WHERE: only the statement's top-level IN operands matter.\n protected override transformSelectQuery(node: SelectQueryNode): SelectQueryNode {\n return node;\n }\n}\n\nexport const wrapSubqueries = (\n where: WhereNode | undefined,\n table: string | undefined,\n): WhereNode | undefined => (where ? new DerivedTableWrapper(table).transformNode<WhereNode>(where) : where);\n\n/**\n * An INSERT whose VALUES read the target table in a scalar subquery (`coalesce(max(position) + 1, 0)`):\n * MySQL rejects that (error 1093) unless the subquery reads a derived table, which it materialises first.\n */\nexport const withDerivedValueSubqueries = (node: InsertQueryNode): InsertQueryNode => {\n const table = node.into?.table.identifier.name;\n if (!table || !node.values || !ValuesNode.is(node.values)) {\n return node;\n }\n let changed = false;\n const rows = node.values.values.map((row) => {\n if (!ValueListNode.is(row)) {\n return row;\n }\n const values = row.values.map((value) => {\n if (SelectQueryNode.is(value) && needsDerivedTable(value, table)) {\n changed = true;\n return derived(value);\n }\n return value;\n });\n return ValueListNode.create(values);\n });\n return changed ? Object.freeze({ ...node, values: ValuesNode.create(rows) }) : node;\n};\n\n/**\n * `UPDATE t SET … FROM u WHERE …` (PostgreSQL) as MySQL's multi-table `UPDATE t, u SET … WHERE …`, which\n * joins the same way: the WHERE relates the tables.\n */\nexport const withFromAsTables = (node: UpdateQueryNode): UpdateQueryNode =>\n node.from && node.table\n ? Object.freeze({ ...node, table: ListNode.create([node.table, ...node.from.froms]), from: undefined })\n : node;\n","import {\n AliasNode,\n BinaryOperationNode,\n ColumnNode,\n IdentifierNode,\n OperatorNode,\n ReferenceNode,\n SelectionNode,\n SelectModifierNode,\n SelectQueryNode,\n TableNode,\n type DeleteQueryNode,\n type UnknownRow,\n type UpdateQueryNode,\n type WhereNode,\n} from 'kysely';\nimport { infoOf, inKeyOrder, keyMatch, ref, resultOf, selectByKeys, tableOf } from './planKeys.js';\nimport type { Compile, StatementPlan } from './planTypes.js';\nimport { DERIVED_ALIAS } from './subqueries.js';\n\n/**\n * UPDATE/DELETE … RETURNING on MySQL (`plans.ts`): lock the matching keys (`SELECT … FOR UPDATE`, or the\n * statement's own `key IN (subquery)`), run the statement by key, then read the returned rows by key.\n */\n\nconst forUpdate = (node: SelectQueryNode): SelectQueryNode =>\n node.endModifiers?.some((modifier) => modifier.modifier === 'ForUpdate')\n ? node\n : Object.freeze({\n ...node,\n endModifiers: [...(node.endModifiers ?? []), SelectModifierNode.create('ForUpdate')],\n });\n\n/** For `key in (subquery)` (possibly wrapped in the plugin's derived table): the subquery. */\nconst keySubquery = (where: WhereNode | undefined, key: readonly string[]): SelectQueryNode | undefined => {\n const condition = where?.where;\n if (\n key.length !== 1 ||\n !condition ||\n !BinaryOperationNode.is(condition) ||\n !OperatorNode.is(condition.operator) ||\n condition.operator.operator !== 'in' ||\n !ReferenceNode.is(condition.leftOperand) ||\n !ColumnNode.is(condition.leftOperand.column) ||\n condition.leftOperand.column.column.name !== key[0] ||\n !SelectQueryNode.is(condition.rightOperand)\n ) {\n return undefined;\n }\n const subquery = condition.rightOperand;\n const from = subquery.from?.froms[0];\n if (from && AliasNode.is(from) && IdentifierNode.is(from.alias) && from.alias.name === DERIVED_ALIAS) {\n return SelectQueryNode.is(from.node) ? from.node : undefined;\n }\n return subquery;\n};\n\n/** `select <key> from <table> where <where> [order/limit] for update` (or the key subquery itself). */\nconst lockingKeySelect = (\n table: string,\n key: readonly string[],\n node: UpdateQueryNode | DeleteQueryNode,\n extra: readonly SelectionNode[],\n): SelectQueryNode => {\n const subquery = extra.length === 0 ? keySubquery(node.where, key) : undefined;\n if (subquery) {\n return forUpdate(subquery);\n }\n return forUpdate(\n Object.freeze({\n ...SelectQueryNode.createFrom([TableNode.create(table)]),\n selections: [\n ...extra,\n ...key.map((column, index) =>\n SelectionNode.create(\n AliasNode.create(ref(column, table), IdentifierNode.create(`__shapio_key_${index}`)),\n ),\n ),\n ],\n where: node.where,\n orderBy: node.orderBy,\n limit: node.limit,\n }),\n );\n};\n\nconst keysOf = (rows: readonly UnknownRow[], key: readonly string[], bySubquery: boolean): unknown[][] =>\n rows.map((row) =>\n bySubquery ? [Object.values(row)[0]] : key.map((_, index) => row[`__shapio_key_${index}`]),\n );\n\nexport const updatePlan = (node: UpdateQueryNode, compile: Compile): StatementPlan => {\n const table = tableOf(node.table, 'UPDATE');\n if (node.from || node.joins?.length) {\n throw new Error(`MySQL: UPDATE … FROM/JOIN on ${table} cannot use RETURNING`);\n }\n const key = infoOf(table).primaryKey;\n const bySubquery = keySubquery(node.where, key) !== undefined;\n const lock = compile(lockingKeySelect(table, key, node, []));\n return (context) =>\n context.atomically(async () => {\n const keys = keysOf((await context.run(lock)).rows, key, bySubquery);\n if (keys.length === 0) {\n return resultOf([], 0);\n }\n await context.run(\n compile(\n Object.freeze({\n ...node,\n where: keyMatch(key, keys),\n returning: undefined,\n limit: undefined,\n orderBy: undefined,\n }),\n ),\n );\n const selected = await context.run(compile(selectByKeys(table, node.returning!, key, keys)));\n return resultOf(inKeyOrder(selected.rows, key, keys), keys.length);\n });\n};\n\nexport const deletePlan = (node: DeleteQueryNode, compile: Compile): StatementPlan => {\n const table = tableOf(node.from.froms[0], 'DELETE');\n if (node.from.froms.length > 1 || node.using || node.joins?.length) {\n throw new Error(`MySQL: DELETE … USING/JOIN on ${table} cannot use RETURNING`);\n }\n const key = infoOf(table).primaryKey;\n const lock = compile(lockingKeySelect(table, key, node, node.returning!.selections));\n return (context) =>\n context.atomically(async () => {\n const locked = (await context.run(lock)).rows;\n const keys = keysOf(locked, key, false);\n if (keys.length === 0) {\n return resultOf([], 0);\n }\n await context.run(\n compile(\n Object.freeze({\n ...node,\n where: keyMatch(key, keys),\n returning: undefined,\n limit: undefined,\n orderBy: undefined,\n }),\n ),\n );\n return resultOf(inKeyOrder(locked, key, keys), keys.length);\n });\n};\n","import type { RootOperationNode } from 'kysely';\nimport { insertPlan } from './insertPlan.js';\nimport { deletePlan, updatePlan } from './keyedWritePlans.js';\nimport type { Compile, StatementPlan } from './planTypes.js';\n\nexport type { Compile, PlanContext, StatementPlan } from './planTypes.js';\n\n/**\n * Statement plans (ADR 0001, \"MySQL\"): MySQL has no `RETURNING` and no `ON CONFLICT (target) DO NOTHING`,\n * so the compiler turns such a statement into a few statements the connection runs atomically (inside the\n * caller's transaction under a savepoint, or in a transaction of its own):\n * - INSERT … RETURNING: the insert, then a SELECT of the returned columns by primary key (keys are known:\n * the plugin generates UUIDs; an identity key comes from `LAST_INSERT_ID()`, one row per statement).\n * - INSERT … ON CONFLICT (target) DO NOTHING [RETURNING]: each row inserted under a savepoint; a duplicate\n * on the target's unique index (any index without a target) rolls that row back and returns nothing for\n * it, so other unique violations still raise, as on PostgreSQL.\n * - UPDATE/DELETE … RETURNING: `SELECT <key> … FOR UPDATE` with the statement's WHERE (or, for\n * `key IN (subquery)`, the subquery itself, keeping its `FOR UPDATE SKIP LOCKED`), the statement by key,\n * then (UPDATE) a SELECT of the returned columns by key. The rows stay locked, so the result is exact.\n */\n/** The plan a statement needs on MySQL, or undefined when it runs as written. */\nexport const planFor = (node: RootOperationNode, compile: Compile): StatementPlan | undefined => {\n switch (node.kind) {\n case 'InsertQueryNode':\n return node.returning || node.onConflict ? insertPlan(node, compile) : undefined;\n case 'UpdateQueryNode':\n return node.returning ? updatePlan(node, compile) : undefined;\n case 'DeleteQueryNode':\n return node.returning ? deletePlan(node, compile) : undefined;\n default:\n return undefined;\n }\n};\n\n/** The statement without the parts a plan replaces (what logs and errors show). */\nexport const plannedStatement = (node: RootOperationNode): RootOperationNode =>\n node.kind === 'InsertQueryNode' || node.kind === 'UpdateQueryNode' || node.kind === 'DeleteQueryNode'\n ? Object.freeze({\n ...node,\n returning: undefined,\n ...(node.kind === 'InsertQueryNode' ? { onConflict: undefined } : {}),\n })\n : node;\n","import {\n MysqlQueryCompiler,\n ValuesNode,\n type CompiledQuery,\n type InsertQueryNode,\n type OnConflictNode,\n type OnDuplicateKeyNode,\n type QueryId,\n type ReturningNode,\n type RootOperationNode,\n} from 'kysely';\nimport { EXCLUDED_ALIAS } from './conflicts.js';\nimport { planFor, plannedStatement, type StatementPlan } from './plans.js';\n\n/** The property of a compiled query that carries its plan (`plans.ts`). */\nexport const STATEMENT_PLAN = Symbol('shapio.mysql.plan');\n\nexport type PlannedQuery = CompiledQuery & { readonly [STATEMENT_PLAN]?: StatementPlan };\n\nexport const planOf = (query: CompiledQuery): StatementPlan | undefined =>\n (query as PlannedQuery)[STATEMENT_PLAN];\n\n/**\n * Kysely's MySQL compiler, plus: statements MySQL cannot run as one get a plan (`plans.ts`), and\n * `ON DUPLICATE KEY UPDATE` names the inserted row `excluded` (MySQL ≥ 8.0.19 row alias), so the\n * `excluded.<column>` references of a PostgreSQL upsert compile unchanged.\n */\nexport class ShapioMysqlQueryCompiler extends MysqlQueryCompiler {\n #insertWithValues = false;\n\n override compileQuery(node: RootOperationNode, queryId: QueryId): CompiledQuery {\n const plan = planFor(node, (statement) =>\n new ShapioMysqlQueryCompiler().compileQuery(statement, queryId),\n );\n if (!plan) {\n return super.compileQuery(node, queryId);\n }\n const shown = super.compileQuery(plannedStatement(node), queryId);\n // `query` stays the full statement: Kysely reads its RETURNING to decide what `execute` returns.\n return Object.freeze({ ...shown, query: node, [STATEMENT_PLAN]: plan });\n }\n\n protected override visitInsertQuery(node: InsertQueryNode): void {\n const previous = this.#insertWithValues;\n this.#insertWithValues = node.values !== undefined && ValuesNode.is(node.values);\n try {\n super.visitInsertQuery(node);\n } finally {\n this.#insertWithValues = previous;\n }\n }\n\n protected override visitOnDuplicateKey(node: OnDuplicateKeyNode): void {\n if (this.#insertWithValues) {\n this.append(\n `as ${this.getLeftIdentifierWrapper()}${EXCLUDED_ALIAS}${this.getRightIdentifierWrapper()} `,\n );\n }\n super.visitOnDuplicateKey(node);\n }\n\n protected override visitOnConflict(_node: OnConflictNode): void {\n throw new Error('MySQL has no ON CONFLICT; the MySQL plugin or a statement plan must replace it');\n }\n\n protected override visitReturning(_node: ReturningNode): void {\n throw new Error('MySQL has no RETURNING; a statement plan must replace it');\n }\n}\n","import { EventEmitter } from 'node:events';\n\n/**\n * In-process notification delivery (ADR 0002 notes notifications are an optimisation; consumers also check\n * a durable version): an event bus per database. Every handle on the same database in this process shares\n * one bus, so two app instances in one test process still hear each other.\n * - SQLite: the only delivery (SQLite deployments are single-process).\n * - MySQL: the fast path for listeners in the publishing process; other processes poll the notifications\n * table (`mysql/notificationListener.ts`), and the row ID lets a listener skip what it already heard.\n */\nconst HUBS = new Map<string, EventEmitter>();\n\nconst hubFor = (databaseKey: string): EventEmitter => {\n let hub = HUBS.get(databaseKey);\n if (!hub) {\n hub = new EventEmitter();\n hub.setMaxListeners(0);\n HUBS.set(databaseKey, hub);\n }\n return hub;\n};\n\nexport type NotificationHandler = (channel: string, payload: string | undefined, id?: string) => void;\n\n/** Delivers on a later turn of the event loop, like a notification arriving from the network. */\nexport const publishNotification = (\n databaseKey: string,\n channel: string,\n payload: string,\n id?: string,\n): void => {\n setImmediate(() => hubFor(databaseKey).emit('notification', channel, payload, id));\n};\n\n/** Subscribes to every channel of the database; returns the unsubscribe function. */\nexport const subscribeNotifications = (databaseKey: string, handler: NotificationHandler): (() => void) => {\n const hub = hubFor(databaseKey);\n hub.on('notification', handler);\n return () => {\n hub.off('notification', handler);\n if (hub.listenerCount('notification') === 0) {\n HUBS.delete(databaseKey);\n }\n };\n};\n","import { AppError } from '../helpers/appError.js';\n\n/**\n * How long a query waits for a free pooled connection (PostgreSQL and MySQL) before it fails with\n * `PoolAcquireTimeoutError`. Without a bound, an exhausted pool queues requests forever and the server\n * stops answering until it restarts. SQLite has no such wait (see `db/sqlite/driver.ts`).\n */\nexport const DEFAULT_POOL_ACQUIRE_TIMEOUT_MS = 10_000;\n\n/**\n * No pooled connection became free in time. A 503 the client may retry; the central error handler logs it\n * as a failed request, so an exhausted pool shows in the logs instead of as a silent hang.\n */\nexport class PoolAcquireTimeoutError extends AppError {\n constructor(timeoutMs: number, poolMax: number, options?: ErrorOptions) {\n super(\n 503,\n 'DATABASE_BUSY',\n `No database connection became free within ${timeoutMs} ms (pool of ${poolMax}); try again shortly`,\n undefined,\n options,\n );\n this.name = 'PoolAcquireTimeoutError';\n }\n}\n\n/**\n * Opening a new connection took longer than the acquire timeout: the database is unreachable or overloaded.\n * A 503 the client may retry, logged by the central error handler like `PoolAcquireTimeoutError`.\n */\nexport class DatabaseUnavailableError extends AppError {\n constructor(timeoutMs: number, options?: ErrorOptions) {\n super(\n 503,\n 'DATABASE_UNAVAILABLE',\n `Could not connect to the database within ${timeoutMs} ms; try again shortly`,\n undefined,\n options,\n );\n this.name = 'DatabaseUnavailableError';\n }\n}\n\n/** pg-pool's error when `connectionTimeoutMillis` passes while the request waits in the pool's queue. */\nconst PG_QUEUE_TIMEOUT_MESSAGE = 'timeout exceeded when trying to connect';\n/** pg-pool's error when `connectionTimeoutMillis` passes while it opens a new connection. */\nconst PG_CONNECT_TIMEOUT_MESSAGE = 'Connection terminated due to connection timeout';\n\n/** The 503 for a pg-pool acquisition error, or the error itself when it is not a timeout. */\nexport const pgAcquireError = (error: unknown, poolMax: number, timeoutMs: number): unknown => {\n if (!(error instanceof Error)) {\n return error;\n }\n if (error.message === PG_QUEUE_TIMEOUT_MESSAGE) {\n return new PoolAcquireTimeoutError(timeoutMs, poolMax, { cause: error });\n }\n if (error.message === PG_CONNECT_TIMEOUT_MESSAGE) {\n return new DatabaseUnavailableError(timeoutMs, { cause: error });\n }\n return error;\n};\n","/**\n * mysql2, loaded on first use. A process on PostgreSQL never loads it, and a bundle of the read path (the\n * in-process delivery runtime) can leave it out as an optional dependency.\n */\nexport const loadMysql = async () => (await import('mysql2')).default;\n","/**\n * Parameters the MySQL connection resolves itself just before a statement runs (ADR 0001, \"MySQL\").\n * They let a `db/` primitive keep its single-expression contract where MySQL needs a statement of its own.\n */\n\n/** The next value of a sequence: allocated from an AUTO_INCREMENT table (no lock held to commit). */\nexport class SequenceValue {\n readonly name: string;\n\n constructor(name: string) {\n this.name = name;\n }\n}\n\n/**\n * A notification's channel. The statement that binds it inserts the notification; the connection also\n * publishes it to listeners in this process once the transaction commits (or at once outside one).\n */\nexport class NotificationChannel {\n readonly channel: string;\n readonly payload: string;\n\n constructor(channel: string, payload: string) {\n this.channel = channel;\n this.payload = payload;\n }\n}\n\n/** The table that backs a sequence. */\nexport const sequenceTableOf = (name: string): string => `sequence_${name}`;\n","import {\n type CompiledQuery,\n type DatabaseConnection,\n type Driver,\n type QueryResult,\n type TransactionSettings,\n type UnknownRow,\n} from 'kysely';\nimport type { Pool, PoolConnection, PoolOptions, ResultSetHeader } from 'mysql2';\nimport { assertNotNested, outsideConnectionScope } from '../connectionScope.js';\nimport { publishNotification } from '../notifyHub.js';\nimport { DEFAULT_POOL_ACQUIRE_TIMEOUT_MS, PoolAcquireTimeoutError } from '../poolAcquire.js';\nimport { encodeParameter, typeCast } from './codec.js';\nimport { planOf } from './compiler.js';\nimport { annotateMysqlError } from './errors.js';\nimport { loadMysql } from './module.js';\nimport { NotificationChannel, SequenceValue, sequenceTableOf } from './parameters.js';\nimport type { PlanContext } from './plans.js';\n\n/**\n * Shapio's MySQL driver (ADR 0001, \"MySQL\") on mysql2's pool. Beyond Kysely's own MySQL driver it:\n * - sets every session up like PostgreSQL behaves: UTC, READ COMMITTED, strict SQL mode, utf8mb4 with the\n * binary `utf8mb4_0900_bin` collation, a large `group_concat_max_len` (JSON aggregates);\n * - pins `NOW()` and `CURRENT_TIMESTAMP` defaults to the transaction's start (`SET timestamp`), as\n * PostgreSQL's `now()` is;\n * - runs statement plans (`plans.ts`) atomically: inside a transaction under a savepoint, otherwise in a\n * transaction of their own;\n * - resolves sequence values and notification channels bound as parameters (`parameters.ts`), and publishes\n * notifications to listeners in this process once their transaction commits;\n * - names the constraint of a constraint error (`errors.ts`).\n */\nexport const SESSION_SETUP =\n \"set names utf8mb4 collate utf8mb4_0900_bin, time_zone = '+00:00', transaction_isolation = 'READ-COMMITTED', \" +\n \"sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,ONLY_FULL_GROUP_BY,NO_ENGINE_SUBSTITUTION', \" +\n 'group_concat_max_len = 1073741824';\n\nconst PIN_TIMESTAMP = 'set timestamp = unix_timestamp(sysdate(6))';\nconst UNPIN_TIMESTAMP = 'set timestamp = default';\n\nexport type MysqlDriverOptions = {\n url: string;\n poolMax: number;\n /**\n * How long `acquireConnection` waits for a free pooled connection (mysql2's pool has no such bound).\n * Default `DEFAULT_POOL_ACQUIRE_TIMEOUT_MS`.\n */\n acquireTimeoutMs?: number;\n /** Fail a pool acquisition inside an open transaction (`db/connectionScope.ts`); tests turn it on. */\n strict?: boolean;\n /** Reported as the `program_name` connection attribute (PostgreSQL's application_name). */\n applicationName?: string;\n /** Reports an idle pooled connection that failed (the pool replaces it). */\n onIdleConnectionError?: (error: Error) => void;\n};\n\n/** `host:port/database` of a mysql: URL: the key listeners in this process share. */\nexport const mysqlDatabaseKey = (url: string): string => {\n const parsed = new URL(url);\n return `mysql:${parsed.hostname}:${parsed.port || '3306'}${parsed.pathname}`;\n};\n\nexport const mysqlPoolOptions = (url: string, poolMax: number, applicationName = 'shapio'): PoolOptions => ({\n uri: url,\n // Visible in performance_schema.session_connect_attrs, like PostgreSQL's application_name.\n connectAttributes: { program_name: applicationName },\n connectionLimit: poolMax,\n // The handshake carries a one-byte collation ID; the session setup sets utf8mb4_0900_bin.\n charset: 'UTF8MB4_GENERAL_CI',\n timezone: 'Z',\n supportBigNumbers: true,\n bigNumberStrings: true,\n decimalNumbers: false,\n typeCast,\n multipleStatements: false,\n});\n\ntype PendingNotification = { channel: string; payload: string; id?: string };\n\ntype RawResult = UnknownRow[] | ResultSetHeader;\n\nconst isResultHeader = (result: RawResult): result is ResultSetHeader =>\n !Array.isArray(result) && typeof result === 'object' && 'affectedRows' in result;\n\nclass MysqlConnection implements DatabaseConnection {\n readonly #connection: PoolConnection;\n readonly #databaseKey: string;\n #inTransaction = false;\n #savepoints = 0;\n #pending: PendingNotification[] = [];\n\n constructor(connection: PoolConnection, databaseKey: string) {\n this.#connection = connection;\n this.#databaseKey = databaseKey;\n }\n\n get inTransaction(): boolean {\n return this.#inTransaction;\n }\n\n release(): void {\n this.#connection.release();\n }\n\n #query(sql: string, parameters: readonly unknown[] = []): Promise<RawResult> {\n return new Promise((resolve, reject) => {\n this.#connection.query(sql, parameters as unknown[], (error, result) => {\n if (error) {\n reject(annotateMysqlError(error));\n } else {\n resolve(result as RawResult);\n }\n });\n });\n }\n\n /** Runs a raw control statement (transactions, savepoints, session settings). */\n async control(sql: string): Promise<void> {\n await this.#query(sql);\n }\n\n async begin(settings: TransactionSettings): Promise<void> {\n const statements: string[] = [];\n if (settings.isolationLevel || settings.accessMode) {\n const parts = [\n ...(settings.isolationLevel ? [`isolation level ${settings.isolationLevel}`] : []),\n ...(settings.accessMode ? [settings.accessMode] : []),\n ];\n statements.push(`set transaction ${parts.join(', ')}`);\n }\n statements.push(PIN_TIMESTAMP, 'begin');\n // mysql2 runs a connection's queries in order; sending them together saves round trips.\n await Promise.all(statements.map((statement) => this.#query(statement)));\n this.#inTransaction = true;\n this.#pending = [];\n }\n\n async end(command: 'commit' | 'rollback'): Promise<void> {\n const pending = this.#pending;\n this.#pending = [];\n this.#inTransaction = false;\n await Promise.all([this.#query(command), this.#query(UNPIN_TIMESTAMP)]);\n if (command === 'commit') {\n // Listeners start work of their own (a schema reload), not work of the transaction that committed.\n outsideConnectionScope(() => {\n for (const { channel, payload, id } of pending) {\n publishNotification(this.#databaseKey, channel, payload, id);\n }\n });\n }\n }\n\n async #nextSequenceValue(name: string): Promise<string> {\n const table = sequenceTableOf(name);\n const inserted = await this.#query(`insert into \\`${table}\\` () values ()`);\n const value = isResultHeader(inserted) ? String(inserted.insertId) : undefined;\n if (value === undefined) {\n throw new Error(`No value from sequence ${name}`);\n }\n await this.#query(`delete from \\`${table}\\` where \\`value\\` = ?`, [value]);\n return value;\n }\n\n /** Encodes parameters, allocating sequence values and noting notifications. */\n async #parametersOf(parameters: readonly unknown[]): Promise<{\n values: unknown[];\n notifications: PendingNotification[];\n }> {\n const values: unknown[] = [];\n const notifications: PendingNotification[] = [];\n for (const [index, parameter] of parameters.entries()) {\n if (parameter instanceof SequenceValue) {\n values.push(await this.#nextSequenceValue(parameter.name));\n } else if (parameter instanceof NotificationChannel) {\n notifications.push({ channel: parameter.channel, payload: parameter.payload });\n values.push(parameter.channel);\n } else {\n values.push(encodeParameter(parameter, index));\n }\n }\n return { values, notifications };\n }\n\n async #execute(query: CompiledQuery): Promise<QueryResult<UnknownRow>> {\n const { values, notifications } = await this.#parametersOf(query.parameters);\n const result = await this.#query(query.sql, values);\n if (notifications.length > 0) {\n // A notification is one inserted row: its ID lets a polling listener skip what it already heard.\n const id = isResultHeader(result) && result.insertId ? String(result.insertId) : undefined;\n const published = notifications.map((notification) => ({ ...notification, id }));\n if (this.#inTransaction) {\n this.#pending.push(...published);\n } else {\n for (const notification of published) {\n publishNotification(this.#databaseKey, notification.channel, notification.payload, notification.id);\n }\n }\n }\n if (!isResultHeader(result)) {\n return { rows: Array.isArray(result) ? result : [] };\n }\n return {\n rows: [],\n numAffectedRows: BigInt(result.affectedRows),\n ...(result.insertId ? { insertId: BigInt(result.insertId) } : {}),\n };\n }\n\n readonly #planContext: PlanContext = {\n run: (query) => this.#execute(query),\n atomically: async (fn) => {\n if (this.#inTransaction) {\n return this.#planContext.savepoint(fn);\n }\n await this.begin({});\n try {\n const result = await fn();\n await this.end('commit');\n return result;\n } catch (error) {\n await this.end('rollback');\n throw error;\n }\n },\n savepoint: async (fn) => {\n const name = `shapio_plan_${(this.#savepoints += 1)}`;\n await this.#query(`savepoint ${name}`);\n try {\n const result = await fn();\n await this.#query(`release savepoint ${name}`);\n return result;\n } catch (error) {\n await this.#query(`rollback to savepoint ${name}`);\n throw error;\n }\n },\n };\n\n async executeQuery<R>(query: CompiledQuery): Promise<QueryResult<R>> {\n const plan = planOf(query);\n const result = plan ? await plan(this.#planContext) : await this.#execute(query);\n return result as QueryResult<R>;\n }\n\n // eslint-disable-next-line require-yield\n async *streamQuery<R>(): AsyncIterableIterator<QueryResult<R>> {\n throw new Error('Streaming queries are not supported on MySQL');\n }\n}\n\nexport class MysqlDriver implements Driver {\n readonly #options: MysqlDriverOptions;\n readonly databaseKey: string;\n\n get strict(): boolean {\n return this.#options.strict ?? false;\n }\n\n #pool: Pool | undefined;\n readonly #connections = new WeakMap<PoolConnection, MysqlConnection>();\n\n constructor(options: MysqlDriverOptions) {\n this.#options = options;\n this.databaseKey = mysqlDatabaseKey(options.url);\n }\n\n async init(): Promise<void> {\n const mysql = await loadMysql();\n const pool = mysql.createPool(\n mysqlPoolOptions(this.#options.url, this.#options.poolMax, this.#options.applicationName),\n );\n pool.on('connection', (connection) => {\n connection.query(SESSION_SETUP, (error) => {\n if (error) {\n this.#options.onIdleConnectionError?.(error);\n connection.destroy();\n }\n });\n // An idle connection that dies emits 'error'; the pool drops it and opens another on demand.\n connection.on('error', (error: Error) => this.#options.onIdleConnectionError?.(error));\n });\n this.#pool = pool;\n }\n\n #pooled(): Pool {\n if (!this.#pool) {\n throw new Error('The MySQL driver is not initialised');\n }\n return this.#pool;\n }\n\n /**\n * A pooled connection, or `PoolAcquireTimeoutError` once `acquireTimeoutMs` passes. mysql2 cannot withdraw\n * a queued request, so a connection that arrives after the timeout goes straight back to the pool.\n */\n #getConnection(): Promise<PoolConnection> {\n const { acquireTimeoutMs = DEFAULT_POOL_ACQUIRE_TIMEOUT_MS, poolMax } = this.#options;\n return new Promise<PoolConnection>((resolve, reject) => {\n let timedOut = false;\n const timer = setTimeout(() => {\n timedOut = true;\n reject(new PoolAcquireTimeoutError(acquireTimeoutMs, poolMax));\n }, acquireTimeoutMs);\n this.#pooled().getConnection((error, connection) => {\n clearTimeout(timer);\n if (timedOut) {\n connection?.release();\n } else if (error) {\n reject(error);\n } else {\n resolve(connection);\n }\n });\n });\n }\n\n async acquireConnection(): Promise<DatabaseConnection> {\n if (this.#options.strict) {\n assertNotNested();\n }\n const raw = await this.#getConnection();\n let connection = this.#connections.get(raw);\n if (!connection) {\n connection = new MysqlConnection(raw, this.databaseKey);\n this.#connections.set(raw, connection);\n }\n return connection;\n }\n\n async beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void> {\n await (connection as MysqlConnection).begin(settings);\n }\n\n async commitTransaction(connection: DatabaseConnection): Promise<void> {\n await (connection as MysqlConnection).end('commit');\n }\n\n async rollbackTransaction(connection: DatabaseConnection): Promise<void> {\n await (connection as MysqlConnection).end('rollback');\n }\n\n async savepoint(connection: DatabaseConnection, name: string): Promise<void> {\n await (connection as MysqlConnection).control(`savepoint \\`${name}\\``);\n }\n\n async rollbackToSavepoint(connection: DatabaseConnection, name: string): Promise<void> {\n await (connection as MysqlConnection).control(`rollback to savepoint \\`${name}\\``);\n }\n\n async releaseSavepoint(connection: DatabaseConnection, name: string): Promise<void> {\n await (connection as MysqlConnection).control(`release savepoint \\`${name}\\``);\n }\n\n async releaseConnection(connection: DatabaseConnection): Promise<void> {\n (connection as MysqlConnection).release();\n }\n\n async destroy(): Promise<void> {\n const pool = this.#pool;\n this.#pool = undefined;\n if (pool) {\n await new Promise<void>((resolve, reject) => pool.end((error) => (error ? reject(error) : resolve())));\n }\n }\n}\n","import {\n AliasNode,\n IdentifierNode,\n type AggregateFunctionNode,\n type FunctionNode,\n type OperationNode,\n type ParensNode,\n type RootOperationNode,\n type SelectionNode,\n type SelectQueryNode,\n} from 'kysely';\nimport { markedResultType, type ResultType } from './typed.js';\n\n/**\n * Result-type markers of a query's output columns (`typed.ts`), for drivers whose database does not report\n * the type of a computed column (SQLite) or reports one PostgreSQL would not (MySQL computes comparisons as\n * integers). Shared by the SQLite and MySQL plugins.\n */\nconst selectionsOf = (node: RootOperationNode): readonly SelectionNode[] | undefined => {\n switch (node.kind) {\n case 'SelectQueryNode':\n return node.selections;\n case 'InsertQueryNode':\n case 'UpdateQueryNode':\n case 'DeleteQueryNode':\n return node.returning?.selections;\n default:\n return undefined;\n }\n};\n\n/** Functions whose result has the type of their (marked) arguments. */\nconst TYPE_PRESERVING_FUNCTIONS = new Set(['coalesce', 'max', 'min', 'ifnull']);\n/** Aggregates PostgreSQL returns as bigint/numeric, which its driver reads as decimal strings. */\nconst BIGINT_AGGREGATES = new Set(['count', 'sum']);\n\n/**\n * The marker of an expression: its own, or one it inherits through `coalesce`/`max`/`min`, parentheses\n * and scalar subqueries (`coalesce((select asJson(…) …), emptyArray())` needs no second marker).\n * `count` and `sum` read as decimal strings, like PostgreSQL's bigint and numeric.\n */\nconst markerOf = (node: OperationNode | undefined): ResultType | undefined => {\n if (!node) {\n return undefined;\n }\n const own = markedResultType(node);\n if (own) {\n return own;\n }\n switch (node.kind) {\n case 'AliasNode':\n return markerOf((node as AliasNode).node);\n case 'ParensNode':\n return markerOf((node as ParensNode).node);\n case 'SelectionNode':\n return markerOf((node as SelectionNode).selection);\n case 'SelectQueryNode': {\n const selections = (node as SelectQueryNode).selections;\n return selections?.length === 1 ? markerOf(selections[0]) : undefined;\n }\n case 'AggregateFunctionNode':\n case 'FunctionNode': {\n const call = node as Partial<FunctionNode> & Partial<AggregateFunctionNode>;\n if (node.kind === 'AggregateFunctionNode' && BIGINT_AGGREGATES.has(String(call.func).toLowerCase())) {\n return 'bigint';\n }\n if (!TYPE_PRESERVING_FUNCTIONS.has(String(call.func).toLowerCase())) {\n return undefined;\n }\n for (const argument of call.aggregated ?? call.arguments ?? []) {\n const marker = markerOf(argument);\n if (marker) {\n return marker;\n }\n }\n return undefined;\n }\n default:\n return undefined;\n }\n};\n\n/** Output column name → marker, for top-level selections that are (or inherit) marked expressions. */\nexport const collectMarkers = (node: RootOperationNode): Map<string, ResultType> | undefined => {\n let markers: Map<string, ResultType> | undefined;\n for (const selection of selectionsOf(node) ?? []) {\n const aliased = selection.selection;\n if (!AliasNode.is(aliased) || !IdentifierNode.is(aliased.alias)) {\n continue;\n }\n const type = markerOf(aliased.node);\n if (type) {\n markers ??= new Map();\n markers.set(aliased.alias.name, type);\n }\n }\n return markers;\n};\n","import { randomUUID } from 'node:crypto';\nimport {\n ColumnNode,\n PrimitiveValueListNode,\n ValueListNode,\n ValueNode,\n ValuesNode,\n type InsertQueryNode,\n type OperationNode,\n} from 'kysely';\nimport { toDatetimeText } from './codec.js';\nimport { SequenceValue } from './parameters.js';\nimport { tableInfo, type MysqlTableInfo } from './tables.js';\n\n/**\n * Values MySQL needs written differently (ADR 0001, \"MySQL\"): columns PostgreSQL defaults that MySQL cannot\n * (UUIDs generated here, so a planned RETURNING knows the key; the change sequence), and ISO-8601 text bound\n * to timestamp columns.\n */\n\nconst ISO_TIMESTAMP = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}/;\n\n/**\n * Text bound to a timestamp column, as UTC `DATETIME` text: PostgreSQL reads ISO-8601 with a zone\n * (`…T…Z`, `+02:00`); MySQL would reject it or ignore the zone.\n */\nconst timestampText = (value: unknown): unknown =>\n typeof value === 'string' && ISO_TIMESTAMP.test(value) ? toDatetimeText(value) : value;\n\nexport const isTimestampColumn = (table: string | undefined, column: string): boolean =>\n table !== undefined && (tableInfo(table)?.timestamps ?? []).includes(column);\n\n/** A value node (or primitive list) bound to a timestamp column, with ISO text normalised. */\nexport const timestampValue = (node: OperationNode): OperationNode => {\n if (ValueNode.is(node)) {\n const value = timestampText(node.value);\n return value === node.value ? node : ValueNode.create(value);\n }\n if (PrimitiveValueListNode.is(node)) {\n return PrimitiveValueListNode.create(node.values.map(timestampText));\n }\n return node;\n};\n\n/** Insert rows with ISO text for timestamp columns normalised. */\nexport const withTimestampValues = (node: InsertQueryNode): InsertQueryNode => {\n const table = node.into?.table.identifier.name;\n const columns = node.columns?.map((column) => column.column.name) ?? [];\n const positions = columns.flatMap((column, index) => (isTimestampColumn(table, column) ? [index] : []));\n if (positions.length === 0 || !node.values || !ValuesNode.is(node.values)) {\n return node;\n }\n const rows = node.values.values.map((row) =>\n PrimitiveValueListNode.is(row)\n ? PrimitiveValueListNode.create(\n row.values.map((value, index) => (positions.includes(index) ? timestampText(value) : value)),\n )\n : ValueListNode.create(\n row.values.map((value, index) => (positions.includes(index) ? timestampValue(value) : value)),\n ),\n );\n return Object.freeze({ ...node, values: ValuesNode.create(rows) });\n};\n\n/** A fresh value for a column PostgreSQL defaults. */\nconst generatedValue = (kind: string): unknown => (kind === 'uuid' ? randomUUID() : new SequenceValue(kind));\n\n/** The insert with every generated column the statement leaves out filled in. */\nexport const withGeneratedColumns = (node: InsertQueryNode, info: MysqlTableInfo): InsertQueryNode => {\n const generated = Object.entries(info.generated ?? {});\n const columns = node.columns?.map((column) => column.column.name) ?? [];\n const missing = generated.filter(([column]) => !columns.includes(column));\n if (missing.length === 0 || !node.values || !ValuesNode.is(node.values) || !node.columns) {\n return node;\n }\n const rows = node.values.values.map((row) => {\n const extra = missing.map(([, kind]) => generatedValue(kind));\n return PrimitiveValueListNode.is(row)\n ? PrimitiveValueListNode.create([...row.values, ...extra])\n : ValueListNode.create([...row.values, ...extra.map((value) => ValueNode.create(value))]);\n });\n return Object.freeze({\n ...node,\n columns: [...node.columns, ...missing.map(([column]) => ColumnNode.create(column))],\n values: ValuesNode.create(rows),\n });\n};\n","import {\n AliasNode,\n BinaryOperationNode,\n ColumnNode,\n IdentifierNode,\n OperatorNode,\n OrderByItemNode,\n ParensNode,\n RawNode,\n ReferenceNode,\n ValueNode,\n type FromNode,\n type JoinNode,\n type OperationNode,\n} from 'kysely';\nimport { tableNameOf } from './subqueries.js';\nimport { tableInfo } from './tables.js';\n\n/**\n * PostgreSQL's NULL placement on MySQL (ADR 0001, \"MySQL\"): PostgreSQL sorts NULLs last ascending and first\n * descending, MySQL the reverse. An ORDER BY item that may be NULL gets an `(expr is null)` item before it;\n * a NOT NULL column of a table in scope (`tables.ts`) does not, so index-ordered scans stay possible.\n */\n\n/** `asc`/`desc` from an order item's direction node. */\nconst directionOf = (node: OrderByItemNode): 'asc' | 'desc' => {\n const direction = node.direction;\n if (direction && RawNode.is(direction)) {\n return direction.sqlFragments.join('').trim().toLowerCase() === 'desc' ? 'desc' : 'asc';\n }\n return 'asc';\n};\n\n/** Tables in scope of one query level: alias (or name) → table, and whether a LEFT JOIN may null them. */\nexport type Scope = Map<string, { table: string; outer: boolean }>;\n\nconst addToScope = (scope: Scope, node: OperationNode, outer: boolean) => {\n if (AliasNode.is(node) && IdentifierNode.is(node.alias)) {\n const table = tableNameOf(node.node);\n if (table) {\n scope.set(node.alias.name, { table, outer });\n }\n return;\n }\n const table = tableNameOf(node);\n if (table) {\n scope.set(table, { table, outer });\n }\n};\n\nexport const scopeOf = (\n from: FromNode | undefined,\n joins: readonly JoinNode[] | undefined,\n extra?: string,\n): Scope => {\n const scope: Scope = new Map();\n for (const item of from?.froms ?? []) {\n addToScope(scope, item, false);\n }\n for (const join of joins ?? []) {\n addToScope(scope, join.table, join.joinType !== 'InnerJoin');\n }\n if (extra) {\n scope.set(extra, { table: extra, outer: false });\n }\n return scope;\n};\n\n/** Whether an ORDER BY expression can never be NULL (a NOT NULL column of a table in scope). */\nconst neverNull = (node: OperationNode, scope: Scope): boolean => {\n if (!ReferenceNode.is(node) || !ColumnNode.is(node.column)) {\n return false;\n }\n const column = node.column.column.name;\n const qualifier = node.table?.table.identifier.name;\n const candidates = qualifier\n ? [scope.get(qualifier)].filter((entry) => entry !== undefined)\n : [...scope.values()].filter((entry) => tableInfo(entry.table)?.columns.includes(column));\n if (candidates.length !== 1) {\n return false;\n }\n const entry = candidates[0]!;\n const info = tableInfo(entry.table);\n return (\n !entry.outer && info !== undefined && info.columns.includes(column) && !info.nullable.includes(column)\n );\n};\n\nconst isNull = (expression: OperationNode): OperationNode =>\n ParensNode.create(\n BinaryOperationNode.create(expression, OperatorNode.create('is'), ValueNode.createImmediate(null)),\n );\n\nconst withDirection = (node: OperationNode, direction: 'asc' | 'desc'): OrderByItemNode =>\n OrderByItemNode.create(node, RawNode.createWithSql(direction));\n\n/** True when a raw ORDER BY item already spells its own direction (the content compiler's SQL). */\nconst spellsDirection = (node: OrderByItemNode): boolean =>\n RawNode.is(node.orderBy) && /\\b(asc|desc)\\b/i.test(node.orderBy.sqlFragments.join(' '));\n\n/** PostgreSQL's NULL placement for one ORDER BY item, as MySQL items. */\nexport const orderItems = (item: OrderByItemNode, scope: Scope): OrderByItemNode[] => {\n if (spellsDirection(item)) {\n return [item];\n }\n const direction = directionOf(item);\n const nullsLast = item.nulls ? item.nulls === 'last' : direction === 'asc';\n // MySQL already puts NULLs first ascending and last descending.\n const mysqlNullsLast = direction === 'desc';\n const plain = Object.freeze({ ...item, nulls: undefined });\n if (nullsLast === mysqlNullsLast || neverNull(item.orderBy, scope)) {\n return [plain];\n }\n return [withDirection(isNull(item.orderBy), nullsLast ? 'asc' : 'desc'), plain];\n};\n","import type { UnknownRow } from 'kysely';\nimport type { ResultType } from '../sql/typed.js';\n\n/** A marked column's value as PostgreSQL's driver would give it (`db/sql/typed.ts`). */\nconst DECODERS: Readonly<Record<ResultType, (value: unknown) => unknown>> = {\n boolean: (value) => Number(value) !== 0,\n bigint: (value) => String(value),\n json: (value) => (typeof value === 'string' ? (JSON.parse(value) as unknown) : value),\n timestamp: (value) => (value instanceof Date ? value : new Date(`${String(value).replace(' ', 'T')}Z`)),\n text: (value) => String(value),\n};\n\nexport const decodeRow = (row: UnknownRow, markers: ReadonlyMap<string, ResultType>): UnknownRow => {\n const decoded: Record<string, unknown> = { ...row };\n for (const [column, type] of markers) {\n const value = decoded[column];\n if (value !== null && value !== undefined) {\n decoded[column] = DECODERS[type](value);\n }\n }\n return decoded;\n};\n","import {\n AliasNode,\n ColumnNode,\n OperationNodeTransformer,\n RawNode,\n ReferenceNode,\n type BinaryOperationNode,\n type CastNode,\n type DataTypeNode,\n type DeleteQueryNode,\n type InsertQueryNode,\n type KyselyPlugin,\n type OrderByNode,\n type PluginTransformQueryArgs,\n type PluginTransformResultArgs,\n type QueryId,\n type QueryResult,\n type RootOperationNode,\n type SelectModifierNode,\n type SelectQueryNode,\n type UnknownRow,\n type UpdateQueryNode,\n} from 'kysely';\nimport { collectMarkers } from '../sql/markers.js';\nimport type { ResultType } from '../sql/typed.js';\nimport { toOnDuplicateKey } from './conflicts.js';\nimport {\n isTimestampColumn,\n timestampValue,\n withGeneratedColumns,\n withTimestampValues,\n} from './insertValues.js';\nimport { orderItems, scopeOf, type Scope } from './nullOrdering.js';\nimport { decodeRow } from './resultDecoding.js';\nimport { tableNameOf, withDerivedValueSubqueries, withFromAsTables, wrapSubqueries } from './subqueries.js';\nimport { tableInfo } from './tables.js';\n\n/**\n * Adapts Kysely queries written for PostgreSQL to MySQL (dialect boundary, ADR 0001, \"MySQL\"). Rewrites that\n * stay one statement happen here; statements MySQL cannot run as one (`RETURNING`, most `ON CONFLICT`) are\n * planned by the compiler (`plans.ts`). This plugin:\n * - fills the columns PostgreSQL defaults that MySQL cannot, and normalises ISO text bound to timestamp\n * columns (`insertValues.ts`);\n * - spells casts MySQL's way (`text` → `char`, `bigint`/`integer` → `signed`) and maps row locks MySQL lacks;\n * - keeps PostgreSQL's NULL placement in ORDER BY (`nullOrdering.ts`);\n * - turns `ON CONFLICT` into `ON DUPLICATE KEY UPDATE` where that means the same (`conflicts.ts`);\n * - rewrites the subquery shapes MySQL rejects and `UPDATE … FROM` (`subqueries.ts`);\n * - decodes result columns marked with `db/sql/typed.ts` (MySQL computes comparisons as integers).\n */\n\nconst CAST_TYPES: Readonly<Record<string, string>> = {\n text: 'char',\n uuid: 'char(36)',\n integer: 'signed',\n bigint: 'signed',\n int4: 'signed',\n int8: 'signed',\n numeric: 'decimal(65,30)',\n};\n\nconst ROW_LOCKS: Readonly<Record<string, string>> = {\n ForNoKeyUpdate: 'ForUpdate',\n ForKeyShare: 'ForShare',\n};\n\nconst emptyScope = (): Scope => new Map<string, { table: string; outer: boolean }>();\n\nclass MysqlTransformer extends OperationNodeTransformer {\n readonly #scopes: Scope[] = [];\n\n protected override transformSelectQuery(node: SelectQueryNode, queryId?: QueryId): SelectQueryNode {\n this.#scopes.push(scopeOf(node.from, node.joins));\n try {\n const transformed = super.transformSelectQuery(node, queryId);\n const where = wrapSubqueries(transformed.where, undefined);\n return where === transformed.where ? transformed : Object.freeze({ ...transformed, where });\n } finally {\n this.#scopes.pop();\n }\n }\n\n protected override transformUpdateQuery(node: UpdateQueryNode, queryId?: QueryId): UpdateQueryNode {\n const table = tableNameOf(node.table && AliasNode.is(node.table) ? node.table.node : node.table);\n this.#scopes.push(scopeOf(node.from, node.joins, table));\n try {\n const transformed = super.transformUpdateQuery(node, queryId);\n const multiTable = withFromAsTables(transformed);\n const updates = multiTable.updates?.map((update) =>\n ColumnNode.is(update.column) && isTimestampColumn(table, update.column.column.name)\n ? Object.freeze({ ...update, value: timestampValue(update.value) })\n : update,\n );\n return Object.freeze({ ...multiTable, updates, where: wrapSubqueries(multiTable.where, table) });\n } finally {\n this.#scopes.pop();\n }\n }\n\n protected override transformDeleteQuery(node: DeleteQueryNode, queryId?: QueryId): DeleteQueryNode {\n const table = tableNameOf(node.from.froms[0]);\n this.#scopes.push(scopeOf(node.from, node.joins));\n try {\n const transformed = super.transformDeleteQuery(node, queryId);\n return Object.freeze({ ...transformed, where: wrapSubqueries(transformed.where, table) });\n } finally {\n this.#scopes.pop();\n }\n }\n\n protected override transformInsertQuery(node: InsertQueryNode, queryId?: QueryId): InsertQueryNode {\n const transformed = withTimestampValues(\n withDerivedValueSubqueries(super.transformInsertQuery(node, queryId)),\n );\n const table = transformed.into?.table.identifier.name;\n const info = table === undefined ? undefined : tableInfo(table);\n let result = transformed;\n // Before generated columns are added: a conflict key the statement leaves out is generated fresh.\n if (table && transformed.onConflict) {\n result = toOnDuplicateKey(result, transformed.onConflict, table);\n }\n return info ? withGeneratedColumns(result, info) : result;\n }\n\n protected override transformOrderBy(node: OrderByNode, queryId?: QueryId): OrderByNode {\n const transformed = super.transformOrderBy(node, queryId);\n const scope = this.#scopes.at(-1) ?? emptyScope();\n return Object.freeze({\n ...transformed,\n items: transformed.items.flatMap((item) => orderItems(item, scope)),\n });\n }\n\n /** `timestamp_column <op> 'ISO text'`: the text as UTC DATETIME text. */\n protected override transformBinaryOperation(\n node: BinaryOperationNode,\n queryId?: QueryId,\n ): BinaryOperationNode {\n const transformed = super.transformBinaryOperation(node, queryId);\n const left = transformed.leftOperand;\n if (!ReferenceNode.is(left) || !ColumnNode.is(left.column)) {\n return transformed;\n }\n const column = left.column.column.name;\n const scope = this.#scopes.at(-1) ?? emptyScope();\n const qualifier = left.table?.table.identifier.name;\n const tables = qualifier\n ? [scope.get(qualifier)?.table]\n : [...scope.values()]\n .map((entry) => entry.table)\n .filter((table) => tableInfo(table)?.columns.includes(column));\n if (tables.length !== 1 || !isTimestampColumn(tables[0], column)) {\n return transformed;\n }\n const right = timestampValue(transformed.rightOperand);\n return right === transformed.rightOperand\n ? transformed\n : Object.freeze({ ...transformed, rightOperand: right });\n }\n\n protected override transformCast(node: CastNode, queryId?: QueryId): CastNode {\n const transformed = super.transformCast(node, queryId);\n const dataType = transformed.dataType as DataTypeNode;\n const mapped = dataType.kind === 'DataTypeNode' ? CAST_TYPES[String(dataType.dataType)] : undefined;\n return mapped ? Object.freeze({ ...transformed, dataType: RawNode.createWithSql(mapped) }) : transformed;\n }\n\n protected override transformSelectModifier(\n node: SelectModifierNode,\n queryId?: QueryId,\n ): SelectModifierNode {\n const transformed = super.transformSelectModifier(node, queryId);\n const mapped = transformed.modifier ? ROW_LOCKS[transformed.modifier] : undefined;\n return mapped\n ? Object.freeze({ ...transformed, modifier: mapped as SelectModifierNode['modifier'] })\n : transformed;\n }\n}\n\nexport class MysqlPlugin implements KyselyPlugin {\n readonly #markers = new WeakMap<QueryId, ReadonlyMap<string, ResultType>>();\n\n transformQuery({ node, queryId }: PluginTransformQueryArgs): RootOperationNode {\n const markers = collectMarkers(node);\n if (markers) {\n this.#markers.set(queryId, markers);\n }\n return new MysqlTransformer().transformNode(node, queryId);\n }\n\n /** Decodes columns marked with a result type (MySQL computes `a is not null` as an integer). */\n async transformResult({ result, queryId }: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>> {\n const markers = this.#markers.get(queryId);\n if (!markers || result.rows.length === 0) {\n return result;\n }\n return { ...result, rows: result.rows.map((row) => decodeRow(row, markers)) };\n }\n}\n","import {\n Kysely,\n MysqlAdapter,\n MysqlIntrospector,\n type DatabaseIntrospector,\n type Dialect,\n type Driver,\n type QueryCompiler,\n type TransactionBuilder,\n} from 'kysely';\nimport { withConnectionScope } from '../connectionScope.js';\nimport { ShapioMysqlQueryCompiler } from './compiler.js';\nimport { MysqlDriver, type MysqlDriverOptions } from './driver.js';\nimport { MysqlPlugin } from './plugin.js';\n\n/**\n * Kysely on MySQL 8.4 (ADR 0001, \"MySQL\"). RETURNING is emulated by statement plans. Migration locking is Shapio's own session lock\n * (`db/migrator.ts`), scoped to the database, so Kysely's server-wide `GET_LOCK` name is not taken.\n */\nclass ShapioMysqlAdapter extends MysqlAdapter {\n /** Statement plans give MySQL RETURNING (`plans.ts`), so builders return the rows. */\n override get supportsReturning(): boolean {\n return true;\n }\n\n override async acquireMigrationLock(): Promise<void> {\n // Shapio's migrator holds a database-scoped session lock around every run.\n }\n\n override async releaseMigrationLock(): Promise<void> {\n // See acquireMigrationLock.\n }\n}\n\nclass ShapioMysqlDialect implements Dialect {\n readonly driver: MysqlDriver;\n\n constructor(driver: MysqlDriver) {\n this.driver = driver;\n }\n\n createAdapter() {\n return new ShapioMysqlAdapter();\n }\n\n createDriver(): Driver {\n return this.driver;\n }\n\n createIntrospector(db: Kysely<unknown>): DatabaseIntrospector {\n return new MysqlIntrospector(db);\n }\n\n createQueryCompiler(): QueryCompiler {\n return new ShapioMysqlQueryCompiler();\n }\n}\n\n/** A Kysely handle on MySQL; the driver is reachable for the database key listeners share. */\nexport class MysqlKysely<DB> extends Kysely<DB> {\n readonly mysqlDriver: MysqlDriver;\n\n constructor(driver: MysqlDriver) {\n super({ dialect: new ShapioMysqlDialect(driver), plugins: [new MysqlPlugin()] });\n this.mysqlDriver = driver;\n }\n\n /** Strict mode runs transactions in a connection scope (`db/connectionScope.ts`). */\n override transaction(): TransactionBuilder<DB> {\n const builder = super.transaction();\n return this.mysqlDriver.strict ? withConnectionScope(builder) : builder;\n }\n}\n\nexport const createMysqlDb = <DB>(options: MysqlDriverOptions): MysqlKysely<DB> =>\n new MysqlKysely<DB>(new MysqlDriver(options));\n\n/** The MySQL driver behind a handle, or undefined for another dialect. */\nexport const mysqlDriverOf = (db: unknown): MysqlDriver | undefined =>\n db instanceof MysqlKysely ? db.mysqlDriver : undefined;\n","import type { SQLInputValue } from 'node:sqlite';\nimport { toStoredTimestamp } from '../sql/time.js';\nimport type { ResultType } from '../sql/typed.js';\n\n/**\n * The SQLite value codec (ADR 0001, \"Dialect boundary\"). SQLite has five storage classes, so Shapio's\n * PostgreSQL types are declared with names that keep both the storage affinity right (`text_*` → TEXT,\n * `integer_*`/`bigint` → INTEGER) and the original type readable; the driver decodes every result column by\n * its declared type (`StatementSync.columns()` reports it even through subqueries, CTEs and RETURNING), so\n * rows have the same JavaScript shape as on PostgreSQL:\n *\n * | PostgreSQL | declared | stored | read as |\n * | -------------- | ------------------- | ------------------------------- | ------------------ |\n * | timestamptz | text_timestamptz | `YYYY-MM-DDTHH:MM:SS.sssZ` | Date |\n * | date | text_date | `YYYY-MM-DD` | string |\n * | jsonb / json | text_jsonb / _json | JSON text | parsed value |\n * | text[] / uuid[]| text_array / _uuid_array | JSON array text | string[] |\n * | uuid | text_uuid | lowercase text | string |\n * | boolean | integer_boolean | 0 / 1 | boolean |\n * | bigint | bigint | integer | decimal string |\n * | integer | integer | integer | number |\n * | real / double | real / double | real | number |\n */\nexport const DECLARED_TYPES = {\n timestamptz: 'text_timestamptz',\n date: 'text_date',\n jsonb: 'text_jsonb',\n json: 'text_json',\n textArray: 'text_array',\n uuidArray: 'text_uuid_array',\n uuid: 'text_uuid',\n boolean: 'integer_boolean',\n bigint: 'bigint',\n integer: 'integer',\n real: 'real',\n double: 'double',\n text: 'text',\n} as const;\n\n/**\n * `bigint` identity primary keys. SQLite only makes a column its auto-incrementing row ID when it is\n * declared exactly `INTEGER PRIMARY KEY`, so these read back as strings by name instead of by type.\n */\nexport const BIGINT_ROWID_COLUMNS: ReadonlySet<string> = new Set(['outbox_events.id', 'publication_log.id']);\n\n/** A parameter that cannot be stored; never silently written as NULL. */\nexport class SqliteBindError extends TypeError {\n constructor(index: number, value: unknown) {\n const kind = value === undefined ? 'undefined' : (value?.constructor?.name ?? typeof value);\n super(`Cannot bind ${kind} to SQLite parameter ${index + 1}`);\n this.name = 'SqliteBindError';\n }\n}\n\nconst isPlainObject = (value: object): boolean => {\n const prototype = Object.getPrototypeOf(value) as unknown;\n return prototype === Object.prototype || prototype === null;\n};\n\n/** A JavaScript value as SQLite stores it (see the table above). Throws on values with no column type. */\nexport const encodeParameter = (value: unknown, index: number): SQLInputValue => {\n switch (typeof value) {\n case 'string':\n case 'number':\n case 'bigint':\n return value;\n case 'boolean':\n return value ? 1 : 0;\n case 'object':\n if (value === null) {\n return null;\n }\n if (value instanceof Date) {\n return toStoredTimestamp(value);\n }\n if (value instanceof Uint8Array) {\n return value;\n }\n if (Array.isArray(value) || isPlainObject(value)) {\n return JSON.stringify(value);\n }\n throw new SqliteBindError(index, value);\n default:\n throw new SqliteBindError(index, value);\n }\n};\n\nexport type Decoder = (value: unknown) => unknown;\n\nconst toNumber = (value: unknown): unknown => (typeof value === 'bigint' ? Number(value) : value);\nconst toDecimalString = (value: unknown): unknown =>\n typeof value === 'bigint' || typeof value === 'number' ? String(value) : value;\nconst toDate = (value: unknown): unknown => (typeof value === 'string' ? new Date(value) : value);\nconst toBoolean = (value: unknown): unknown => (value === null ? null : Number(value) !== 0);\nconst parseJson = (value: unknown): unknown =>\n typeof value === 'string' ? (JSON.parse(value) as unknown) : value;\nconst passText = (value: unknown): unknown => (typeof value === 'bigint' ? String(value) : value);\n\n/** Integers arrive as bigint (`setReadBigInts`); an untyped one is a number when it fits, else a string. */\nconst untyped: Decoder = (value) => {\n if (typeof value !== 'bigint') {\n return value;\n }\n return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER)\n ? Number(value)\n : String(value);\n};\n\nconst BY_DECLARED_TYPE: Readonly<Record<string, Decoder>> = {\n [DECLARED_TYPES.timestamptz]: toDate,\n [DECLARED_TYPES.date]: passText,\n [DECLARED_TYPES.jsonb]: parseJson,\n [DECLARED_TYPES.json]: parseJson,\n [DECLARED_TYPES.textArray]: parseJson,\n [DECLARED_TYPES.uuidArray]: parseJson,\n [DECLARED_TYPES.uuid]: passText,\n [DECLARED_TYPES.boolean]: toBoolean,\n [DECLARED_TYPES.bigint]: toDecimalString,\n [DECLARED_TYPES.integer]: toNumber,\n [DECLARED_TYPES.real]: toNumber,\n [DECLARED_TYPES.double]: toNumber,\n [DECLARED_TYPES.text]: passText,\n};\n\nconst BY_MARKER: Readonly<Record<ResultType, Decoder>> = {\n json: parseJson,\n timestamp: toDate,\n boolean: toBoolean,\n bigint: toDecimalString,\n text: passText,\n};\n\nexport type ColumnMetadata = {\n name: string;\n table: string | null;\n column: string | null;\n type: string | null;\n};\n\n/** The decoder of one result column: a marker wins, then the origin column, then the declared type. */\nexport const decoderFor = (metadata: ColumnMetadata, marker: ResultType | undefined): Decoder => {\n if (marker) {\n return BY_MARKER[marker];\n }\n if (metadata.table !== null && BIGINT_ROWID_COLUMNS.has(`${metadata.table}.${metadata.column ?? ''}`)) {\n return toDecimalString;\n }\n const declared = metadata.type?.toLowerCase();\n return (declared === undefined ? undefined : BY_DECLARED_TYPE[declared]) ?? untyped;\n};\n\nconst STORED_TIMESTAMP = /^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d\\.\\d{3}Z$/;\n\n/**\n * Strict mode (tests): an unmarked computed column whose text looks like a stored timestamp or a JSON\n * document was almost certainly meant to be decoded; fail loudly so the query gets a `db/sql/typed` marker.\n */\nexport const assertNotUndecoded = (name: string, value: unknown): void => {\n if (typeof value !== 'string') {\n return;\n }\n if (STORED_TIMESTAMP.test(value)) {\n throw new Error(\n `SQLite result column \"${name}\" is a computed timestamp without a type marker; wrap it in asTimestamp() (db/sql/typed.ts)`,\n );\n }\n const first = value[0];\n if (first === '{' || first === '[') {\n try {\n JSON.parse(value);\n } catch {\n return;\n }\n throw new Error(\n `SQLite result column \"${name}\" is computed JSON without a type marker; wrap it in asJson() (db/sql/typed.ts)`,\n );\n }\n};\n","import type { DatabaseSync } from 'node:sqlite';\n\n/**\n * SQLite errors in the shape `db/sql/errors.ts` classifies: `code` is the extended result code's name and,\n * like PostgreSQL's error fields, `constraint` names the violated unique index and `table` the table a\n * failed foreign-key write targeted (SQLite reports no constraint name for foreign keys).\n */\nexport class SqliteDatabaseError extends Error {\n readonly code: string;\n readonly errcode: number;\n readonly constraint: string | undefined;\n readonly table: string | undefined;\n /** The failed statement's SQL (values are bound separately and never included). */\n readonly sql: string | undefined;\n\n constructor(\n message: string,\n fields: { code: string; errcode: number; constraint?: string; table?: string; sql?: string },\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = 'SqliteDatabaseError';\n this.code = fields.code;\n this.errcode = fields.errcode;\n this.constraint = fields.constraint;\n this.table = fields.table;\n this.sql = fields.sql;\n }\n}\n\n/** Extended result codes Shapio distinguishes (sqlite.org/rescode.html). */\nconst CODE_NAMES: Readonly<Record<number, string>> = {\n 5: 'SQLITE_BUSY',\n 19: 'SQLITE_CONSTRAINT',\n 275: 'SQLITE_CONSTRAINT_CHECK',\n 787: 'SQLITE_CONSTRAINT_FOREIGNKEY',\n 1299: 'SQLITE_CONSTRAINT_NOTNULL',\n 1555: 'SQLITE_CONSTRAINT_PRIMARYKEY',\n 1811: 'SQLITE_CONSTRAINT_TRIGGER',\n 2067: 'SQLITE_CONSTRAINT_UNIQUE',\n};\n\nconst NAMED_INDEX = /UNIQUE constraint failed: index '([^']+)'/;\nconst COLUMN_LIST = /(?:UNIQUE) constraint failed: (.+)$/;\n\ntype IndexRow = { name: string; origin: string };\ntype IndexColumnRow = { name: string | null };\n\n/** The unique index on exactly `columns` of `table` (PostgreSQL names the primary key `<table>_pkey`). */\nconst uniqueIndexOn = (\n database: DatabaseSync,\n table: string,\n columns: readonly string[],\n): string | undefined => {\n const indexes = database\n .prepare(`select name, origin from pragma_index_list(?) where \"unique\" = 1`)\n .all(table) as unknown as IndexRow[];\n for (const index of indexes) {\n const indexColumns = (\n database\n .prepare('select name from pragma_index_info(?) order by seqno')\n .all(index.name) as unknown as IndexColumnRow[]\n ).map((row) => row.name);\n if (indexColumns.length === columns.length && indexColumns.every((name, at) => name === columns[at])) {\n return index.origin === 'pk' ? `${table}_pkey` : index.name;\n }\n }\n return undefined;\n};\n\n/** `t.a, t.b` → table `t`, columns `[a, b]`. */\nconst parseColumnList = (list: string): { table: string; columns: string[] } | undefined => {\n const parts = list.split(',').map((part) => part.trim().split('.'));\n const table = parts[0]?.[0];\n if (!table || parts.some((part) => part.length !== 2 || part[0] !== table)) {\n return undefined;\n }\n return { table, columns: parts.map((part) => part[1] ?? '') };\n};\n\nconst uniqueConstraintOf = (database: DatabaseSync, message: string): string | undefined => {\n const named = NAMED_INDEX.exec(message);\n if (named) {\n return named[1];\n }\n const list = COLUMN_LIST.exec(message)?.[1];\n const parsed = list === undefined ? undefined : parseColumnList(list);\n return parsed && uniqueIndexOn(database, parsed.table, parsed.columns);\n};\n\n/**\n * Wraps a `node:sqlite` error with the constraint details services ask about. `writtenTable` is the table an\n * INSERT or UPDATE targeted (attached to foreign-key failures). Other errors pass through unchanged.\n */\nexport const translateSqliteError = (\n error: unknown,\n database: DatabaseSync,\n writtenTable: string | undefined,\n statement?: string,\n): unknown => {\n const errcode = (error as { errcode?: unknown } | null)?.errcode;\n if (!(error instanceof Error) || typeof errcode !== 'number') {\n return error;\n }\n const code = CODE_NAMES[errcode] ?? `SQLITE_${errcode}`;\n const fields: { code: string; errcode: number; constraint?: string; table?: string; sql?: string } = {\n code,\n errcode,\n ...(statement === undefined ? {} : { sql: statement }),\n };\n if (code === 'SQLITE_CONSTRAINT_UNIQUE' || code === 'SQLITE_CONSTRAINT_PRIMARYKEY') {\n const constraint = uniqueConstraintOf(database, error.message);\n if (constraint) {\n fields.constraint = constraint;\n }\n }\n if (code === 'SQLITE_CONSTRAINT_FOREIGNKEY' && writtenTable) {\n fields.table = writtenTable;\n }\n return new SqliteDatabaseError(error.message, fields, { cause: error });\n};\n","import { randomUUID } from 'node:crypto';\nimport type { DatabaseSync, SQLInputValue, SQLOutputValue } from 'node:sqlite';\n\n/**\n * Functions Shapio registers on every SQLite connection, so SQL, column defaults, CHECK constraints and\n * index expressions written for PostgreSQL have an equivalent. Deterministic ones may appear in indexes and\n * constraints; a database file is therefore only fully usable through Shapio (another SQLite client lacks\n * them).\n */\nexport type ConnectionHooks = {\n /** The transaction's start time (or this statement's, outside a transaction), as stored text. */\n now: () => string;\n /** Next value of a named counter in `sequences`. */\n nextval: (name: string) => bigint;\n /** Queues a notification (delivered on commit, or at once outside a transaction). */\n notify: (channel: string, payload: string) => void;\n /** Throws unless this connection is the writer inside a transaction. */\n assertWriteTransaction: () => void;\n};\n\n/** Unicode-aware case folding (SQLite's own `lower`/`upper`/`LIKE` only fold ASCII). */\nconst fold = (value: SQLOutputValue): SQLInputValue =>\n typeof value === 'string' ? value.toLowerCase() : value;\nconst upper = (value: SQLOutputValue): SQLInputValue =>\n typeof value === 'string' ? value.toUpperCase() : value;\n\nconst PATTERNS = new Map<string, RegExp>();\nconst compiled = (pattern: string): RegExp => {\n let regexp = PATTERNS.get(pattern);\n if (!regexp) {\n regexp = new RegExp(pattern, 'u');\n PATTERNS.set(pattern, regexp);\n }\n return regexp;\n};\n\n/** `value REGEXP pattern` (PostgreSQL `~`), which SQLite rewrites to `regexp(pattern, value)`. */\nconst regexp = (pattern: SQLOutputValue, value: SQLOutputValue): SQLInputValue => {\n if (pattern === null || value === null) {\n return null;\n }\n return compiled(String(pattern)).test(String(value)) ? 1 : 0;\n};\n\n/** PostgreSQL's `split_part(text, delimiter, n)` for n ≥ 1: empty text past the last part. */\nconst splitPart = (\n value: SQLOutputValue,\n delimiter: SQLOutputValue,\n position: SQLOutputValue,\n): SQLInputValue => {\n if (value === null || delimiter === null || position === null) {\n return null;\n }\n const index = Number(position);\n if (!Number.isInteger(index) || index < 1) {\n throw new Error('split_part: field position must be a positive integer');\n }\n return String(value).split(String(delimiter))[index - 1] ?? '';\n};\n\nconst DETERMINISTIC = { deterministic: true } as const;\n\nexport const registerFunctions = (database: DatabaseSync, hooks: ConnectionHooks): void => {\n database.function('shapio_fold', DETERMINISTIC, fold);\n database.function('lower', DETERMINISTIC, fold);\n database.function('upper', DETERMINISTIC, upper);\n database.function('regexp', DETERMINISTIC, regexp);\n database.function('split_part', DETERMINISTIC, splitPart);\n database.function('gen_random_uuid', () => randomUUID());\n database.function('shapio_now', () => hooks.now());\n database.function('shapio_nextval', (name: SQLOutputValue) => hooks.nextval(String(name)));\n database.function('shapio_assert_write_transaction', () => {\n hooks.assertWriteTransaction();\n return 1;\n });\n database.function('shapio_notify', (channel: SQLOutputValue, payload: SQLOutputValue) => {\n hooks.notify(String(channel), payload === null ? '' : String(payload));\n return null;\n });\n};\n","import { closeSync, openSync } from 'node:fs';\nimport { DatabaseSync, type StatementSync } from 'node:sqlite';\nimport type { CompiledQuery, QueryResult } from 'kysely';\nimport { publishNotification } from '../notifyHub.js';\nimport { toStoredTimestamp } from '../sql/time.js';\nimport type { ResultType } from '../sql/typed.js';\nimport {\n assertNotUndecoded,\n decoderFor,\n encodeParameter,\n type ColumnMetadata,\n type Decoder,\n} from './codec.js';\nimport { translateSqliteError } from './errors.js';\nimport { registerFunctions } from './functions.js';\n\nexport type ConnectionOptions = {\n /** File path, or ':memory:'. */\n location: string;\n /** Key of the database's notification bus (the resolved file path). */\n databaseKey: string;\n role: 'writer' | 'reader';\n busyTimeoutMs: number;\n /** Fail on computed columns that look like undecoded timestamps or JSON (tests). */\n strict: boolean;\n};\n\n/** What the driver knows about a statement beyond its SQL. */\nexport type StatementContext = {\n /** Result-type markers by output column name (`db/sql/typed.ts`). */\n markers: ReadonlyMap<string, ResultType> | undefined;\n /** The table an INSERT or UPDATE writes (for foreign-key error attribution). */\n writtenTable: string | undefined;\n /**\n * Hand-written SQL (a raw `sql` query) decodes its own computed columns, so strict mode skips it; it\n * checks queries built with Kysely, where a `db/sql/typed` marker belongs.\n */\n handWritten: boolean;\n};\n\ntype PreparedStatement = {\n statement: StatementSync;\n /** Column metadata, or undefined for statements that return no rows. */\n columns: ColumnMetadata[] | undefined;\n decoders: Map<string, Decoder[]>;\n};\n\nconst STATEMENT_CACHE_SIZE = 500;\n\n/**\n * Creates a new database file readable by its owner only (it holds password hashes and, without\n * SESSION_SECRET, the generated signing secret). `node:sqlite` takes no file mode, so the empty file is made\n * first; SQLite gives its `-wal` and `-shm` files the same permissions. An existing file is left as it is.\n */\nconst createPrivateFile = (path: string) => {\n try {\n closeSync(openSync(path, 'wx', 0o600));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error;\n }\n }\n};\n\n/**\n * One `node:sqlite` connection. The writer runs every write transaction; readers run read-only\n * transactions and autocommit reads (WAL lets them read while the writer works). Calls are synchronous:\n * a statement blocks the event loop while it runs.\n */\nexport class SqliteConnection {\n readonly role: 'writer' | 'reader';\n readonly #database: DatabaseSync;\n readonly #options: ConnectionOptions;\n readonly #statements = new Map<string, PreparedStatement>();\n #transactionStart: string | undefined;\n #statementStart: string | undefined;\n #pendingNotifications: Array<[string, string]> = [];\n\n constructor(options: ConnectionOptions) {\n this.#options = options;\n this.role = options.role;\n if (options.location !== ':memory:') {\n createPrivateFile(options.location);\n }\n this.#database = new DatabaseSync(options.location, { enableForeignKeyConstraints: true });\n this.#database.exec(`pragma busy_timeout = ${options.busyTimeoutMs}`);\n if (options.location !== ':memory:') {\n if (options.role === 'writer') {\n this.#database.exec('pragma journal_mode = wal');\n }\n this.#database.exec('pragma synchronous = normal');\n }\n if (options.role === 'reader') {\n this.#database.exec('pragma query_only = 1');\n }\n const nextvalStatement = (): StatementSync => {\n const statement = this.#database.prepare(\n 'update sequences set value = value + 1 where name = ? returning value',\n );\n statement.setReadBigInts(true);\n return statement;\n };\n let nextval: StatementSync | undefined;\n registerFunctions(this.#database, {\n now: () => this.#transactionStart ?? this.#statementStart ?? toStoredTimestamp(new Date()),\n nextval: (name) => {\n nextval ??= nextvalStatement();\n const row = nextval.get(name) as { value: bigint } | undefined;\n if (!row) {\n throw new Error(`Unknown sequence ${name}`);\n }\n return row.value;\n },\n assertWriteTransaction: () => {\n if (this.role !== 'writer' || this.#transactionStart === undefined) {\n throw new Error('A transaction-level lock needs a write transaction on SQLite');\n }\n },\n notify: (channel, payload) => {\n if (this.#transactionStart === undefined) {\n publishNotification(this.#options.databaseKey, channel, payload);\n } else {\n this.#pendingNotifications.push([channel, payload]);\n }\n },\n });\n }\n\n get inTransaction(): boolean {\n return this.#transactionStart !== undefined;\n }\n\n /** Opens a transaction (`begin immediate` takes SQLite's write lock up front). */\n begin(mode: 'deferred' | 'immediate'): void {\n this.#database.exec(mode === 'immediate' ? 'begin immediate' : 'begin');\n this.#transactionStart = toStoredTimestamp(new Date());\n this.#pendingNotifications = [];\n }\n\n /** Commits and delivers the notifications queued inside the transaction. */\n commit(): void {\n try {\n this.#database.exec('commit');\n } catch (error) {\n this.rollback();\n throw error;\n }\n const notifications = this.#pendingNotifications;\n this.#end();\n for (const [channel, payload] of notifications) {\n publishNotification(this.#options.databaseKey, channel, payload);\n }\n }\n\n /** Rolls back (a no-op when SQLite already ended the transaction) and drops queued notifications. */\n rollback(): void {\n try {\n if (this.#database.isTransaction) {\n this.#database.exec('rollback');\n }\n } finally {\n this.#end();\n }\n }\n\n #end(): void {\n this.#transactionStart = undefined;\n this.#pendingNotifications = [];\n }\n\n #prepare(sql: string): PreparedStatement {\n const cached = this.#statements.get(sql);\n if (cached) {\n this.#statements.delete(sql);\n this.#statements.set(sql, cached);\n return cached;\n }\n const statement = this.#database.prepare(sql);\n statement.setReadBigInts(true);\n const metadata = statement.columns();\n const prepared: PreparedStatement = {\n statement,\n columns: metadata.length === 0 ? undefined : metadata,\n decoders: new Map(),\n };\n this.#statements.set(sql, prepared);\n if (this.#statements.size > STATEMENT_CACHE_SIZE) {\n const oldest = this.#statements.keys().next().value;\n if (oldest !== undefined) {\n this.#statements.delete(oldest);\n }\n }\n return prepared;\n }\n\n #decodersOf(prepared: PreparedStatement, context: StatementContext): Decoder[] {\n const { markers } = context;\n const strict = this.#options.strict && !context.handWritten;\n const cacheKey = markers === undefined ? String(strict) : undefined;\n let decoders = cacheKey === undefined ? undefined : prepared.decoders.get(cacheKey);\n if (!decoders) {\n decoders = (prepared.columns ?? []).map((column) => {\n const marker = markers?.get(column.name);\n const decoder = decoderFor(column, marker);\n if (!strict || marker || column.type !== null) {\n return decoder;\n }\n return (value: unknown) => {\n assertNotUndecoded(column.name, value);\n return decoder(value);\n };\n });\n if (cacheKey !== undefined) {\n prepared.decoders.set(cacheKey, decoders);\n }\n }\n return decoders;\n }\n\n /** Runs one compiled statement and decodes its rows. */\n execute<R>(query: CompiledQuery, context: StatementContext): QueryResult<R> {\n this.#statementStart = this.#transactionStart === undefined ? toStoredTimestamp(new Date()) : undefined;\n try {\n const prepared = this.#prepare(query.sql);\n const parameters = query.parameters.map(encodeParameter);\n if (!prepared.columns) {\n const { changes, lastInsertRowid } = prepared.statement.run(...parameters);\n return {\n numAffectedRows: BigInt(changes),\n insertId: BigInt(lastInsertRowid),\n rows: [],\n };\n }\n const columns = prepared.columns;\n const decoders = this.#decodersOf(prepared, context);\n const raw = prepared.statement.all(...parameters) as Array<Record<string, unknown>>;\n const rows = raw.map((source) => {\n const row: Record<string, unknown> = {};\n for (const [index, column] of columns.entries()) {\n row[column.name] = decoders[index]!(source[column.name]);\n }\n return row as R;\n });\n return { rows };\n } catch (error) {\n throw translateSqliteError(error, this.#database, context.writtenTable, query.sql);\n } finally {\n this.#statementStart = undefined;\n }\n }\n\n /** The planner statistics this database holds (`sqlite_stat1`), as text to compare; '' when it has none. */\n statistics(): string {\n try {\n const row = this.#database\n .prepare(\n `select group_concat(tbl || ' ' || coalesce(idx, '') || ' ' || stat, char(10)) as stats from sqlite_stat1`,\n )\n .get() as { stats: string | null } | undefined;\n return row?.stats ?? '';\n } catch {\n // No sqlite_stat1 table yet: nothing has been analyzed.\n return '';\n }\n }\n\n /** Runs SQL text with no parameters or results (pragmas, `vacuum into`). */\n exec(sql: string): void {\n this.#database.exec(sql);\n }\n\n close(): void {\n this.#statements.clear();\n if (this.#database.isOpen) {\n this.#database.close();\n }\n }\n}\n","/**\n * PostgreSQL's three `UNIQUE NULLS NOT DISTINCT` constraints. SQLite treats NULLs as distinct in unique\n * indexes, so the baseline migration creates each as a unique index over `coalesce(column, '')` for its\n * nullable columns (same name), and the SQLite plugin rewrites `onConflict` column targets on these\n * columns to the index's expressions, which SQLite requires the target to match.\n */\nexport type NullsNotDistinctIndex = {\n name: string;\n table: string;\n columns: readonly string[];\n nullable: readonly string[];\n};\n\nexport const NULLS_NOT_DISTINCT_INDEXES: readonly NullsNotDistinctIndex[] = [\n {\n name: 'admin_role_permissions_grant_uq',\n table: 'admin_role_permissions',\n columns: ['role_id', 'action', 'model_id'],\n nullable: ['model_id'],\n },\n {\n name: 'app_role_permissions_grant_uq',\n table: 'app_role_permissions',\n columns: ['role_id', 'action', 'model_id'],\n nullable: ['model_id'],\n },\n {\n name: 'admin_user_roles_assignment_uq',\n table: 'admin_user_roles',\n columns: ['admin_user_id', 'role_id', 'site_id'],\n nullable: ['site_id'],\n },\n];\n\nconst quote = (identifier: string) => `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n\n/** The index's column list as SQL: `\"a\", \"b\", coalesce(\"c\", '')`. */\nexport const indexExpressionSql = (index: NullsNotDistinctIndex): string =>\n index.columns\n .map((column) => (index.nullable.includes(column) ? `coalesce(${quote(column)}, '')` : quote(column)))\n .join(', ');\n\n/** The index whose columns are exactly `columns` (in any order) on `table`. */\nexport const nullsNotDistinctIndexFor = (\n table: string,\n columns: readonly string[],\n): NullsNotDistinctIndex | undefined =>\n NULLS_NOT_DISTINCT_INDEXES.find(\n (index) =>\n index.table === table &&\n index.columns.length === columns.length &&\n index.columns.every((column) => columns.includes(column)),\n );\n","import {\n OperationNodeTransformer,\n RawNode,\n ValueNode,\n type DefaultInsertValueNode,\n type InsertQueryNode,\n type KyselyPlugin,\n type OnConflictNode,\n type OrderByItemNode,\n type PluginTransformQueryArgs,\n type PluginTransformResultArgs,\n type QueryId,\n type QueryResult,\n type RootOperationNode,\n type SelectQueryNode,\n type UnknownRow,\n} from 'kysely';\nimport { collectMarkers } from '../sql/markers.js';\nimport type { ResultType } from '../sql/typed.js';\nimport { indexExpressionSql, nullsNotDistinctIndexFor } from './nullsNotDistinct.js';\n\n/** Row-lock modifiers PostgreSQL needs and SQLite rejects; its write transactions are already serialised. */\nconst ROW_LOCKS = new Set(['ForUpdate', 'ForNoKeyUpdate', 'ForShare', 'ForKeyShare', 'NoWait', 'SkipLocked']);\n\nconst MARKERS = new WeakMap<QueryId, ReadonlyMap<string, ResultType>>();\n\n/** The result-type markers of a query's output columns (read by the driver when it decodes rows). */\nexport const markersOf = (queryId: QueryId): ReadonlyMap<string, ResultType> | undefined =>\n MARKERS.get(queryId);\n\n/** `asc`/`desc` from an order item's direction node (Kysely emits it as a raw `asc`/`desc`). */\nconst directionOf = (node: OrderByItemNode): 'asc' | 'desc' => {\n const direction = node.direction;\n if (direction && RawNode.is(direction)) {\n return direction.sqlFragments.join('').trim().toLowerCase() === 'desc' ? 'desc' : 'asc';\n }\n return 'asc';\n};\n\n/** Writes bound values as literals (SQLite proves a partial index's WHERE only from literal values). */\nclass InlineValues extends OperationNodeTransformer {\n protected override transformValue(node: ValueNode): ValueNode {\n return node.immediate ? node : ValueNode.createImmediate(node.value);\n }\n}\n\nconst inlineValues = new InlineValues();\n\n/** The conflict target's WHERE (matching a partial unique index) with its values written inline. */\nconst withInlineIndexWhere = (node: OnConflictNode): OnConflictNode =>\n node.indexWhere\n ? Object.freeze({ ...node, indexWhere: inlineValues.transformNode(node.indexWhere) })\n : node;\n\nclass SqliteTransformer extends OperationNodeTransformer {\n #insertTable: string | undefined;\n\n protected override transformSelectQuery(node: SelectQueryNode, queryId?: QueryId): SelectQueryNode {\n const transformed = super.transformSelectQuery(node, queryId);\n const modifiers = transformed.endModifiers?.filter(\n (modifier) => modifier.modifier === undefined || !ROW_LOCKS.has(modifier.modifier),\n );\n if (modifiers === transformed.endModifiers) {\n return transformed;\n }\n return Object.freeze({\n ...transformed,\n endModifiers: modifiers?.length ? Object.freeze(modifiers) : undefined,\n });\n }\n\n /** PostgreSQL places NULLs last ascending and first descending; SQLite does the reverse. Keep PostgreSQL's. */\n protected override transformOrderByItem(node: OrderByItemNode, queryId?: QueryId): OrderByItemNode {\n const transformed = super.transformOrderByItem(node, queryId);\n if (transformed.nulls) {\n return transformed;\n }\n const rawOrder = RawNode.is(transformed.orderBy) ? transformed.orderBy.sqlFragments.join(' ') : '';\n if (/\\b(asc|desc|nulls)\\s*$/i.test(rawOrder)) {\n throw new Error(\n `Write the direction with orderBy(expr, 'asc' | 'desc'), not inside raw SQL: ${rawOrder}`,\n );\n }\n return Object.freeze({ ...transformed, nulls: directionOf(transformed) === 'asc' ? 'last' : 'first' });\n }\n\n protected override transformInsertQuery(node: InsertQueryNode, queryId?: QueryId): InsertQueryNode {\n const previous = this.#insertTable;\n this.#insertTable = node.into?.table.identifier.name;\n try {\n return super.transformInsertQuery(node, queryId);\n } finally {\n this.#insertTable = previous;\n }\n }\n\n /** A column target on a NULLS NOT DISTINCT constraint becomes the SQLite index's expressions. */\n protected override transformOnConflict(node: OnConflictNode, queryId?: QueryId): OnConflictNode {\n const transformed = withInlineIndexWhere(super.transformOnConflict(node, queryId));\n const columns = transformed.columns?.map((column) => column.column.name);\n const index =\n columns && this.#insertTable !== undefined\n ? nullsNotDistinctIndexFor(this.#insertTable, columns)\n : undefined;\n if (!index) {\n return transformed;\n }\n return Object.freeze({\n ...transformed,\n columns: undefined,\n indexExpression: RawNode.createWithSql(indexExpressionSql(index)),\n });\n }\n\n /** SQLite has no DEFAULT keyword in VALUES; Kysely would write NULL there instead of the default. */\n protected override transformDefaultInsertValue(_node: DefaultInsertValueNode): DefaultInsertValueNode {\n throw new Error(\n 'A multi-row insert leaves a column out of some rows; SQLite cannot insert DEFAULT there. Give every row the same columns.',\n );\n }\n}\n\n/**\n * Adapts Kysely queries written for PostgreSQL to SQLite (dialect boundary, ADR 0001): drops row locks,\n * spells out PostgreSQL's NULL ordering, retargets conflicts on NULLS NOT DISTINCT constraints and records\n * the result-type markers of computed columns for the driver.\n */\nexport class SqlitePlugin implements KyselyPlugin {\n readonly #transformer = new SqliteTransformer();\n\n transformQuery({ node, queryId }: PluginTransformQueryArgs): RootOperationNode {\n const markers = collectMarkers(node);\n if (markers) {\n MARKERS.set(queryId, markers);\n }\n return this.#transformer.transformNode(node, queryId);\n }\n\n async transformResult({ result }: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>> {\n return result;\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\n/**\n * The single writer (ADR 0001, \"Dialect boundary\"): SQLite allows one write transaction at a time, and a\n * second connection asking for it would block the whole event loop in `busy_timeout`. So every write in\n * this process queues here first, and only the holder talks to the write connection.\n *\n * On PostgreSQL, code inside a transaction may still write through the pool (another connection). On SQLite\n * that write would wait for the transaction that is waiting for it: a silent hang. Transactions therefore run\n * inside a `TransactionScope`, and a write that would queue behind its own enclosing write transaction fails\n * at once with `SqliteNestedWriteError` instead.\n */\nexport type TransactionScope = { holdsWriteLock: boolean; parent: TransactionScope | undefined };\n\nconst scopes = new AsyncLocalStorage<TransactionScope>();\n\n/** Runs `fn` (a Kysely transaction, including its begin) in a fresh transaction scope. */\nexport const runInTransactionScope = <T>(fn: () => Promise<T>): Promise<T> =>\n scopes.run({ holdsWriteLock: false, parent: scopes.getStore() }, fn);\n\n/** Whether `scope` or a transaction enclosing it holds the write lock. */\nconst insideWriter = (scope: TransactionScope | undefined): boolean => {\n for (let current = scope; current; current = current.parent) {\n if (current.holdsWriteLock) {\n return true;\n }\n }\n return false;\n};\n\nexport const currentTransactionScope = (): TransactionScope | undefined => scopes.getStore();\n\nexport class SqliteNestedWriteError extends Error {\n constructor(statement: string) {\n super(\n 'A write outside the open SQLite write transaction would wait for that transaction forever. ' +\n `Run it on the transaction (trx) instead: ${statement.slice(0, 200)}`,\n );\n this.name = 'SqliteNestedWriteError';\n }\n}\n\nexport class WriteLock {\n #tail: Promise<void> = Promise.resolve();\n #holder: TransactionScope | undefined;\n\n /**\n * Waits for the write lock and returns its release function. `scope` is the transaction taking it (it\n * then holds the lock until commit or rollback), or undefined for one autocommit statement.\n */\n async acquire(statement: string, scope: TransactionScope | undefined): Promise<() => void> {\n if (this.#holder !== undefined && insideWriter(scopes.getStore())) {\n throw new SqliteNestedWriteError(statement);\n }\n const previous = this.#tail;\n let release!: () => void;\n this.#tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous;\n this.#holder = scope;\n if (scope) {\n scope.holdsWriteLock = true;\n }\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n if (scope) {\n scope.holdsWriteLock = false;\n }\n this.#holder = undefined;\n release();\n };\n }\n}\n","import { resolve } from 'node:path';\nimport {\n InsertQueryNode,\n RawNode,\n SelectQueryNode,\n UpdateQueryNode,\n type CompiledQuery,\n type DatabaseConnection,\n type Driver,\n type QueryResult,\n type TransactionSettings,\n} from 'kysely';\nimport type { SqliteLocation } from '../dialect.js';\nimport { SqliteConnection, type StatementContext } from './connection.js';\nimport { markersOf } from './plugin.js';\nimport { currentTransactionScope, WriteLock } from './writeLock.js';\n\nexport type SqliteDriverOptions = {\n location: SqliteLocation;\n /** Read connections (read-only transactions run on their own; autocommit reads share one). */\n readers: number;\n busyTimeoutMs: number;\n strict: boolean;\n};\n\n/** Statement text that may write (or call a function that writes). Anything unsure counts as a write. */\nconst WRITE_WORDS =\n /\\b(insert|update|delete|replace|create|drop|alter|vacuum|pragma|shapio_nextval|begin|commit|rollback|savepoint|release)\\b/i;\n\nconst isRead = (query: CompiledQuery): boolean => {\n if (SelectQueryNode.is(query.query)) {\n return !query.sql.includes('shapio_nextval(');\n }\n if (RawNode.is(query.query)) {\n return /^\\s*(select|with)\\b/i.test(query.sql) && !WRITE_WORDS.test(query.sql);\n }\n return false;\n};\n\nconst tableNameOf = (node: unknown): string | undefined => {\n const table = (node as { table?: { identifier?: { name?: string } } } | undefined)?.table;\n return table?.identifier?.name;\n};\n\nconst writtenTableOf = (query: CompiledQuery): string | undefined => {\n const node = query.query;\n if (InsertQueryNode.is(node)) {\n return tableNameOf(node.into);\n }\n if (UpdateQueryNode.is(node) && node.table) {\n return tableNameOf(node.table) ?? tableNameOf((node.table as { node?: unknown }).node);\n }\n return undefined;\n};\n\n/**\n * The key a database's notification bus and session locks use: the absolute file path (every in-memory\n * database shares one key; notifications are only hints).\n */\nexport const notificationKeyOf = (location: SqliteLocation): string =>\n location.kind === 'memory' ? ':memory:' : resolve(location.path);\n\nconst contextOf = (query: CompiledQuery): StatementContext => ({\n markers: markersOf(query.queryId),\n writtenTable: writtenTableOf(query),\n handWritten: RawNode.is(query.query),\n});\n\n/** How often the writer refreshes the query planner's statistics. */\nexport const STATISTICS_INTERVAL_MS = 10 * 60 * 1000;\n\n/**\n * Planner statistics (`sqlite_stat1`), as SQLite recommends for long-lived connections: `full` also\n * analyzes tables that were never analyzed (0x10000: every table, not only those this connection queried);\n * `refresh` re-analyzes the tables whose size changed a lot since. Both are usually no-ops. Without\n * statistics SQLite cannot tell that a list in `created_at` order is best read through the entries index.\n * A connection loads statistics when it opens (or its schema changes), so when they change the readers\n * are reopened: idle ones at once, busy ones when released.\n */\nconst OPTIMIZE = { full: 'pragma optimize=0x10002', refresh: 'pragma optimize' } as const;\n\n/**\n * A Kysely driver over Node's built-in `node:sqlite` (no native dependency). One writer connection runs\n * every write, serialised by an in-process lock (`writeLock.ts`, `BEGIN IMMEDIATE`); reader connections\n * serve read-only transactions and autocommit reads concurrently (WAL). An in-memory database has the\n * writer only, and every statement takes the lock.\n */\nexport class SqliteDriver implements Driver {\n readonly #options: SqliteDriverOptions;\n readonly #writeLock = new WriteLock();\n readonly databaseKey: string;\n #writer: SqliteConnection | undefined;\n #autocommitReader: SqliteConnection | undefined;\n #idleReaders: SqliteConnection[] = [];\n #openReaders = 0;\n #readerWaiters: Array<(reader: SqliteConnection) => void> = [];\n #allConnections: SqliteConnection[] = [];\n #statisticsTimer: NodeJS.Timeout | undefined;\n /** Bumped when the statistics change; a reader opened under an older one is closed on release. */\n #statisticsGeneration = 0;\n readonly #readerGenerations = new WeakMap<SqliteConnection, number>();\n\n constructor(options: SqliteDriverOptions) {\n this.#options = options;\n this.databaseKey = notificationKeyOf(options.location);\n }\n\n get #hasReaders(): boolean {\n return this.#options.location.kind === 'file';\n }\n\n #open(role: 'writer' | 'reader'): SqliteConnection {\n const connection = new SqliteConnection({\n location: this.#options.location.kind === 'memory' ? ':memory:' : this.databaseKey,\n databaseKey: this.databaseKey,\n role,\n busyTimeoutMs: this.#options.busyTimeoutMs,\n strict: this.#options.strict,\n });\n this.#allConnections.push(connection);\n if (role === 'reader') {\n this.#readerGenerations.set(connection, this.#statisticsGeneration);\n }\n return connection;\n }\n\n #close(connection: SqliteConnection): void {\n connection.close();\n this.#allConnections = this.#allConnections.filter((candidate) => candidate !== connection);\n }\n\n /** Closes readers that hold old statistics: the autocommit one and idle ones now, busy ones on release. */\n #retireReaders(): void {\n this.#statisticsGeneration += 1;\n if (this.#autocommitReader) {\n // Statements run synchronously, so no statement is running on it between awaits.\n this.#close(this.#autocommitReader);\n this.#autocommitReader = undefined;\n }\n for (const reader of this.#idleReaders) {\n this.#close(reader);\n this.#openReaders -= 1;\n }\n this.#idleReaders = [];\n }\n\n get writer(): SqliteConnection {\n if (!this.#writer) {\n this.#writer = this.#open('writer');\n // Nothing else can use a writer that is being opened, so this runs outside the write lock.\n this.#writer.exec(OPTIMIZE.full);\n this.#statisticsTimer = setInterval(() => {\n this.optimizeStatistics('refresh').catch((error: unknown) => {\n process.emitWarning(`SQLite statistics refresh (PRAGMA optimize) failed: ${String(error)}`);\n });\n }, STATISTICS_INTERVAL_MS);\n this.#statisticsTimer.unref();\n }\n return this.#writer;\n }\n\n /** Refreshes planner statistics on the writer, between write transactions (after migrations: `full`). */\n async optimizeStatistics(mode: keyof typeof OPTIMIZE): Promise<void> {\n const release = await this.lockWriter(OPTIMIZE[mode], false);\n try {\n const before = this.writer.statistics();\n this.writer.exec(OPTIMIZE[mode]);\n if (this.writer.statistics() !== before) {\n this.#retireReaders();\n }\n } finally {\n release();\n }\n }\n\n async init(): Promise<void> {\n // Opening the writer first creates the file and switches it to WAL before any reader opens it.\n void this.writer;\n }\n\n async acquireConnection(): Promise<DatabaseConnection> {\n return new SqliteSession(this);\n }\n\n async beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void> {\n await (connection as SqliteSession).begin(settings.accessMode === 'read only');\n }\n\n async commitTransaction(connection: DatabaseConnection): Promise<void> {\n (connection as SqliteSession).commit();\n }\n\n async rollbackTransaction(connection: DatabaseConnection): Promise<void> {\n (connection as SqliteSession).rollback();\n }\n\n async savepoint(connection: DatabaseConnection, savepointName: string): Promise<void> {\n (connection as SqliteSession).savepointCommand('savepoint', savepointName);\n }\n\n async rollbackToSavepoint(connection: DatabaseConnection, savepointName: string): Promise<void> {\n (connection as SqliteSession).savepointCommand('rollback to', savepointName);\n }\n\n async releaseSavepoint(connection: DatabaseConnection, savepointName: string): Promise<void> {\n (connection as SqliteSession).savepointCommand('release', savepointName);\n }\n\n async releaseConnection(connection: DatabaseConnection): Promise<void> {\n (connection as SqliteSession).release();\n }\n\n async destroy(): Promise<void> {\n clearInterval(this.#statisticsTimer);\n this.#statisticsTimer = undefined;\n for (const connection of this.#allConnections) {\n connection.close();\n }\n this.#allConnections = [];\n this.#writer = undefined;\n this.#autocommitReader = undefined;\n this.#idleReaders = [];\n }\n\n /** Takes the write lock for one statement or a whole transaction (see `writeLock.ts`). */\n lockWriter(statement: string, transaction: boolean): Promise<() => void> {\n return this.#writeLock.acquire(statement, transaction ? currentTransactionScope() : undefined);\n }\n\n /** The connection autocommit reads use: a reader, or the writer for an in-memory database. */\n readerForStatement(): SqliteConnection | undefined {\n if (!this.#hasReaders) {\n return undefined;\n }\n this.#autocommitReader ??= this.#open('reader');\n return this.#autocommitReader;\n }\n\n /** A reader for a read-only transaction; waits when `readers` are all in use. */\n async acquireReader(): Promise<SqliteConnection | undefined> {\n if (!this.#hasReaders) {\n return undefined;\n }\n const idle = this.#idleReaders.pop();\n if (idle) {\n return idle;\n }\n if (this.#openReaders < this.#options.readers) {\n this.#openReaders += 1;\n return this.#open('reader');\n }\n return new Promise((resolve) => this.#readerWaiters.push(resolve));\n }\n\n releaseReader(released: SqliteConnection): void {\n let reader = released;\n if ((this.#readerGenerations.get(released) ?? 0) < this.#statisticsGeneration) {\n this.#close(released);\n reader = this.#open('reader');\n }\n const waiter = this.#readerWaiters.shift();\n if (waiter) {\n waiter(reader);\n } else {\n this.#idleReaders.push(reader);\n }\n }\n}\n\n/**\n * The connection Kysely holds for one query or transaction. It binds to a physical connection lazily:\n * a write transaction to the writer (holding the write lock until it ends), a read-only one to a reader, and\n * a single statement to whichever fits.\n */\nclass SqliteSession implements DatabaseConnection {\n readonly #driver: SqliteDriver;\n #transaction: SqliteConnection | undefined;\n #releaseWriteLock: (() => void) | undefined;\n\n constructor(driver: SqliteDriver) {\n this.#driver = driver;\n }\n\n async begin(readOnly: boolean): Promise<void> {\n const reader = readOnly ? await this.#driver.acquireReader() : undefined;\n if (reader) {\n try {\n reader.begin('deferred');\n } catch (error) {\n this.#driver.releaseReader(reader);\n throw error;\n }\n this.#transaction = reader;\n return;\n }\n const release = await this.#driver.lockWriter('begin', true);\n try {\n this.#driver.writer.begin('immediate');\n } catch (error) {\n release();\n throw error;\n }\n this.#releaseWriteLock = release;\n this.#transaction = this.#driver.writer;\n }\n\n #finish(end: (connection: SqliteConnection) => void): void {\n const connection = this.#transaction;\n if (!connection) {\n return;\n }\n this.#transaction = undefined;\n try {\n end(connection);\n } finally {\n if (connection.role === 'reader') {\n this.#driver.releaseReader(connection);\n } else {\n this.#releaseWriteLock?.();\n this.#releaseWriteLock = undefined;\n }\n }\n }\n\n commit(): void {\n this.#finish((connection) => connection.commit());\n }\n\n rollback(): void {\n this.#finish((connection) => connection.rollback());\n }\n\n /** Kysely releases the connection after a failed begin or commit too: never leave a lock behind. */\n release(): void {\n if (this.#transaction) {\n this.rollback();\n }\n }\n\n savepointCommand(command: 'savepoint' | 'rollback to' | 'release', name: string): void {\n if (!this.#transaction) {\n throw new Error('Savepoints need an open transaction');\n }\n this.#transaction.exec(`${command} \"${name.replace(/\"/g, '\"\"')}\"`);\n }\n\n async executeQuery<R>(query: CompiledQuery): Promise<QueryResult<R>> {\n const context = contextOf(query);\n if (this.#transaction) {\n return this.#transaction.execute<R>(query, context);\n }\n const reader = isRead(query) ? this.#driver.readerForStatement() : undefined;\n if (reader) {\n return reader.execute<R>(query, context);\n }\n const release = await this.#driver.lockWriter(query.sql, false);\n try {\n return this.#driver.writer.execute<R>(query, context);\n } finally {\n release();\n }\n }\n\n async *streamQuery<R>(query: CompiledQuery): AsyncIterableIterator<QueryResult<R>> {\n const result = await this.executeQuery<R>(query);\n for (const row of result.rows) {\n yield { rows: [row] };\n }\n }\n}\n","import {\n Kysely,\n SqliteAdapter,\n SqliteIntrospector,\n SqliteQueryCompiler,\n type DatabaseIntrospector,\n type Dialect,\n type Driver,\n type KyselyConfig,\n type TransactionBuilder,\n} from 'kysely';\nimport type { SqliteLocation } from '../dialect.js';\nimport { SqliteDriver } from './driver.js';\nimport { SqlitePlugin } from './plugin.js';\nimport { runInTransactionScope } from './writeLock.js';\n\n/**\n * SQLite runs DDL inside transactions, so each migration commits or rolls back whole. The driver handles\n * concurrency itself (one writer, several readers), so Kysely must not serialise connections on top.\n */\nclass ShapioSqliteAdapter extends SqliteAdapter {\n override get supportsTransactionalDdl(): boolean {\n return true;\n }\n\n override get supportsMultipleConnections(): boolean {\n return true;\n }\n}\n\nclass ShapioSqliteDialect implements Dialect {\n readonly driver: SqliteDriver;\n\n constructor(driver: SqliteDriver) {\n this.driver = driver;\n }\n\n createAdapter() {\n return new ShapioSqliteAdapter();\n }\n\n createDriver(): Driver {\n return this.driver;\n }\n\n createIntrospector(db: Kysely<unknown>): DatabaseIntrospector {\n return new SqliteIntrospector(db);\n }\n\n createQueryCompiler() {\n return new SqliteQueryCompiler();\n }\n}\n\n/** Runs every `execute` of a transaction builder (and of the builders it returns) in a transaction scope. */\nconst scoped = <DB>(builder: TransactionBuilder<DB>): TransactionBuilder<DB> =>\n new Proxy(builder, {\n get(target, property, receiver) {\n if (property === 'execute') {\n return <T>(callback: Parameters<TransactionBuilder<DB>['execute']>[0]) =>\n runInTransactionScope(() => target.execute(callback) as Promise<T>);\n }\n if (property === 'setIsolationLevel' || property === 'setAccessMode') {\n return (value: never) => scoped(target[property](value));\n }\n return Reflect.get(target, property, receiver) as unknown;\n },\n });\n\n/**\n * Kysely on SQLite. Transactions run in a scope so a write that would wait for its own enclosing write\n * transaction fails at once instead of hanging (`writeLock.ts`).\n */\nexport class SqliteKysely<DB> extends Kysely<DB> {\n readonly sqliteDriver: SqliteDriver;\n\n constructor(config: KyselyConfig & { dialect: ShapioSqliteDialect }) {\n super(config);\n this.sqliteDriver = config.dialect.driver;\n }\n\n override transaction(): TransactionBuilder<DB> {\n return scoped(super.transaction());\n }\n}\n\nexport type CreateSqliteDbOptions = {\n location: SqliteLocation;\n readers: number;\n busyTimeoutMs?: number;\n strict?: boolean;\n};\n\nexport const DEFAULT_BUSY_TIMEOUT_MS = 5000;\n\nexport const createSqliteDb = <DB>({\n location,\n readers,\n busyTimeoutMs = DEFAULT_BUSY_TIMEOUT_MS,\n strict = false,\n}: CreateSqliteDbOptions): SqliteKysely<DB> =>\n new SqliteKysely<DB>({\n dialect: new ShapioSqliteDialect(new SqliteDriver({ location, readers, busyTimeoutMs, strict })),\n plugins: [new SqlitePlugin()],\n });\n\n/** The SQLite driver behind a handle, or undefined for another dialect. */\nexport const sqliteDriverOf = (db: unknown): SqliteDriver | undefined =>\n db instanceof SqliteKysely ? db.sqliteDriver : undefined;\n\nexport type { SqliteDriver };\n","import { createHash } from 'node:crypto';\nimport { sql, type Kysely, type Transaction } from 'kysely';\nimport { sleep } from '../helpers/sleep.js';\nimport { isMysql, isSqlite } from './dialect.js';\nimport { sqliteDriverOf } from './sqlite/index.js';\nimport { withKeyedMutex } from './sqlite/keyedMutex.js';\nimport type { DB } from './types.js';\n\n/**\n * Advisory-lock primitives. Kept in `db/` beside the Kysely instance so no other module writes lock SQL.\n * Keys are (namespace, key) int4 pairs; see constants/lockKeys.ts.\n *\n * PostgreSQL: advisory locks. SQLite (single process): session locks are an in-process mutex per database\n * and key; transaction locks are checks only, because every write transaction already holds SQLite's single\n * write lock, so no other transaction can run while one holds them.\n */\n\n/** Stable 32-bit signed key for a string ID (e.g. a model UUID). Collisions only cost extra serialization. */\nexport const lockKeyFromId = (id: string): number => createHash('sha256').update(id).digest().readInt32BE(0);\n\n/** The in-process mutex standing in for a session lock on a SQLite handle, or undefined on PostgreSQL. */\nconst sqliteSessionLock = <T>(\n db: Kysely<DB>,\n namespace: number,\n key: number,\n fn: () => Promise<T>,\n): Promise<T> | undefined => {\n const driver = sqliteDriverOf(db);\n return driver && withKeyedMutex(`${driver.databaseKey}:${namespace}:${key}`, fn);\n};\n\n/** MySQL: the `GET_LOCK` name of a (namespace, key) pair in this database (at most 64 characters). */\nconst mysqlLockName = (namespace: number, key: number) =>\n sql`concat('shapio:', left(sha2(database(), 256), 16), ':', ${namespace}, ':', ${key})`;\n\nconst mysqlSessionLock = <T>(\n db: Kysely<DB>,\n namespace: number,\n key: number,\n fn: () => Promise<T>,\n pollMs: number | undefined,\n): Promise<T> =>\n db.connection().execute(async (connection) => {\n const name = mysqlLockName(namespace, key);\n const tryLock = async (timeout: number) =>\n String(\n (await sql<{ locked: unknown }>`select get_lock(${name}, ${timeout}) as locked`.execute(connection))\n .rows[0]?.locked,\n ) === '1';\n if (pollMs === undefined) {\n if (!(await tryLock(-1))) {\n throw new Error(`Could not take MySQL lock ${namespace}:${key}`);\n }\n } else {\n while (!(await tryLock(0))) {\n await sleep(pollMs);\n }\n }\n try {\n return await fn();\n } finally {\n await sql`select release_lock(${name})`.execute(connection);\n }\n });\n\n/**\n * Holds a session-level advisory lock on a dedicated pooled connection while `fn` runs, then releases it.\n * `fn` may use the pool freely (it does not run on the locking connection). Blocks until the lock is free.\n */\nexport const withSessionAdvisoryLock = async <T>(\n db: Kysely<DB>,\n namespace: number,\n key: number,\n fn: () => Promise<T>,\n): Promise<T> =>\n sqliteSessionLock(db, namespace, key, fn) ??\n (isMysql() ? mysqlSessionLock(db, namespace, key, fn, undefined) : undefined) ??\n db.connection().execute(async (connection) => {\n await sql`select pg_advisory_lock(${namespace}::int4, ${key}::int4)`.execute(connection);\n try {\n return await fn();\n } finally {\n await sql`select pg_advisory_unlock(${namespace}::int4, ${key}::int4)`.execute(connection);\n }\n });\n\n/**\n * Like `withSessionAdvisoryLock`, but waits by polling `pg_try_advisory_lock` between pauses instead of\n * blocking inside a statement. Use it around `CREATE INDEX CONCURRENTLY`: a session blocked in\n * `pg_advisory_lock` is an open transaction with a snapshot, which a concurrent index build waits for while\n * its own job holds the lock — a wait cycle PostgreSQL does not detect. (SQLite has no such cycle: the\n * plain mutex.)\n */\nexport const withPolledSessionAdvisoryLock = async <T>(\n db: Kysely<DB>,\n namespace: number,\n key: number,\n fn: () => Promise<T>,\n pollMs = 200,\n): Promise<T> =>\n sqliteSessionLock(db, namespace, key, fn) ??\n (isMysql() ? mysqlSessionLock(db, namespace, key, fn, pollMs) : undefined) ??\n db.connection().execute(async (connection) => {\n const tryLock = async () =>\n (\n await sql<{\n locked: boolean;\n }>`select pg_try_advisory_lock(${namespace}::int4, ${key}::int4) as locked`.execute(connection)\n ).rows[0]?.locked === true;\n while (!(await tryLock())) {\n await sleep(pollMs);\n }\n try {\n return await fn();\n } finally {\n await sql`select pg_advisory_unlock(${namespace}::int4, ${key}::int4)`.execute(connection);\n }\n });\n\n/** On SQLite a transaction lock only checks that `trx` is a write transaction (see above). */\nconst assertSqliteWriteTransaction = async (trx: Transaction<DB>): Promise<void> => {\n await sql`select shapio_assert_write_transaction()`.execute(trx);\n};\n\n/** MySQL: an exclusive row lock on the pair's row (created if missing), held until commit or rollback. */\nconst mysqlExclusiveRowLock = async (trx: Transaction<DB>, namespace: number, key: number) => {\n await sql`insert into advisory_locks (namespace, lock_key) values (${namespace}, ${key})\n on duplicate key update lock_key = lock_key`.execute(trx);\n};\n\n/**\n * MySQL: a shared row lock on the pair's row. The first lock of a pair creates its row, which takes the\n * row exclusively for that one transaction (stronger than shared, so still correct).\n */\nconst mysqlSharedRowLock = async (trx: Transaction<DB>, namespace: number, key: number) => {\n const { rows } = await sql`select 1 from advisory_locks\n where namespace = ${namespace} and lock_key = ${key} for share`.execute(trx);\n if (rows.length === 0) {\n await mysqlExclusiveRowLock(trx, namespace, key);\n }\n};\n\n/** Exclusive transaction-level lock, released at commit/rollback. */\nexport const acquireXactLock = async (\n trx: Transaction<DB>,\n namespace: number,\n key: number,\n): Promise<void> => {\n if (isSqlite()) {\n return assertSqliteWriteTransaction(trx);\n }\n if (isMysql()) {\n return mysqlExclusiveRowLock(trx, namespace, key);\n }\n await sql`select pg_advisory_xact_lock(${namespace}::int4, ${key}::int4)`.execute(trx);\n};\n\n/** Shared transaction-level lock: many holders at once, blocks (and is blocked by) the exclusive form. */\nexport const acquireXactLockShared = async (\n trx: Transaction<DB>,\n namespace: number,\n key: number,\n): Promise<void> => {\n if (isSqlite()) {\n return assertSqliteWriteTransaction(trx);\n }\n if (isMysql()) {\n return mysqlSharedRowLock(trx, namespace, key);\n }\n await sql`select pg_advisory_xact_lock_shared(${namespace}::int4, ${key}::int4)`.execute(trx);\n};\n"],"mappings":";;;;;;;;;;;;AAIA,IAAa,WAAb,cAA8B,MAAM;CAClC;CACA;CACA;CAEA,YAAY,YAAoB,MAAc,SAAiB,SAAmB,SAAwB;EACxG,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO;EACZ,KAAK,aAAa;EAClB,KAAK,OAAO;EACZ,KAAK,UAAU;CACjB;AACF;;;;;;;;;;;;;;;;;;;;;;;ACOA,IAAa,iBAAb,cAAoC,UAAU;CAC5C,YAAY,OAAe,OAAgB;EACzC,MAAM,OAAO,UAAU,KAAA,IAAY,cAAe,OAAO,aAAa,QAAQ,OAAO;EACrF,MAAM,eAAe,KAAK,sBAAsB,QAAQ,GAAG;EAC3D,KAAK,OAAO;CACd;AACF;AAEA,MAAM,OAAO,OAAe,QAAQ,MAAM,OAAO,KAAK,CAAC,CAAC,SAAS,OAAO,GAAG;;AAG3E,MAAa,kBAAkB,SAC7B,GAAG,KAAK,eAAe,EAAE,GAAG,IAAI,KAAK,YAAY,IAAI,CAAC,EAAE,GAAG,IAAI,KAAK,WAAW,CAAC,EAAE,GAC/E,IAAI,KAAK,YAAY,CAAC,EAAE,GAAG,IAAI,KAAK,cAAc,CAAC,EAAE,GAAG,IAAI,KAAK,cAAc,CAAC,EAAE,GAAG,IAAI,KAAK,mBAAmB,GAAG,CAAC;AAE1H,MAAM,UAAU;;;;;AAMhB,MAAa,kBAAkB,UAAiC;CAC9D,IAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,QAAQ,QAAQ,KAAK,KAAK;EAChC,IAAI,OACF,OAAO,GAAG,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,MAAM,MAAM,GAAA,CAAI,OAAO,GAAG,GAAG;CAEpE;CACA,MAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;CAC3D,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAC7B,MAAM,IAAI,WAAW,sBAAsB,OAAO,KAAK,GAAG;CAE5D,OAAO,eAAe,IAAI;AAC5B;AAEA,MAAMA,mBAAiB,UAA2B;CAChD,MAAM,YAAY,OAAO,eAAe,KAAK;CAC7C,OAAO,cAAc,OAAO,aAAa,cAAc;AACzD;;AAGA,MAAaC,qBAAmB,OAAgB,UAA2B;CACzE,QAAQ,OAAO,OAAf;EACE,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK,WACH,OAAO,QAAQ,IAAI;EACrB,KAAK;GACH,IAAI,UAAU,QAAQ,iBAAiB,YACrC,OAAO;GAET,IAAI,iBAAiB,MACnB,OAAO,eAAe,KAAK;GAE7B,IAAI,MAAM,QAAQ,KAAK,KAAKD,gBAAc,KAAK,GAC7C,OAAO,KAAK,UAAU,KAAK;GAE7B,MAAM,IAAI,eAAe,OAAO,KAAK;EACvC,SACE,MAAM,IAAI,eAAe,OAAO,KAAK;CACzC;AACF;;;;;AAMA,MAAa,YAAsB,OAAO,SAAS;CACjD,IAAI,MAAM,SAAS,UAAU,MAAM,WAAW,GAAG;EAC/C,MAAM,OAAO,MAAM,OAAO;EAC1B,OAAO,SAAS,OAAO,OAAO,SAAS;CACzC;CACA,IAAI,MAAM,SAAS,QACjB,OAAO,MAAM,OAAO;CAEtB,OAAO,KAAK;AACd;;;ACpFA,MAAM,yBAAS,IAAI,QAAmC;;AAGtD,MAAa,oBAAoB,SAAgD,OAAO,IAAI,IAAI;;;;;;;;;;;;;;;;;;ACChG,MAAa,qBAAqB,UAAiC;CACjE,MAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;CAC3D,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAC7B,MAAM,IAAI,WAAW,sBAAsB,OAAO,KAAK,GAAG;CAE5D,OAAO,KAAK,YAAY;AAC1B;;;ACfA,MAAME,WAAS,IAAI,kBAAmC;AAEtD,IAAa,yBAAb,cAA4C,MAAM;CAChD,cAAc;EACZ,MACE,oKAEF;EACA,KAAK,OAAO;CACd;AACF;AAEA,MAAM,mBAAmB,UAAgD;CACvE,KAAK,IAAI,UAAU,OAAO,SAAS,UAAU,QAAQ,QACnD,IAAI,QAAQ,UACV,OAAO;CAGX,OAAO;AACT;;;;;;AAOA,MAAa,wBAA8B;CACzC,MAAM,QAAQA,SAAO,SAAS;CAC9B,IAAI,CAAC,OACH;CAEF,IAAI,gBAAgB,KAAK,GACvB,MAAM,IAAI,uBAAuB;CAEnC,MAAM,WAAW;AACnB;;;;;AAMA,MAAa,0BAA6B,OAAmBA,SAAO,KAAK,EAAE;;AAG3E,MAAa,uBAA2B,YACtC,IAAI,MAAM,SAAS,EACjB,IAAI,QAAQ,UAAU,UAAU;CAC9B,IAAI,aAAa,WACf,QAAW,aACTA,SAAO,IACL;EAAE,UAAU;EAAO,QAAQA,SAAO,SAAS;CAAE,SACvC,OAAO,QAAQ,QAAQ,CAC/B;CAEJ,IAAI,aAAa,uBAAuB,aAAa,iBACnD,QAAQ,UAAiB,oBAAoB,OAAO,SAAS,CAAC,KAAK,CAAC;CAEtE,OAAO,QAAQ,IAAI,QAAQ,UAAU,QAAQ;AAC/C,EACF,CAAC;;;AC9CH,MAAa,eAAyD;CACpE,mBAAmB;EACjB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GAAC;GAAc;GAAc;GAAe;EAAY;EAClE,YAAY;GAAC;GAAc;GAAe;GAAc;GAAc;EAAY;EAClF,YAAY,CACV;GAAE,MAAM;GAA0B,SAAS,CAAC,IAAI;EAAE,GAClD;GAAE,MAAM;GAAoC,SAAS,CAAC,YAAY;EAAE,CACtE;CACF;CACA,wBAAwB;EACtB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GAAC;GAAM;GAAW;GAAU;GAAY;GAAa;GAAa;GAAc;EAAY;EACrG,UAAU;GAAC;GAAY;GAAa;EAAW;EAC/C,YAAY,CAAC,cAAc,YAAY;EACvC,YAAY,CACV;GAAE,MAAM;GAAmC,SAAS;IAAC;IAAW;IAAU;GAAU;EAAE,GACtF;GAAE,MAAM;GAA+B,SAAS,CAAC,IAAI;EAAE,CACzD;CACF;CACA,aAAa;EACX,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GAAC;GAAM;GAAO;GAAQ;GAAe;GAAQ;GAAa;GAAW;GAAc;EAAY;EACxG,UAAU,CAAC;EACX,YAAY,CAAC,cAAc,YAAY;EACvC,YAAY,CACV;GAAE,MAAM;GAAuB,SAAS,CAAC,KAAK;EAAE,GAChD;GAAE,MAAM;GAAoB,SAAS,CAAC,IAAI;EAAE,CAC9C;CACF;CACA,gBAAgB;EACd,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GAAC;GAAM;GAAc;EAAY;EAC3C,YAAY;GAAC;GAAgB;GAAc;GAAc;GAAc;EAAY;EACnF,YAAY,CACV;GAAE,MAAM;GAAuB,SAAS,CAAC,IAAI;EAAE,GAC/C;GAAE,MAAM;GAAiC,SAAS,CAAC,YAAY;EAAE,CACnE;CACF;CACA,kBAAkB;EAChB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GAAC;GAAiB;GAAW;GAAc;GAAc;GAAW;EAAI;EACjF,UAAU,CAAC,SAAS;EACpB,YAAY,CAAC,cAAc,YAAY;EACvC,YAAY,CACV;GAAE,MAAM;GAAkC,SAAS;IAAC;IAAiB;IAAW;GAAS;EAAE,GAC3F;GAAE,MAAM;GAAuB,SAAS,CAAC,IAAI;EAAE,CACjD;CACF;CACA,aAAa;EACX,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU,CAAC,eAAe;EAC1B,YAAY;GAAC;GAAiB;GAAuB;GAAc;EAAY;EAC/E,YAAY,CACV;GAAE,MAAM;GAAyB,SAAS,CAAC,OAAO;EAAE,GACpD;GAAE,MAAM;GAAoB,SAAS,CAAC,IAAI;EAAE,CAC9C;CACF;CACA,YAAY;EACV,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GAAC;GAAc;GAAc;GAAgB;GAAc;EAAS;EAC9E,YAAY;GAAC;GAAc;GAAgB;GAAc;GAAc;EAAY;EACnF,YAAY,CACV;GAAE,MAAM;GAAmB,SAAS,CAAC,IAAI;EAAE,GAC3C;GAAE,MAAM;GAA6B,SAAS,CAAC,YAAY;EAAE,CAC/D;CACF;CACA,iBAAiB;EACf,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GAAC;GAAM;GAAe;GAAa;GAAc;GAAW;GAAc;EAAgB;EACnG,UAAU,CAAC,SAAS;EACpB,YAAY;GAAC;GAAc;GAAW;EAAY;EAClD,YAAY,CACV;GAAE,MAAM;GAAiC,SAAS,CAAC,WAAW;EAAE,GAChE;GAAE,MAAM;GAAwB,SAAS,CAAC,IAAI;EAAE,CAClD;CACF;CACA,oBAAoB;EAClB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU,CAAC,OAAO;EAClB,YAAY,CAAC,cAAc,YAAY;EACvC,YAAY,CACV;GAAE,MAAM;GAAkC,SAAS;IAAC;IAAW;IAAY;GAAkB;EAAE,GAC/F;GAAE,MAAM;GAA2B,SAAS,CAAC,IAAI;EAAE,CACrD;CACF;CACA,qBAAqB;EACnB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU,CAAC,cAAc,SAAS;EAClC,YAAY;GAAC;GAAc;GAAW;GAAc;EAAY;EAChE,YAAY,CACV;GAAE,MAAM;GAA4B,SAAS,CAAC,IAAI;EAAE,GACpD;GAAE,MAAM;GAAsC,SAAS,CAAC,YAAY;EAAE,CACxE;CACF;CACA,oBAAoB;EAClB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GAAC;GAAW;GAAuB;GAAc;GAAkB;GAAM;EAAY;EAC/F,YAAY;GAAC;GAAc;GAAW;GAAuB;GAAc;EAAY;EACvF,YAAY,CACV;GAAE,MAAM;GAA2B,SAAS,CAAC,IAAI;EAAE,GACnD;GAAE,MAAM;GAAqC,SAAS,CAAC,YAAY;EAAE,CACvE;CACF;CACA,sBAAsB;EACpB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GAAC;GAAM;GAAW;GAAU;GAAY;GAAa;GAAa;GAAc;EAAY;EACrG,UAAU;GAAC;GAAY;GAAa;EAAW;EAC/C,YAAY,CAAC,cAAc,YAAY;EACvC,YAAY,CACV;GAAE,MAAM;GAAiC,SAAS;IAAC;IAAW;IAAU;GAAU;EAAE,GACpF;GAAE,MAAM;GAA6B,SAAS,CAAC,IAAI;EAAE,CACvD;CACF;CACA,WAAW;EACT,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GAAC;GAAM;GAAO;GAAQ;GAAe;GAAa;GAAW;GAAc;EAAY;EAChG,UAAU,CAAC;EACX,YAAY,CAAC,cAAc,YAAY;EACvC,YAAY,CACV;GAAE,MAAM;GAAqB,SAAS,CAAC,KAAK;EAAE,GAC9C;GAAE,MAAM;GAAkB,SAAS,CAAC,IAAI;EAAE,CAC5C;CACF;CACA,gBAAgB;EACd,YAAY,CAAC,eAAe,SAAS;EACrC,SAAS;GAAC;GAAe;GAAW;GAAc;EAAS;EAC3D,UAAU,CAAC;EACX,YAAY,CAAC,YAAY;EACzB,YAAY,CAAC;GAAE,MAAM;GAAqB,SAAS,CAAC,eAAe,SAAS;EAAE,CAAC;CACjF;CACA,WAAW;EACT,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GACR;GACA;GACA;GACA;GACA;GACA;EACF;EACA,YAAY;GACV;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,YAAY,CACV;GAAE,MAAM;GAAsB,SAAS,CAAC,WAAW,OAAO;EAAE,GAC5D;GAAE,MAAM;GAAkB,SAAS,CAAC,IAAI;EAAE,CAC5C;CACF;CACA,aAAa;EACX,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GAAC;GAAQ;GAAc;GAAU;EAAa;EACxD,YAAY,CAAC,cAAc,aAAa;EACxC,YAAY,CAAC;GAAE,MAAM;GAAoB,SAAS,CAAC,IAAI;EAAE,CAAC;CAC5D;CACA,cAAc;EACZ,YAAY,CAAC,IAAI;EACjB,UAAU;EACV,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GAAC;GAAY;GAAe;GAAa;GAAc;GAAM;EAAS;EAChF,YAAY,CAAC,aAAa;EAC1B,YAAY,CACV;GAAE,MAAM;GAAqB,SAAS,CAAC,IAAI;EAAE,GAC7C;GAAE,MAAM;GAAwB,SAAS,CAAC,KAAK;EAAE,CACnD;CACF;CACA,kBAAkB;EAChB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GACR;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,YAAY,CAAC,YAAY;EACzB,YAAY;GACV;IAAE,MAAM;IAA6B,SAAS,CAAC,iBAAiB;GAAE;GAClE;IAAE,MAAM;IAA6B,SAAS;KAAC;KAAiB;KAAY;IAAQ;GAAE;GACtF;IAAE,MAAM;IAAyB,SAAS,CAAC,IAAI;GAAE;EACnD;CACF;CACA,aAAa;EACX,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GACR;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,YAAY;GAAC;GAAiB;GAAc;GAAc;EAAY;EACtE,YAAY,CACV;GAAE,MAAM;GAA0B,SAAS,CAAC,MAAM,SAAS;EAAE,GAC7D;GAAE,MAAM;GAAoB,SAAS,CAAC,IAAI;EAAE,CAC9C;CACF;CACA,yBAAyB;EACvB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU,CAAC,QAAQ,aAAa;EAChC,YAAY;GAAC;GAAiB;GAAgB;EAAa;EAC3D,YAAY,CACV;GACE,MAAM;GACN,SAAS;IAAC;IAAY;IAAU;IAAQ;GAAS;EACnD,GACA;GAAE,MAAM;GAAgC,SAAS,CAAC,IAAI;EAAE,CAC1D;CACF;CACA,mBAAmB;EACjB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU,CAAC,aAAa,oBAAoB;EAC5C,YAAY,CAAC,YAAY;EACzB,YAAY,CAAC;GAAE,MAAM;GAA0B,SAAS,CAAC,IAAI;EAAE,CAAC;CAClE;CACA,wBAAwB;EACtB,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GAAC;GAAoB;GAAwB;EAAY;EACnE,YAAY,CAAC,cAAc,YAAY;EACvC,YAAY,CAAC;GAAE,MAAM;GAA+B,SAAS,CAAC,IAAI;EAAE,CAAC;CACvE;CACA,iBAAiB;EACf,YAAY,CAAC,IAAI;EACjB,WAAW,EAAE,IAAI,OAAO;EACxB,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,UAAU;GACR;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,YAAY;GAAC;GAAgB;GAAe;GAAc;EAAY;EACtE,YAAY,CACV;GAAE,MAAM;GAAwB,SAAS,CAAC,IAAI;EAAE,GAChD;GAAE,MAAM;GAA6B,SAAS,CAAC,eAAe;EAAE,CAClE;CACF;CACA,iBAAiB;EACf,YAA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"}