@prisma-next/adapter-sqlite 0.13.0-dev.15 → 0.13.0-dev.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter-CPydDe3Y.d.mts.map +1 -1
- package/dist/{adapter-BSYqYUMq.mjs → adapter-fApyx9L1.mjs} +113 -82
- package/dist/adapter-fApyx9L1.mjs.map +1 -0
- package/dist/adapter.mjs +1 -1
- package/dist/control.d.mts +17 -1
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +22 -22
- package/src/core/adapter.ts +3 -2
- package/src/core/control-adapter.ts +184 -4
- package/src/core/control-codecs.ts +25 -0
- package/src/core/marker-ledger.ts +2 -18
- package/dist/adapter-BSYqYUMq.mjs.map +0 -1
- package/src/core/ddl-renderer.ts +0 -146
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-CPydDe3Y.d.mts","names":[],"sources":["../src/core/adapter.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"adapter-CPydDe3Y.d.mts","names":[],"sources":["../src/core/adapter.ts"],"mappings":";;;;;;cAoDM,iBAAA,YAA6B,OAAA,CAAQ,WAAA,EAAa,cAAA,EAAgB,sBAAA;EAAA,SAC7D,QAAA;EAAA,SACA,QAAA;EAAA,SAEA,OAAA,EAAS,cAAA;cAEN,OAAA,GAAU,oBAAA;EAyBtB,KAAA,CACE,GAAA,EAAK,WAAA,GAAc,aAAA,EACnB,OAAA,EAAS,cAAA,CAAe,cAAA,IACvB,sBAAA;AAAA;;cAWQ,qBAAA,EAAuB,eAoBnC;AAAA,iBAygBe,mBAAA,CAAoB,OAAA,GAAU,oBAAA,GAAoB,QAAA,CAAA,iBAAA"}
|
|
@@ -1,94 +1,30 @@
|
|
|
1
|
-
import { APP_SPACE_ID } from "@prisma-next/framework-components/control";
|
|
1
|
+
import { APP_SPACE_ID, extractCodecLookup } from "@prisma-next/framework-components/control";
|
|
2
2
|
import { RawExpr, isDdlNode } from "@prisma-next/sql-relational-core/ast";
|
|
3
3
|
import { escapeLiteral, quoteIdentifier } from "@prisma-next/target-sqlite/sql-utils";
|
|
4
4
|
import { parseMarkerRowSafely, withMarkerReadErrorHandling } from "@prisma-next/errors/execution";
|
|
5
5
|
import { parseContractMarkerRow } from "@prisma-next/family-sql/verify";
|
|
6
|
+
import { REFERENTIAL_ACTION_SQL } from "@prisma-next/sql-contract/referential-action-sql";
|
|
7
|
+
import { sqliteCodecRegistry } from "@prisma-next/target-sqlite/codecs";
|
|
6
8
|
import { buildControlTableBootstrapQueries, buildSignMarkerBootstrapQueries, datetime, integer, jsonText, sqliteTable, text } from "@prisma-next/target-sqlite/contract-free";
|
|
7
9
|
import { parseSqliteDefault } from "@prisma-next/target-sqlite/default-normalizer";
|
|
8
10
|
import { normalizeSqliteNativeType } from "@prisma-next/target-sqlite/native-type-normalizer";
|
|
9
11
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
10
12
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
11
|
-
import { REFERENTIAL_ACTION_SQL } from "@prisma-next/sql-contract/referential-action-sql";
|
|
12
13
|
import { createAstCodecRegistry, deriveParamMetadata, encodeParamsWithMetadata } from "@prisma-next/sql-runtime";
|
|
13
14
|
import { SQLITE_DATETIME_CODEC_ID } from "@prisma-next/target-sqlite/codec-ids";
|
|
14
|
-
import { sqliteCodecRegistry } from "@prisma-next/target-sqlite/codecs";
|
|
15
15
|
//#region ../../../1-framework/3-tooling/migration/dist/exports/ledger-origin.mjs
|
|
16
16
|
function ledgerOriginFromStored(originCoreHash) {
|
|
17
17
|
if (originCoreHash === null || originCoreHash === "" || originCoreHash === "sha256:empty") return null;
|
|
18
18
|
return originCoreHash;
|
|
19
19
|
}
|
|
20
20
|
//#endregion
|
|
21
|
-
//#region src/core/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return `PRIMARY KEY (${cols})`;
|
|
29
|
-
}
|
|
30
|
-
function renderForeignKeyConstraint(constraint) {
|
|
31
|
-
const cols = constraint.columns.map(quoteIdentifier).join(", ");
|
|
32
|
-
const refCols = constraint.refColumns.map(quoteIdentifier).join(", ");
|
|
33
|
-
let sql = `FOREIGN KEY (${cols}) REFERENCES ${quoteQualifiedIdentifier(constraint.refTable)} (${refCols})`;
|
|
34
|
-
if (constraint.onDelete !== void 0) sql += ` ON DELETE ${REFERENTIAL_ACTION_SQL[constraint.onDelete]}`;
|
|
35
|
-
if (constraint.onUpdate !== void 0) sql += ` ON UPDATE ${REFERENTIAL_ACTION_SQL[constraint.onUpdate]}`;
|
|
36
|
-
if (constraint.name !== void 0) sql = `CONSTRAINT ${quoteIdentifier(constraint.name)} ${sql}`;
|
|
37
|
-
return sql;
|
|
38
|
-
}
|
|
39
|
-
function renderUniqueConstraint(constraint) {
|
|
40
|
-
const cols = constraint.columns.map(quoteIdentifier).join(", ");
|
|
41
|
-
if (constraint.name !== void 0) return `CONSTRAINT ${quoteIdentifier(constraint.name)} UNIQUE (${cols})`;
|
|
42
|
-
return `UNIQUE (${cols})`;
|
|
43
|
-
}
|
|
44
|
-
function renderTableConstraint(constraint) {
|
|
45
|
-
switch (constraint.kind) {
|
|
46
|
-
case "primary-key": return renderPrimaryKeyConstraint(constraint);
|
|
47
|
-
case "foreign-key": return renderForeignKeyConstraint(constraint);
|
|
48
|
-
case "unique": return renderUniqueConstraint(constraint);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
var SqliteDdlVisitorImpl = class {
|
|
52
|
-
createTable(node) {
|
|
53
|
-
const ifNotExists = node.ifNotExists ? "IF NOT EXISTS " : "";
|
|
54
|
-
const tableRef = quoteIdentifier(node.table);
|
|
55
|
-
const columnDefs = node.columns.map((column) => renderColumn$1(column));
|
|
56
|
-
const constraintDefs = node.constraints !== void 0 ? node.constraints.map(renderTableConstraint) : [];
|
|
57
|
-
return `CREATE TABLE ${ifNotExists}${tableRef} (\n ${[...columnDefs, ...constraintDefs].join(",\n ")}\n)`;
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const defaultVisitor = {
|
|
61
|
-
literal(node, _ctx) {
|
|
62
|
-
const { value } = node;
|
|
63
|
-
if (value instanceof Date) return `DEFAULT '${escapeLiteral(value.toISOString())}'`;
|
|
64
|
-
if (typeof value === "string") return `DEFAULT '${escapeLiteral(value)}'`;
|
|
65
|
-
if (typeof value === "number") return `DEFAULT ${String(value)}`;
|
|
66
|
-
if (typeof value === "boolean") return `DEFAULT ${value ? "1" : "0"}`;
|
|
67
|
-
if (typeof value === "bigint") return `DEFAULT ${String(value)}`;
|
|
68
|
-
if (value === null) return "DEFAULT NULL";
|
|
69
|
-
return `DEFAULT '${escapeLiteral(JSON.stringify(value))}'`;
|
|
70
|
-
},
|
|
71
|
-
function(node, _ctx) {
|
|
72
|
-
if (node.expression === "autoincrement()") return "";
|
|
73
|
-
if (node.expression === "now()") return "DEFAULT (datetime('now'))";
|
|
74
|
-
return `DEFAULT (${node.expression})`;
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
function renderColumn$1(column) {
|
|
78
|
-
if (column.type.includes("AUTOINCREMENT")) return `${quoteIdentifier(column.name)} ${column.type}`;
|
|
79
|
-
const parts = [quoteIdentifier(column.name), column.type];
|
|
80
|
-
if (column.notNull) parts.push("NOT NULL");
|
|
81
|
-
if (column.primaryKey) parts.push("PRIMARY KEY");
|
|
82
|
-
const defaultClause = column.default ? column.default.accept(defaultVisitor, { nativeType: column.type }) : "";
|
|
83
|
-
if (defaultClause.length > 0) parts.push(defaultClause);
|
|
84
|
-
return parts.join(" ");
|
|
85
|
-
}
|
|
86
|
-
function renderLoweredDdl(ast) {
|
|
87
|
-
const sql = ast.accept(new SqliteDdlVisitorImpl());
|
|
88
|
-
return Object.freeze({
|
|
89
|
-
sql,
|
|
90
|
-
params: Object.freeze([])
|
|
91
|
-
});
|
|
21
|
+
//#region src/core/control-codecs.ts
|
|
22
|
+
const CONTROL_CODECS = createAstCodecRegistry(sqliteCodecRegistry);
|
|
23
|
+
async function encodeControlQueryParams(lowered, ast, codecs = CONTROL_CODECS) {
|
|
24
|
+
return encodeParamsWithMetadata(lowered.params.map((slot) => {
|
|
25
|
+
if (slot.kind === "literal") return slot.value;
|
|
26
|
+
throw new Error(`control query lowered to a bind slot '${slot.name}', which is unsupported`);
|
|
27
|
+
}), deriveParamMetadata(ast), {}, codecs);
|
|
92
28
|
}
|
|
93
29
|
//#endregion
|
|
94
30
|
//#region src/core/ledger-decode.ts
|
|
@@ -110,7 +46,6 @@ function operationCountFromStored(operations) {
|
|
|
110
46
|
}
|
|
111
47
|
//#endregion
|
|
112
48
|
//#region src/core/marker-ledger.ts
|
|
113
|
-
const CONTROL_CODECS = createAstCodecRegistry(sqliteCodecRegistry);
|
|
114
49
|
const marker = sqliteTable("_prisma_marker", {
|
|
115
50
|
space: text(),
|
|
116
51
|
core_hash: text(),
|
|
@@ -165,10 +100,7 @@ function mergeInvariants(current, incoming) {
|
|
|
165
100
|
}
|
|
166
101
|
async function execute(lower, driver, query) {
|
|
167
102
|
const lowered = lower(query);
|
|
168
|
-
const encoded = await
|
|
169
|
-
if (slot.kind === "literal") return slot.value;
|
|
170
|
-
throw new Error("SQLite control DML lowered to a bind parameter, which is unsupported");
|
|
171
|
-
}), deriveParamMetadata(query), {}, CONTROL_CODECS);
|
|
103
|
+
const encoded = await encodeControlQueryParams(lowered, query);
|
|
172
104
|
return (await driver.query(lowered.sql, encoded)).rows;
|
|
173
105
|
}
|
|
174
106
|
function decodeSqliteMarkerRow(row) {
|
|
@@ -191,9 +123,24 @@ function decodeSqliteMarkerRow(row) {
|
|
|
191
123
|
//#region src/core/control-adapter.ts
|
|
192
124
|
const SQLITE_MARKER_TABLE = "_prisma_marker";
|
|
193
125
|
const SQLITE_LEDGER_TABLE = "_prisma_ledger";
|
|
126
|
+
function createSqliteBuiltinCodecLookup() {
|
|
127
|
+
return extractCodecLookup([{
|
|
128
|
+
id: "sqlite-builtin-codecs",
|
|
129
|
+
types: { codecTypes: { codecDescriptors: Array.from(sqliteCodecRegistry.values()) } }
|
|
130
|
+
}]);
|
|
131
|
+
}
|
|
194
132
|
var SqliteControlAdapter = class {
|
|
195
133
|
familyId = "sql";
|
|
196
134
|
targetId = "sqlite";
|
|
135
|
+
codecLookup;
|
|
136
|
+
/**
|
|
137
|
+
* @param codecLookup - Codec lookup used to resolve codecs for DDL literal-default encoding.
|
|
138
|
+
* Defaults to a SQLite-builtins-only lookup when omitted. Stack-aware callers supply
|
|
139
|
+
* `stack.codecLookup` so extension codecs are visible to the DDL walker.
|
|
140
|
+
*/
|
|
141
|
+
constructor(codecLookup) {
|
|
142
|
+
this.codecLookup = codecLookup ?? createSqliteBuiltinCodecLookup();
|
|
143
|
+
}
|
|
197
144
|
normalizeDefault = parseSqliteDefault;
|
|
198
145
|
normalizeNativeType = normalizeSqliteNativeType;
|
|
199
146
|
bootstrapControlTableQueries() {
|
|
@@ -211,10 +158,26 @@ var SqliteControlAdapter = class {
|
|
|
211
158
|
* without instantiating the runtime adapter.
|
|
212
159
|
*/
|
|
213
160
|
lower(ast, context) {
|
|
214
|
-
if (isDdlNode(ast))
|
|
161
|
+
if (isDdlNode(ast)) throw new Error("lower() cannot lower DDL: DDL default literals require inline codec encoding, which is async. Use lowerToExecuteRequest().");
|
|
215
162
|
return renderLoweredSql(ast, context.contract);
|
|
216
163
|
}
|
|
217
164
|
/**
|
|
165
|
+
* Lower an AST all the way to a driver-ready statement. For DDL nodes,
|
|
166
|
+
* literal column defaults are formatted as inline SQL with SQLite-specific
|
|
167
|
+
* literal syntax (no cast suffix, boolean as 0/1, blob via X'hex'). For
|
|
168
|
+
* query ASTs, params are kept as `?` placeholders; wire values go in
|
|
169
|
+
* `params`. Does NOT call `this.lower()` — independent implementation.
|
|
170
|
+
*/
|
|
171
|
+
async lowerToExecuteRequest(ast, context) {
|
|
172
|
+
if (isDdlNode(ast)) return sqliteRenderDdlExecuteRequest(blindCast(ast), this.codecLookup);
|
|
173
|
+
const lowered = renderLoweredSql(ast, blindCast(context?.contract));
|
|
174
|
+
const params = await encodeControlQueryParams(lowered, ast);
|
|
175
|
+
return {
|
|
176
|
+
sql: lowered.sql,
|
|
177
|
+
params
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
218
181
|
* Reads the contract marker from `_prisma_marker`. Probes `sqlite_master`
|
|
219
182
|
* first so a fresh database (no marker table) returns `null` instead of a
|
|
220
183
|
* "no such table" error.
|
|
@@ -445,6 +408,74 @@ function mapSqliteReferentialAction(rule) {
|
|
|
445
408
|
if (mapped === "noAction") return void 0;
|
|
446
409
|
return mapped;
|
|
447
410
|
}
|
|
411
|
+
function sqliteInlineLiteral(wire) {
|
|
412
|
+
if (wire === null) return "NULL";
|
|
413
|
+
if (typeof wire === "boolean") return wire ? "1" : "0";
|
|
414
|
+
if (typeof wire === "number") {
|
|
415
|
+
if (!Number.isFinite(wire)) throw new Error(`sqliteRenderDdlExecuteRequest: non-finite number wire value ${String(wire)} cannot be emitted as a DEFAULT literal`);
|
|
416
|
+
return String(wire);
|
|
417
|
+
}
|
|
418
|
+
if (typeof wire === "bigint") return String(wire);
|
|
419
|
+
if (wire instanceof Date) {
|
|
420
|
+
if (Number.isNaN(wire.getTime())) throw new Error("sqliteRenderDdlExecuteRequest: invalid Date value cannot be emitted as a DEFAULT literal");
|
|
421
|
+
return `'${escapeLiteral(wire.toISOString())}'`;
|
|
422
|
+
}
|
|
423
|
+
if (typeof wire === "string") return `'${escapeLiteral(wire)}'`;
|
|
424
|
+
if (wire instanceof Uint8Array) return `X'${Array.from(wire).map((b) => b.toString(16).padStart(2, "0")).join("")}'`;
|
|
425
|
+
if (typeof wire === "object") return `'${escapeLiteral(JSON.stringify(wire))}'`;
|
|
426
|
+
throw new Error(`sqliteRenderDdlExecuteRequest: unexpected wire type "${typeof wire}"`);
|
|
427
|
+
}
|
|
428
|
+
async function sqliteRenderDdlColumnDefault(def, codecLookup, codecRef) {
|
|
429
|
+
if (def.kind === "function") {
|
|
430
|
+
if (def.expression === "autoincrement()") return "";
|
|
431
|
+
if (def.expression === "now()") return "DEFAULT (datetime('now'))";
|
|
432
|
+
return `DEFAULT (${def.expression})`;
|
|
433
|
+
}
|
|
434
|
+
if (codecRef !== void 0) {
|
|
435
|
+
const codec = codecLookup.get(codecRef.codecId);
|
|
436
|
+
if (codec !== void 0) return `DEFAULT ${sqliteInlineLiteral(await codec.encode(def.value, {}))}`;
|
|
437
|
+
}
|
|
438
|
+
return `DEFAULT ${sqliteInlineLiteral(def.value)}`;
|
|
439
|
+
}
|
|
440
|
+
async function sqliteRenderDdlColumn(column, codecLookup) {
|
|
441
|
+
if (column.type.includes("AUTOINCREMENT")) return `${quoteIdentifier(column.name)} ${column.type}`;
|
|
442
|
+
const parts = [quoteIdentifier(column.name), column.type];
|
|
443
|
+
if (column.notNull) parts.push("NOT NULL");
|
|
444
|
+
if (column.primaryKey) parts.push("PRIMARY KEY");
|
|
445
|
+
if (column.default) {
|
|
446
|
+
const clause = await sqliteRenderDdlColumnDefault(column.default, codecLookup, column.codecRef);
|
|
447
|
+
if (clause.length > 0) parts.push(clause);
|
|
448
|
+
}
|
|
449
|
+
return parts.join(" ");
|
|
450
|
+
}
|
|
451
|
+
function sqliteRenderDdlConstraint(constraint) {
|
|
452
|
+
if (constraint.kind === "primary-key") {
|
|
453
|
+
const cols = constraint.columns.map(quoteIdentifier).join(", ");
|
|
454
|
+
if (constraint.name !== void 0) return `CONSTRAINT ${quoteIdentifier(constraint.name)} PRIMARY KEY (${cols})`;
|
|
455
|
+
return `PRIMARY KEY (${cols})`;
|
|
456
|
+
}
|
|
457
|
+
if (constraint.kind === "foreign-key") {
|
|
458
|
+
let sql = `FOREIGN KEY (${constraint.columns.map(quoteIdentifier).join(", ")}) REFERENCES ${constraint.refTable.split(".").map(quoteIdentifier).join(".")} (${constraint.refColumns.map(quoteIdentifier).join(", ")})`;
|
|
459
|
+
if (constraint.onDelete !== void 0) sql += ` ON DELETE ${REFERENTIAL_ACTION_SQL[constraint.onDelete]}`;
|
|
460
|
+
if (constraint.onUpdate !== void 0) sql += ` ON UPDATE ${REFERENTIAL_ACTION_SQL[constraint.onUpdate]}`;
|
|
461
|
+
if (constraint.name !== void 0) sql = `CONSTRAINT ${quoteIdentifier(constraint.name)} ${sql}`;
|
|
462
|
+
return sql;
|
|
463
|
+
}
|
|
464
|
+
const cols = constraint.columns.map(quoteIdentifier).join(", ");
|
|
465
|
+
if (constraint.name !== void 0) return `CONSTRAINT ${quoteIdentifier(constraint.name)} UNIQUE (${cols})`;
|
|
466
|
+
return `UNIQUE (${cols})`;
|
|
467
|
+
}
|
|
468
|
+
async function sqliteRenderDdlExecuteRequest(ast, codecLookup) {
|
|
469
|
+
const node = blindCast(ast);
|
|
470
|
+
const ifNotExists = node.ifNotExists ? "IF NOT EXISTS " : "";
|
|
471
|
+
const tableRef = quoteIdentifier(node.table);
|
|
472
|
+
const columnDefs = await Promise.all(node.columns.map((col) => sqliteRenderDdlColumn(col, codecLookup)));
|
|
473
|
+
const constraintDefs = node.constraints !== void 0 ? node.constraints.map(sqliteRenderDdlConstraint) : [];
|
|
474
|
+
return {
|
|
475
|
+
sql: `CREATE TABLE ${ifNotExists}${tableRef} (\n ${[...columnDefs, ...constraintDefs].join(",\n ")}\n)`,
|
|
476
|
+
params: []
|
|
477
|
+
};
|
|
478
|
+
}
|
|
448
479
|
//#endregion
|
|
449
480
|
//#region src/core/adapter.ts
|
|
450
481
|
const defaultCapabilities = Object.freeze({ sql: {
|
|
@@ -476,7 +507,7 @@ var SqliteAdapterImpl = class {
|
|
|
476
507
|
});
|
|
477
508
|
}
|
|
478
509
|
lower(ast, context) {
|
|
479
|
-
if (isDdlNode(ast))
|
|
510
|
+
if (isDdlNode(ast)) throw new Error("lower() does not lower DDL on the runtime adapter — DDL lowering is a control-plane concern handled by the control adapter.");
|
|
480
511
|
return renderLoweredSql(ast, context.contract);
|
|
481
512
|
}
|
|
482
513
|
};
|
|
@@ -799,4 +830,4 @@ function createSqliteAdapter(options) {
|
|
|
799
830
|
//#endregion
|
|
800
831
|
export { sqliteRawCodecInferer as n, SqliteControlAdapter as r, createSqliteAdapter as t };
|
|
801
832
|
|
|
802
|
-
//# sourceMappingURL=adapter-
|
|
833
|
+
//# sourceMappingURL=adapter-fApyx9L1.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-fApyx9L1.mjs","names":[],"sources":["../../../../1-framework/3-tooling/migration/dist/exports/ledger-origin.mjs","../src/core/control-codecs.ts","../src/core/ledger-decode.ts","../src/core/marker-ledger.ts","../src/core/control-adapter.ts","../src/core/adapter.ts"],"sourcesContent":["import \"../constants-YnG8_EGO.mjs\";\n//#region src/ledger-origin.ts\nfunction ledgerOriginFromStored(originCoreHash) {\n\tif (originCoreHash === null || originCoreHash === \"\" || originCoreHash === \"sha256:empty\") return null;\n\treturn originCoreHash;\n}\n//#endregion\nexport { ledgerOriginFromStored };\n\n//# sourceMappingURL=ledger-origin.mjs.map","import type {\n AnyQueryAst,\n ContractCodecRegistry,\n LoweredStatement,\n} from '@prisma-next/sql-relational-core/ast';\nimport {\n createAstCodecRegistry,\n deriveParamMetadata,\n encodeParamsWithMetadata,\n} from '@prisma-next/sql-runtime';\nimport { sqliteCodecRegistry } from '@prisma-next/target-sqlite/codecs';\n\nexport const CONTROL_CODECS = createAstCodecRegistry(sqliteCodecRegistry);\n\nexport async function encodeControlQueryParams(\n lowered: LoweredStatement,\n ast: AnyQueryAst,\n codecs: ContractCodecRegistry = CONTROL_CODECS,\n): Promise<readonly unknown[]> {\n const values = lowered.params.map((slot) => {\n if (slot.kind === 'literal') return slot.value;\n throw new Error(`control query lowered to a bind slot '${slot.name}', which is unsupported`);\n });\n return encodeParamsWithMetadata(values, deriveParamMetadata(ast), {}, codecs);\n}\n","const DESIGNATOR_LESS_UTC_DATETIME = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(\\.\\d+)?$/;\n\nexport function coerceLedgerAppliedAt(value: Date | string): Date {\n if (value instanceof Date) {\n return value;\n }\n if (DESIGNATOR_LESS_UTC_DATETIME.test(value)) {\n return new Date(`${value.replace(' ', 'T')}Z`);\n }\n return new Date(value);\n}\n\nexport function operationCountFromStored(operations: unknown): number {\n if (Array.isArray(operations)) {\n return operations.length;\n }\n if (typeof operations === 'string') {\n try {\n const parsed: unknown = JSON.parse(operations);\n return Array.isArray(parsed) ? parsed.length : 0;\n } catch {\n return 0;\n }\n }\n return 0;\n}\n","import type { SqlControlDriverInstance } from '@prisma-next/sql-contract/types';\nimport {\n type AnyQueryAst,\n type LoweredStatement,\n RawExpr,\n} from '@prisma-next/sql-relational-core/ast';\nimport { SQLITE_DATETIME_CODEC_ID } from '@prisma-next/target-sqlite/codec-ids';\nimport {\n datetime,\n integer,\n jsonText,\n sqliteTable,\n text,\n} from '@prisma-next/target-sqlite/contract-free';\nimport { encodeControlQueryParams } from './control-codecs';\n\nexport const marker = sqliteTable('_prisma_marker', {\n space: text(),\n core_hash: text(),\n profile_hash: text(),\n contract_json: jsonText({ nullable: true }),\n canonical_version: integer({ nullable: true }),\n updated_at: datetime(),\n app_tag: text({ nullable: true }),\n meta: jsonText({ nullable: true }),\n invariants: jsonText(),\n});\n\n/**\n * Writeable subset of `_prisma_ledger`. Omits the DB-generated `id`\n * (`INTEGER PRIMARY KEY AUTOINCREMENT`) and `created_at` (default\n * `strftime(...)`).\n */\nexport const ledger = sqliteTable('_prisma_ledger', {\n space: text(),\n migration_name: text(),\n migration_hash: text(),\n origin_core_hash: text({ nullable: true }),\n destination_core_hash: text(),\n operations: jsonText(),\n});\n\n/**\n * Read-side handle covering every column of `_prisma_ledger`, including\n * the DB-generated `id` (for ORDER BY) and `created_at`.\n */\nexport const ledgerReadShape = sqliteTable('_prisma_ledger', {\n id: integer(),\n space: text(),\n migration_name: text(),\n migration_hash: text(),\n origin_core_hash: text({ nullable: true }),\n destination_core_hash: text(),\n operations: jsonText(),\n created_at: text(),\n});\n\nexport const sqliteCatalog = sqliteTable('sqlite_master', { type: text(), name: text() });\n\nexport const NOW = new RawExpr({\n parts: [\"datetime('now')\"],\n returns: { codecId: SQLITE_DATETIME_CODEC_ID, nullable: false },\n});\n\ntype Lower = (query: AnyQueryAst) => LoweredStatement;\n\ntype MarkerDriver = {\n query<Row = Record<string, unknown>>(\n sql: string,\n params?: readonly unknown[],\n ): Promise<{ readonly rows: ReadonlyArray<Row> }>;\n};\n\nexport function mergeInvariants(\n current: readonly string[],\n incoming: readonly string[],\n): readonly string[] {\n return [...new Set([...current, ...incoming])].sort();\n}\n\nexport async function execute(\n lower: Lower,\n driver: MarkerDriver,\n query: AnyQueryAst,\n): Promise<readonly Record<string, unknown>[]> {\n const lowered = lower(query);\n const encoded = await encodeControlQueryParams(lowered, query);\n const result = await driver.query(lowered.sql, encoded);\n return result.rows;\n}\n\nexport function decodeSqliteMarkerRow(row: unknown): unknown {\n if (typeof row !== 'object' || row === null || !('invariants' in row)) {\n return row;\n }\n const record = row as { invariants: unknown };\n if (typeof record.invariants !== 'string') return row;\n let parsed: unknown;\n try {\n parsed = JSON.parse(record.invariants);\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n throw new Error(`Invalid contract marker row: invariants is not valid JSON: ${detail}`);\n }\n return { ...record, invariants: parsed };\n}\n\nexport type SqliteMarkerWriteDriver = SqlControlDriverInstance<'sqlite'>;\n","import type { ContractMarkerRecord, LedgerEntryRecord } from '@prisma-next/contract/types';\nimport { parseMarkerRowSafely, withMarkerReadErrorHandling } from '@prisma-next/errors/execution';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport { parseContractMarkerRow } from '@prisma-next/family-sql/verify';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { APP_SPACE_ID, extractCodecLookup } from '@prisma-next/framework-components/control';\nimport { ledgerOriginFromStored } from '@prisma-next/migration-tools/ledger-origin';\nimport { REFERENTIAL_ACTION_SQL } from '@prisma-next/sql-contract/referential-action-sql';\nimport type { SqlControlDriverInstance } from '@prisma-next/sql-contract/types';\nimport type {\n AnyQueryAst,\n CodecRef,\n DdlColumn,\n DdlNode,\n DdlTableConstraint,\n FunctionColumnDefault,\n LiteralColumnDefault,\n LoweredStatement,\n LowererContext,\n MarkerReadResult,\n SqlExecuteRequest,\n} from '@prisma-next/sql-relational-core/ast';\nimport { isDdlNode } from '@prisma-next/sql-relational-core/ast';\nimport type {\n PrimaryKey,\n SqlColumnIR,\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlReferentialAction,\n SqlSchemaIR,\n SqlTableIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\nimport { sqliteCodecRegistry } from '@prisma-next/target-sqlite/codecs';\nimport {\n buildControlTableBootstrapQueries,\n buildSignMarkerBootstrapQueries,\n} from '@prisma-next/target-sqlite/contract-free';\nimport type { SqliteCreateTable, SqliteDdlNode } from '@prisma-next/target-sqlite/ddl';\nimport { parseSqliteDefault } from '@prisma-next/target-sqlite/default-normalizer';\nimport { normalizeSqliteNativeType } from '@prisma-next/target-sqlite/native-type-normalizer';\nimport { escapeLiteral, quoteIdentifier } from '@prisma-next/target-sqlite/sql-utils';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { renderLoweredSql } from './adapter';\nimport { encodeControlQueryParams } from './control-codecs';\nimport { coerceLedgerAppliedAt, operationCountFromStored } from './ledger-decode';\nimport {\n decodeSqliteMarkerRow,\n execute,\n ledger,\n ledgerReadShape,\n marker,\n mergeInvariants,\n NOW,\n sqliteCatalog,\n} from './marker-ledger';\nimport type { SqliteContract } from './types';\n\nconst SQLITE_MARKER_TABLE = '_prisma_marker';\nconst SQLITE_LEDGER_TABLE = '_prisma_ledger';\n\ntype SqliteLedgerRow = {\n readonly space: string;\n readonly migration_name: string;\n readonly migration_hash: string;\n readonly origin_core_hash: string | null;\n readonly destination_core_hash: string;\n readonly operations: unknown;\n readonly created_at: Date | string;\n};\n\n// PRAGMA result row types\ntype PragmaTableInfoRow = {\n cid: number;\n name: string;\n type: string;\n notnull: number;\n dflt_value: string | null;\n pk: number;\n};\n\ntype PragmaForeignKeyRow = {\n id: number;\n seq: number;\n table: string;\n from: string;\n to: string;\n on_update: string;\n on_delete: string;\n};\n\ntype PragmaIndexListRow = {\n seq: number;\n name: string;\n unique: number;\n origin: string;\n partial: number;\n};\n\ntype PragmaIndexInfoRow = {\n seqno: number;\n cid: number;\n name: string;\n};\n\ntype FkAccumulator = {\n columns: string[];\n referencedTable: string;\n referencedColumns: string[];\n onDelete: string;\n onUpdate: string;\n};\n\nfunction createSqliteBuiltinCodecLookup(): CodecLookup {\n return extractCodecLookup([\n {\n id: 'sqlite-builtin-codecs',\n types: { codecTypes: { codecDescriptors: Array.from(sqliteCodecRegistry.values()) } },\n },\n ]);\n}\n\nexport class SqliteControlAdapter implements SqlControlAdapter<'sqlite'> {\n readonly familyId = 'sql' as const;\n readonly targetId = 'sqlite' as const;\n\n private readonly codecLookup: CodecLookup;\n\n /**\n * @param codecLookup - Codec lookup used to resolve codecs for DDL literal-default encoding.\n * Defaults to a SQLite-builtins-only lookup when omitted. Stack-aware callers supply\n * `stack.codecLookup` so extension codecs are visible to the DDL walker.\n */\n constructor(codecLookup?: CodecLookup) {\n this.codecLookup = codecLookup ?? createSqliteBuiltinCodecLookup();\n }\n\n readonly normalizeDefault = parseSqliteDefault;\n readonly normalizeNativeType = normalizeSqliteNativeType;\n\n bootstrapControlTableQueries(): readonly DdlNode[] {\n return buildControlTableBootstrapQueries();\n }\n\n bootstrapSignMarkerQueries(): readonly DdlNode[] {\n return buildSignMarkerBootstrapQueries();\n }\n\n /**\n * Lower a SQL query AST into a SQLite-flavored `{ sql, params }` payload.\n *\n * Delegates to the shared `renderLoweredSql` renderer so the control adapter\n * emits byte-identical SQL to `SqliteAdapterImpl.lower()` for the same AST\n * and contract. Used at migration plan/emit time (e.g. by `dataTransform`)\n * without instantiating the runtime adapter.\n */\n lower(ast: AnyQueryAst | SqliteDdlNode, context: LowererContext<unknown>): LoweredStatement {\n if (isDdlNode(ast)) {\n throw new Error(\n 'lower() cannot lower DDL: DDL default literals require inline codec encoding, which is async. Use lowerToExecuteRequest().',\n );\n }\n return renderLoweredSql(ast, context.contract as SqliteContract);\n }\n\n /**\n * Lower an AST all the way to a driver-ready statement. For DDL nodes,\n * literal column defaults are formatted as inline SQL with SQLite-specific\n * literal syntax (no cast suffix, boolean as 0/1, blob via X'hex'). For\n * query ASTs, params are kept as `?` placeholders; wire values go in\n * `params`. Does NOT call `this.lower()` — independent implementation.\n */\n async lowerToExecuteRequest(\n ast: AnyQueryAst | SqliteDdlNode,\n context?: LowererContext<unknown>,\n ): Promise<SqlExecuteRequest> {\n if (isDdlNode(ast)) {\n return sqliteRenderDdlExecuteRequest(\n blindCast<SqliteDdlNode, 'isDdlNode guard'>(ast),\n this.codecLookup,\n );\n }\n const lowered = renderLoweredSql(\n ast,\n blindCast<SqliteContract, 'Caller must supply matching contract'>(context?.contract),\n );\n const params = await encodeControlQueryParams(lowered, ast);\n return { sql: lowered.sql, params };\n }\n\n /**\n * Reads the contract marker from `_prisma_marker`. Probes `sqlite_master`\n * first so a fresh database (no marker table) returns `null` instead of a\n * \"no such table\" error.\n */\n async readMarker(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n ): Promise<ContractMarkerRecord | null> {\n const result = await this.readMarkerDiscriminated(driver, space);\n return result.kind === 'present' ? result.record : null;\n }\n\n async readMarkerDiscriminated(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n ): Promise<MarkerReadResult> {\n const markerContext = { space, markerLocation: SQLITE_MARKER_TABLE };\n return withMarkerReadErrorHandling(() => this.readMarkerResult(driver, space), markerContext);\n }\n\n /**\n * Reads every row from `_prisma_marker` and returns them keyed by\n * `space`. Mirrors the existence probe in {@link readMarker}: a\n * fresh database without the marker table returns an empty map.\n */\n async readAllMarkers(\n driver: SqlControlDriverInstance<'sqlite'>,\n ): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const markerContext = { space: APP_SPACE_ID, markerLocation: SQLITE_MARKER_TABLE };\n return withMarkerReadErrorHandling(() => this.readAllMarkersResult(driver), markerContext);\n }\n\n private async readAllMarkersResult(\n driver: SqlControlDriverInstance<'sqlite'>,\n ): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const lower = (query: AnyQueryAst) => this.lower(query, { contract: undefined });\n const probe = sqliteCatalog\n .select(sqliteCatalog.name)\n .where(sqliteCatalog.type.eq('table').and(sqliteCatalog.name.eq('_prisma_marker')))\n .build();\n const exists = await execute(lower, driver, probe);\n if (exists.length === 0) {\n return new Map();\n }\n\n const fetch = marker\n .select(\n marker.space,\n marker.core_hash,\n marker.profile_hash,\n marker.contract_json,\n marker.canonical_version,\n marker.updated_at,\n marker.app_tag,\n marker.meta,\n marker.invariants,\n )\n .build();\n const rawRows = await execute(lower, driver, fetch);\n const rows = blindCast<\n ReadonlyArray<{ space: string } & Record<string, unknown>>,\n 'Driver returns rows shaped by SELECT'\n >(rawRows);\n\n const out = new Map<string, ContractMarkerRecord>();\n for (const row of rows) {\n out.set(\n row.space,\n parseMarkerRowSafely(row, (raw) => parseContractMarkerRow(decodeSqliteMarkerRow(raw)), {\n space: row.space,\n markerLocation: SQLITE_MARKER_TABLE,\n }),\n );\n }\n return out;\n }\n\n /**\n * Reads per-migration ledger rows from `_prisma_ledger` in apply order.\n * Probes `sqlite_master` first so a fresh database without the ledger\n * table returns `[]` instead of raising \"no such table\".\n */\n async readLedger(\n driver: SqlControlDriverInstance<'sqlite'>,\n space?: string,\n ): Promise<readonly LedgerEntryRecord[]> {\n const ledgerContext = { space: space ?? '*', markerLocation: SQLITE_LEDGER_TABLE };\n return withMarkerReadErrorHandling(() => this.readLedgerResult(driver, space), ledgerContext);\n }\n\n private async readLedgerResult(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string | undefined,\n ): Promise<readonly LedgerEntryRecord[]> {\n const lower = (query: AnyQueryAst) => this.lower(query, { contract: undefined });\n const probe = sqliteCatalog\n .select(sqliteCatalog.name)\n .where(sqliteCatalog.type.eq('table').and(sqliteCatalog.name.eq('_prisma_ledger')))\n .build();\n const exists = await execute(lower, driver, probe);\n if (exists.length === 0) {\n return [];\n }\n\n const base = ledgerReadShape.select(\n ledgerReadShape.space,\n ledgerReadShape.migration_name,\n ledgerReadShape.migration_hash,\n ledgerReadShape.origin_core_hash,\n ledgerReadShape.destination_core_hash,\n ledgerReadShape.operations,\n ledgerReadShape.created_at,\n );\n const filtered = space !== undefined ? base.where(ledgerReadShape.space.eq(space)) : base;\n const rawRows = await execute(lower, driver, filtered.orderBy(ledgerReadShape.id).build());\n const rows = blindCast<readonly SqliteLedgerRow[], 'Driver returns rows shaped by SELECT'>(\n rawRows,\n );\n\n return rows.map((row) => ({\n space: row.space,\n migrationName: row.migration_name,\n migrationHash: row.migration_hash,\n from: ledgerOriginFromStored(row.origin_core_hash),\n to: row.destination_core_hash,\n appliedAt: coerceLedgerAppliedAt(row.created_at),\n operationCount: operationCountFromStored(row.operations),\n }));\n }\n\n /**\n * Stamps the initial marker row for `space` via the shared contract-free DML\n * builder, lowered through {@link lower} and executed on the driver. See the\n * `SqlControlAdapter.initMarker` contract.\n */\n async insertMarker(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<void> {\n await execute(\n (query) => this.lower(query, { contract: undefined }),\n driver,\n marker\n .insert({\n space,\n core_hash: destination.storageHash,\n profile_hash: destination.profileHash,\n contract_json: null,\n canonical_version: null,\n updated_at: NOW,\n app_tag: null,\n meta: {},\n invariants: destination.invariants ?? [],\n })\n .build(),\n );\n }\n\n async initMarker(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<void> {\n await execute(\n (query) => this.lower(query, { contract: undefined }),\n driver,\n marker\n .upsert({\n space,\n core_hash: destination.storageHash,\n profile_hash: destination.profileHash,\n contract_json: null,\n canonical_version: null,\n updated_at: NOW,\n app_tag: null,\n meta: {},\n invariants: destination.invariants ?? [],\n })\n .onConflict(marker.space)\n .doUpdate((excluded) => ({\n core_hash: excluded.core_hash,\n profile_hash: excluded.profile_hash,\n contract_json: excluded.contract_json,\n canonical_version: excluded.canonical_version,\n updated_at: NOW,\n app_tag: excluded.app_tag,\n meta: excluded.meta,\n invariants: excluded.invariants,\n }))\n .build(),\n );\n }\n\n /**\n * Compare-and-swap advance of the marker row for `space`. See the\n * `SqlControlAdapter.updateMarker` contract.\n */\n async updateMarker(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n expectedFrom: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<boolean> {\n const currentInvariants =\n destination.invariants === undefined\n ? []\n : ((await this.readMarker(driver, space))?.invariants ?? []);\n const mergedInvariants =\n destination.invariants === undefined\n ? undefined\n : mergeInvariants(currentInvariants, destination.invariants);\n\n const query = marker\n .update()\n .set({\n core_hash: destination.storageHash,\n profile_hash: destination.profileHash,\n updated_at: NOW,\n ...(mergedInvariants !== undefined ? { invariants: mergedInvariants } : {}),\n })\n .where(marker.space.eq(space).and(marker.core_hash.eq(expectedFrom)))\n .returning(marker.space)\n .build();\n\n const rows = await execute((q) => this.lower(q, { contract: undefined }), driver, query);\n return rows.length > 0;\n }\n\n /**\n * Appends a ledger entry for `space`. See the\n * `SqlControlAdapter.writeLedgerEntry` contract.\n */\n async writeLedgerEntry(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n readonly migrationName: string;\n readonly migrationHash: string;\n readonly operations: readonly unknown[];\n },\n ): Promise<void> {\n await execute(\n (query) => this.lower(query, { contract: undefined }),\n driver,\n ledger\n .insert({\n space,\n migration_name: entry.migrationName,\n migration_hash: entry.migrationHash,\n origin_core_hash: entry.from,\n destination_core_hash: entry.to,\n operations: entry.operations,\n })\n .build(),\n );\n }\n\n private async readMarkerResult(driver: SqlControlDriverInstance<'sqlite'>, space: string) {\n const lower = (query: AnyQueryAst) => this.lower(query, { contract: undefined });\n const probe = sqliteCatalog\n .select(sqliteCatalog.name)\n .where(sqliteCatalog.type.eq('table').and(sqliteCatalog.name.eq('_prisma_marker')))\n .build();\n const exists = await execute(lower, driver, probe);\n if (exists.length === 0) return { kind: 'no-table' as const };\n\n const fetch = marker\n .select(\n marker.core_hash,\n marker.profile_hash,\n marker.contract_json,\n marker.canonical_version,\n marker.updated_at,\n marker.app_tag,\n marker.meta,\n marker.invariants,\n )\n .where(marker.space.eq(space))\n .build();\n const result = await execute(lower, driver, fetch);\n const row = result[0];\n if (!row) return { kind: 'absent' as const };\n return {\n kind: 'present' as const,\n record: parseContractMarkerRow(decodeSqliteMarkerRow(row)),\n };\n }\n\n async introspect(\n driver: SqlControlDriverInstance<'sqlite'>,\n _contract?: unknown,\n ): Promise<SqlSchemaIR> {\n // Filter out runner-managed control tables (`_prisma_marker`,\n // `_prisma_ledger`) — they're an implementation detail of the migration\n // runner, not part of the user-authored contract, so they must not\n // appear in introspection output (otherwise strict schema verification\n // flags them as `extra_table`).\n const tablesResult = await driver.query<{ name: string }>(\n `SELECT name FROM sqlite_master\n WHERE type = 'table'\n AND name NOT LIKE 'sqlite_%'\n AND name NOT IN ('_prisma_marker', '_prisma_ledger')\n ORDER BY name`,\n );\n\n const tables: Record<string, SqlTableIR> = {};\n\n for (const tableRow of tablesResult.rows) {\n const tableName = tableRow.name;\n\n // SQLite's synchronous driver serializes reads — no benefit from Promise.all\n const columnsResult = await driver.query<PragmaTableInfoRow>(\n `PRAGMA table_info(\"${escapePragmaArg(tableName)}\")`,\n );\n const fkResult = await driver.query<PragmaForeignKeyRow>(\n `PRAGMA foreign_key_list(\"${escapePragmaArg(tableName)}\")`,\n );\n const indexListResult = await driver.query<PragmaIndexListRow>(\n `PRAGMA index_list(\"${escapePragmaArg(tableName)}\")`,\n );\n\n const columns: Record<string, SqlColumnIR> = {};\n const pkColumns: Array<{ name: string; pk: number }> = [];\n\n for (const col of columnsResult.rows) {\n columns[col.name] = {\n name: col.name,\n nativeType: col.type.toLowerCase(),\n nullable: col.notnull === 0 && col.pk === 0,\n ...ifDefined('default', col.dflt_value ?? undefined),\n };\n if (col.pk > 0) {\n pkColumns.push({ name: col.name, pk: col.pk });\n }\n }\n\n pkColumns.sort((a, b) => a.pk - b.pk);\n const primaryKey: PrimaryKey | undefined =\n pkColumns.length > 0 ? { columns: pkColumns.map((c) => c.name) } : undefined;\n\n const fkMap = new Map<number, FkAccumulator>();\n for (const fk of fkResult.rows) {\n const existing = fkMap.get(fk.id);\n if (existing) {\n existing.columns.push(fk.from);\n existing.referencedColumns.push(fk.to);\n } else {\n fkMap.set(fk.id, {\n columns: [fk.from],\n referencedTable: fk.table,\n referencedColumns: [fk.to],\n onDelete: fk.on_delete,\n onUpdate: fk.on_update,\n });\n }\n }\n const foreignKeys: readonly SqlForeignKeyIR[] = Array.from(fkMap.values()).map((fk) => ({\n columns: Object.freeze([...fk.columns]) as readonly string[],\n referencedTable: fk.referencedTable,\n referencedColumns: Object.freeze([...fk.referencedColumns]) as readonly string[],\n ...ifDefined('onDelete', mapSqliteReferentialAction(fk.onDelete)),\n ...ifDefined('onUpdate', mapSqliteReferentialAction(fk.onUpdate)),\n }));\n\n const uniques: SqlUniqueIR[] = [];\n const indexes: SqlIndexIR[] = [];\n\n for (const idx of indexListResult.rows) {\n // origin: 'c' = CREATE INDEX, 'u' = UNIQUE constraint, 'pk' = PRIMARY KEY\n const idxInfoResult = await driver.query<PragmaIndexInfoRow>(\n `PRAGMA index_info(\"${escapePragmaArg(idx.name)}\")`,\n );\n\n const idxColumns = idxInfoResult.rows.sort((a, b) => a.seqno - b.seqno).map((r) => r.name);\n\n if (idx.origin === 'u') {\n uniques.push({\n columns: Object.freeze([...idxColumns]) as readonly string[],\n name: idx.name,\n });\n } else if (idx.origin === 'c') {\n indexes.push({\n columns: Object.freeze([...idxColumns]) as readonly string[],\n name: idx.name,\n unique: idx.unique === 1,\n });\n }\n // Skip 'pk' origin — already captured in primaryKey\n }\n\n tables[tableName] = {\n name: tableName,\n columns,\n ...ifDefined('primaryKey', primaryKey),\n foreignKeys,\n uniques,\n indexes,\n };\n }\n\n return {\n tables,\n };\n }\n}\n\n// PRAGMA queries use the function-argument form (`PRAGMA table_info(\"name\")`)\n// which doesn't support `?` placeholders — the argument is part of the\n// statement name, not a bound parameter. We quote-escape the table name instead.\nfunction escapePragmaArg(name: string): string {\n return name.replace(/\"/g, '\"\"');\n}\n\nconst SQLITE_REFERENTIAL_ACTION_MAP: Record<string, SqlReferentialAction> = {\n 'NO ACTION': 'noAction',\n RESTRICT: 'restrict',\n CASCADE: 'cascade',\n 'SET NULL': 'setNull',\n 'SET DEFAULT': 'setDefault',\n};\n\nfunction mapSqliteReferentialAction(rule: string): SqlReferentialAction | undefined {\n const normalized = rule.toUpperCase();\n const mapped = SQLITE_REFERENTIAL_ACTION_MAP[normalized];\n if (mapped === undefined) {\n throw new Error(\n `Unknown SQLite referential action rule: \"${rule}\". ` +\n 'Expected one of: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.',\n );\n }\n if (mapped === 'noAction') return undefined;\n return mapped;\n}\n\n// ---------------------------------------------------------------------------\n// sqliteRenderDdlExecuteRequest — independent DDL walker for lowerToExecuteRequest\n// ---------------------------------------------------------------------------\n\nfunction sqliteInlineLiteral(wire: unknown): string {\n if (wire === null) return 'NULL';\n if (typeof wire === 'boolean') return wire ? '1' : '0';\n if (typeof wire === 'number') {\n if (!Number.isFinite(wire)) {\n throw new Error(\n `sqliteRenderDdlExecuteRequest: non-finite number wire value ${String(wire)} cannot be emitted as a DEFAULT literal`,\n );\n }\n return String(wire);\n }\n if (typeof wire === 'bigint') return String(wire);\n if (wire instanceof Date) {\n if (Number.isNaN(wire.getTime())) {\n throw new Error(\n 'sqliteRenderDdlExecuteRequest: invalid Date value cannot be emitted as a DEFAULT literal',\n );\n }\n return `'${escapeLiteral(wire.toISOString())}'`;\n }\n if (typeof wire === 'string') return `'${escapeLiteral(wire)}'`;\n if (wire instanceof Uint8Array) {\n const hex = Array.from(wire)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `X'${hex}'`;\n }\n if (typeof wire === 'object') return `'${escapeLiteral(JSON.stringify(wire))}'`;\n throw new Error(`sqliteRenderDdlExecuteRequest: unexpected wire type \"${typeof wire}\"`);\n}\n\nasync function sqliteRenderDdlColumnDefault(\n def: LiteralColumnDefault | FunctionColumnDefault,\n codecLookup: CodecLookup,\n codecRef: CodecRef | undefined,\n): Promise<string> {\n if (def.kind === 'function') {\n if (def.expression === 'autoincrement()') return '';\n // SQLite has no `now()` function; the contract canonicalizes\n // `CURRENT_TIMESTAMP` / `datetime('now')` to `now()`, so map it back to a\n // valid SQLite expression on the way out.\n if (def.expression === 'now()') return \"DEFAULT (datetime('now'))\";\n return `DEFAULT (${def.expression})`;\n }\n if (codecRef !== undefined) {\n const codec = codecLookup.get(codecRef.codecId);\n if (codec !== undefined) {\n const wire = await codec.encode(def.value, {});\n return `DEFAULT ${sqliteInlineLiteral(wire)}`;\n }\n }\n // Fallback: codec-less literal defaults follow RawSqlLiteral wire-scalar semantics.\n return `DEFAULT ${sqliteInlineLiteral(def.value)}`;\n}\n\nasync function sqliteRenderDdlColumn(column: DdlColumn, codecLookup: CodecLookup): Promise<string> {\n if (column.type.includes('AUTOINCREMENT')) {\n return `${quoteIdentifier(column.name)} ${column.type}`;\n }\n const parts = [quoteIdentifier(column.name), column.type];\n if (column.notNull) parts.push('NOT NULL');\n if (column.primaryKey) parts.push('PRIMARY KEY');\n if (column.default) {\n const clause = await sqliteRenderDdlColumnDefault(column.default, codecLookup, column.codecRef);\n if (clause.length > 0) parts.push(clause);\n }\n return parts.join(' ');\n}\n\nfunction sqliteRenderDdlConstraint(constraint: DdlTableConstraint): string {\n if (constraint.kind === 'primary-key') {\n const cols = constraint.columns.map(quoteIdentifier).join(', ');\n if (constraint.name !== undefined) {\n return `CONSTRAINT ${quoteIdentifier(constraint.name)} PRIMARY KEY (${cols})`;\n }\n return `PRIMARY KEY (${cols})`;\n }\n if (constraint.kind === 'foreign-key') {\n const cols = constraint.columns.map(quoteIdentifier).join(', ');\n const refTable = constraint.refTable.split('.').map(quoteIdentifier).join('.');\n const refCols = constraint.refColumns.map(quoteIdentifier).join(', ');\n let sql = `FOREIGN KEY (${cols}) REFERENCES ${refTable} (${refCols})`;\n if (constraint.onDelete !== undefined) {\n sql += ` ON DELETE ${REFERENTIAL_ACTION_SQL[constraint.onDelete]}`;\n }\n if (constraint.onUpdate !== undefined) {\n sql += ` ON UPDATE ${REFERENTIAL_ACTION_SQL[constraint.onUpdate]}`;\n }\n if (constraint.name !== undefined) {\n sql = `CONSTRAINT ${quoteIdentifier(constraint.name)} ${sql}`;\n }\n return sql;\n }\n const cols = constraint.columns.map(quoteIdentifier).join(', ');\n if (constraint.name !== undefined) {\n return `CONSTRAINT ${quoteIdentifier(constraint.name)} UNIQUE (${cols})`;\n }\n return `UNIQUE (${cols})`;\n}\n\nasync function sqliteRenderDdlExecuteRequest(\n ast: SqliteDdlNode,\n codecLookup: CodecLookup,\n): Promise<SqlExecuteRequest> {\n const node = blindCast<SqliteCreateTable, 'SQLite DDL only has create-table'>(ast);\n const ifNotExists = node.ifNotExists ? 'IF NOT EXISTS ' : '';\n const tableRef = quoteIdentifier(node.table);\n const columnDefs = await Promise.all(\n node.columns.map((col) => sqliteRenderDdlColumn(col, codecLookup)),\n );\n const constraintDefs =\n node.constraints !== undefined ? node.constraints.map(sqliteRenderDdlConstraint) : [];\n const allDefs = [...columnDefs, ...constraintDefs].join(',\\n ');\n return {\n sql: `CREATE TABLE ${ifNotExists}${tableRef} (\\n ${allDefs}\\n)`,\n params: [],\n };\n}\n","import { APP_SPACE_ID } from '@prisma-next/framework-components/control';\nimport type {\n Adapter,\n AdapterProfile,\n AggregateExpr,\n AnyExpression,\n AnyFromSource,\n AnyQueryAst,\n BinaryExpr,\n ColumnRef,\n DeleteAst,\n InsertAst,\n InsertValue,\n JoinAst,\n JoinOnExpr,\n JsonArrayAggExpr,\n JsonObjectExpr,\n ListExpression,\n LiteralExpr,\n LoweredParam,\n LowererContext,\n NullCheckExpr,\n OperationExpr,\n OrderByItem,\n ProjectionItem,\n RawExpr,\n RawSqlLiteral,\n SelectAst,\n SqlQueryable,\n SubqueryExpr,\n TableSource,\n UpdateAst,\n WindowFuncExpr,\n} from '@prisma-next/sql-relational-core/ast';\nimport { isDdlNode } from '@prisma-next/sql-relational-core/ast';\nimport type { RawCodecInferer } from '@prisma-next/sql-relational-core/expression';\nimport type { SqliteDdlNode } from '@prisma-next/target-sqlite/ddl';\nimport { escapeLiteral, quoteIdentifier } from '@prisma-next/target-sqlite/sql-utils';\nimport { SqliteControlAdapter } from './control-adapter';\nimport type { SqliteAdapterOptions, SqliteContract, SqliteLoweredStatement } from './types';\n\nconst defaultCapabilities = Object.freeze({\n sql: {\n orderBy: true,\n limit: true,\n lateral: false,\n jsonAgg: true,\n returning: true,\n enums: false,\n },\n});\n\nclass SqliteAdapterImpl implements Adapter<AnyQueryAst, SqliteContract, SqliteLoweredStatement> {\n readonly familyId = 'sql' as const;\n readonly targetId = 'sqlite' as const;\n\n readonly profile: AdapterProfile<'sqlite'>;\n\n constructor(options?: SqliteAdapterOptions) {\n const controlAdapter = new SqliteControlAdapter();\n this.profile = Object.freeze({\n id: options?.profileId ?? 'sqlite/default@1',\n target: 'sqlite',\n capabilities: defaultCapabilities,\n readMarker: (queryable: SqlQueryable) =>\n controlAdapter.readMarkerDiscriminated(\n {\n familyId: 'sql',\n targetId: 'sqlite',\n query: async <Row = Record<string, unknown>>(\n sql: string,\n params?: readonly unknown[],\n ) => {\n const result = await queryable.query<Row>(sql, params);\n return { rows: [...result.rows] };\n },\n close: async () => {},\n },\n APP_SPACE_ID,\n ),\n });\n }\n\n lower(\n ast: AnyQueryAst | SqliteDdlNode,\n context: LowererContext<SqliteContract>,\n ): SqliteLoweredStatement {\n if (isDdlNode(ast)) {\n throw new Error(\n 'lower() does not lower DDL on the runtime adapter — DDL lowering is a control-plane concern handled by the control adapter.',\n );\n }\n return renderLoweredSql(ast, context.contract);\n }\n}\n\n/** Codec-id lookup for bare-literal interpolations used by `fns.raw` on a sqlite client. Contributed as the descriptor's static `rawCodecInferer` slot. */\nexport const sqliteRawCodecInferer: RawCodecInferer = {\n inferCodec(value: RawSqlLiteral): string {\n switch (typeof value) {\n case 'number':\n return Number.isSafeInteger(value) && value % 1 === 0\n ? 'sqlite/integer@1'\n : 'sqlite/real@1';\n case 'bigint':\n return 'sqlite/bigint@1';\n case 'string':\n return 'sqlite/text@1';\n case 'boolean':\n return 'sqlite/integer@1';\n case 'object':\n if (value instanceof Uint8Array) return 'sqlite/blob@1';\n }\n throw new Error(\n 'unsupported JS value type for raw-SQL interpolation: wrap this value in `param(...)` with an explicit codec',\n );\n },\n};\n\n/**\n * Lower a SQL query AST into a SQLite-flavored `{ sql, params }` payload.\n *\n * Shared between the runtime adapter (`SqliteAdapterImpl.lower`) and the control adapter (`SqliteControlAdapter.lower`) so both produce byte-identical SQL for the same AST and contract.\n */\nexport function renderLoweredSql(\n ast: AnyQueryAst,\n contract: SqliteContract,\n): SqliteLoweredStatement {\n const collectedParamRefs = ast.collectParamRefs();\n const params: LoweredParam[] = [];\n for (const ref of collectedParamRefs) {\n params.push(\n ref.kind === 'prepared-param-ref'\n ? { kind: 'bind', name: ref.name }\n : { kind: 'literal', value: ref.value },\n );\n }\n\n let sql: string;\n\n const node = ast;\n switch (node.kind) {\n case 'select':\n sql = renderSelect(node, contract);\n break;\n case 'insert':\n sql = renderInsert(node, contract);\n break;\n case 'update':\n sql = renderUpdate(node, contract);\n break;\n case 'delete':\n sql = renderDelete(node, contract);\n break;\n default:\n throw new Error(`Unsupported AST node kind: ${(node as { kind: string }).kind}`);\n }\n\n return Object.freeze({ sql, params });\n}\n\nfunction renderLimitOffset(\n keyword: 'LIMIT' | 'OFFSET',\n value: SelectAst['limit'] | SelectAst['offset'],\n contract?: SqliteContract,\n): string {\n if (value === undefined) return '';\n if (typeof value === 'number') return `${keyword} ${value}`;\n return `${keyword} ${renderExpr(value, contract)}`;\n}\n\nfunction renderSelect(ast: SelectAst, contract: SqliteContract): string {\n const distinctPrefix = ast.distinct ? 'DISTINCT ' : '';\n const selectClause = `SELECT ${distinctPrefix}${renderProjection(ast.projection, contract)}`;\n const fromClause = `FROM ${renderSource(ast.from, contract)}`;\n\n const joinsClause = ast.joins?.length\n ? ast.joins.map((join) => renderJoin(join, contract)).join(' ')\n : '';\n\n const whereClause = ast.where ? `WHERE ${renderExpr(ast.where, contract)}` : '';\n const groupByClause = ast.groupBy?.length\n ? `GROUP BY ${ast.groupBy.map((expr) => renderExpr(expr, contract)).join(', ')}`\n : '';\n const havingClause = ast.having ? `HAVING ${renderExpr(ast.having, contract)}` : '';\n const orderClause = ast.orderBy?.length\n ? `ORDER BY ${ast.orderBy\n .map((order) => `${renderExpr(order.expr, contract)} ${order.dir.toUpperCase()}`)\n .join(', ')}`\n : '';\n const limitClause = renderLimitOffset('LIMIT', ast.limit, contract);\n const offsetClause = renderLimitOffset('OFFSET', ast.offset, contract);\n\n return [\n selectClause,\n fromClause,\n joinsClause,\n whereClause,\n groupByClause,\n havingClause,\n orderClause,\n limitClause,\n offsetClause,\n ]\n .filter((part) => part.length > 0)\n .join(' ')\n .trim();\n}\n\nfunction renderProjection(\n projection: ReadonlyArray<ProjectionItem>,\n contract?: SqliteContract,\n): string {\n return projection\n .map((item) => {\n const alias = quoteIdentifier(item.alias);\n if (item.expr.kind === 'literal') {\n return `${renderLiteral(item.expr)} AS ${alias}`;\n }\n return `${renderExpr(item.expr, contract)} AS ${alias}`;\n })\n .join(', ');\n}\n\nfunction qualifyTableFromNamespaceCoordinate(\n table: Pick<TableSource, 'name' | 'namespaceId'>,\n contract: SqliteContract,\n): string {\n if (table.namespaceId === undefined) {\n return quoteIdentifier(table.name);\n }\n const namespace = contract.storage.namespaces[table.namespaceId];\n if (namespace === undefined) {\n throw new Error(\n `Table \"${table.name}\" references namespace \"${table.namespaceId}\" which is not present on the contract`,\n );\n }\n const qualifyTable = namespace.qualifyTable;\n if (qualifyTable === undefined) {\n throw new Error(\n `Table \"${table.name}\" references namespace \"${table.namespaceId}\" which is not materialised for SQL rendering on the contract`,\n );\n }\n return qualifyTable.call(namespace, table.name);\n}\n\nfunction renderTableSource(source: TableSource, contract: SqliteContract): string {\n const qualified = qualifyTableFromNamespaceCoordinate(source, contract);\n if (!source.alias) {\n return qualified;\n }\n return `${qualified} AS ${quoteIdentifier(source.alias)}`;\n}\n\nfunction renderSource(source: AnyFromSource, contract: SqliteContract): string {\n const node = source;\n switch (node.kind) {\n case 'table-source':\n return renderTableSource(node, contract);\n case 'derived-table-source':\n return `(${renderSelect(node.query, contract)}) AS ${quoteIdentifier(node.alias)}`;\n default:\n throw new Error(`Unsupported source node kind: ${(node as { kind: string }).kind}`);\n }\n}\n\nfunction renderExpr(expr: AnyExpression, contract?: SqliteContract): string {\n const node = expr;\n switch (node.kind) {\n case 'column-ref':\n return renderColumn(node);\n case 'identifier-ref':\n return quoteIdentifier(node.name);\n case 'operation':\n return renderOperation(node, contract);\n case 'subquery':\n return renderSubqueryExpr(node, contract);\n case 'aggregate':\n return renderAggregateExpr(node, contract);\n case 'window-func':\n return renderWindowFuncExpr(node, contract);\n case 'json-object':\n return renderJsonObjectExpr(node, contract);\n case 'json-array-agg':\n return renderJsonArrayAggExpr(node, contract);\n case 'binary':\n return renderBinary(node, contract);\n case 'and':\n if (node.exprs.length === 0) {\n return 'TRUE';\n }\n return `(${node.exprs.map((part) => renderExpr(part, contract)).join(' AND ')})`;\n case 'or':\n if (node.exprs.length === 0) {\n return 'FALSE';\n }\n return `(${node.exprs.map((part) => renderExpr(part, contract)).join(' OR ')})`;\n case 'exists': {\n if (contract === undefined) {\n throw new Error('EXISTS subquery rendering requires a Sqlite contract');\n }\n const notKeyword = node.notExists ? 'NOT ' : '';\n const subquery = renderSelect(node.subquery, contract);\n return `${notKeyword}EXISTS (${subquery})`;\n }\n case 'null-check':\n return renderNullCheck(node, contract);\n case 'not':\n return `NOT (${renderExpr(node.expr, contract)})`;\n case 'param-ref':\n case 'prepared-param-ref':\n return '?';\n case 'literal':\n return renderLiteral(node);\n case 'list':\n return renderListLiteral(node);\n case 'raw-expr':\n return renderRawExpr(node, contract);\n default:\n throw new Error(`Unsupported expression node kind: ${(node as { kind: string }).kind}`);\n }\n}\n\nfunction renderRawExpr(node: RawExpr, contract?: SqliteContract): string {\n return node.parts\n .map((part) => (typeof part === 'string' ? part : renderExpr(part, contract)))\n .join('');\n}\n\n// `excluded` is a pseudo-table in ON CONFLICT DO UPDATE that references the row proposed for insertion. It is not quoted because it's a keyword.\nfunction renderColumn(ref: ColumnRef): string {\n if (ref.table === 'excluded') {\n return `excluded.${quoteIdentifier(ref.column)}`;\n }\n return `${quoteIdentifier(ref.table)}.${quoteIdentifier(ref.column)}`;\n}\n\nfunction renderLiteral(expr: LiteralExpr): string {\n if (typeof expr.value === 'string') {\n return `'${escapeLiteral(expr.value)}'`;\n }\n if (typeof expr.value === 'number' || typeof expr.value === 'boolean') {\n return String(expr.value);\n }\n if (typeof expr.value === 'bigint') {\n return String(expr.value);\n }\n if (expr.value === null || expr.value === undefined) {\n return 'NULL';\n }\n if (expr.value instanceof Date) {\n return `'${escapeLiteral(expr.value.toISOString())}'`;\n }\n const json = JSON.stringify(expr.value);\n if (json === undefined) {\n return 'NULL';\n }\n return `'${escapeLiteral(json)}'`;\n}\n\nfunction renderOperation(expr: OperationExpr, contract?: SqliteContract): string {\n const self = renderExpr(expr.self, contract);\n const args = expr.args.map((arg) => renderExpr(arg, contract));\n\n let result = expr.lowering.template;\n result = result.replace(/\\{\\{self\\}\\}/g, self);\n for (let i = 0; i < args.length; i++) {\n result = result.replace(new RegExp(`\\\\{\\\\{arg${i}\\\\}\\\\}`, 'g'), args[i] ?? '');\n }\n\n return result;\n}\n\nfunction renderSubqueryExpr(expr: SubqueryExpr, contract?: SqliteContract): string {\n if (expr.query.projection.length !== 1) {\n throw new Error('Subquery expressions must project exactly one column');\n }\n if (contract === undefined) {\n throw new Error('Subquery expression rendering requires a Sqlite contract');\n }\n return `(${renderSelect(expr.query, contract)})`;\n}\n\nfunction renderNullCheck(expr: NullCheckExpr, contract?: SqliteContract): string {\n const rendered = renderExpr(expr.expr, contract);\n const renderedExpr =\n expr.expr.kind === 'operation' || expr.expr.kind === 'subquery' ? `(${rendered})` : rendered;\n return expr.isNull ? `${renderedExpr} IS NULL` : `${renderedExpr} IS NOT NULL`;\n}\n\nfunction renderBinary(expr: BinaryExpr, contract?: SqliteContract): string {\n if (expr.right.kind === 'list' && expr.right.values.length === 0) {\n if (expr.op === 'in') {\n return 'FALSE';\n }\n if (expr.op === 'notIn') {\n return 'TRUE';\n }\n }\n\n const leftExpr = expr.left;\n const left = renderExpr(leftExpr, contract);\n const leftRendered =\n leftExpr.kind === 'operation' || leftExpr.kind === 'subquery' ? `(${left})` : left;\n\n const rightNode = expr.right;\n let right: string;\n switch (rightNode.kind) {\n case 'list':\n right = renderListLiteral(rightNode);\n break;\n case 'literal':\n right = renderLiteral(rightNode);\n break;\n case 'column-ref':\n right = renderColumn(rightNode);\n break;\n case 'param-ref':\n case 'prepared-param-ref':\n right = '?';\n break;\n default:\n right = renderExpr(rightNode, contract);\n break;\n }\n\n const operatorMap: Record<BinaryExpr['op'], string> = {\n eq: '=',\n neq: '!=',\n gt: '>',\n lt: '<',\n gte: '>=',\n lte: '<=',\n like: 'LIKE',\n in: 'IN',\n notIn: 'NOT IN',\n };\n\n return `${leftRendered} ${operatorMap[expr.op]} ${right}`;\n}\n\nfunction renderListLiteral(expr: ListExpression): string {\n if (expr.values.length === 0) {\n return '(NULL)';\n }\n const values = expr.values\n .map((v) => {\n if (v.kind === 'param-ref' || v.kind === 'prepared-param-ref') return '?';\n if (v.kind === 'literal') return renderLiteral(v);\n return renderExpr(v);\n })\n .join(', ');\n return `(${values})`;\n}\n\nfunction renderAggregateExpr(expr: AggregateExpr, contract?: SqliteContract): string {\n const fn = expr.fn.toUpperCase();\n if (!expr.expr) {\n return `${fn}(*)`;\n }\n return `${fn}(${renderExpr(expr.expr, contract)})`;\n}\n\nfunction renderWindowFuncExpr(expr: WindowFuncExpr, contract?: SqliteContract): string {\n const fn = expr.fn.toUpperCase();\n const args = expr.args.map((arg) => renderExpr(arg, contract)).join(', ');\n const partitionClause =\n expr.partitionBy && expr.partitionBy.length > 0\n ? `PARTITION BY ${expr.partitionBy.map((e) => renderExpr(e, contract)).join(', ')}`\n : '';\n const orderClause =\n expr.orderBy && expr.orderBy.length > 0\n ? `ORDER BY ${renderOrderByItems(expr.orderBy, contract)}`\n : '';\n const over = [partitionClause, orderClause].filter((part) => part.length > 0).join(' ');\n return `${fn}(${args}) OVER (${over})`;\n}\n\nfunction renderJsonObjectExpr(expr: JsonObjectExpr, contract?: SqliteContract): string {\n const args = expr.entries\n .flatMap((entry): [string, string] => {\n const key = `'${escapeLiteral(entry.key)}'`;\n if (entry.value.kind === 'literal') {\n return [key, renderLiteral(entry.value)];\n }\n return [key, renderExpr(entry.value, contract)];\n })\n .join(', ');\n return `json_object(${args})`;\n}\n\nfunction renderOrderByItems(items: ReadonlyArray<OrderByItem>, contract?: SqliteContract): string {\n return items\n .map((item) => `${renderExpr(item.expr, contract)} ${item.dir.toUpperCase()}`)\n .join(', ');\n}\n\nfunction renderJsonArrayAggExpr(expr: JsonArrayAggExpr, contract?: SqliteContract): string {\n const aggregateOrderBy =\n expr.orderBy && expr.orderBy.length > 0\n ? ` ORDER BY ${renderOrderByItems(expr.orderBy, contract)}`\n : '';\n const aggregated = `json_group_array(${renderExpr(expr.expr, contract)}${aggregateOrderBy})`;\n if (expr.onEmpty === 'emptyArray') {\n return `coalesce(${aggregated}, '[]')`;\n }\n return aggregated;\n}\n\nfunction renderJoin(join: JoinAst, contract?: SqliteContract): string {\n if (contract === undefined) {\n throw new Error('JOIN rendering requires a Sqlite contract');\n }\n const joinType = join.joinType.toUpperCase();\n const source = renderSource(join.source, contract);\n const onClause = renderJoinOn(join.on, contract);\n return `${joinType} JOIN ${source} ON ${onClause}`;\n}\n\nfunction renderJoinOn(on: JoinOnExpr, contract?: SqliteContract): string {\n if (on.kind === 'eq-col-join-on') {\n return `${renderColumn(on.left)} = ${renderColumn(on.right)}`;\n }\n return renderExpr(on, contract);\n}\n\nfunction renderInsertValue(value: InsertValue): string {\n switch (value.kind) {\n case 'param-ref':\n case 'prepared-param-ref':\n return '?';\n case 'column-ref':\n return renderColumn(value);\n case 'raw-expr':\n return renderExpr(value);\n case 'default-value':\n throw new Error('SQLite does not support DEFAULT as a value in INSERT ... VALUES');\n default:\n throw new Error(`Unsupported value node in INSERT: ${(value as { kind: string }).kind}`);\n }\n}\n\nfunction renderInsert(ast: InsertAst, contract: SqliteContract): string {\n const table = qualifyTableFromNamespaceCoordinate(ast.table, contract);\n const rows = ast.rows;\n if (rows.length === 0) {\n throw new Error('INSERT requires at least one row');\n }\n\n const firstRow = rows[0] as Readonly<Record<string, InsertValue>>;\n const columnOrder = Object.keys(firstRow);\n\n let insertClause: string;\n if (columnOrder.length === 0) {\n insertClause = `INSERT INTO ${table} DEFAULT VALUES`;\n } else {\n const columns = columnOrder.map((column) => quoteIdentifier(column));\n const values = rows\n .map((row) => {\n const renderedRow = columnOrder.map((column) => {\n const value = row[column];\n if (value === undefined) {\n throw new Error(`Missing value for column \"${column}\" in INSERT row`);\n }\n return renderInsertValue(value);\n });\n return `(${renderedRow.join(', ')})`;\n })\n .join(', ');\n insertClause = `INSERT INTO ${table} (${columns.join(', ')}) VALUES ${values}`;\n }\n\n let onConflictClause = '';\n if (ast.onConflict) {\n const conflictColumns = ast.onConflict.columns.map((col) => quoteIdentifier(col.column));\n if (conflictColumns.length === 0) {\n throw new Error('INSERT onConflict requires at least one conflict column');\n }\n\n const action = ast.onConflict.action;\n switch (action.kind) {\n case 'do-nothing':\n onConflictClause = ` ON CONFLICT (${conflictColumns.join(', ')}) DO NOTHING`;\n break;\n case 'do-update-set': {\n const updates = Object.entries(action.set).map(([colName, value]) => {\n return `${quoteIdentifier(colName)} = ${renderExpr(value, contract)}`;\n });\n onConflictClause = ` ON CONFLICT (${conflictColumns.join(', ')}) DO UPDATE SET ${updates.join(', ')}`;\n break;\n }\n default:\n throw new Error(`Unsupported onConflict action: ${(action as { kind: string }).kind}`);\n }\n }\n\n const returningClause = renderReturning(ast.returning);\n\n return `${insertClause}${onConflictClause}${returningClause}`;\n}\n\nfunction renderUpdate(ast: UpdateAst, contract: SqliteContract): string {\n const table = qualifyTableFromNamespaceCoordinate(ast.table, contract);\n const setClauses = Object.entries(ast.set).map(([col, val]) => {\n return `${quoteIdentifier(col)} = ${renderExpr(val, contract)}`;\n });\n\n const whereClause = ast.where ? ` WHERE ${renderExpr(ast.where, contract)}` : '';\n const returningClause = renderReturning(ast.returning);\n\n return `UPDATE ${table} SET ${setClauses.join(', ')}${whereClause}${returningClause}`;\n}\n\nfunction renderDelete(ast: DeleteAst, contract: SqliteContract): string {\n const table = qualifyTableFromNamespaceCoordinate(ast.table, contract);\n const whereClause = ast.where ? ` WHERE ${renderExpr(ast.where)}` : '';\n const returningClause = renderReturning(ast.returning);\n\n return `DELETE FROM ${table}${whereClause}${returningClause}`;\n}\n\nfunction renderReturning(returning: ReadonlyArray<ProjectionItem> | undefined): string {\n if (!returning?.length) {\n return '';\n }\n return ` RETURNING ${returning\n .map((item) => {\n if (item.expr.kind === 'column-ref') {\n const rendered = `${quoteIdentifier(item.expr.table)}.${quoteIdentifier(item.expr.column)}`;\n return item.expr.column === item.alias\n ? rendered\n : `${rendered} AS ${quoteIdentifier(item.alias)}`;\n }\n return `${renderExpr(item.expr)} AS ${quoteIdentifier(item.alias)}`;\n })\n .join(', ')}`;\n}\n\nexport function createSqliteAdapter(options?: SqliteAdapterOptions) {\n return Object.freeze(new SqliteAdapterImpl(options));\n}\n"],"mappings":";;;;;;;;;;;;;;;AAEA,SAAS,uBAAuB,gBAAgB;CAC/C,IAAI,mBAAmB,QAAQ,mBAAmB,MAAM,mBAAmB,gBAAgB,OAAO;CAClG,OAAO;AACR;;;ACOA,MAAa,iBAAiB,uBAAuB,mBAAmB;AAExE,eAAsB,yBACpB,SACA,KACA,SAAgC,gBACH;CAK7B,OAAO,yBAJQ,QAAQ,OAAO,KAAK,SAAS;EAC1C,IAAI,KAAK,SAAS,WAAW,OAAO,KAAK;EACzC,MAAM,IAAI,MAAM,yCAAyC,KAAK,KAAK,wBAAwB;CAC7F,CACqC,GAAG,oBAAoB,GAAG,GAAG,CAAC,GAAG,MAAM;AAC9E;;;ACxBA,MAAM,+BAA+B;AAErC,SAAgB,sBAAsB,OAA4B;CAChE,IAAI,iBAAiB,MACnB,OAAO;CAET,IAAI,6BAA6B,KAAK,KAAK,GACzC,uBAAO,IAAI,KAAK,GAAG,MAAM,QAAQ,KAAK,GAAG,EAAE,EAAE;CAE/C,OAAO,IAAI,KAAK,KAAK;AACvB;AAEA,SAAgB,yBAAyB,YAA6B;CACpE,IAAI,MAAM,QAAQ,UAAU,GAC1B,OAAO,WAAW;CAEpB,IAAI,OAAO,eAAe,UACxB,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,UAAU;EAC7C,OAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,SAAS;CACjD,QAAQ;EACN,OAAO;CACT;CAEF,OAAO;AACT;;;ACTA,MAAa,SAAS,YAAY,kBAAkB;CAClD,OAAO,KAAK;CACZ,WAAW,KAAK;CAChB,cAAc,KAAK;CACnB,eAAe,SAAS,EAAE,UAAU,KAAK,CAAC;CAC1C,mBAAmB,QAAQ,EAAE,UAAU,KAAK,CAAC;CAC7C,YAAY,SAAS;CACrB,SAAS,KAAK,EAAE,UAAU,KAAK,CAAC;CAChC,MAAM,SAAS,EAAE,UAAU,KAAK,CAAC;CACjC,YAAY,SAAS;AACvB,CAAC;;;;;;AAOD,MAAa,SAAS,YAAY,kBAAkB;CAClD,OAAO,KAAK;CACZ,gBAAgB,KAAK;CACrB,gBAAgB,KAAK;CACrB,kBAAkB,KAAK,EAAE,UAAU,KAAK,CAAC;CACzC,uBAAuB,KAAK;CAC5B,YAAY,SAAS;AACvB,CAAC;;;;;AAMD,MAAa,kBAAkB,YAAY,kBAAkB;CAC3D,IAAI,QAAQ;CACZ,OAAO,KAAK;CACZ,gBAAgB,KAAK;CACrB,gBAAgB,KAAK;CACrB,kBAAkB,KAAK,EAAE,UAAU,KAAK,CAAC;CACzC,uBAAuB,KAAK;CAC5B,YAAY,SAAS;CACrB,YAAY,KAAK;AACnB,CAAC;AAED,MAAa,gBAAgB,YAAY,iBAAiB;CAAE,MAAM,KAAK;CAAG,MAAM,KAAK;AAAE,CAAC;AAExF,MAAa,MAAM,IAAI,QAAQ;CAC7B,OAAO,CAAC,iBAAiB;CACzB,SAAS;EAAE,SAAS;EAA0B,UAAU;CAAM;AAChE,CAAC;AAWD,SAAgB,gBACd,SACA,UACmB;CACnB,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK;AACtD;AAEA,eAAsB,QACpB,OACA,QACA,OAC6C;CAC7C,MAAM,UAAU,MAAM,KAAK;CAC3B,MAAM,UAAU,MAAM,yBAAyB,SAAS,KAAK;CAE7D,QAAO,MADc,OAAO,MAAM,QAAQ,KAAK,OAAO,EAAA,CACxC;AAChB;AAEA,SAAgB,sBAAsB,KAAuB;CAC3D,IAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,EAAE,gBAAgB,MAC/D,OAAO;CAET,MAAM,SAAS;CACf,IAAI,OAAO,OAAO,eAAe,UAAU,OAAO;CAClD,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,OAAO,UAAU;CACvC,SAAS,KAAK;EACZ,MAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EAC9D,MAAM,IAAI,MAAM,8DAA8D,QAAQ;CACxF;CACA,OAAO;EAAE,GAAG;EAAQ,YAAY;CAAO;AACzC;;;AC9CA,MAAM,sBAAsB;AAC5B,MAAM,sBAAsB;AAsD5B,SAAS,iCAA8C;CACrD,OAAO,mBAAmB,CACxB;EACE,IAAI;EACJ,OAAO,EAAE,YAAY,EAAE,kBAAkB,MAAM,KAAK,oBAAoB,OAAO,CAAC,EAAE,EAAE;CACtF,CACF,CAAC;AACH;AAEA,IAAa,uBAAb,MAAyE;CACvE,WAAoB;CACpB,WAAoB;CAEpB;;;;;;CAOA,YAAY,aAA2B;EACrC,KAAK,cAAc,eAAe,+BAA+B;CACnE;CAEA,mBAA4B;CAC5B,sBAA+B;CAE/B,+BAAmD;EACjD,OAAO,kCAAkC;CAC3C;CAEA,6BAAiD;EAC/C,OAAO,gCAAgC;CACzC;;;;;;;;;CAUA,MAAM,KAAkC,SAAoD;EAC1F,IAAI,UAAU,GAAG,GACf,MAAM,IAAI,MACR,4HACF;EAEF,OAAO,iBAAiB,KAAK,QAAQ,QAA0B;CACjE;;;;;;;;CASA,MAAM,sBACJ,KACA,SAC4B;EAC5B,IAAI,UAAU,GAAG,GACf,OAAO,8BACL,UAA4C,GAAG,GAC/C,KAAK,WACP;EAEF,MAAM,UAAU,iBACd,KACA,UAAkE,SAAS,QAAQ,CACrF;EACA,MAAM,SAAS,MAAM,yBAAyB,SAAS,GAAG;EAC1D,OAAO;GAAE,KAAK,QAAQ;GAAK;EAAO;CACpC;;;;;;CAOA,MAAM,WACJ,QACA,OACsC;EACtC,MAAM,SAAS,MAAM,KAAK,wBAAwB,QAAQ,KAAK;EAC/D,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS;CACrD;CAEA,MAAM,wBACJ,QACA,OAC2B;EAE3B,OAAO,kCAAkC,KAAK,iBAAiB,QAAQ,KAAK,GAAG;GADvD;GAAO,gBAAgB;EAC4C,CAAC;CAC9F;;;;;;CAOA,MAAM,eACJ,QACoD;EAEpD,OAAO,kCAAkC,KAAK,qBAAqB,MAAM,GAAG;GADpD,OAAO;GAAc,gBAAgB;EAC2B,CAAC;CAC3F;CAEA,MAAc,qBACZ,QACoD;EACpD,MAAM,SAAS,UAAuB,KAAK,MAAM,OAAO,EAAE,UAAU,KAAA,EAAU,CAAC;EAM/E,KAAI,MADiB,QAAQ,OAAO,QAJtB,cACX,OAAO,cAAc,IAAI,CAAC,CAC1B,MAAM,cAAc,KAAK,GAAG,OAAO,CAAC,CAAC,IAAI,cAAc,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAClF,MAC6C,CAAC,EAAA,CACtC,WAAW,GACpB,uBAAO,IAAI,IAAI;EAiBjB,MAAM,OAAO,UAGX,MAJoB,QAAQ,OAAO,QAbvB,OACX,OACC,OAAO,OACP,OAAO,WACP,OAAO,cACP,OAAO,eACP,OAAO,mBACP,OAAO,YACP,OAAO,SACP,OAAO,MACP,OAAO,UACT,CAAC,CACA,MAC8C,CAAC,CAIzC;EAET,MAAM,sBAAM,IAAI,IAAkC;EAClD,KAAK,MAAM,OAAO,MAChB,IAAI,IACF,IAAI,OACJ,qBAAqB,MAAM,QAAQ,uBAAuB,sBAAsB,GAAG,CAAC,GAAG;GACrF,OAAO,IAAI;GACX,gBAAgB;EAClB,CAAC,CACH;EAEF,OAAO;CACT;;;;;;CAOA,MAAM,WACJ,QACA,OACuC;EAEvC,OAAO,kCAAkC,KAAK,iBAAiB,QAAQ,KAAK,GAAG;GADvD,OAAO,SAAS;GAAK,gBAAgB;EAC8B,CAAC;CAC9F;CAEA,MAAc,iBACZ,QACA,OACuC;EACvC,MAAM,SAAS,UAAuB,KAAK,MAAM,OAAO,EAAE,UAAU,KAAA,EAAU,CAAC;EAM/E,KAAI,MADiB,QAAQ,OAAO,QAJtB,cACX,OAAO,cAAc,IAAI,CAAC,CAC1B,MAAM,cAAc,KAAK,GAAG,OAAO,CAAC,CAAC,IAAI,cAAc,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAClF,MAC6C,CAAC,EAAA,CACtC,WAAW,GACpB,OAAO,CAAC;EAGV,MAAM,OAAO,gBAAgB,OAC3B,gBAAgB,OAChB,gBAAgB,gBAChB,gBAAgB,gBAChB,gBAAgB,kBAChB,gBAAgB,uBAChB,gBAAgB,YAChB,gBAAgB,UAClB;EAOA,OAJa,UACX,MAFoB,QAAQ,OAAO,SADpB,UAAU,KAAA,IAAY,KAAK,MAAM,gBAAgB,MAAM,GAAG,KAAK,CAAC,IAAI,KAAA,CAC/B,QAAQ,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAK/E,CAAC,CAAC,KAAK,SAAS;GACxB,OAAO,IAAI;GACX,eAAe,IAAI;GACnB,eAAe,IAAI;GACnB,MAAM,uBAAuB,IAAI,gBAAgB;GACjD,IAAI,IAAI;GACR,WAAW,sBAAsB,IAAI,UAAU;GAC/C,gBAAgB,yBAAyB,IAAI,UAAU;EACzD,EAAE;CACJ;;;;;;CAOA,MAAM,aACJ,QACA,OACA,aAKe;EACf,MAAM,SACH,UAAU,KAAK,MAAM,OAAO,EAAE,UAAU,KAAA,EAAU,CAAC,GACpD,QACA,OACG,OAAO;GACN;GACA,WAAW,YAAY;GACvB,cAAc,YAAY;GAC1B,eAAe;GACf,mBAAmB;GACnB,YAAY;GACZ,SAAS;GACT,MAAM,CAAC;GACP,YAAY,YAAY,cAAc,CAAC;EACzC,CAAC,CAAC,CACD,MAAM,CACX;CACF;CAEA,MAAM,WACJ,QACA,OACA,aAKe;EACf,MAAM,SACH,UAAU,KAAK,MAAM,OAAO,EAAE,UAAU,KAAA,EAAU,CAAC,GACpD,QACA,OACG,OAAO;GACN;GACA,WAAW,YAAY;GACvB,cAAc,YAAY;GAC1B,eAAe;GACf,mBAAmB;GACnB,YAAY;GACZ,SAAS;GACT,MAAM,CAAC;GACP,YAAY,YAAY,cAAc,CAAC;EACzC,CAAC,CAAC,CACD,WAAW,OAAO,KAAK,CAAC,CACxB,UAAU,cAAc;GACvB,WAAW,SAAS;GACpB,cAAc,SAAS;GACvB,eAAe,SAAS;GACxB,mBAAmB,SAAS;GAC5B,YAAY;GACZ,SAAS,SAAS;GAClB,MAAM,SAAS;GACf,YAAY,SAAS;EACvB,EAAE,CAAC,CACF,MAAM,CACX;CACF;;;;;CAMA,MAAM,aACJ,QACA,OACA,cACA,aAKkB;EAClB,MAAM,oBACJ,YAAY,eAAe,KAAA,IACvB,CAAC,KACC,MAAM,KAAK,WAAW,QAAQ,KAAK,EAAA,EAAI,cAAc,CAAC;EAC9D,MAAM,mBACJ,YAAY,eAAe,KAAA,IACvB,KAAA,IACA,gBAAgB,mBAAmB,YAAY,UAAU;EAe/D,QAAO,MADY,SAAS,MAAM,KAAK,MAAM,GAAG,EAAE,UAAU,KAAA,EAAU,CAAC,GAAG,QAZ5D,OACX,OAAO,CAAC,CACR,IAAI;GACH,WAAW,YAAY;GACvB,cAAc,YAAY;GAC1B,YAAY;GACZ,GAAI,qBAAqB,KAAA,IAAY,EAAE,YAAY,iBAAiB,IAAI,CAAC;EAC3E,CAAC,CAAC,CACD,MAAM,OAAO,MAAM,GAAG,KAAK,CAAC,CAAC,IAAI,OAAO,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,CACpE,UAAU,OAAO,KAAK,CAAC,CACvB,MAEmF,CAAC,EAAA,CAC3E,SAAS;CACvB;;;;;CAMA,MAAM,iBACJ,QACA,OACA,OAQe;EACf,MAAM,SACH,UAAU,KAAK,MAAM,OAAO,EAAE,UAAU,KAAA,EAAU,CAAC,GACpD,QACA,OACG,OAAO;GACN;GACA,gBAAgB,MAAM;GACtB,gBAAgB,MAAM;GACtB,kBAAkB,MAAM;GACxB,uBAAuB,MAAM;GAC7B,YAAY,MAAM;EACpB,CAAC,CAAC,CACD,MAAM,CACX;CACF;CAEA,MAAc,iBAAiB,QAA4C,OAAe;EACxF,MAAM,SAAS,UAAuB,KAAK,MAAM,OAAO,EAAE,UAAU,KAAA,EAAU,CAAC;EAM/E,KAAI,MADiB,QAAQ,OAAO,QAJtB,cACX,OAAO,cAAc,IAAI,CAAC,CAC1B,MAAM,cAAc,KAAK,GAAG,OAAO,CAAC,CAAC,IAAI,cAAc,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAClF,MAC6C,CAAC,EAAA,CACtC,WAAW,GAAG,OAAO,EAAE,MAAM,WAAoB;EAgB5D,MAAM,OAAM,MADS,QAAQ,OAAO,QAbtB,OACX,OACC,OAAO,WACP,OAAO,cACP,OAAO,eACP,OAAO,mBACP,OAAO,YACP,OAAO,SACP,OAAO,MACP,OAAO,UACT,CAAC,CACA,MAAM,OAAO,MAAM,GAAG,KAAK,CAAC,CAAC,CAC7B,MAC6C,CAAC,EAAA,CAC9B;EACnB,IAAI,CAAC,KAAK,OAAO,EAAE,MAAM,SAAkB;EAC3C,OAAO;GACL,MAAM;GACN,QAAQ,uBAAuB,sBAAsB,GAAG,CAAC;EAC3D;CACF;CAEA,MAAM,WACJ,QACA,WACsB;EAMtB,MAAM,eAAe,MAAM,OAAO,MAChC;;;;qBAKF;EAEA,MAAM,SAAqC,CAAC;EAE5C,KAAK,MAAM,YAAY,aAAa,MAAM;GACxC,MAAM,YAAY,SAAS;GAG3B,MAAM,gBAAgB,MAAM,OAAO,MACjC,sBAAsB,gBAAgB,SAAS,EAAE,GACnD;GACA,MAAM,WAAW,MAAM,OAAO,MAC5B,4BAA4B,gBAAgB,SAAS,EAAE,GACzD;GACA,MAAM,kBAAkB,MAAM,OAAO,MACnC,sBAAsB,gBAAgB,SAAS,EAAE,GACnD;GAEA,MAAM,UAAuC,CAAC;GAC9C,MAAM,YAAiD,CAAC;GAExD,KAAK,MAAM,OAAO,cAAc,MAAM;IACpC,QAAQ,IAAI,QAAQ;KAClB,MAAM,IAAI;KACV,YAAY,IAAI,KAAK,YAAY;KACjC,UAAU,IAAI,YAAY,KAAK,IAAI,OAAO;KAC1C,GAAG,UAAU,WAAW,IAAI,cAAc,KAAA,CAAS;IACrD;IACA,IAAI,IAAI,KAAK,GACX,UAAU,KAAK;KAAE,MAAM,IAAI;KAAM,IAAI,IAAI;IAAG,CAAC;GAEjD;GAEA,UAAU,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;GACpC,MAAM,aACJ,UAAU,SAAS,IAAI,EAAE,SAAS,UAAU,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,KAAA;GAErE,MAAM,wBAAQ,IAAI,IAA2B;GAC7C,KAAK,MAAM,MAAM,SAAS,MAAM;IAC9B,MAAM,WAAW,MAAM,IAAI,GAAG,EAAE;IAChC,IAAI,UAAU;KACZ,SAAS,QAAQ,KAAK,GAAG,IAAI;KAC7B,SAAS,kBAAkB,KAAK,GAAG,EAAE;IACvC,OACE,MAAM,IAAI,GAAG,IAAI;KACf,SAAS,CAAC,GAAG,IAAI;KACjB,iBAAiB,GAAG;KACpB,mBAAmB,CAAC,GAAG,EAAE;KACzB,UAAU,GAAG;KACb,UAAU,GAAG;IACf,CAAC;GAEL;GACA,MAAM,cAA0C,MAAM,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ;IACtF,SAAS,OAAO,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC;IACtC,iBAAiB,GAAG;IACpB,mBAAmB,OAAO,OAAO,CAAC,GAAG,GAAG,iBAAiB,CAAC;IAC1D,GAAG,UAAU,YAAY,2BAA2B,GAAG,QAAQ,CAAC;IAChE,GAAG,UAAU,YAAY,2BAA2B,GAAG,QAAQ,CAAC;GAClE,EAAE;GAEF,MAAM,UAAyB,CAAC;GAChC,MAAM,UAAwB,CAAC;GAE/B,KAAK,MAAM,OAAO,gBAAgB,MAAM;IAMtC,MAAM,cAAa,MAJS,OAAO,MACjC,sBAAsB,gBAAgB,IAAI,IAAI,EAAE,GAClD,EAAA,CAEiC,KAAK,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;IAEzF,IAAI,IAAI,WAAW,KACjB,QAAQ,KAAK;KACX,SAAS,OAAO,OAAO,CAAC,GAAG,UAAU,CAAC;KACtC,MAAM,IAAI;IACZ,CAAC;SACI,IAAI,IAAI,WAAW,KACxB,QAAQ,KAAK;KACX,SAAS,OAAO,OAAO,CAAC,GAAG,UAAU,CAAC;KACtC,MAAM,IAAI;KACV,QAAQ,IAAI,WAAW;IACzB,CAAC;GAGL;GAEA,OAAO,aAAa;IAClB,MAAM;IACN;IACA,GAAG,UAAU,cAAc,UAAU;IACrC;IACA;IACA;GACF;EACF;EAEA,OAAO,EACL,OACF;CACF;AACF;AAKA,SAAS,gBAAgB,MAAsB;CAC7C,OAAO,KAAK,QAAQ,MAAM,MAAI;AAChC;AAEA,MAAM,gCAAsE;CAC1E,aAAa;CACb,UAAU;CACV,SAAS;CACT,YAAY;CACZ,eAAe;AACjB;AAEA,SAAS,2BAA2B,MAAgD;CAElF,MAAM,SAAS,8BADI,KAAK,YAC8B;CACtD,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,MACR,4CAA4C,KAAK,yEAEnD;CAEF,IAAI,WAAW,YAAY,OAAO,KAAA;CAClC,OAAO;AACT;AAMA,SAAS,oBAAoB,MAAuB;CAClD,IAAI,SAAS,MAAM,OAAO;CAC1B,IAAI,OAAO,SAAS,WAAW,OAAO,OAAO,MAAM;CACnD,IAAI,OAAO,SAAS,UAAU;EAC5B,IAAI,CAAC,OAAO,SAAS,IAAI,GACvB,MAAM,IAAI,MACR,+DAA+D,OAAO,IAAI,EAAE,wCAC9E;EAEF,OAAO,OAAO,IAAI;CACpB;CACA,IAAI,OAAO,SAAS,UAAU,OAAO,OAAO,IAAI;CAChD,IAAI,gBAAgB,MAAM;EACxB,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAC7B,MAAM,IAAI,MACR,0FACF;EAEF,OAAO,IAAI,cAAc,KAAK,YAAY,CAAC,EAAE;CAC/C;CACA,IAAI,OAAO,SAAS,UAAU,OAAO,IAAI,cAAc,IAAI,EAAE;CAC7D,IAAI,gBAAgB,YAIlB,OAAO,KAHK,MAAM,KAAK,IAAI,CAAC,CACzB,KAAK,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAC3C,KAAK,EACM,EAAE;CAElB,IAAI,OAAO,SAAS,UAAU,OAAO,IAAI,cAAc,KAAK,UAAU,IAAI,CAAC,EAAE;CAC7E,MAAM,IAAI,MAAM,wDAAwD,OAAO,KAAK,EAAE;AACxF;AAEA,eAAe,6BACb,KACA,aACA,UACiB;CACjB,IAAI,IAAI,SAAS,YAAY;EAC3B,IAAI,IAAI,eAAe,mBAAmB,OAAO;EAIjD,IAAI,IAAI,eAAe,SAAS,OAAO;EACvC,OAAO,YAAY,IAAI,WAAW;CACpC;CACA,IAAI,aAAa,KAAA,GAAW;EAC1B,MAAM,QAAQ,YAAY,IAAI,SAAS,OAAO;EAC9C,IAAI,UAAU,KAAA,GAEZ,OAAO,WAAW,oBAAoB,MADnB,MAAM,OAAO,IAAI,OAAO,CAAC,CAAC,CACH;CAE9C;CAEA,OAAO,WAAW,oBAAoB,IAAI,KAAK;AACjD;AAEA,eAAe,sBAAsB,QAAmB,aAA2C;CACjG,IAAI,OAAO,KAAK,SAAS,eAAe,GACtC,OAAO,GAAG,gBAAgB,OAAO,IAAI,EAAE,GAAG,OAAO;CAEnD,MAAM,QAAQ,CAAC,gBAAgB,OAAO,IAAI,GAAG,OAAO,IAAI;CACxD,IAAI,OAAO,SAAS,MAAM,KAAK,UAAU;CACzC,IAAI,OAAO,YAAY,MAAM,KAAK,aAAa;CAC/C,IAAI,OAAO,SAAS;EAClB,MAAM,SAAS,MAAM,6BAA6B,OAAO,SAAS,aAAa,OAAO,QAAQ;EAC9F,IAAI,OAAO,SAAS,GAAG,MAAM,KAAK,MAAM;CAC1C;CACA,OAAO,MAAM,KAAK,GAAG;AACvB;AAEA,SAAS,0BAA0B,YAAwC;CACzE,IAAI,WAAW,SAAS,eAAe;EACrC,MAAM,OAAO,WAAW,QAAQ,IAAI,eAAe,CAAC,CAAC,KAAK,IAAI;EAC9D,IAAI,WAAW,SAAS,KAAA,GACtB,OAAO,cAAc,gBAAgB,WAAW,IAAI,EAAE,gBAAgB,KAAK;EAE7E,OAAO,gBAAgB,KAAK;CAC9B;CACA,IAAI,WAAW,SAAS,eAAe;EAIrC,IAAI,MAAM,gBAHG,WAAW,QAAQ,IAAI,eAAe,CAAC,CAAC,KAAK,IAG7B,EAAE,eAFd,WAAW,SAAS,MAAM,GAAG,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,KAAK,GAErB,EAAE,IADvC,WAAW,WAAW,IAAI,eAAe,CAAC,CAAC,KAAK,IACC,EAAE;EACnE,IAAI,WAAW,aAAa,KAAA,GAC1B,OAAO,cAAc,uBAAuB,WAAW;EAEzD,IAAI,WAAW,aAAa,KAAA,GAC1B,OAAO,cAAc,uBAAuB,WAAW;EAEzD,IAAI,WAAW,SAAS,KAAA,GACtB,MAAM,cAAc,gBAAgB,WAAW,IAAI,EAAE,GAAG;EAE1D,OAAO;CACT;CACA,MAAM,OAAO,WAAW,QAAQ,IAAI,eAAe,CAAC,CAAC,KAAK,IAAI;CAC9D,IAAI,WAAW,SAAS,KAAA,GACtB,OAAO,cAAc,gBAAgB,WAAW,IAAI,EAAE,WAAW,KAAK;CAExE,OAAO,WAAW,KAAK;AACzB;AAEA,eAAe,8BACb,KACA,aAC4B;CAC5B,MAAM,OAAO,UAAiE,GAAG;CACjF,MAAM,cAAc,KAAK,cAAc,mBAAmB;CAC1D,MAAM,WAAW,gBAAgB,KAAK,KAAK;CAC3C,MAAM,aAAa,MAAM,QAAQ,IAC/B,KAAK,QAAQ,KAAK,QAAQ,sBAAsB,KAAK,WAAW,CAAC,CACnE;CACA,MAAM,iBACJ,KAAK,gBAAgB,KAAA,IAAY,KAAK,YAAY,IAAI,yBAAyB,IAAI,CAAC;CAEtF,OAAO;EACL,KAAK,gBAAgB,cAAc,SAAS,QAF9B,CAAC,GAAG,YAAY,GAAG,cAAc,CAAC,CAAC,KAAK,OAEI,EAAE;EAC5D,QAAQ,CAAC;CACX;AACF;;;ACltBA,MAAM,sBAAsB,OAAO,OAAO,EACxC,KAAK;CACH,SAAS;CACT,OAAO;CACP,SAAS;CACT,SAAS;CACT,WAAW;CACX,OAAO;AACT,EACF,CAAC;AAED,IAAM,oBAAN,MAAgG;CAC9F,WAAoB;CACpB,WAAoB;CAEpB;CAEA,YAAY,SAAgC;EAC1C,MAAM,iBAAiB,IAAI,qBAAqB;EAChD,KAAK,UAAU,OAAO,OAAO;GAC3B,IAAI,SAAS,aAAa;GAC1B,QAAQ;GACR,cAAc;GACd,aAAa,cACX,eAAe,wBACb;IACE,UAAU;IACV,UAAU;IACV,OAAO,OACL,KACA,WACG;KAEH,OAAO,EAAE,MAAM,CAAC,IAAG,MADE,UAAU,MAAW,KAAK,MAAM,EAAA,CAC3B,IAAI,EAAE;IAClC;IACA,OAAO,YAAY,CAAC;GACtB,GACA,YACF;EACJ,CAAC;CACH;CAEA,MACE,KACA,SACwB;EACxB,IAAI,UAAU,GAAG,GACf,MAAM,IAAI,MACR,6HACF;EAEF,OAAO,iBAAiB,KAAK,QAAQ,QAAQ;CAC/C;AACF;;AAGA,MAAa,wBAAyC,EACpD,WAAW,OAA8B;CACvC,QAAQ,OAAO,OAAf;EACE,KAAK,UACH,OAAO,OAAO,cAAc,KAAK,KAAK,QAAQ,MAAM,IAChD,qBACA;EACN,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK,UACH,IAAI,iBAAiB,YAAY,OAAO;CAC5C;CACA,MAAM,IAAI,MACR,6GACF;AACF,EACF;;;;;;AAOA,SAAgB,iBACd,KACA,UACwB;CACxB,MAAM,qBAAqB,IAAI,iBAAiB;CAChD,MAAM,SAAyB,CAAC;CAChC,KAAK,MAAM,OAAO,oBAChB,OAAO,KACL,IAAI,SAAS,uBACT;EAAE,MAAM;EAAQ,MAAM,IAAI;CAAK,IAC/B;EAAE,MAAM;EAAW,OAAO,IAAI;CAAM,CAC1C;CAGF,IAAI;CAEJ,MAAM,OAAO;CACb,QAAQ,KAAK,MAAb;EACE,KAAK;GACH,MAAM,aAAa,MAAM,QAAQ;GACjC;EACF,KAAK;GACH,MAAM,aAAa,MAAM,QAAQ;GACjC;EACF,KAAK;GACH,MAAM,aAAa,MAAM,QAAQ;GACjC;EACF,KAAK;GACH,MAAM,aAAa,MAAM,QAAQ;GACjC;EACF,SACE,MAAM,IAAI,MAAM,8BAA+B,KAA0B,MAAM;CACnF;CAEA,OAAO,OAAO,OAAO;EAAE;EAAK;CAAO,CAAC;AACtC;AAEA,SAAS,kBACP,SACA,OACA,UACQ;CACR,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,OAAO,UAAU,UAAU,OAAO,GAAG,QAAQ,GAAG;CACpD,OAAO,GAAG,QAAQ,GAAG,WAAW,OAAO,QAAQ;AACjD;AAEA,SAAS,aAAa,KAAgB,UAAkC;CAsBtE,OAAO;EACL,UAtBqB,IAAI,WAAW,cAAc,KACJ,iBAAiB,IAAI,YAAY,QAAQ;EAsBvF,QArByB,aAAa,IAAI,MAAM,QAAQ;EAEtC,IAAI,OAAO,SAC3B,IAAI,MAAM,KAAK,SAAS,WAAW,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,IAC5D;EAEgB,IAAI,QAAQ,SAAS,WAAW,IAAI,OAAO,QAAQ,MAAM;EACvD,IAAI,SAAS,SAC/B,YAAY,IAAI,QAAQ,KAAK,SAAS,WAAW,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,MAC3E;EACiB,IAAI,SAAS,UAAU,WAAW,IAAI,QAAQ,QAAQ,MAAM;EAC7D,IAAI,SAAS,SAC7B,YAAY,IAAI,QACb,KAAK,UAAU,GAAG,WAAW,MAAM,MAAM,QAAQ,EAAE,GAAG,MAAM,IAAI,YAAY,GAAG,CAAC,CAChF,KAAK,IAAI,MACZ;EACgB,kBAAkB,SAAS,IAAI,OAAO,QAW9C;EAVS,kBAAkB,UAAU,IAAI,QAAQ,QAWhD;CACb,CAAC,CACE,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CACjC,KAAK,GAAG,CAAC,CACT,KAAK;AACV;AAEA,SAAS,iBACP,YACA,UACQ;CACR,OAAO,WACJ,KAAK,SAAS;EACb,MAAM,QAAQ,gBAAgB,KAAK,KAAK;EACxC,IAAI,KAAK,KAAK,SAAS,WACrB,OAAO,GAAG,cAAc,KAAK,IAAI,EAAE,MAAM;EAE3C,OAAO,GAAG,WAAW,KAAK,MAAM,QAAQ,EAAE,MAAM;CAClD,CAAC,CAAC,CACD,KAAK,IAAI;AACd;AAEA,SAAS,oCACP,OACA,UACQ;CACR,IAAI,MAAM,gBAAgB,KAAA,GACxB,OAAO,gBAAgB,MAAM,IAAI;CAEnC,MAAM,YAAY,SAAS,QAAQ,WAAW,MAAM;CACpD,IAAI,cAAc,KAAA,GAChB,MAAM,IAAI,MACR,UAAU,MAAM,KAAK,0BAA0B,MAAM,YAAY,uCACnE;CAEF,MAAM,eAAe,UAAU;CAC/B,IAAI,iBAAiB,KAAA,GACnB,MAAM,IAAI,MACR,UAAU,MAAM,KAAK,0BAA0B,MAAM,YAAY,8DACnE;CAEF,OAAO,aAAa,KAAK,WAAW,MAAM,IAAI;AAChD;AAEA,SAAS,kBAAkB,QAAqB,UAAkC;CAChF,MAAM,YAAY,oCAAoC,QAAQ,QAAQ;CACtE,IAAI,CAAC,OAAO,OACV,OAAO;CAET,OAAO,GAAG,UAAU,MAAM,gBAAgB,OAAO,KAAK;AACxD;AAEA,SAAS,aAAa,QAAuB,UAAkC;CAC7E,MAAM,OAAO;CACb,QAAQ,KAAK,MAAb;EACE,KAAK,gBACH,OAAO,kBAAkB,MAAM,QAAQ;EACzC,KAAK,wBACH,OAAO,IAAI,aAAa,KAAK,OAAO,QAAQ,EAAE,OAAO,gBAAgB,KAAK,KAAK;EACjF,SACE,MAAM,IAAI,MAAM,iCAAkC,KAA0B,MAAM;CACtF;AACF;AAEA,SAAS,WAAW,MAAqB,UAAmC;CAC1E,MAAM,OAAO;CACb,QAAQ,KAAK,MAAb;EACE,KAAK,cACH,OAAO,aAAa,IAAI;EAC1B,KAAK,kBACH,OAAO,gBAAgB,KAAK,IAAI;EAClC,KAAK,aACH,OAAO,gBAAgB,MAAM,QAAQ;EACvC,KAAK,YACH,OAAO,mBAAmB,MAAM,QAAQ;EAC1C,KAAK,aACH,OAAO,oBAAoB,MAAM,QAAQ;EAC3C,KAAK,eACH,OAAO,qBAAqB,MAAM,QAAQ;EAC5C,KAAK,eACH,OAAO,qBAAqB,MAAM,QAAQ;EAC5C,KAAK,kBACH,OAAO,uBAAuB,MAAM,QAAQ;EAC9C,KAAK,UACH,OAAO,aAAa,MAAM,QAAQ;EACpC,KAAK;GACH,IAAI,KAAK,MAAM,WAAW,GACxB,OAAO;GAET,OAAO,IAAI,KAAK,MAAM,KAAK,SAAS,WAAW,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE;EAChF,KAAK;GACH,IAAI,KAAK,MAAM,WAAW,GACxB,OAAO;GAET,OAAO,IAAI,KAAK,MAAM,KAAK,SAAS,WAAW,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE;EAC/E,KAAK;GACH,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,MAAM,sDAAsD;GAIxE,OAAO,GAFY,KAAK,YAAY,SAAS,GAExB,UADJ,aAAa,KAAK,UAAU,QACP,EAAE;EAE1C,KAAK,cACH,OAAO,gBAAgB,MAAM,QAAQ;EACvC,KAAK,OACH,OAAO,QAAQ,WAAW,KAAK,MAAM,QAAQ,EAAE;EACjD,KAAK;EACL,KAAK,sBACH,OAAO;EACT,KAAK,WACH,OAAO,cAAc,IAAI;EAC3B,KAAK,QACH,OAAO,kBAAkB,IAAI;EAC/B,KAAK,YACH,OAAO,cAAc,MAAM,QAAQ;EACrC,SACE,MAAM,IAAI,MAAM,qCAAsC,KAA0B,MAAM;CAC1F;AACF;AAEA,SAAS,cAAc,MAAe,UAAmC;CACvE,OAAO,KAAK,MACT,KAAK,SAAU,OAAO,SAAS,WAAW,OAAO,WAAW,MAAM,QAAQ,CAAE,CAAC,CAC7E,KAAK,EAAE;AACZ;AAGA,SAAS,aAAa,KAAwB;CAC5C,IAAI,IAAI,UAAU,YAChB,OAAO,YAAY,gBAAgB,IAAI,MAAM;CAE/C,OAAO,GAAG,gBAAgB,IAAI,KAAK,EAAE,GAAG,gBAAgB,IAAI,MAAM;AACpE;AAEA,SAAS,cAAc,MAA2B;CAChD,IAAI,OAAO,KAAK,UAAU,UACxB,OAAO,IAAI,cAAc,KAAK,KAAK,EAAE;CAEvC,IAAI,OAAO,KAAK,UAAU,YAAY,OAAO,KAAK,UAAU,WAC1D,OAAO,OAAO,KAAK,KAAK;CAE1B,IAAI,OAAO,KAAK,UAAU,UACxB,OAAO,OAAO,KAAK,KAAK;CAE1B,IAAI,KAAK,UAAU,QAAQ,KAAK,UAAU,KAAA,GACxC,OAAO;CAET,IAAI,KAAK,iBAAiB,MACxB,OAAO,IAAI,cAAc,KAAK,MAAM,YAAY,CAAC,EAAE;CAErD,MAAM,OAAO,KAAK,UAAU,KAAK,KAAK;CACtC,IAAI,SAAS,KAAA,GACX,OAAO;CAET,OAAO,IAAI,cAAc,IAAI,EAAE;AACjC;AAEA,SAAS,gBAAgB,MAAqB,UAAmC;CAC/E,MAAM,OAAO,WAAW,KAAK,MAAM,QAAQ;CAC3C,MAAM,OAAO,KAAK,KAAK,KAAK,QAAQ,WAAW,KAAK,QAAQ,CAAC;CAE7D,IAAI,SAAS,KAAK,SAAS;CAC3B,SAAS,OAAO,QAAQ,iBAAiB,IAAI;CAC7C,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAC/B,SAAS,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,SAAS,GAAG,GAAG,KAAK,MAAM,EAAE;CAG/E,OAAO;AACT;AAEA,SAAS,mBAAmB,MAAoB,UAAmC;CACjF,IAAI,KAAK,MAAM,WAAW,WAAW,GACnC,MAAM,IAAI,MAAM,sDAAsD;CAExE,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,MAAM,0DAA0D;CAE5E,OAAO,IAAI,aAAa,KAAK,OAAO,QAAQ,EAAE;AAChD;AAEA,SAAS,gBAAgB,MAAqB,UAAmC;CAC/E,MAAM,WAAW,WAAW,KAAK,MAAM,QAAQ;CAC/C,MAAM,eACJ,KAAK,KAAK,SAAS,eAAe,KAAK,KAAK,SAAS,aAAa,IAAI,SAAS,KAAK;CACtF,OAAO,KAAK,SAAS,GAAG,aAAa,YAAY,GAAG,aAAa;AACnE;AAEA,SAAS,aAAa,MAAkB,UAAmC;CACzE,IAAI,KAAK,MAAM,SAAS,UAAU,KAAK,MAAM,OAAO,WAAW,GAAG;EAChE,IAAI,KAAK,OAAO,MACd,OAAO;EAET,IAAI,KAAK,OAAO,SACd,OAAO;CAEX;CAEA,MAAM,WAAW,KAAK;CACtB,MAAM,OAAO,WAAW,UAAU,QAAQ;CAC1C,MAAM,eACJ,SAAS,SAAS,eAAe,SAAS,SAAS,aAAa,IAAI,KAAK,KAAK;CAEhF,MAAM,YAAY,KAAK;CACvB,IAAI;CACJ,QAAQ,UAAU,MAAlB;EACE,KAAK;GACH,QAAQ,kBAAkB,SAAS;GACnC;EACF,KAAK;GACH,QAAQ,cAAc,SAAS;GAC/B;EACF,KAAK;GACH,QAAQ,aAAa,SAAS;GAC9B;EACF,KAAK;EACL,KAAK;GACH,QAAQ;GACR;EACF;GACE,QAAQ,WAAW,WAAW,QAAQ;GACtC;CACJ;CAcA,OAAO,GAAG,aAAa,GAAG;EAXxB,IAAI;EACJ,KAAK;EACL,IAAI;EACJ,IAAI;EACJ,KAAK;EACL,KAAK;EACL,MAAM;EACN,IAAI;EACJ,OAAO;CAG2B,EAAE,KAAK,IAAI,GAAG;AACpD;AAEA,SAAS,kBAAkB,MAA8B;CACvD,IAAI,KAAK,OAAO,WAAW,GACzB,OAAO;CAST,OAAO,IAPQ,KAAK,OACjB,KAAK,MAAM;EACV,IAAI,EAAE,SAAS,eAAe,EAAE,SAAS,sBAAsB,OAAO;EACtE,IAAI,EAAE,SAAS,WAAW,OAAO,cAAc,CAAC;EAChD,OAAO,WAAW,CAAC;CACrB,CAAC,CAAC,CACD,KAAK,IACQ,EAAE;AACpB;AAEA,SAAS,oBAAoB,MAAqB,UAAmC;CACnF,MAAM,KAAK,KAAK,GAAG,YAAY;CAC/B,IAAI,CAAC,KAAK,MACR,OAAO,GAAG,GAAG;CAEf,OAAO,GAAG,GAAG,GAAG,WAAW,KAAK,MAAM,QAAQ,EAAE;AAClD;AAEA,SAAS,qBAAqB,MAAsB,UAAmC;CAYrF,OAAO,GAXI,KAAK,GAAG,YAWR,EAAE,GAVA,KAAK,KAAK,KAAK,QAAQ,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,IAUjD,EAAE,UADR,CAPX,KAAK,eAAe,KAAK,YAAY,SAAS,IAC1C,gBAAgB,KAAK,YAAY,KAAK,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,MAC9E,IAEJ,KAAK,WAAW,KAAK,QAAQ,SAAS,IAClC,YAAY,mBAAmB,KAAK,SAAS,QAAQ,MACrD,EACoC,CAAC,CAAC,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,GACjD,EAAE;AACtC;AAEA,SAAS,qBAAqB,MAAsB,UAAmC;CAUrF,OAAO,eATM,KAAK,QACf,SAAS,UAA4B;EACpC,MAAM,MAAM,IAAI,cAAc,MAAM,GAAG,EAAE;EACzC,IAAI,MAAM,MAAM,SAAS,WACvB,OAAO,CAAC,KAAK,cAAc,MAAM,KAAK,CAAC;EAEzC,OAAO,CAAC,KAAK,WAAW,MAAM,OAAO,QAAQ,CAAC;CAChD,CAAC,CAAC,CACD,KAAK,IACiB,EAAE;AAC7B;AAEA,SAAS,mBAAmB,OAAmC,UAAmC;CAChG,OAAO,MACJ,KAAK,SAAS,GAAG,WAAW,KAAK,MAAM,QAAQ,EAAE,GAAG,KAAK,IAAI,YAAY,GAAG,CAAC,CAC7E,KAAK,IAAI;AACd;AAEA,SAAS,uBAAuB,MAAwB,UAAmC;CACzF,MAAM,mBACJ,KAAK,WAAW,KAAK,QAAQ,SAAS,IAClC,aAAa,mBAAmB,KAAK,SAAS,QAAQ,MACtD;CACN,MAAM,aAAa,oBAAoB,WAAW,KAAK,MAAM,QAAQ,IAAI,iBAAiB;CAC1F,IAAI,KAAK,YAAY,cACnB,OAAO,YAAY,WAAW;CAEhC,OAAO;AACT;AAEA,SAAS,WAAW,MAAe,UAAmC;CACpE,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,MAAM,2CAA2C;CAK7D,OAAO,GAHU,KAAK,SAAS,YAGd,EAAE,QAFJ,aAAa,KAAK,QAAQ,QAET,EAAE,MADjB,aAAa,KAAK,IAAI,QACQ;AACjD;AAEA,SAAS,aAAa,IAAgB,UAAmC;CACvE,IAAI,GAAG,SAAS,kBACd,OAAO,GAAG,aAAa,GAAG,IAAI,EAAE,KAAK,aAAa,GAAG,KAAK;CAE5D,OAAO,WAAW,IAAI,QAAQ;AAChC;AAEA,SAAS,kBAAkB,OAA4B;CACrD,QAAQ,MAAM,MAAd;EACE,KAAK;EACL,KAAK,sBACH,OAAO;EACT,KAAK,cACH,OAAO,aAAa,KAAK;EAC3B,KAAK,YACH,OAAO,WAAW,KAAK;EACzB,KAAK,iBACH,MAAM,IAAI,MAAM,iEAAiE;EACnF,SACE,MAAM,IAAI,MAAM,qCAAsC,MAA2B,MAAM;CAC3F;AACF;AAEA,SAAS,aAAa,KAAgB,UAAkC;CACtE,MAAM,QAAQ,oCAAoC,IAAI,OAAO,QAAQ;CACrE,MAAM,OAAO,IAAI;CACjB,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,MAAM,kCAAkC;CAGpD,MAAM,WAAW,KAAK;CACtB,MAAM,cAAc,OAAO,KAAK,QAAQ;CAExC,IAAI;CACJ,IAAI,YAAY,WAAW,GACzB,eAAe,eAAe,MAAM;MAC/B;EACL,MAAM,UAAU,YAAY,KAAK,WAAW,gBAAgB,MAAM,CAAC;EACnE,MAAM,SAAS,KACZ,KAAK,QAAQ;GAQZ,OAAO,IAPa,YAAY,KAAK,WAAW;IAC9C,MAAM,QAAQ,IAAI;IAClB,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,6BAA6B,OAAO,gBAAgB;IAEtE,OAAO,kBAAkB,KAAK;GAChC,CACqB,CAAC,CAAC,KAAK,IAAI,EAAE;EACpC,CAAC,CAAC,CACD,KAAK,IAAI;EACZ,eAAe,eAAe,MAAM,IAAI,QAAQ,KAAK,IAAI,EAAE,WAAW;CACxE;CAEA,IAAI,mBAAmB;CACvB,IAAI,IAAI,YAAY;EAClB,MAAM,kBAAkB,IAAI,WAAW,QAAQ,KAAK,QAAQ,gBAAgB,IAAI,MAAM,CAAC;EACvF,IAAI,gBAAgB,WAAW,GAC7B,MAAM,IAAI,MAAM,yDAAyD;EAG3E,MAAM,SAAS,IAAI,WAAW;EAC9B,QAAQ,OAAO,MAAf;GACE,KAAK;IACH,mBAAmB,iBAAiB,gBAAgB,KAAK,IAAI,EAAE;IAC/D;GACF,KAAK,iBAAiB;IACpB,MAAM,UAAU,OAAO,QAAQ,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,WAAW;KACnE,OAAO,GAAG,gBAAgB,OAAO,EAAE,KAAK,WAAW,OAAO,QAAQ;IACpE,CAAC;IACD,mBAAmB,iBAAiB,gBAAgB,KAAK,IAAI,EAAE,kBAAkB,QAAQ,KAAK,IAAI;IAClG;GACF;GACA,SACE,MAAM,IAAI,MAAM,kCAAmC,OAA4B,MAAM;EACzF;CACF;CAEA,MAAM,kBAAkB,gBAAgB,IAAI,SAAS;CAErD,OAAO,GAAG,eAAe,mBAAmB;AAC9C;AAEA,SAAS,aAAa,KAAgB,UAAkC;CACtE,MAAM,QAAQ,oCAAoC,IAAI,OAAO,QAAQ;CACrE,MAAM,aAAa,OAAO,QAAQ,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,SAAS;EAC7D,OAAO,GAAG,gBAAgB,GAAG,EAAE,KAAK,WAAW,KAAK,QAAQ;CAC9D,CAAC;CAED,MAAM,cAAc,IAAI,QAAQ,UAAU,WAAW,IAAI,OAAO,QAAQ,MAAM;CAC9E,MAAM,kBAAkB,gBAAgB,IAAI,SAAS;CAErD,OAAO,UAAU,MAAM,OAAO,WAAW,KAAK,IAAI,IAAI,cAAc;AACtE;AAEA,SAAS,aAAa,KAAgB,UAAkC;CAKtE,OAAO,eAJO,oCAAoC,IAAI,OAAO,QAInC,IAHN,IAAI,QAAQ,UAAU,WAAW,IAAI,KAAK,MAAM,KAC5C,gBAAgB,IAAI,SAEc;AAC5D;AAEA,SAAS,gBAAgB,WAA8D;CACrF,IAAI,CAAC,WAAW,QACd,OAAO;CAET,OAAO,cAAc,UAClB,KAAK,SAAS;EACb,IAAI,KAAK,KAAK,SAAS,cAAc;GACnC,MAAM,WAAW,GAAG,gBAAgB,KAAK,KAAK,KAAK,EAAE,GAAG,gBAAgB,KAAK,KAAK,MAAM;GACxF,OAAO,KAAK,KAAK,WAAW,KAAK,QAC7B,WACA,GAAG,SAAS,MAAM,gBAAgB,KAAK,KAAK;EAClD;EACA,OAAO,GAAG,WAAW,KAAK,IAAI,EAAE,MAAM,gBAAgB,KAAK,KAAK;CAClE,CAAC,CAAC,CACD,KAAK,IAAI;AACd;AAEA,SAAgB,oBAAoB,SAAgC;CAClE,OAAO,OAAO,OAAO,IAAI,kBAAkB,OAAO,CAAC;AACrD"}
|
package/dist/adapter.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as sqliteRawCodecInferer, t as createSqliteAdapter } from "./adapter-
|
|
1
|
+
import { n as sqliteRawCodecInferer, t as createSqliteAdapter } from "./adapter-fApyx9L1.mjs";
|
|
2
2
|
export { createSqliteAdapter, sqliteRawCodecInferer };
|
package/dist/control.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyQueryAst, DdlNode, LoweredStatement, LowererContext, MarkerReadResult } from "@prisma-next/sql-relational-core/ast";
|
|
1
|
+
import { AnyQueryAst, DdlNode, LoweredStatement, LowererContext, MarkerReadResult, SqlExecuteRequest } from "@prisma-next/sql-relational-core/ast";
|
|
2
2
|
import { SqlEscapeError, escapeLiteral, quoteIdentifier } from "@prisma-next/target-sqlite/sql-utils";
|
|
3
3
|
import { parseSqliteDefault, parseSqliteDefault as parseSqliteDefault$1 } from "@prisma-next/target-sqlite/default-normalizer";
|
|
4
4
|
import { normalizeSqliteNativeType, normalizeSqliteNativeType as normalizeSqliteNativeType$1 } from "@prisma-next/target-sqlite/native-type-normalizer";
|
|
@@ -7,12 +7,20 @@ import { SqliteDdlNode } from "@prisma-next/target-sqlite/ddl";
|
|
|
7
7
|
import { ContractMarkerRecord, LedgerEntryRecord } from "@prisma-next/contract/types";
|
|
8
8
|
import { SqlControlDriverInstance } from "@prisma-next/sql-contract/types";
|
|
9
9
|
import { SqlControlAdapter } from "@prisma-next/family-sql/control-adapter";
|
|
10
|
+
import { CodecLookup } from "@prisma-next/framework-components/codec";
|
|
10
11
|
import { SqlSchemaIR } from "@prisma-next/sql-schema-ir/types";
|
|
11
12
|
|
|
12
13
|
//#region src/core/control-adapter.d.ts
|
|
13
14
|
declare class SqliteControlAdapter implements SqlControlAdapter<'sqlite'> {
|
|
14
15
|
readonly familyId: "sql";
|
|
15
16
|
readonly targetId: "sqlite";
|
|
17
|
+
private readonly codecLookup;
|
|
18
|
+
/**
|
|
19
|
+
* @param codecLookup - Codec lookup used to resolve codecs for DDL literal-default encoding.
|
|
20
|
+
* Defaults to a SQLite-builtins-only lookup when omitted. Stack-aware callers supply
|
|
21
|
+
* `stack.codecLookup` so extension codecs are visible to the DDL walker.
|
|
22
|
+
*/
|
|
23
|
+
constructor(codecLookup?: CodecLookup);
|
|
16
24
|
readonly normalizeDefault: typeof parseSqliteDefault$1;
|
|
17
25
|
readonly normalizeNativeType: typeof normalizeSqliteNativeType$1;
|
|
18
26
|
bootstrapControlTableQueries(): readonly DdlNode[];
|
|
@@ -26,6 +34,14 @@ declare class SqliteControlAdapter implements SqlControlAdapter<'sqlite'> {
|
|
|
26
34
|
* without instantiating the runtime adapter.
|
|
27
35
|
*/
|
|
28
36
|
lower(ast: AnyQueryAst | SqliteDdlNode, context: LowererContext<unknown>): LoweredStatement;
|
|
37
|
+
/**
|
|
38
|
+
* Lower an AST all the way to a driver-ready statement. For DDL nodes,
|
|
39
|
+
* literal column defaults are formatted as inline SQL with SQLite-specific
|
|
40
|
+
* literal syntax (no cast suffix, boolean as 0/1, blob via X'hex'). For
|
|
41
|
+
* query ASTs, params are kept as `?` placeholders; wire values go in
|
|
42
|
+
* `params`. Does NOT call `this.lower()` — independent implementation.
|
|
43
|
+
*/
|
|
44
|
+
lowerToExecuteRequest(ast: AnyQueryAst | SqliteDdlNode, context?: LowererContext<unknown>): Promise<SqlExecuteRequest>;
|
|
29
45
|
/**
|
|
30
46
|
* Reads the contract marker from `_prisma_marker`. Probes `sqlite_master`
|
|
31
47
|
* first so a fresh database (no marker table) returns `null` instead of a
|
package/dist/control.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-adapter.ts","../src/exports/control.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-adapter.ts","../src/exports/control.ts"],"mappings":";;;;;;;;;;;;;cA2Ha,oBAAA,YAAgC,iBAAA;EAAA,SAClC,QAAA;EAAA,SACA,QAAA;EAAA,iBAEQ,WAAA;EAJN;;;;;cAWC,WAAA,GAAc,WAAA;EAAA,SAIjB,gBAAA,SAAgB,oBAAA;EAAA,SAChB,mBAAA,SAAmB,2BAAA;EAE5B,4BAAA,aAAyC,OAAA;EAIzC,0BAAA,aAAuC,OAAA;EAYU;;;;;;;;EAAjD,KAAA,CAAM,GAAA,EAAK,WAAA,GAAc,aAAA,EAAe,OAAA,EAAS,cAAA,YAA0B,gBAAA;EA0CxE;;;;;;;EA1BG,qBAAA,CACJ,GAAA,EAAK,WAAA,GAAc,aAAA,EACnB,OAAA,GAAU,cAAA,YACT,OAAA,CAAQ,iBAAA;EAmGD;;;;;EA/EJ,UAAA,CACJ,MAAA,EAAQ,wBAAA,YACR,KAAA,WACC,OAAA,CAAQ,oBAAA;EAKL,uBAAA,CACJ,MAAA,EAAQ,wBAAA,YACR,KAAA,WACC,OAAA,CAAQ,gBAAA;EAgMD;;;;;EAtLJ,cAAA,CACJ,MAAA,EAAQ,wBAAA,aACP,OAAA,CAAQ,WAAA,SAAoB,oBAAA;EAAA,QAKjB,oBAAA;EArG6B;;;;;EAuJrC,UAAA,CACJ,MAAA,EAAQ,wBAAA,YACR,KAAA,YACC,OAAA,UAAiB,iBAAA;EAAA,QAKN,gBAAA;;;;;;EA6CR,YAAA,CACJ,MAAA,EAAQ,wBAAA,YACR,KAAA,UACA,WAAA;IAAA,SACW,WAAA;IAAA,SACA,WAAA;IAAA,SACA,UAAA;EAAA,IAEV,OAAA;EAoBG,UAAA,CACJ,MAAA,EAAQ,wBAAA,YACR,KAAA,UACA,WAAA;IAAA,SACW,WAAA;IAAA,SACA,WAAA;IAAA,SACA,UAAA;EAAA,IAEV,OAAA;EA9M8C;;;;EAiP3C,YAAA,CACJ,MAAA,EAAQ,wBAAA,YACR,KAAA,UACA,YAAA,UACA,WAAA;IAAA,SACW,WAAA;IAAA,SACA,WAAA;IAAA,SACA,UAAA;EAAA,IAEV,OAAA;EAvOA;;;;EAqQG,gBAAA,CACJ,MAAA,EAAQ,wBAAA,YACR,KAAA,UACA,KAAA;IAAA,SACW,MAAA;IAAA,SACA,IAAA;IAAA,SACA,EAAA;IAAA,SACA,aAAA;IAAA,SACA,aAAA;IAAA,SACA,UAAA;EAAA,IAEV,OAAA;EAAA,QAiBW,gBAAA;EA+BR,UAAA,CACJ,MAAA,EAAQ,wBAAA,YACR,SAAA,aACC,OAAA,CAAQ,WAAA;AAAA;;;cCzeP,uBAAA,EAAyB,2BAA2B"}
|
package/dist/control.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as SqliteControlAdapter } from "./adapter-
|
|
1
|
+
import { r as SqliteControlAdapter } from "./adapter-fApyx9L1.mjs";
|
|
2
2
|
import { t as sqliteAdapterDescriptorMeta } from "./descriptor-meta-Du5OgSxS.mjs";
|
|
3
3
|
import { SqlEscapeError, escapeLiteral, quoteIdentifier } from "@prisma-next/target-sqlite/sql-utils";
|
|
4
4
|
import { parseSqliteDefault } from "@prisma-next/target-sqlite/default-normalizer";
|
package/dist/runtime.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as sqliteRawCodecInferer, t as createSqliteAdapter } from "./adapter-
|
|
1
|
+
import { n as sqliteRawCodecInferer, t as createSqliteAdapter } from "./adapter-fApyx9L1.mjs";
|
|
2
2
|
import { t as sqliteAdapterDescriptorMeta } from "./descriptor-meta-Du5OgSxS.mjs";
|
|
3
3
|
import { sqliteCodecRegistry } from "@prisma-next/target-sqlite/codecs";
|
|
4
4
|
import { builtinGeneratorIds } from "@prisma-next/ids";
|
package/package.json
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/adapter-sqlite",
|
|
3
|
-
"version": "0.13.0-dev.
|
|
3
|
+
"version": "0.13.0-dev.16",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@prisma-next/cli": "0.13.0-dev.
|
|
9
|
-
"@prisma-next/contract": "0.13.0-dev.
|
|
10
|
-
"@prisma-next/contract-authoring": "0.13.0-dev.
|
|
11
|
-
"@prisma-next/errors": "0.13.0-dev.
|
|
12
|
-
"@prisma-next/framework-components": "0.13.0-dev.
|
|
13
|
-
"@prisma-next/family-sql": "0.13.0-dev.
|
|
14
|
-
"@prisma-next/ids": "0.13.0-dev.
|
|
15
|
-
"@prisma-next/sql-contract": "0.13.0-dev.
|
|
16
|
-
"@prisma-next/sql-contract-psl": "0.13.0-dev.
|
|
17
|
-
"@prisma-next/sql-contract-ts": "0.13.0-dev.
|
|
18
|
-
"@prisma-next/sql-operations": "0.13.0-dev.
|
|
19
|
-
"@prisma-next/sql-relational-core": "0.13.0-dev.
|
|
20
|
-
"@prisma-next/sql-runtime": "0.13.0-dev.
|
|
21
|
-
"@prisma-next/sql-schema-ir": "0.13.0-dev.
|
|
22
|
-
"@prisma-next/target-sqlite": "0.13.0-dev.
|
|
23
|
-
"@prisma-next/utils": "0.13.0-dev.
|
|
8
|
+
"@prisma-next/cli": "0.13.0-dev.16",
|
|
9
|
+
"@prisma-next/contract": "0.13.0-dev.16",
|
|
10
|
+
"@prisma-next/contract-authoring": "0.13.0-dev.16",
|
|
11
|
+
"@prisma-next/errors": "0.13.0-dev.16",
|
|
12
|
+
"@prisma-next/framework-components": "0.13.0-dev.16",
|
|
13
|
+
"@prisma-next/family-sql": "0.13.0-dev.16",
|
|
14
|
+
"@prisma-next/ids": "0.13.0-dev.16",
|
|
15
|
+
"@prisma-next/sql-contract": "0.13.0-dev.16",
|
|
16
|
+
"@prisma-next/sql-contract-psl": "0.13.0-dev.16",
|
|
17
|
+
"@prisma-next/sql-contract-ts": "0.13.0-dev.16",
|
|
18
|
+
"@prisma-next/sql-operations": "0.13.0-dev.16",
|
|
19
|
+
"@prisma-next/sql-relational-core": "0.13.0-dev.16",
|
|
20
|
+
"@prisma-next/sql-runtime": "0.13.0-dev.16",
|
|
21
|
+
"@prisma-next/sql-schema-ir": "0.13.0-dev.16",
|
|
22
|
+
"@prisma-next/target-sqlite": "0.13.0-dev.16",
|
|
23
|
+
"@prisma-next/utils": "0.13.0-dev.16",
|
|
24
24
|
"arktype": "^2.2.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@prisma-next/driver-sqlite": "0.13.0-dev.
|
|
28
|
-
"@prisma-next/migration-tools": "0.13.0-dev.
|
|
29
|
-
"@prisma-next/test-utils": "0.13.0-dev.
|
|
30
|
-
"@prisma-next/tsconfig": "0.13.0-dev.
|
|
31
|
-
"@prisma-next/tsdown": "0.13.0-dev.
|
|
27
|
+
"@prisma-next/driver-sqlite": "0.13.0-dev.16",
|
|
28
|
+
"@prisma-next/migration-tools": "0.13.0-dev.16",
|
|
29
|
+
"@prisma-next/test-utils": "0.13.0-dev.16",
|
|
30
|
+
"@prisma-next/tsconfig": "0.13.0-dev.16",
|
|
31
|
+
"@prisma-next/tsdown": "0.13.0-dev.16",
|
|
32
32
|
"pathe": "^2.0.3",
|
|
33
33
|
"tsdown": "0.22.1",
|
|
34
34
|
"typescript": "5.9.3",
|
package/src/core/adapter.ts
CHANGED
|
@@ -37,7 +37,6 @@ import type { RawCodecInferer } from '@prisma-next/sql-relational-core/expressio
|
|
|
37
37
|
import type { SqliteDdlNode } from '@prisma-next/target-sqlite/ddl';
|
|
38
38
|
import { escapeLiteral, quoteIdentifier } from '@prisma-next/target-sqlite/sql-utils';
|
|
39
39
|
import { SqliteControlAdapter } from './control-adapter';
|
|
40
|
-
import { renderLoweredDdl } from './ddl-renderer';
|
|
41
40
|
import type { SqliteAdapterOptions, SqliteContract, SqliteLoweredStatement } from './types';
|
|
42
41
|
|
|
43
42
|
const defaultCapabilities = Object.freeze({
|
|
@@ -87,7 +86,9 @@ class SqliteAdapterImpl implements Adapter<AnyQueryAst, SqliteContract, SqliteLo
|
|
|
87
86
|
context: LowererContext<SqliteContract>,
|
|
88
87
|
): SqliteLoweredStatement {
|
|
89
88
|
if (isDdlNode(ast)) {
|
|
90
|
-
|
|
89
|
+
throw new Error(
|
|
90
|
+
'lower() does not lower DDL on the runtime adapter — DDL lowering is a control-plane concern handled by the control adapter.',
|
|
91
|
+
);
|
|
91
92
|
}
|
|
92
93
|
return renderLoweredSql(ast, context.contract);
|
|
93
94
|
}
|
|
@@ -2,15 +2,23 @@ import type { ContractMarkerRecord, LedgerEntryRecord } from '@prisma-next/contr
|
|
|
2
2
|
import { parseMarkerRowSafely, withMarkerReadErrorHandling } from '@prisma-next/errors/execution';
|
|
3
3
|
import type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';
|
|
4
4
|
import { parseContractMarkerRow } from '@prisma-next/family-sql/verify';
|
|
5
|
-
import {
|
|
5
|
+
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
6
|
+
import { APP_SPACE_ID, extractCodecLookup } from '@prisma-next/framework-components/control';
|
|
6
7
|
import { ledgerOriginFromStored } from '@prisma-next/migration-tools/ledger-origin';
|
|
8
|
+
import { REFERENTIAL_ACTION_SQL } from '@prisma-next/sql-contract/referential-action-sql';
|
|
7
9
|
import type { SqlControlDriverInstance } from '@prisma-next/sql-contract/types';
|
|
8
10
|
import type {
|
|
9
11
|
AnyQueryAst,
|
|
12
|
+
CodecRef,
|
|
13
|
+
DdlColumn,
|
|
10
14
|
DdlNode,
|
|
15
|
+
DdlTableConstraint,
|
|
16
|
+
FunctionColumnDefault,
|
|
17
|
+
LiteralColumnDefault,
|
|
11
18
|
LoweredStatement,
|
|
12
19
|
LowererContext,
|
|
13
20
|
MarkerReadResult,
|
|
21
|
+
SqlExecuteRequest,
|
|
14
22
|
} from '@prisma-next/sql-relational-core/ast';
|
|
15
23
|
import { isDdlNode } from '@prisma-next/sql-relational-core/ast';
|
|
16
24
|
import type {
|
|
@@ -23,17 +31,19 @@ import type {
|
|
|
23
31
|
SqlTableIR,
|
|
24
32
|
SqlUniqueIR,
|
|
25
33
|
} from '@prisma-next/sql-schema-ir/types';
|
|
34
|
+
import { sqliteCodecRegistry } from '@prisma-next/target-sqlite/codecs';
|
|
26
35
|
import {
|
|
27
36
|
buildControlTableBootstrapQueries,
|
|
28
37
|
buildSignMarkerBootstrapQueries,
|
|
29
38
|
} from '@prisma-next/target-sqlite/contract-free';
|
|
30
|
-
import type { SqliteDdlNode } from '@prisma-next/target-sqlite/ddl';
|
|
39
|
+
import type { SqliteCreateTable, SqliteDdlNode } from '@prisma-next/target-sqlite/ddl';
|
|
31
40
|
import { parseSqliteDefault } from '@prisma-next/target-sqlite/default-normalizer';
|
|
32
41
|
import { normalizeSqliteNativeType } from '@prisma-next/target-sqlite/native-type-normalizer';
|
|
42
|
+
import { escapeLiteral, quoteIdentifier } from '@prisma-next/target-sqlite/sql-utils';
|
|
33
43
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
34
44
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
35
45
|
import { renderLoweredSql } from './adapter';
|
|
36
|
-
import {
|
|
46
|
+
import { encodeControlQueryParams } from './control-codecs';
|
|
37
47
|
import { coerceLedgerAppliedAt, operationCountFromStored } from './ledger-decode';
|
|
38
48
|
import {
|
|
39
49
|
decodeSqliteMarkerRow,
|
|
@@ -102,10 +112,30 @@ type FkAccumulator = {
|
|
|
102
112
|
onUpdate: string;
|
|
103
113
|
};
|
|
104
114
|
|
|
115
|
+
function createSqliteBuiltinCodecLookup(): CodecLookup {
|
|
116
|
+
return extractCodecLookup([
|
|
117
|
+
{
|
|
118
|
+
id: 'sqlite-builtin-codecs',
|
|
119
|
+
types: { codecTypes: { codecDescriptors: Array.from(sqliteCodecRegistry.values()) } },
|
|
120
|
+
},
|
|
121
|
+
]);
|
|
122
|
+
}
|
|
123
|
+
|
|
105
124
|
export class SqliteControlAdapter implements SqlControlAdapter<'sqlite'> {
|
|
106
125
|
readonly familyId = 'sql' as const;
|
|
107
126
|
readonly targetId = 'sqlite' as const;
|
|
108
127
|
|
|
128
|
+
private readonly codecLookup: CodecLookup;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param codecLookup - Codec lookup used to resolve codecs for DDL literal-default encoding.
|
|
132
|
+
* Defaults to a SQLite-builtins-only lookup when omitted. Stack-aware callers supply
|
|
133
|
+
* `stack.codecLookup` so extension codecs are visible to the DDL walker.
|
|
134
|
+
*/
|
|
135
|
+
constructor(codecLookup?: CodecLookup) {
|
|
136
|
+
this.codecLookup = codecLookup ?? createSqliteBuiltinCodecLookup();
|
|
137
|
+
}
|
|
138
|
+
|
|
109
139
|
readonly normalizeDefault = parseSqliteDefault;
|
|
110
140
|
readonly normalizeNativeType = normalizeSqliteNativeType;
|
|
111
141
|
|
|
@@ -127,11 +157,38 @@ export class SqliteControlAdapter implements SqlControlAdapter<'sqlite'> {
|
|
|
127
157
|
*/
|
|
128
158
|
lower(ast: AnyQueryAst | SqliteDdlNode, context: LowererContext<unknown>): LoweredStatement {
|
|
129
159
|
if (isDdlNode(ast)) {
|
|
130
|
-
|
|
160
|
+
throw new Error(
|
|
161
|
+
'lower() cannot lower DDL: DDL default literals require inline codec encoding, which is async. Use lowerToExecuteRequest().',
|
|
162
|
+
);
|
|
131
163
|
}
|
|
132
164
|
return renderLoweredSql(ast, context.contract as SqliteContract);
|
|
133
165
|
}
|
|
134
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Lower an AST all the way to a driver-ready statement. For DDL nodes,
|
|
169
|
+
* literal column defaults are formatted as inline SQL with SQLite-specific
|
|
170
|
+
* literal syntax (no cast suffix, boolean as 0/1, blob via X'hex'). For
|
|
171
|
+
* query ASTs, params are kept as `?` placeholders; wire values go in
|
|
172
|
+
* `params`. Does NOT call `this.lower()` — independent implementation.
|
|
173
|
+
*/
|
|
174
|
+
async lowerToExecuteRequest(
|
|
175
|
+
ast: AnyQueryAst | SqliteDdlNode,
|
|
176
|
+
context?: LowererContext<unknown>,
|
|
177
|
+
): Promise<SqlExecuteRequest> {
|
|
178
|
+
if (isDdlNode(ast)) {
|
|
179
|
+
return sqliteRenderDdlExecuteRequest(
|
|
180
|
+
blindCast<SqliteDdlNode, 'isDdlNode guard'>(ast),
|
|
181
|
+
this.codecLookup,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
const lowered = renderLoweredSql(
|
|
185
|
+
ast,
|
|
186
|
+
blindCast<SqliteContract, 'Caller must supply matching contract'>(context?.contract),
|
|
187
|
+
);
|
|
188
|
+
const params = await encodeControlQueryParams(lowered, ast);
|
|
189
|
+
return { sql: lowered.sql, params };
|
|
190
|
+
}
|
|
191
|
+
|
|
135
192
|
/**
|
|
136
193
|
* Reads the contract marker from `_prisma_marker`. Probes `sqlite_master`
|
|
137
194
|
* first so a fresh database (no marker table) returns `null` instead of a
|
|
@@ -582,3 +639,126 @@ function mapSqliteReferentialAction(rule: string): SqlReferentialAction | undefi
|
|
|
582
639
|
if (mapped === 'noAction') return undefined;
|
|
583
640
|
return mapped;
|
|
584
641
|
}
|
|
642
|
+
|
|
643
|
+
// ---------------------------------------------------------------------------
|
|
644
|
+
// sqliteRenderDdlExecuteRequest — independent DDL walker for lowerToExecuteRequest
|
|
645
|
+
// ---------------------------------------------------------------------------
|
|
646
|
+
|
|
647
|
+
function sqliteInlineLiteral(wire: unknown): string {
|
|
648
|
+
if (wire === null) return 'NULL';
|
|
649
|
+
if (typeof wire === 'boolean') return wire ? '1' : '0';
|
|
650
|
+
if (typeof wire === 'number') {
|
|
651
|
+
if (!Number.isFinite(wire)) {
|
|
652
|
+
throw new Error(
|
|
653
|
+
`sqliteRenderDdlExecuteRequest: non-finite number wire value ${String(wire)} cannot be emitted as a DEFAULT literal`,
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
return String(wire);
|
|
657
|
+
}
|
|
658
|
+
if (typeof wire === 'bigint') return String(wire);
|
|
659
|
+
if (wire instanceof Date) {
|
|
660
|
+
if (Number.isNaN(wire.getTime())) {
|
|
661
|
+
throw new Error(
|
|
662
|
+
'sqliteRenderDdlExecuteRequest: invalid Date value cannot be emitted as a DEFAULT literal',
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
return `'${escapeLiteral(wire.toISOString())}'`;
|
|
666
|
+
}
|
|
667
|
+
if (typeof wire === 'string') return `'${escapeLiteral(wire)}'`;
|
|
668
|
+
if (wire instanceof Uint8Array) {
|
|
669
|
+
const hex = Array.from(wire)
|
|
670
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
671
|
+
.join('');
|
|
672
|
+
return `X'${hex}'`;
|
|
673
|
+
}
|
|
674
|
+
if (typeof wire === 'object') return `'${escapeLiteral(JSON.stringify(wire))}'`;
|
|
675
|
+
throw new Error(`sqliteRenderDdlExecuteRequest: unexpected wire type "${typeof wire}"`);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
async function sqliteRenderDdlColumnDefault(
|
|
679
|
+
def: LiteralColumnDefault | FunctionColumnDefault,
|
|
680
|
+
codecLookup: CodecLookup,
|
|
681
|
+
codecRef: CodecRef | undefined,
|
|
682
|
+
): Promise<string> {
|
|
683
|
+
if (def.kind === 'function') {
|
|
684
|
+
if (def.expression === 'autoincrement()') return '';
|
|
685
|
+
// SQLite has no `now()` function; the contract canonicalizes
|
|
686
|
+
// `CURRENT_TIMESTAMP` / `datetime('now')` to `now()`, so map it back to a
|
|
687
|
+
// valid SQLite expression on the way out.
|
|
688
|
+
if (def.expression === 'now()') return "DEFAULT (datetime('now'))";
|
|
689
|
+
return `DEFAULT (${def.expression})`;
|
|
690
|
+
}
|
|
691
|
+
if (codecRef !== undefined) {
|
|
692
|
+
const codec = codecLookup.get(codecRef.codecId);
|
|
693
|
+
if (codec !== undefined) {
|
|
694
|
+
const wire = await codec.encode(def.value, {});
|
|
695
|
+
return `DEFAULT ${sqliteInlineLiteral(wire)}`;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
// Fallback: codec-less literal defaults follow RawSqlLiteral wire-scalar semantics.
|
|
699
|
+
return `DEFAULT ${sqliteInlineLiteral(def.value)}`;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
async function sqliteRenderDdlColumn(column: DdlColumn, codecLookup: CodecLookup): Promise<string> {
|
|
703
|
+
if (column.type.includes('AUTOINCREMENT')) {
|
|
704
|
+
return `${quoteIdentifier(column.name)} ${column.type}`;
|
|
705
|
+
}
|
|
706
|
+
const parts = [quoteIdentifier(column.name), column.type];
|
|
707
|
+
if (column.notNull) parts.push('NOT NULL');
|
|
708
|
+
if (column.primaryKey) parts.push('PRIMARY KEY');
|
|
709
|
+
if (column.default) {
|
|
710
|
+
const clause = await sqliteRenderDdlColumnDefault(column.default, codecLookup, column.codecRef);
|
|
711
|
+
if (clause.length > 0) parts.push(clause);
|
|
712
|
+
}
|
|
713
|
+
return parts.join(' ');
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
function sqliteRenderDdlConstraint(constraint: DdlTableConstraint): string {
|
|
717
|
+
if (constraint.kind === 'primary-key') {
|
|
718
|
+
const cols = constraint.columns.map(quoteIdentifier).join(', ');
|
|
719
|
+
if (constraint.name !== undefined) {
|
|
720
|
+
return `CONSTRAINT ${quoteIdentifier(constraint.name)} PRIMARY KEY (${cols})`;
|
|
721
|
+
}
|
|
722
|
+
return `PRIMARY KEY (${cols})`;
|
|
723
|
+
}
|
|
724
|
+
if (constraint.kind === 'foreign-key') {
|
|
725
|
+
const cols = constraint.columns.map(quoteIdentifier).join(', ');
|
|
726
|
+
const refTable = constraint.refTable.split('.').map(quoteIdentifier).join('.');
|
|
727
|
+
const refCols = constraint.refColumns.map(quoteIdentifier).join(', ');
|
|
728
|
+
let sql = `FOREIGN KEY (${cols}) REFERENCES ${refTable} (${refCols})`;
|
|
729
|
+
if (constraint.onDelete !== undefined) {
|
|
730
|
+
sql += ` ON DELETE ${REFERENTIAL_ACTION_SQL[constraint.onDelete]}`;
|
|
731
|
+
}
|
|
732
|
+
if (constraint.onUpdate !== undefined) {
|
|
733
|
+
sql += ` ON UPDATE ${REFERENTIAL_ACTION_SQL[constraint.onUpdate]}`;
|
|
734
|
+
}
|
|
735
|
+
if (constraint.name !== undefined) {
|
|
736
|
+
sql = `CONSTRAINT ${quoteIdentifier(constraint.name)} ${sql}`;
|
|
737
|
+
}
|
|
738
|
+
return sql;
|
|
739
|
+
}
|
|
740
|
+
const cols = constraint.columns.map(quoteIdentifier).join(', ');
|
|
741
|
+
if (constraint.name !== undefined) {
|
|
742
|
+
return `CONSTRAINT ${quoteIdentifier(constraint.name)} UNIQUE (${cols})`;
|
|
743
|
+
}
|
|
744
|
+
return `UNIQUE (${cols})`;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
async function sqliteRenderDdlExecuteRequest(
|
|
748
|
+
ast: SqliteDdlNode,
|
|
749
|
+
codecLookup: CodecLookup,
|
|
750
|
+
): Promise<SqlExecuteRequest> {
|
|
751
|
+
const node = blindCast<SqliteCreateTable, 'SQLite DDL only has create-table'>(ast);
|
|
752
|
+
const ifNotExists = node.ifNotExists ? 'IF NOT EXISTS ' : '';
|
|
753
|
+
const tableRef = quoteIdentifier(node.table);
|
|
754
|
+
const columnDefs = await Promise.all(
|
|
755
|
+
node.columns.map((col) => sqliteRenderDdlColumn(col, codecLookup)),
|
|
756
|
+
);
|
|
757
|
+
const constraintDefs =
|
|
758
|
+
node.constraints !== undefined ? node.constraints.map(sqliteRenderDdlConstraint) : [];
|
|
759
|
+
const allDefs = [...columnDefs, ...constraintDefs].join(',\n ');
|
|
760
|
+
return {
|
|
761
|
+
sql: `CREATE TABLE ${ifNotExists}${tableRef} (\n ${allDefs}\n)`,
|
|
762
|
+
params: [],
|
|
763
|
+
};
|
|
764
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AnyQueryAst,
|
|
3
|
+
ContractCodecRegistry,
|
|
4
|
+
LoweredStatement,
|
|
5
|
+
} from '@prisma-next/sql-relational-core/ast';
|
|
6
|
+
import {
|
|
7
|
+
createAstCodecRegistry,
|
|
8
|
+
deriveParamMetadata,
|
|
9
|
+
encodeParamsWithMetadata,
|
|
10
|
+
} from '@prisma-next/sql-runtime';
|
|
11
|
+
import { sqliteCodecRegistry } from '@prisma-next/target-sqlite/codecs';
|
|
12
|
+
|
|
13
|
+
export const CONTROL_CODECS = createAstCodecRegistry(sqliteCodecRegistry);
|
|
14
|
+
|
|
15
|
+
export async function encodeControlQueryParams(
|
|
16
|
+
lowered: LoweredStatement,
|
|
17
|
+
ast: AnyQueryAst,
|
|
18
|
+
codecs: ContractCodecRegistry = CONTROL_CODECS,
|
|
19
|
+
): Promise<readonly unknown[]> {
|
|
20
|
+
const values = lowered.params.map((slot) => {
|
|
21
|
+
if (slot.kind === 'literal') return slot.value;
|
|
22
|
+
throw new Error(`control query lowered to a bind slot '${slot.name}', which is unsupported`);
|
|
23
|
+
});
|
|
24
|
+
return encodeParamsWithMetadata(values, deriveParamMetadata(ast), {}, codecs);
|
|
25
|
+
}
|
|
@@ -4,13 +4,7 @@ import {
|
|
|
4
4
|
type LoweredStatement,
|
|
5
5
|
RawExpr,
|
|
6
6
|
} from '@prisma-next/sql-relational-core/ast';
|
|
7
|
-
import {
|
|
8
|
-
createAstCodecRegistry,
|
|
9
|
-
deriveParamMetadata,
|
|
10
|
-
encodeParamsWithMetadata,
|
|
11
|
-
} from '@prisma-next/sql-runtime';
|
|
12
7
|
import { SQLITE_DATETIME_CODEC_ID } from '@prisma-next/target-sqlite/codec-ids';
|
|
13
|
-
import { sqliteCodecRegistry } from '@prisma-next/target-sqlite/codecs';
|
|
14
8
|
import {
|
|
15
9
|
datetime,
|
|
16
10
|
integer,
|
|
@@ -18,8 +12,7 @@ import {
|
|
|
18
12
|
sqliteTable,
|
|
19
13
|
text,
|
|
20
14
|
} from '@prisma-next/target-sqlite/contract-free';
|
|
21
|
-
|
|
22
|
-
const CONTROL_CODECS = createAstCodecRegistry(sqliteCodecRegistry);
|
|
15
|
+
import { encodeControlQueryParams } from './control-codecs';
|
|
23
16
|
|
|
24
17
|
export const marker = sqliteTable('_prisma_marker', {
|
|
25
18
|
space: text(),
|
|
@@ -91,16 +84,7 @@ export async function execute(
|
|
|
91
84
|
query: AnyQueryAst,
|
|
92
85
|
): Promise<readonly Record<string, unknown>[]> {
|
|
93
86
|
const lowered = lower(query);
|
|
94
|
-
const
|
|
95
|
-
if (slot.kind === 'literal') return slot.value;
|
|
96
|
-
throw new Error('SQLite control DML lowered to a bind parameter, which is unsupported');
|
|
97
|
-
});
|
|
98
|
-
const encoded = await encodeParamsWithMetadata(
|
|
99
|
-
values,
|
|
100
|
-
deriveParamMetadata(query),
|
|
101
|
-
{},
|
|
102
|
-
CONTROL_CODECS,
|
|
103
|
-
);
|
|
87
|
+
const encoded = await encodeControlQueryParams(lowered, query);
|
|
104
88
|
const result = await driver.query(lowered.sql, encoded);
|
|
105
89
|
return result.rows;
|
|
106
90
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-BSYqYUMq.mjs","names":["renderColumn"],"sources":["../../../../1-framework/3-tooling/migration/dist/exports/ledger-origin.mjs","../src/core/ddl-renderer.ts","../src/core/ledger-decode.ts","../src/core/marker-ledger.ts","../src/core/control-adapter.ts","../src/core/adapter.ts"],"sourcesContent":["import \"../constants-YnG8_EGO.mjs\";\n//#region src/ledger-origin.ts\nfunction ledgerOriginFromStored(originCoreHash) {\n\tif (originCoreHash === null || originCoreHash === \"\" || originCoreHash === \"sha256:empty\") return null;\n\treturn originCoreHash;\n}\n//#endregion\nexport { ledgerOriginFromStored };\n\n//# sourceMappingURL=ledger-origin.mjs.map","import { REFERENTIAL_ACTION_SQL } from '@prisma-next/sql-contract/referential-action-sql';\nimport type {\n DdlColumn,\n DdlColumnDefaultVisitor,\n DdlTableConstraint,\n ForeignKeyConstraint,\n FunctionColumnDefault,\n LiteralColumnDefault,\n PrimaryKeyConstraint,\n UniqueConstraint,\n} from '@prisma-next/sql-relational-core/ast';\nimport type {\n SqliteCreateTable,\n SqliteDdlNode,\n SqliteDdlVisitor,\n} from '@prisma-next/target-sqlite/ddl';\nimport { escapeLiteral, quoteIdentifier } from '@prisma-next/target-sqlite/sql-utils';\nimport type { SqliteLoweredStatement } from './types';\n\nfunction quoteQualifiedIdentifier(name: string): string {\n return name.split('.').map(quoteIdentifier).join('.');\n}\n\nfunction renderPrimaryKeyConstraint(constraint: PrimaryKeyConstraint): string {\n const cols = constraint.columns.map(quoteIdentifier).join(', ');\n if (constraint.name !== undefined) {\n return `CONSTRAINT ${quoteIdentifier(constraint.name)} PRIMARY KEY (${cols})`;\n }\n return `PRIMARY KEY (${cols})`;\n}\n\nfunction renderForeignKeyConstraint(constraint: ForeignKeyConstraint): string {\n const cols = constraint.columns.map(quoteIdentifier).join(', ');\n const refCols = constraint.refColumns.map(quoteIdentifier).join(', ');\n let sql = `FOREIGN KEY (${cols}) REFERENCES ${quoteQualifiedIdentifier(constraint.refTable)} (${refCols})`;\n if (constraint.onDelete !== undefined) {\n sql += ` ON DELETE ${REFERENTIAL_ACTION_SQL[constraint.onDelete]}`;\n }\n if (constraint.onUpdate !== undefined) {\n sql += ` ON UPDATE ${REFERENTIAL_ACTION_SQL[constraint.onUpdate]}`;\n }\n if (constraint.name !== undefined) {\n sql = `CONSTRAINT ${quoteIdentifier(constraint.name)} ${sql}`;\n }\n return sql;\n}\n\nfunction renderUniqueConstraint(constraint: UniqueConstraint): string {\n const cols = constraint.columns.map(quoteIdentifier).join(', ');\n if (constraint.name !== undefined) {\n return `CONSTRAINT ${quoteIdentifier(constraint.name)} UNIQUE (${cols})`;\n }\n return `UNIQUE (${cols})`;\n}\n\nfunction renderTableConstraint(constraint: DdlTableConstraint): string {\n switch (constraint.kind) {\n case 'primary-key':\n return renderPrimaryKeyConstraint(constraint);\n case 'foreign-key':\n return renderForeignKeyConstraint(constraint);\n case 'unique':\n return renderUniqueConstraint(constraint);\n }\n}\n\nclass SqliteDdlVisitorImpl implements SqliteDdlVisitor<string> {\n createTable(node: SqliteCreateTable): string {\n const ifNotExists = node.ifNotExists ? 'IF NOT EXISTS ' : '';\n const tableRef = quoteIdentifier(node.table);\n const columnDefs = node.columns.map((column) => renderColumn(column));\n const constraintDefs =\n node.constraints !== undefined ? node.constraints.map(renderTableConstraint) : [];\n const allDefs = [...columnDefs, ...constraintDefs].join(',\\n ');\n return `CREATE TABLE ${ifNotExists}${tableRef} (\\n ${allDefs}\\n)`;\n }\n}\n\nconst defaultVisitor: DdlColumnDefaultVisitor<string> = {\n // SQLite has no `jsonb` / `json` column type, so the ctx is unused — but\n // the visitor interface requires it for cross-dialect symmetry with the\n // Postgres renderer, which uses ctx.nativeType to emit JSON casts.\n literal(node: LiteralColumnDefault, _ctx): string {\n const { value } = node;\n if (value instanceof Date) {\n return `DEFAULT '${escapeLiteral(value.toISOString())}'`;\n }\n if (typeof value === 'string') {\n return `DEFAULT '${escapeLiteral(value)}'`;\n }\n if (typeof value === 'number') {\n return `DEFAULT ${String(value)}`;\n }\n if (typeof value === 'boolean') {\n // SQLite has no boolean type; store as 0/1 to match the pre-slice format.\n return `DEFAULT ${value ? '1' : '0'}`;\n }\n if (typeof value === 'bigint') {\n // Defensive: bigint is not in ColumnDefaultLiteralInputValue but guard\n // against JSON.stringify throwing if one ever reaches this path.\n return `DEFAULT ${String(value)}`;\n }\n if (value === null) {\n return 'DEFAULT NULL';\n }\n return `DEFAULT '${escapeLiteral(JSON.stringify(value))}'`;\n },\n function(node: FunctionColumnDefault, _ctx): string {\n if (node.expression === 'autoincrement()') {\n return '';\n }\n if (node.expression === 'now()') return \"DEFAULT (datetime('now'))\";\n return `DEFAULT (${node.expression})`;\n },\n};\n\nfunction renderColumn(column: DdlColumn): string {\n // The `tableToDdlParts` helper in issue-planner.ts encodes the\n // `INTEGER PRIMARY KEY AUTOINCREMENT` inline column definition directly into\n // `DdlColumn.type` (rather than setting a column-level flag) because\n // `DdlColumn` has no SQLite-specific autoincrement field. Both sites must\n // stay in sync: when one changes the encoded string the other must change\n // the detection. The structural fix is tracked in TML-2866.\n if (column.type.includes('AUTOINCREMENT')) {\n return `${quoteIdentifier(column.name)} ${column.type}`;\n }\n const parts = [quoteIdentifier(column.name), column.type];\n if (column.notNull) {\n parts.push('NOT NULL');\n }\n if (column.primaryKey) {\n parts.push('PRIMARY KEY');\n }\n const defaultClause = column.default\n ? column.default.accept(defaultVisitor, { nativeType: column.type })\n : '';\n if (defaultClause.length > 0) {\n parts.push(defaultClause);\n }\n return parts.join(' ');\n}\n\nexport function renderLoweredDdl(ast: SqliteDdlNode): SqliteLoweredStatement {\n const sql = ast.accept(new SqliteDdlVisitorImpl());\n return Object.freeze({ sql, params: Object.freeze([]) });\n}\n","const DESIGNATOR_LESS_UTC_DATETIME = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(\\.\\d+)?$/;\n\nexport function coerceLedgerAppliedAt(value: Date | string): Date {\n if (value instanceof Date) {\n return value;\n }\n if (DESIGNATOR_LESS_UTC_DATETIME.test(value)) {\n return new Date(`${value.replace(' ', 'T')}Z`);\n }\n return new Date(value);\n}\n\nexport function operationCountFromStored(operations: unknown): number {\n if (Array.isArray(operations)) {\n return operations.length;\n }\n if (typeof operations === 'string') {\n try {\n const parsed: unknown = JSON.parse(operations);\n return Array.isArray(parsed) ? parsed.length : 0;\n } catch {\n return 0;\n }\n }\n return 0;\n}\n","import type { SqlControlDriverInstance } from '@prisma-next/sql-contract/types';\nimport {\n type AnyQueryAst,\n type LoweredStatement,\n RawExpr,\n} from '@prisma-next/sql-relational-core/ast';\nimport {\n createAstCodecRegistry,\n deriveParamMetadata,\n encodeParamsWithMetadata,\n} from '@prisma-next/sql-runtime';\nimport { SQLITE_DATETIME_CODEC_ID } from '@prisma-next/target-sqlite/codec-ids';\nimport { sqliteCodecRegistry } from '@prisma-next/target-sqlite/codecs';\nimport {\n datetime,\n integer,\n jsonText,\n sqliteTable,\n text,\n} from '@prisma-next/target-sqlite/contract-free';\n\nconst CONTROL_CODECS = createAstCodecRegistry(sqliteCodecRegistry);\n\nexport const marker = sqliteTable('_prisma_marker', {\n space: text(),\n core_hash: text(),\n profile_hash: text(),\n contract_json: jsonText({ nullable: true }),\n canonical_version: integer({ nullable: true }),\n updated_at: datetime(),\n app_tag: text({ nullable: true }),\n meta: jsonText({ nullable: true }),\n invariants: jsonText(),\n});\n\n/**\n * Writeable subset of `_prisma_ledger`. Omits the DB-generated `id`\n * (`INTEGER PRIMARY KEY AUTOINCREMENT`) and `created_at` (default\n * `strftime(...)`).\n */\nexport const ledger = sqliteTable('_prisma_ledger', {\n space: text(),\n migration_name: text(),\n migration_hash: text(),\n origin_core_hash: text({ nullable: true }),\n destination_core_hash: text(),\n operations: jsonText(),\n});\n\n/**\n * Read-side handle covering every column of `_prisma_ledger`, including\n * the DB-generated `id` (for ORDER BY) and `created_at`.\n */\nexport const ledgerReadShape = sqliteTable('_prisma_ledger', {\n id: integer(),\n space: text(),\n migration_name: text(),\n migration_hash: text(),\n origin_core_hash: text({ nullable: true }),\n destination_core_hash: text(),\n operations: jsonText(),\n created_at: text(),\n});\n\nexport const sqliteCatalog = sqliteTable('sqlite_master', { type: text(), name: text() });\n\nexport const NOW = new RawExpr({\n parts: [\"datetime('now')\"],\n returns: { codecId: SQLITE_DATETIME_CODEC_ID, nullable: false },\n});\n\ntype Lower = (query: AnyQueryAst) => LoweredStatement;\n\ntype MarkerDriver = {\n query<Row = Record<string, unknown>>(\n sql: string,\n params?: readonly unknown[],\n ): Promise<{ readonly rows: ReadonlyArray<Row> }>;\n};\n\nexport function mergeInvariants(\n current: readonly string[],\n incoming: readonly string[],\n): readonly string[] {\n return [...new Set([...current, ...incoming])].sort();\n}\n\nexport async function execute(\n lower: Lower,\n driver: MarkerDriver,\n query: AnyQueryAst,\n): Promise<readonly Record<string, unknown>[]> {\n const lowered = lower(query);\n const values = lowered.params.map((slot) => {\n if (slot.kind === 'literal') return slot.value;\n throw new Error('SQLite control DML lowered to a bind parameter, which is unsupported');\n });\n const encoded = await encodeParamsWithMetadata(\n values,\n deriveParamMetadata(query),\n {},\n CONTROL_CODECS,\n );\n const result = await driver.query(lowered.sql, encoded);\n return result.rows;\n}\n\nexport function decodeSqliteMarkerRow(row: unknown): unknown {\n if (typeof row !== 'object' || row === null || !('invariants' in row)) {\n return row;\n }\n const record = row as { invariants: unknown };\n if (typeof record.invariants !== 'string') return row;\n let parsed: unknown;\n try {\n parsed = JSON.parse(record.invariants);\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n throw new Error(`Invalid contract marker row: invariants is not valid JSON: ${detail}`);\n }\n return { ...record, invariants: parsed };\n}\n\nexport type SqliteMarkerWriteDriver = SqlControlDriverInstance<'sqlite'>;\n","import type { ContractMarkerRecord, LedgerEntryRecord } from '@prisma-next/contract/types';\nimport { parseMarkerRowSafely, withMarkerReadErrorHandling } from '@prisma-next/errors/execution';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport { parseContractMarkerRow } from '@prisma-next/family-sql/verify';\nimport { APP_SPACE_ID } from '@prisma-next/framework-components/control';\nimport { ledgerOriginFromStored } from '@prisma-next/migration-tools/ledger-origin';\nimport type { SqlControlDriverInstance } from '@prisma-next/sql-contract/types';\nimport type {\n AnyQueryAst,\n DdlNode,\n LoweredStatement,\n LowererContext,\n MarkerReadResult,\n} from '@prisma-next/sql-relational-core/ast';\nimport { isDdlNode } from '@prisma-next/sql-relational-core/ast';\nimport type {\n PrimaryKey,\n SqlColumnIR,\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlReferentialAction,\n SqlSchemaIR,\n SqlTableIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\nimport {\n buildControlTableBootstrapQueries,\n buildSignMarkerBootstrapQueries,\n} from '@prisma-next/target-sqlite/contract-free';\nimport type { SqliteDdlNode } from '@prisma-next/target-sqlite/ddl';\nimport { parseSqliteDefault } from '@prisma-next/target-sqlite/default-normalizer';\nimport { normalizeSqliteNativeType } from '@prisma-next/target-sqlite/native-type-normalizer';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { renderLoweredSql } from './adapter';\nimport { renderLoweredDdl } from './ddl-renderer';\nimport { coerceLedgerAppliedAt, operationCountFromStored } from './ledger-decode';\nimport {\n decodeSqliteMarkerRow,\n execute,\n ledger,\n ledgerReadShape,\n marker,\n mergeInvariants,\n NOW,\n sqliteCatalog,\n} from './marker-ledger';\nimport type { SqliteContract } from './types';\n\nconst SQLITE_MARKER_TABLE = '_prisma_marker';\nconst SQLITE_LEDGER_TABLE = '_prisma_ledger';\n\ntype SqliteLedgerRow = {\n readonly space: string;\n readonly migration_name: string;\n readonly migration_hash: string;\n readonly origin_core_hash: string | null;\n readonly destination_core_hash: string;\n readonly operations: unknown;\n readonly created_at: Date | string;\n};\n\n// PRAGMA result row types\ntype PragmaTableInfoRow = {\n cid: number;\n name: string;\n type: string;\n notnull: number;\n dflt_value: string | null;\n pk: number;\n};\n\ntype PragmaForeignKeyRow = {\n id: number;\n seq: number;\n table: string;\n from: string;\n to: string;\n on_update: string;\n on_delete: string;\n};\n\ntype PragmaIndexListRow = {\n seq: number;\n name: string;\n unique: number;\n origin: string;\n partial: number;\n};\n\ntype PragmaIndexInfoRow = {\n seqno: number;\n cid: number;\n name: string;\n};\n\ntype FkAccumulator = {\n columns: string[];\n referencedTable: string;\n referencedColumns: string[];\n onDelete: string;\n onUpdate: string;\n};\n\nexport class SqliteControlAdapter implements SqlControlAdapter<'sqlite'> {\n readonly familyId = 'sql' as const;\n readonly targetId = 'sqlite' as const;\n\n readonly normalizeDefault = parseSqliteDefault;\n readonly normalizeNativeType = normalizeSqliteNativeType;\n\n bootstrapControlTableQueries(): readonly DdlNode[] {\n return buildControlTableBootstrapQueries();\n }\n\n bootstrapSignMarkerQueries(): readonly DdlNode[] {\n return buildSignMarkerBootstrapQueries();\n }\n\n /**\n * Lower a SQL query AST into a SQLite-flavored `{ sql, params }` payload.\n *\n * Delegates to the shared `renderLoweredSql` renderer so the control adapter\n * emits byte-identical SQL to `SqliteAdapterImpl.lower()` for the same AST\n * and contract. Used at migration plan/emit time (e.g. by `dataTransform`)\n * without instantiating the runtime adapter.\n */\n lower(ast: AnyQueryAst | SqliteDdlNode, context: LowererContext<unknown>): LoweredStatement {\n if (isDdlNode(ast)) {\n return renderLoweredDdl(ast);\n }\n return renderLoweredSql(ast, context.contract as SqliteContract);\n }\n\n /**\n * Reads the contract marker from `_prisma_marker`. Probes `sqlite_master`\n * first so a fresh database (no marker table) returns `null` instead of a\n * \"no such table\" error.\n */\n async readMarker(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n ): Promise<ContractMarkerRecord | null> {\n const result = await this.readMarkerDiscriminated(driver, space);\n return result.kind === 'present' ? result.record : null;\n }\n\n async readMarkerDiscriminated(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n ): Promise<MarkerReadResult> {\n const markerContext = { space, markerLocation: SQLITE_MARKER_TABLE };\n return withMarkerReadErrorHandling(() => this.readMarkerResult(driver, space), markerContext);\n }\n\n /**\n * Reads every row from `_prisma_marker` and returns them keyed by\n * `space`. Mirrors the existence probe in {@link readMarker}: a\n * fresh database without the marker table returns an empty map.\n */\n async readAllMarkers(\n driver: SqlControlDriverInstance<'sqlite'>,\n ): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const markerContext = { space: APP_SPACE_ID, markerLocation: SQLITE_MARKER_TABLE };\n return withMarkerReadErrorHandling(() => this.readAllMarkersResult(driver), markerContext);\n }\n\n private async readAllMarkersResult(\n driver: SqlControlDriverInstance<'sqlite'>,\n ): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const lower = (query: AnyQueryAst) => this.lower(query, { contract: undefined });\n const probe = sqliteCatalog\n .select(sqliteCatalog.name)\n .where(sqliteCatalog.type.eq('table').and(sqliteCatalog.name.eq('_prisma_marker')))\n .build();\n const exists = await execute(lower, driver, probe);\n if (exists.length === 0) {\n return new Map();\n }\n\n const fetch = marker\n .select(\n marker.space,\n marker.core_hash,\n marker.profile_hash,\n marker.contract_json,\n marker.canonical_version,\n marker.updated_at,\n marker.app_tag,\n marker.meta,\n marker.invariants,\n )\n .build();\n const rawRows = await execute(lower, driver, fetch);\n const rows = blindCast<\n ReadonlyArray<{ space: string } & Record<string, unknown>>,\n 'Driver returns rows shaped by SELECT'\n >(rawRows);\n\n const out = new Map<string, ContractMarkerRecord>();\n for (const row of rows) {\n out.set(\n row.space,\n parseMarkerRowSafely(row, (raw) => parseContractMarkerRow(decodeSqliteMarkerRow(raw)), {\n space: row.space,\n markerLocation: SQLITE_MARKER_TABLE,\n }),\n );\n }\n return out;\n }\n\n /**\n * Reads per-migration ledger rows from `_prisma_ledger` in apply order.\n * Probes `sqlite_master` first so a fresh database without the ledger\n * table returns `[]` instead of raising \"no such table\".\n */\n async readLedger(\n driver: SqlControlDriverInstance<'sqlite'>,\n space?: string,\n ): Promise<readonly LedgerEntryRecord[]> {\n const ledgerContext = { space: space ?? '*', markerLocation: SQLITE_LEDGER_TABLE };\n return withMarkerReadErrorHandling(() => this.readLedgerResult(driver, space), ledgerContext);\n }\n\n private async readLedgerResult(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string | undefined,\n ): Promise<readonly LedgerEntryRecord[]> {\n const lower = (query: AnyQueryAst) => this.lower(query, { contract: undefined });\n const probe = sqliteCatalog\n .select(sqliteCatalog.name)\n .where(sqliteCatalog.type.eq('table').and(sqliteCatalog.name.eq('_prisma_ledger')))\n .build();\n const exists = await execute(lower, driver, probe);\n if (exists.length === 0) {\n return [];\n }\n\n const base = ledgerReadShape.select(\n ledgerReadShape.space,\n ledgerReadShape.migration_name,\n ledgerReadShape.migration_hash,\n ledgerReadShape.origin_core_hash,\n ledgerReadShape.destination_core_hash,\n ledgerReadShape.operations,\n ledgerReadShape.created_at,\n );\n const filtered = space !== undefined ? base.where(ledgerReadShape.space.eq(space)) : base;\n const rawRows = await execute(lower, driver, filtered.orderBy(ledgerReadShape.id).build());\n const rows = blindCast<readonly SqliteLedgerRow[], 'Driver returns rows shaped by SELECT'>(\n rawRows,\n );\n\n return rows.map((row) => ({\n space: row.space,\n migrationName: row.migration_name,\n migrationHash: row.migration_hash,\n from: ledgerOriginFromStored(row.origin_core_hash),\n to: row.destination_core_hash,\n appliedAt: coerceLedgerAppliedAt(row.created_at),\n operationCount: operationCountFromStored(row.operations),\n }));\n }\n\n /**\n * Stamps the initial marker row for `space` via the shared contract-free DML\n * builder, lowered through {@link lower} and executed on the driver. See the\n * `SqlControlAdapter.initMarker` contract.\n */\n async insertMarker(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<void> {\n await execute(\n (query) => this.lower(query, { contract: undefined }),\n driver,\n marker\n .insert({\n space,\n core_hash: destination.storageHash,\n profile_hash: destination.profileHash,\n contract_json: null,\n canonical_version: null,\n updated_at: NOW,\n app_tag: null,\n meta: {},\n invariants: destination.invariants ?? [],\n })\n .build(),\n );\n }\n\n async initMarker(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<void> {\n await execute(\n (query) => this.lower(query, { contract: undefined }),\n driver,\n marker\n .upsert({\n space,\n core_hash: destination.storageHash,\n profile_hash: destination.profileHash,\n contract_json: null,\n canonical_version: null,\n updated_at: NOW,\n app_tag: null,\n meta: {},\n invariants: destination.invariants ?? [],\n })\n .onConflict(marker.space)\n .doUpdate((excluded) => ({\n core_hash: excluded.core_hash,\n profile_hash: excluded.profile_hash,\n contract_json: excluded.contract_json,\n canonical_version: excluded.canonical_version,\n updated_at: NOW,\n app_tag: excluded.app_tag,\n meta: excluded.meta,\n invariants: excluded.invariants,\n }))\n .build(),\n );\n }\n\n /**\n * Compare-and-swap advance of the marker row for `space`. See the\n * `SqlControlAdapter.updateMarker` contract.\n */\n async updateMarker(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n expectedFrom: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<boolean> {\n const currentInvariants =\n destination.invariants === undefined\n ? []\n : ((await this.readMarker(driver, space))?.invariants ?? []);\n const mergedInvariants =\n destination.invariants === undefined\n ? undefined\n : mergeInvariants(currentInvariants, destination.invariants);\n\n const query = marker\n .update()\n .set({\n core_hash: destination.storageHash,\n profile_hash: destination.profileHash,\n updated_at: NOW,\n ...(mergedInvariants !== undefined ? { invariants: mergedInvariants } : {}),\n })\n .where(marker.space.eq(space).and(marker.core_hash.eq(expectedFrom)))\n .returning(marker.space)\n .build();\n\n const rows = await execute((q) => this.lower(q, { contract: undefined }), driver, query);\n return rows.length > 0;\n }\n\n /**\n * Appends a ledger entry for `space`. See the\n * `SqlControlAdapter.writeLedgerEntry` contract.\n */\n async writeLedgerEntry(\n driver: SqlControlDriverInstance<'sqlite'>,\n space: string,\n entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n readonly migrationName: string;\n readonly migrationHash: string;\n readonly operations: readonly unknown[];\n },\n ): Promise<void> {\n await execute(\n (query) => this.lower(query, { contract: undefined }),\n driver,\n ledger\n .insert({\n space,\n migration_name: entry.migrationName,\n migration_hash: entry.migrationHash,\n origin_core_hash: entry.from,\n destination_core_hash: entry.to,\n operations: entry.operations,\n })\n .build(),\n );\n }\n\n private async readMarkerResult(driver: SqlControlDriverInstance<'sqlite'>, space: string) {\n const lower = (query: AnyQueryAst) => this.lower(query, { contract: undefined });\n const probe = sqliteCatalog\n .select(sqliteCatalog.name)\n .where(sqliteCatalog.type.eq('table').and(sqliteCatalog.name.eq('_prisma_marker')))\n .build();\n const exists = await execute(lower, driver, probe);\n if (exists.length === 0) return { kind: 'no-table' as const };\n\n const fetch = marker\n .select(\n marker.core_hash,\n marker.profile_hash,\n marker.contract_json,\n marker.canonical_version,\n marker.updated_at,\n marker.app_tag,\n marker.meta,\n marker.invariants,\n )\n .where(marker.space.eq(space))\n .build();\n const result = await execute(lower, driver, fetch);\n const row = result[0];\n if (!row) return { kind: 'absent' as const };\n return {\n kind: 'present' as const,\n record: parseContractMarkerRow(decodeSqliteMarkerRow(row)),\n };\n }\n\n async introspect(\n driver: SqlControlDriverInstance<'sqlite'>,\n _contract?: unknown,\n ): Promise<SqlSchemaIR> {\n // Filter out runner-managed control tables (`_prisma_marker`,\n // `_prisma_ledger`) — they're an implementation detail of the migration\n // runner, not part of the user-authored contract, so they must not\n // appear in introspection output (otherwise strict schema verification\n // flags them as `extra_table`).\n const tablesResult = await driver.query<{ name: string }>(\n `SELECT name FROM sqlite_master\n WHERE type = 'table'\n AND name NOT LIKE 'sqlite_%'\n AND name NOT IN ('_prisma_marker', '_prisma_ledger')\n ORDER BY name`,\n );\n\n const tables: Record<string, SqlTableIR> = {};\n\n for (const tableRow of tablesResult.rows) {\n const tableName = tableRow.name;\n\n // SQLite's synchronous driver serializes reads — no benefit from Promise.all\n const columnsResult = await driver.query<PragmaTableInfoRow>(\n `PRAGMA table_info(\"${escapePragmaArg(tableName)}\")`,\n );\n const fkResult = await driver.query<PragmaForeignKeyRow>(\n `PRAGMA foreign_key_list(\"${escapePragmaArg(tableName)}\")`,\n );\n const indexListResult = await driver.query<PragmaIndexListRow>(\n `PRAGMA index_list(\"${escapePragmaArg(tableName)}\")`,\n );\n\n const columns: Record<string, SqlColumnIR> = {};\n const pkColumns: Array<{ name: string; pk: number }> = [];\n\n for (const col of columnsResult.rows) {\n columns[col.name] = {\n name: col.name,\n nativeType: col.type.toLowerCase(),\n nullable: col.notnull === 0 && col.pk === 0,\n ...ifDefined('default', col.dflt_value ?? undefined),\n };\n if (col.pk > 0) {\n pkColumns.push({ name: col.name, pk: col.pk });\n }\n }\n\n pkColumns.sort((a, b) => a.pk - b.pk);\n const primaryKey: PrimaryKey | undefined =\n pkColumns.length > 0 ? { columns: pkColumns.map((c) => c.name) } : undefined;\n\n const fkMap = new Map<number, FkAccumulator>();\n for (const fk of fkResult.rows) {\n const existing = fkMap.get(fk.id);\n if (existing) {\n existing.columns.push(fk.from);\n existing.referencedColumns.push(fk.to);\n } else {\n fkMap.set(fk.id, {\n columns: [fk.from],\n referencedTable: fk.table,\n referencedColumns: [fk.to],\n onDelete: fk.on_delete,\n onUpdate: fk.on_update,\n });\n }\n }\n const foreignKeys: readonly SqlForeignKeyIR[] = Array.from(fkMap.values()).map((fk) => ({\n columns: Object.freeze([...fk.columns]) as readonly string[],\n referencedTable: fk.referencedTable,\n referencedColumns: Object.freeze([...fk.referencedColumns]) as readonly string[],\n ...ifDefined('onDelete', mapSqliteReferentialAction(fk.onDelete)),\n ...ifDefined('onUpdate', mapSqliteReferentialAction(fk.onUpdate)),\n }));\n\n const uniques: SqlUniqueIR[] = [];\n const indexes: SqlIndexIR[] = [];\n\n for (const idx of indexListResult.rows) {\n // origin: 'c' = CREATE INDEX, 'u' = UNIQUE constraint, 'pk' = PRIMARY KEY\n const idxInfoResult = await driver.query<PragmaIndexInfoRow>(\n `PRAGMA index_info(\"${escapePragmaArg(idx.name)}\")`,\n );\n\n const idxColumns = idxInfoResult.rows.sort((a, b) => a.seqno - b.seqno).map((r) => r.name);\n\n if (idx.origin === 'u') {\n uniques.push({\n columns: Object.freeze([...idxColumns]) as readonly string[],\n name: idx.name,\n });\n } else if (idx.origin === 'c') {\n indexes.push({\n columns: Object.freeze([...idxColumns]) as readonly string[],\n name: idx.name,\n unique: idx.unique === 1,\n });\n }\n // Skip 'pk' origin — already captured in primaryKey\n }\n\n tables[tableName] = {\n name: tableName,\n columns,\n ...ifDefined('primaryKey', primaryKey),\n foreignKeys,\n uniques,\n indexes,\n };\n }\n\n return {\n tables,\n };\n }\n}\n\n// PRAGMA queries use the function-argument form (`PRAGMA table_info(\"name\")`)\n// which doesn't support `?` placeholders — the argument is part of the\n// statement name, not a bound parameter. We quote-escape the table name instead.\nfunction escapePragmaArg(name: string): string {\n return name.replace(/\"/g, '\"\"');\n}\n\nconst SQLITE_REFERENTIAL_ACTION_MAP: Record<string, SqlReferentialAction> = {\n 'NO ACTION': 'noAction',\n RESTRICT: 'restrict',\n CASCADE: 'cascade',\n 'SET NULL': 'setNull',\n 'SET DEFAULT': 'setDefault',\n};\n\nfunction mapSqliteReferentialAction(rule: string): SqlReferentialAction | undefined {\n const normalized = rule.toUpperCase();\n const mapped = SQLITE_REFERENTIAL_ACTION_MAP[normalized];\n if (mapped === undefined) {\n throw new Error(\n `Unknown SQLite referential action rule: \"${rule}\". ` +\n 'Expected one of: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.',\n );\n }\n if (mapped === 'noAction') return undefined;\n return mapped;\n}\n","import { APP_SPACE_ID } from '@prisma-next/framework-components/control';\nimport type {\n Adapter,\n AdapterProfile,\n AggregateExpr,\n AnyExpression,\n AnyFromSource,\n AnyQueryAst,\n BinaryExpr,\n ColumnRef,\n DeleteAst,\n InsertAst,\n InsertValue,\n JoinAst,\n JoinOnExpr,\n JsonArrayAggExpr,\n JsonObjectExpr,\n ListExpression,\n LiteralExpr,\n LoweredParam,\n LowererContext,\n NullCheckExpr,\n OperationExpr,\n OrderByItem,\n ProjectionItem,\n RawExpr,\n RawSqlLiteral,\n SelectAst,\n SqlQueryable,\n SubqueryExpr,\n TableSource,\n UpdateAst,\n WindowFuncExpr,\n} from '@prisma-next/sql-relational-core/ast';\nimport { isDdlNode } from '@prisma-next/sql-relational-core/ast';\nimport type { RawCodecInferer } from '@prisma-next/sql-relational-core/expression';\nimport type { SqliteDdlNode } from '@prisma-next/target-sqlite/ddl';\nimport { escapeLiteral, quoteIdentifier } from '@prisma-next/target-sqlite/sql-utils';\nimport { SqliteControlAdapter } from './control-adapter';\nimport { renderLoweredDdl } from './ddl-renderer';\nimport type { SqliteAdapterOptions, SqliteContract, SqliteLoweredStatement } from './types';\n\nconst defaultCapabilities = Object.freeze({\n sql: {\n orderBy: true,\n limit: true,\n lateral: false,\n jsonAgg: true,\n returning: true,\n enums: false,\n },\n});\n\nclass SqliteAdapterImpl implements Adapter<AnyQueryAst, SqliteContract, SqliteLoweredStatement> {\n readonly familyId = 'sql' as const;\n readonly targetId = 'sqlite' as const;\n\n readonly profile: AdapterProfile<'sqlite'>;\n\n constructor(options?: SqliteAdapterOptions) {\n const controlAdapter = new SqliteControlAdapter();\n this.profile = Object.freeze({\n id: options?.profileId ?? 'sqlite/default@1',\n target: 'sqlite',\n capabilities: defaultCapabilities,\n readMarker: (queryable: SqlQueryable) =>\n controlAdapter.readMarkerDiscriminated(\n {\n familyId: 'sql',\n targetId: 'sqlite',\n query: async <Row = Record<string, unknown>>(\n sql: string,\n params?: readonly unknown[],\n ) => {\n const result = await queryable.query<Row>(sql, params);\n return { rows: [...result.rows] };\n },\n close: async () => {},\n },\n APP_SPACE_ID,\n ),\n });\n }\n\n lower(\n ast: AnyQueryAst | SqliteDdlNode,\n context: LowererContext<SqliteContract>,\n ): SqliteLoweredStatement {\n if (isDdlNode(ast)) {\n return renderLoweredDdl(ast);\n }\n return renderLoweredSql(ast, context.contract);\n }\n}\n\n/** Codec-id lookup for bare-literal interpolations used by `fns.raw` on a sqlite client. Contributed as the descriptor's static `rawCodecInferer` slot. */\nexport const sqliteRawCodecInferer: RawCodecInferer = {\n inferCodec(value: RawSqlLiteral): string {\n switch (typeof value) {\n case 'number':\n return Number.isSafeInteger(value) && value % 1 === 0\n ? 'sqlite/integer@1'\n : 'sqlite/real@1';\n case 'bigint':\n return 'sqlite/bigint@1';\n case 'string':\n return 'sqlite/text@1';\n case 'boolean':\n return 'sqlite/integer@1';\n case 'object':\n if (value instanceof Uint8Array) return 'sqlite/blob@1';\n }\n throw new Error(\n 'unsupported JS value type for raw-SQL interpolation: wrap this value in `param(...)` with an explicit codec',\n );\n },\n};\n\n/**\n * Lower a SQL query AST into a SQLite-flavored `{ sql, params }` payload.\n *\n * Shared between the runtime adapter (`SqliteAdapterImpl.lower`) and the control adapter (`SqliteControlAdapter.lower`) so both produce byte-identical SQL for the same AST and contract.\n */\nexport function renderLoweredSql(\n ast: AnyQueryAst,\n contract: SqliteContract,\n): SqliteLoweredStatement {\n const collectedParamRefs = ast.collectParamRefs();\n const params: LoweredParam[] = [];\n for (const ref of collectedParamRefs) {\n params.push(\n ref.kind === 'prepared-param-ref'\n ? { kind: 'bind', name: ref.name }\n : { kind: 'literal', value: ref.value },\n );\n }\n\n let sql: string;\n\n const node = ast;\n switch (node.kind) {\n case 'select':\n sql = renderSelect(node, contract);\n break;\n case 'insert':\n sql = renderInsert(node, contract);\n break;\n case 'update':\n sql = renderUpdate(node, contract);\n break;\n case 'delete':\n sql = renderDelete(node, contract);\n break;\n default:\n throw new Error(`Unsupported AST node kind: ${(node as { kind: string }).kind}`);\n }\n\n return Object.freeze({ sql, params });\n}\n\nfunction renderLimitOffset(\n keyword: 'LIMIT' | 'OFFSET',\n value: SelectAst['limit'] | SelectAst['offset'],\n contract?: SqliteContract,\n): string {\n if (value === undefined) return '';\n if (typeof value === 'number') return `${keyword} ${value}`;\n return `${keyword} ${renderExpr(value, contract)}`;\n}\n\nfunction renderSelect(ast: SelectAst, contract: SqliteContract): string {\n const distinctPrefix = ast.distinct ? 'DISTINCT ' : '';\n const selectClause = `SELECT ${distinctPrefix}${renderProjection(ast.projection, contract)}`;\n const fromClause = `FROM ${renderSource(ast.from, contract)}`;\n\n const joinsClause = ast.joins?.length\n ? ast.joins.map((join) => renderJoin(join, contract)).join(' ')\n : '';\n\n const whereClause = ast.where ? `WHERE ${renderExpr(ast.where, contract)}` : '';\n const groupByClause = ast.groupBy?.length\n ? `GROUP BY ${ast.groupBy.map((expr) => renderExpr(expr, contract)).join(', ')}`\n : '';\n const havingClause = ast.having ? `HAVING ${renderExpr(ast.having, contract)}` : '';\n const orderClause = ast.orderBy?.length\n ? `ORDER BY ${ast.orderBy\n .map((order) => `${renderExpr(order.expr, contract)} ${order.dir.toUpperCase()}`)\n .join(', ')}`\n : '';\n const limitClause = renderLimitOffset('LIMIT', ast.limit, contract);\n const offsetClause = renderLimitOffset('OFFSET', ast.offset, contract);\n\n return [\n selectClause,\n fromClause,\n joinsClause,\n whereClause,\n groupByClause,\n havingClause,\n orderClause,\n limitClause,\n offsetClause,\n ]\n .filter((part) => part.length > 0)\n .join(' ')\n .trim();\n}\n\nfunction renderProjection(\n projection: ReadonlyArray<ProjectionItem>,\n contract?: SqliteContract,\n): string {\n return projection\n .map((item) => {\n const alias = quoteIdentifier(item.alias);\n if (item.expr.kind === 'literal') {\n return `${renderLiteral(item.expr)} AS ${alias}`;\n }\n return `${renderExpr(item.expr, contract)} AS ${alias}`;\n })\n .join(', ');\n}\n\nfunction qualifyTableFromNamespaceCoordinate(\n table: Pick<TableSource, 'name' | 'namespaceId'>,\n contract: SqliteContract,\n): string {\n if (table.namespaceId === undefined) {\n return quoteIdentifier(table.name);\n }\n const namespace = contract.storage.namespaces[table.namespaceId];\n if (namespace === undefined) {\n throw new Error(\n `Table \"${table.name}\" references namespace \"${table.namespaceId}\" which is not present on the contract`,\n );\n }\n const qualifyTable = namespace.qualifyTable;\n if (qualifyTable === undefined) {\n throw new Error(\n `Table \"${table.name}\" references namespace \"${table.namespaceId}\" which is not materialised for SQL rendering on the contract`,\n );\n }\n return qualifyTable.call(namespace, table.name);\n}\n\nfunction renderTableSource(source: TableSource, contract: SqliteContract): string {\n const qualified = qualifyTableFromNamespaceCoordinate(source, contract);\n if (!source.alias) {\n return qualified;\n }\n return `${qualified} AS ${quoteIdentifier(source.alias)}`;\n}\n\nfunction renderSource(source: AnyFromSource, contract: SqliteContract): string {\n const node = source;\n switch (node.kind) {\n case 'table-source':\n return renderTableSource(node, contract);\n case 'derived-table-source':\n return `(${renderSelect(node.query, contract)}) AS ${quoteIdentifier(node.alias)}`;\n default:\n throw new Error(`Unsupported source node kind: ${(node as { kind: string }).kind}`);\n }\n}\n\nfunction renderExpr(expr: AnyExpression, contract?: SqliteContract): string {\n const node = expr;\n switch (node.kind) {\n case 'column-ref':\n return renderColumn(node);\n case 'identifier-ref':\n return quoteIdentifier(node.name);\n case 'operation':\n return renderOperation(node, contract);\n case 'subquery':\n return renderSubqueryExpr(node, contract);\n case 'aggregate':\n return renderAggregateExpr(node, contract);\n case 'window-func':\n return renderWindowFuncExpr(node, contract);\n case 'json-object':\n return renderJsonObjectExpr(node, contract);\n case 'json-array-agg':\n return renderJsonArrayAggExpr(node, contract);\n case 'binary':\n return renderBinary(node, contract);\n case 'and':\n if (node.exprs.length === 0) {\n return 'TRUE';\n }\n return `(${node.exprs.map((part) => renderExpr(part, contract)).join(' AND ')})`;\n case 'or':\n if (node.exprs.length === 0) {\n return 'FALSE';\n }\n return `(${node.exprs.map((part) => renderExpr(part, contract)).join(' OR ')})`;\n case 'exists': {\n if (contract === undefined) {\n throw new Error('EXISTS subquery rendering requires a Sqlite contract');\n }\n const notKeyword = node.notExists ? 'NOT ' : '';\n const subquery = renderSelect(node.subquery, contract);\n return `${notKeyword}EXISTS (${subquery})`;\n }\n case 'null-check':\n return renderNullCheck(node, contract);\n case 'not':\n return `NOT (${renderExpr(node.expr, contract)})`;\n case 'param-ref':\n case 'prepared-param-ref':\n return '?';\n case 'literal':\n return renderLiteral(node);\n case 'list':\n return renderListLiteral(node);\n case 'raw-expr':\n return renderRawExpr(node, contract);\n default:\n throw new Error(`Unsupported expression node kind: ${(node as { kind: string }).kind}`);\n }\n}\n\nfunction renderRawExpr(node: RawExpr, contract?: SqliteContract): string {\n return node.parts\n .map((part) => (typeof part === 'string' ? part : renderExpr(part, contract)))\n .join('');\n}\n\n// `excluded` is a pseudo-table in ON CONFLICT DO UPDATE that references the row proposed for insertion. It is not quoted because it's a keyword.\nfunction renderColumn(ref: ColumnRef): string {\n if (ref.table === 'excluded') {\n return `excluded.${quoteIdentifier(ref.column)}`;\n }\n return `${quoteIdentifier(ref.table)}.${quoteIdentifier(ref.column)}`;\n}\n\nfunction renderLiteral(expr: LiteralExpr): string {\n if (typeof expr.value === 'string') {\n return `'${escapeLiteral(expr.value)}'`;\n }\n if (typeof expr.value === 'number' || typeof expr.value === 'boolean') {\n return String(expr.value);\n }\n if (typeof expr.value === 'bigint') {\n return String(expr.value);\n }\n if (expr.value === null || expr.value === undefined) {\n return 'NULL';\n }\n if (expr.value instanceof Date) {\n return `'${escapeLiteral(expr.value.toISOString())}'`;\n }\n const json = JSON.stringify(expr.value);\n if (json === undefined) {\n return 'NULL';\n }\n return `'${escapeLiteral(json)}'`;\n}\n\nfunction renderOperation(expr: OperationExpr, contract?: SqliteContract): string {\n const self = renderExpr(expr.self, contract);\n const args = expr.args.map((arg) => renderExpr(arg, contract));\n\n let result = expr.lowering.template;\n result = result.replace(/\\{\\{self\\}\\}/g, self);\n for (let i = 0; i < args.length; i++) {\n result = result.replace(new RegExp(`\\\\{\\\\{arg${i}\\\\}\\\\}`, 'g'), args[i] ?? '');\n }\n\n return result;\n}\n\nfunction renderSubqueryExpr(expr: SubqueryExpr, contract?: SqliteContract): string {\n if (expr.query.projection.length !== 1) {\n throw new Error('Subquery expressions must project exactly one column');\n }\n if (contract === undefined) {\n throw new Error('Subquery expression rendering requires a Sqlite contract');\n }\n return `(${renderSelect(expr.query, contract)})`;\n}\n\nfunction renderNullCheck(expr: NullCheckExpr, contract?: SqliteContract): string {\n const rendered = renderExpr(expr.expr, contract);\n const renderedExpr =\n expr.expr.kind === 'operation' || expr.expr.kind === 'subquery' ? `(${rendered})` : rendered;\n return expr.isNull ? `${renderedExpr} IS NULL` : `${renderedExpr} IS NOT NULL`;\n}\n\nfunction renderBinary(expr: BinaryExpr, contract?: SqliteContract): string {\n if (expr.right.kind === 'list' && expr.right.values.length === 0) {\n if (expr.op === 'in') {\n return 'FALSE';\n }\n if (expr.op === 'notIn') {\n return 'TRUE';\n }\n }\n\n const leftExpr = expr.left;\n const left = renderExpr(leftExpr, contract);\n const leftRendered =\n leftExpr.kind === 'operation' || leftExpr.kind === 'subquery' ? `(${left})` : left;\n\n const rightNode = expr.right;\n let right: string;\n switch (rightNode.kind) {\n case 'list':\n right = renderListLiteral(rightNode);\n break;\n case 'literal':\n right = renderLiteral(rightNode);\n break;\n case 'column-ref':\n right = renderColumn(rightNode);\n break;\n case 'param-ref':\n case 'prepared-param-ref':\n right = '?';\n break;\n default:\n right = renderExpr(rightNode, contract);\n break;\n }\n\n const operatorMap: Record<BinaryExpr['op'], string> = {\n eq: '=',\n neq: '!=',\n gt: '>',\n lt: '<',\n gte: '>=',\n lte: '<=',\n like: 'LIKE',\n in: 'IN',\n notIn: 'NOT IN',\n };\n\n return `${leftRendered} ${operatorMap[expr.op]} ${right}`;\n}\n\nfunction renderListLiteral(expr: ListExpression): string {\n if (expr.values.length === 0) {\n return '(NULL)';\n }\n const values = expr.values\n .map((v) => {\n if (v.kind === 'param-ref' || v.kind === 'prepared-param-ref') return '?';\n if (v.kind === 'literal') return renderLiteral(v);\n return renderExpr(v);\n })\n .join(', ');\n return `(${values})`;\n}\n\nfunction renderAggregateExpr(expr: AggregateExpr, contract?: SqliteContract): string {\n const fn = expr.fn.toUpperCase();\n if (!expr.expr) {\n return `${fn}(*)`;\n }\n return `${fn}(${renderExpr(expr.expr, contract)})`;\n}\n\nfunction renderWindowFuncExpr(expr: WindowFuncExpr, contract?: SqliteContract): string {\n const fn = expr.fn.toUpperCase();\n const args = expr.args.map((arg) => renderExpr(arg, contract)).join(', ');\n const partitionClause =\n expr.partitionBy && expr.partitionBy.length > 0\n ? `PARTITION BY ${expr.partitionBy.map((e) => renderExpr(e, contract)).join(', ')}`\n : '';\n const orderClause =\n expr.orderBy && expr.orderBy.length > 0\n ? `ORDER BY ${renderOrderByItems(expr.orderBy, contract)}`\n : '';\n const over = [partitionClause, orderClause].filter((part) => part.length > 0).join(' ');\n return `${fn}(${args}) OVER (${over})`;\n}\n\nfunction renderJsonObjectExpr(expr: JsonObjectExpr, contract?: SqliteContract): string {\n const args = expr.entries\n .flatMap((entry): [string, string] => {\n const key = `'${escapeLiteral(entry.key)}'`;\n if (entry.value.kind === 'literal') {\n return [key, renderLiteral(entry.value)];\n }\n return [key, renderExpr(entry.value, contract)];\n })\n .join(', ');\n return `json_object(${args})`;\n}\n\nfunction renderOrderByItems(items: ReadonlyArray<OrderByItem>, contract?: SqliteContract): string {\n return items\n .map((item) => `${renderExpr(item.expr, contract)} ${item.dir.toUpperCase()}`)\n .join(', ');\n}\n\nfunction renderJsonArrayAggExpr(expr: JsonArrayAggExpr, contract?: SqliteContract): string {\n const aggregateOrderBy =\n expr.orderBy && expr.orderBy.length > 0\n ? ` ORDER BY ${renderOrderByItems(expr.orderBy, contract)}`\n : '';\n const aggregated = `json_group_array(${renderExpr(expr.expr, contract)}${aggregateOrderBy})`;\n if (expr.onEmpty === 'emptyArray') {\n return `coalesce(${aggregated}, '[]')`;\n }\n return aggregated;\n}\n\nfunction renderJoin(join: JoinAst, contract?: SqliteContract): string {\n if (contract === undefined) {\n throw new Error('JOIN rendering requires a Sqlite contract');\n }\n const joinType = join.joinType.toUpperCase();\n const source = renderSource(join.source, contract);\n const onClause = renderJoinOn(join.on, contract);\n return `${joinType} JOIN ${source} ON ${onClause}`;\n}\n\nfunction renderJoinOn(on: JoinOnExpr, contract?: SqliteContract): string {\n if (on.kind === 'eq-col-join-on') {\n return `${renderColumn(on.left)} = ${renderColumn(on.right)}`;\n }\n return renderExpr(on, contract);\n}\n\nfunction renderInsertValue(value: InsertValue): string {\n switch (value.kind) {\n case 'param-ref':\n case 'prepared-param-ref':\n return '?';\n case 'column-ref':\n return renderColumn(value);\n case 'raw-expr':\n return renderExpr(value);\n case 'default-value':\n throw new Error('SQLite does not support DEFAULT as a value in INSERT ... VALUES');\n default:\n throw new Error(`Unsupported value node in INSERT: ${(value as { kind: string }).kind}`);\n }\n}\n\nfunction renderInsert(ast: InsertAst, contract: SqliteContract): string {\n const table = qualifyTableFromNamespaceCoordinate(ast.table, contract);\n const rows = ast.rows;\n if (rows.length === 0) {\n throw new Error('INSERT requires at least one row');\n }\n\n const firstRow = rows[0] as Readonly<Record<string, InsertValue>>;\n const columnOrder = Object.keys(firstRow);\n\n let insertClause: string;\n if (columnOrder.length === 0) {\n insertClause = `INSERT INTO ${table} DEFAULT VALUES`;\n } else {\n const columns = columnOrder.map((column) => quoteIdentifier(column));\n const values = rows\n .map((row) => {\n const renderedRow = columnOrder.map((column) => {\n const value = row[column];\n if (value === undefined) {\n throw new Error(`Missing value for column \"${column}\" in INSERT row`);\n }\n return renderInsertValue(value);\n });\n return `(${renderedRow.join(', ')})`;\n })\n .join(', ');\n insertClause = `INSERT INTO ${table} (${columns.join(', ')}) VALUES ${values}`;\n }\n\n let onConflictClause = '';\n if (ast.onConflict) {\n const conflictColumns = ast.onConflict.columns.map((col) => quoteIdentifier(col.column));\n if (conflictColumns.length === 0) {\n throw new Error('INSERT onConflict requires at least one conflict column');\n }\n\n const action = ast.onConflict.action;\n switch (action.kind) {\n case 'do-nothing':\n onConflictClause = ` ON CONFLICT (${conflictColumns.join(', ')}) DO NOTHING`;\n break;\n case 'do-update-set': {\n const updates = Object.entries(action.set).map(([colName, value]) => {\n return `${quoteIdentifier(colName)} = ${renderExpr(value, contract)}`;\n });\n onConflictClause = ` ON CONFLICT (${conflictColumns.join(', ')}) DO UPDATE SET ${updates.join(', ')}`;\n break;\n }\n default:\n throw new Error(`Unsupported onConflict action: ${(action as { kind: string }).kind}`);\n }\n }\n\n const returningClause = renderReturning(ast.returning);\n\n return `${insertClause}${onConflictClause}${returningClause}`;\n}\n\nfunction renderUpdate(ast: UpdateAst, contract: SqliteContract): string {\n const table = qualifyTableFromNamespaceCoordinate(ast.table, contract);\n const setClauses = Object.entries(ast.set).map(([col, val]) => {\n return `${quoteIdentifier(col)} = ${renderExpr(val, contract)}`;\n });\n\n const whereClause = ast.where ? ` WHERE ${renderExpr(ast.where, contract)}` : '';\n const returningClause = renderReturning(ast.returning);\n\n return `UPDATE ${table} SET ${setClauses.join(', ')}${whereClause}${returningClause}`;\n}\n\nfunction renderDelete(ast: DeleteAst, contract: SqliteContract): string {\n const table = qualifyTableFromNamespaceCoordinate(ast.table, contract);\n const whereClause = ast.where ? ` WHERE ${renderExpr(ast.where)}` : '';\n const returningClause = renderReturning(ast.returning);\n\n return `DELETE FROM ${table}${whereClause}${returningClause}`;\n}\n\nfunction renderReturning(returning: ReadonlyArray<ProjectionItem> | undefined): string {\n if (!returning?.length) {\n return '';\n }\n return ` RETURNING ${returning\n .map((item) => {\n if (item.expr.kind === 'column-ref') {\n const rendered = `${quoteIdentifier(item.expr.table)}.${quoteIdentifier(item.expr.column)}`;\n return item.expr.column === item.alias\n ? rendered\n : `${rendered} AS ${quoteIdentifier(item.alias)}`;\n }\n return `${renderExpr(item.expr)} AS ${quoteIdentifier(item.alias)}`;\n })\n .join(', ')}`;\n}\n\nexport function createSqliteAdapter(options?: SqliteAdapterOptions) {\n return Object.freeze(new SqliteAdapterImpl(options));\n}\n"],"mappings":"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"}
|
package/src/core/ddl-renderer.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { REFERENTIAL_ACTION_SQL } from '@prisma-next/sql-contract/referential-action-sql';
|
|
2
|
-
import type {
|
|
3
|
-
DdlColumn,
|
|
4
|
-
DdlColumnDefaultVisitor,
|
|
5
|
-
DdlTableConstraint,
|
|
6
|
-
ForeignKeyConstraint,
|
|
7
|
-
FunctionColumnDefault,
|
|
8
|
-
LiteralColumnDefault,
|
|
9
|
-
PrimaryKeyConstraint,
|
|
10
|
-
UniqueConstraint,
|
|
11
|
-
} from '@prisma-next/sql-relational-core/ast';
|
|
12
|
-
import type {
|
|
13
|
-
SqliteCreateTable,
|
|
14
|
-
SqliteDdlNode,
|
|
15
|
-
SqliteDdlVisitor,
|
|
16
|
-
} from '@prisma-next/target-sqlite/ddl';
|
|
17
|
-
import { escapeLiteral, quoteIdentifier } from '@prisma-next/target-sqlite/sql-utils';
|
|
18
|
-
import type { SqliteLoweredStatement } from './types';
|
|
19
|
-
|
|
20
|
-
function quoteQualifiedIdentifier(name: string): string {
|
|
21
|
-
return name.split('.').map(quoteIdentifier).join('.');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function renderPrimaryKeyConstraint(constraint: PrimaryKeyConstraint): string {
|
|
25
|
-
const cols = constraint.columns.map(quoteIdentifier).join(', ');
|
|
26
|
-
if (constraint.name !== undefined) {
|
|
27
|
-
return `CONSTRAINT ${quoteIdentifier(constraint.name)} PRIMARY KEY (${cols})`;
|
|
28
|
-
}
|
|
29
|
-
return `PRIMARY KEY (${cols})`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function renderForeignKeyConstraint(constraint: ForeignKeyConstraint): string {
|
|
33
|
-
const cols = constraint.columns.map(quoteIdentifier).join(', ');
|
|
34
|
-
const refCols = constraint.refColumns.map(quoteIdentifier).join(', ');
|
|
35
|
-
let sql = `FOREIGN KEY (${cols}) REFERENCES ${quoteQualifiedIdentifier(constraint.refTable)} (${refCols})`;
|
|
36
|
-
if (constraint.onDelete !== undefined) {
|
|
37
|
-
sql += ` ON DELETE ${REFERENTIAL_ACTION_SQL[constraint.onDelete]}`;
|
|
38
|
-
}
|
|
39
|
-
if (constraint.onUpdate !== undefined) {
|
|
40
|
-
sql += ` ON UPDATE ${REFERENTIAL_ACTION_SQL[constraint.onUpdate]}`;
|
|
41
|
-
}
|
|
42
|
-
if (constraint.name !== undefined) {
|
|
43
|
-
sql = `CONSTRAINT ${quoteIdentifier(constraint.name)} ${sql}`;
|
|
44
|
-
}
|
|
45
|
-
return sql;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function renderUniqueConstraint(constraint: UniqueConstraint): string {
|
|
49
|
-
const cols = constraint.columns.map(quoteIdentifier).join(', ');
|
|
50
|
-
if (constraint.name !== undefined) {
|
|
51
|
-
return `CONSTRAINT ${quoteIdentifier(constraint.name)} UNIQUE (${cols})`;
|
|
52
|
-
}
|
|
53
|
-
return `UNIQUE (${cols})`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function renderTableConstraint(constraint: DdlTableConstraint): string {
|
|
57
|
-
switch (constraint.kind) {
|
|
58
|
-
case 'primary-key':
|
|
59
|
-
return renderPrimaryKeyConstraint(constraint);
|
|
60
|
-
case 'foreign-key':
|
|
61
|
-
return renderForeignKeyConstraint(constraint);
|
|
62
|
-
case 'unique':
|
|
63
|
-
return renderUniqueConstraint(constraint);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
class SqliteDdlVisitorImpl implements SqliteDdlVisitor<string> {
|
|
68
|
-
createTable(node: SqliteCreateTable): string {
|
|
69
|
-
const ifNotExists = node.ifNotExists ? 'IF NOT EXISTS ' : '';
|
|
70
|
-
const tableRef = quoteIdentifier(node.table);
|
|
71
|
-
const columnDefs = node.columns.map((column) => renderColumn(column));
|
|
72
|
-
const constraintDefs =
|
|
73
|
-
node.constraints !== undefined ? node.constraints.map(renderTableConstraint) : [];
|
|
74
|
-
const allDefs = [...columnDefs, ...constraintDefs].join(',\n ');
|
|
75
|
-
return `CREATE TABLE ${ifNotExists}${tableRef} (\n ${allDefs}\n)`;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const defaultVisitor: DdlColumnDefaultVisitor<string> = {
|
|
80
|
-
// SQLite has no `jsonb` / `json` column type, so the ctx is unused — but
|
|
81
|
-
// the visitor interface requires it for cross-dialect symmetry with the
|
|
82
|
-
// Postgres renderer, which uses ctx.nativeType to emit JSON casts.
|
|
83
|
-
literal(node: LiteralColumnDefault, _ctx): string {
|
|
84
|
-
const { value } = node;
|
|
85
|
-
if (value instanceof Date) {
|
|
86
|
-
return `DEFAULT '${escapeLiteral(value.toISOString())}'`;
|
|
87
|
-
}
|
|
88
|
-
if (typeof value === 'string') {
|
|
89
|
-
return `DEFAULT '${escapeLiteral(value)}'`;
|
|
90
|
-
}
|
|
91
|
-
if (typeof value === 'number') {
|
|
92
|
-
return `DEFAULT ${String(value)}`;
|
|
93
|
-
}
|
|
94
|
-
if (typeof value === 'boolean') {
|
|
95
|
-
// SQLite has no boolean type; store as 0/1 to match the pre-slice format.
|
|
96
|
-
return `DEFAULT ${value ? '1' : '0'}`;
|
|
97
|
-
}
|
|
98
|
-
if (typeof value === 'bigint') {
|
|
99
|
-
// Defensive: bigint is not in ColumnDefaultLiteralInputValue but guard
|
|
100
|
-
// against JSON.stringify throwing if one ever reaches this path.
|
|
101
|
-
return `DEFAULT ${String(value)}`;
|
|
102
|
-
}
|
|
103
|
-
if (value === null) {
|
|
104
|
-
return 'DEFAULT NULL';
|
|
105
|
-
}
|
|
106
|
-
return `DEFAULT '${escapeLiteral(JSON.stringify(value))}'`;
|
|
107
|
-
},
|
|
108
|
-
function(node: FunctionColumnDefault, _ctx): string {
|
|
109
|
-
if (node.expression === 'autoincrement()') {
|
|
110
|
-
return '';
|
|
111
|
-
}
|
|
112
|
-
if (node.expression === 'now()') return "DEFAULT (datetime('now'))";
|
|
113
|
-
return `DEFAULT (${node.expression})`;
|
|
114
|
-
},
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
function renderColumn(column: DdlColumn): string {
|
|
118
|
-
// The `tableToDdlParts` helper in issue-planner.ts encodes the
|
|
119
|
-
// `INTEGER PRIMARY KEY AUTOINCREMENT` inline column definition directly into
|
|
120
|
-
// `DdlColumn.type` (rather than setting a column-level flag) because
|
|
121
|
-
// `DdlColumn` has no SQLite-specific autoincrement field. Both sites must
|
|
122
|
-
// stay in sync: when one changes the encoded string the other must change
|
|
123
|
-
// the detection. The structural fix is tracked in TML-2866.
|
|
124
|
-
if (column.type.includes('AUTOINCREMENT')) {
|
|
125
|
-
return `${quoteIdentifier(column.name)} ${column.type}`;
|
|
126
|
-
}
|
|
127
|
-
const parts = [quoteIdentifier(column.name), column.type];
|
|
128
|
-
if (column.notNull) {
|
|
129
|
-
parts.push('NOT NULL');
|
|
130
|
-
}
|
|
131
|
-
if (column.primaryKey) {
|
|
132
|
-
parts.push('PRIMARY KEY');
|
|
133
|
-
}
|
|
134
|
-
const defaultClause = column.default
|
|
135
|
-
? column.default.accept(defaultVisitor, { nativeType: column.type })
|
|
136
|
-
: '';
|
|
137
|
-
if (defaultClause.length > 0) {
|
|
138
|
-
parts.push(defaultClause);
|
|
139
|
-
}
|
|
140
|
-
return parts.join(' ');
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export function renderLoweredDdl(ast: SqliteDdlNode): SqliteLoweredStatement {
|
|
144
|
-
const sql = ast.accept(new SqliteDdlVisitorImpl());
|
|
145
|
-
return Object.freeze({ sql, params: Object.freeze([]) });
|
|
146
|
-
}
|