qubu 0.0.0 → 0.3.3
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/canonical-BbnqavJm.mjs +972 -0
- package/dist/codegen.d.mts +107 -0
- package/dist/codegen.mjs +1199 -0
- package/dist/column-CXMxx8Hq.mjs +118 -0
- package/dist/complete-D5Djh-zo.mjs +1788 -0
- package/dist/complete-types-BdFqUfbb.d.mts +371 -0
- package/dist/core.d.mts +33 -0
- package/dist/core.mjs +36 -0
- package/dist/ddl.d.mts +118 -0
- package/dist/ddl.mjs +1120 -0
- package/dist/dialect-b2-Z6uBF.mjs +13 -0
- package/dist/diff.d.mts +2 -0
- package/dist/diff.mjs +883 -0
- package/dist/drizzle-mysql.d.mts +24 -0
- package/dist/drizzle-mysql.mjs +72 -0
- package/dist/drizzle-postgres.d.mts +24 -0
- package/dist/drizzle-postgres.mjs +73 -0
- package/dist/drizzle-sqlite.d.mts +24 -0
- package/dist/drizzle-sqlite.mjs +82 -0
- package/dist/drizzle.d.mts +13 -0
- package/dist/drizzle.mjs +2 -0
- package/dist/errors-BGCoLe_r.mjs +14 -0
- package/dist/errors-Dxv73YJu.mjs +26 -0
- package/dist/explain-CkIK13L_.mjs +98 -0
- package/dist/index-Ds7-mhJi.d.mts +146 -0
- package/dist/index-Dug5HnLB.d.mts +204 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +1276 -0
- package/dist/introspection.d.mts +117 -0
- package/dist/introspection.mjs +4341 -0
- package/dist/json-CUZlv4HT.mjs +169 -0
- package/dist/migration.d.mts +215 -0
- package/dist/migration.mjs +1161 -0
- package/dist/mysql-DqkqXB6A.mjs +355 -0
- package/dist/mysql.d.mts +5 -0
- package/dist/mysql.mjs +50 -0
- package/dist/naming-QVCOnSj2.mjs +20 -0
- package/dist/omit-OxV58AwX.mjs +5 -0
- package/dist/on-conflict-BxnxubMb.mjs +143 -0
- package/dist/postgres-DEBBeh52.mjs +235 -0
- package/dist/postgres.d.mts +123 -0
- package/dist/postgres.mjs +52 -0
- package/dist/registry-BufIskVN.mjs +569 -0
- package/dist/relational-DCZrrNia.mjs +77 -0
- package/dist/runtime-BTr-MTlo.mjs +193 -0
- package/dist/schema.d.mts +2 -0
- package/dist/schema.mjs +5 -0
- package/dist/serialize-PF1cfH2P.mjs +556 -0
- package/dist/snapshot-CWPgzxNx.mjs +392 -0
- package/dist/snapshot.d.mts +4 -0
- package/dist/snapshot.mjs +8 -0
- package/dist/source-DUoJVXmL.mjs +68 -0
- package/dist/sqlite-BU6DBxef.mjs +320 -0
- package/dist/sqlite.d.mts +5 -0
- package/dist/sqlite.mjs +48 -0
- package/dist/standard-BTVYKh_F.mjs +12 -0
- package/dist/table-llv9tsZ8.mjs +384 -0
- package/dist/types-4Q076HKo.d.mts +3636 -0
- package/dist/types-BX0mckiU.d.mts +644 -0
- package/dist/types-CO1KaRNc.d.mts +46 -0
- package/dist/types-Cec0xzo4.mjs +116 -0
- package/dist/value-BvilP0oz.mjs +29 -0
- package/dist/vite/ambient.d.ts +449 -0
- package/dist/vite.d.mts +35 -0
- package/dist/vite.mjs +498 -0
- package/docs/config.json +21 -0
- package/docs/dialects-and-execution.md +427 -0
- package/docs/getting-started.md +96 -0
- package/docs/guides/compose-queries.md +225 -0
- package/docs/guides/drizzle.md +129 -0
- package/docs/guides/extensions/dialects.md +40 -0
- package/docs/guides/extensions/overview.md +36 -0
- package/docs/guides/extensions/sources-and-clauses.md +82 -0
- package/docs/guides/extensions/typed-expressions.md +94 -0
- package/docs/guides/extensions/unsafe-syntax.md +27 -0
- package/docs/guides/json.md +65 -0
- package/docs/guides/mutations.md +138 -0
- package/docs/guides/select/conditions.md +110 -0
- package/docs/guides/select/grouping-and-windows.md +82 -0
- package/docs/guides/select/ordering-and-pagination.md +78 -0
- package/docs/guides/select/overview.md +139 -0
- package/docs/guides/sql-templates.md +157 -0
- package/docs/guides/vite-plugin.md +92 -0
- package/docs/index.md +111 -0
- package/docs/query-model/fragments.md +109 -0
- package/docs/query-model/result-shapes.md +125 -0
- package/docs/query-model/source-scope.md +182 -0
- package/docs/reference/introspection-support.md +196 -0
- package/docs/reference/mysql-snapshot.md +55 -0
- package/docs/reference/postgres-snapshot.md +61 -0
- package/docs/reference/sqlite-snapshot.md +53 -0
- package/docs/reference/supported-surface.md +104 -0
- package/docs/schema/catalog-model.md +58 -0
- package/docs/schema/code-generation.md +139 -0
- package/docs/schema/columns-and-writes.md +130 -0
- package/docs/schema/constraints-and-indexes.md +180 -0
- package/docs/schema/ddl-emission.md +75 -0
- package/docs/schema/diff.md +75 -0
- package/docs/schema/introspection.md +214 -0
- package/docs/schema/migration-plans.md +76 -0
- package/docs/schema/snapshots.md +93 -0
- package/docs/schema/storage-and-schema-sql.md +104 -0
- package/docs/schema/tables-and-names.md +106 -0
- package/docs/sql-semantic-types.md +141 -0
- package/docs/troubleshooting.md +151 -0
- package/package.json +132 -10
- package/skills/qubu/SKILL.md +42 -0
- package/skills/qubu/agents/openai.yaml +6 -0
- package/readme.md +0 -1
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
import { t as standardDialect } from "./standard-BTVYKh_F.mjs";
|
|
2
|
+
import { r as isColumnReference } from "./column-CXMxx8Hq.mjs";
|
|
3
|
+
import { _ as isUnsafeSchemaSql, k as generatedSchemaObjectName, n as defaultSchemaNamingPolicy, y as renderSchemaExpression } from "./registry-BufIskVN.mjs";
|
|
4
|
+
import { t as createSchemaDialect } from "./dialect-b2-Z6uBF.mjs";
|
|
5
|
+
import { a as toSnapshotJsonValue, f as schemaSnapshotFormat, i as schemaSnapshotDigest, o as SnapshotValidationError, r as encodeCanonicalSnapshot, s as assertSchemaSnapshot, u as neutralSnapshotDialect } from "./canonical-BbnqavJm.mjs";
|
|
6
|
+
//#region src/snapshot/serialize.ts
|
|
7
|
+
const neutralSchemaDialect = createSchemaDialect(Object.freeze({
|
|
8
|
+
...standardDialect(),
|
|
9
|
+
name: neutralSnapshotDialect.name
|
|
10
|
+
}), { version: 1 });
|
|
11
|
+
/** Error raised when a live Qubu schema cannot be represented as a snapshot. */
|
|
12
|
+
var SnapshotSerializationError = class extends SnapshotValidationError {
|
|
13
|
+
name = "SnapshotSerializationError";
|
|
14
|
+
};
|
|
15
|
+
/** Create a neutral or adapter-owned immutable snapshot from a live schema. */
|
|
16
|
+
function createSchemaSnapshot(schema, options = {}) {
|
|
17
|
+
const result = tryCreateSchemaSnapshot(schema, options);
|
|
18
|
+
if (!result.ok) throw new SnapshotSerializationError(result.diagnostics);
|
|
19
|
+
return result.value;
|
|
20
|
+
}
|
|
21
|
+
/** Non-throwing form of {@link createSchemaSnapshot}. */
|
|
22
|
+
function tryCreateSchemaSnapshot(schema, options = {}) {
|
|
23
|
+
const diagnostics = [];
|
|
24
|
+
if (!isSchemaRoot(schema)) return {
|
|
25
|
+
ok: false,
|
|
26
|
+
diagnostics: [{
|
|
27
|
+
code: "invalid-schema",
|
|
28
|
+
message: "Snapshot input must be a Qubu schema registry",
|
|
29
|
+
path: []
|
|
30
|
+
}]
|
|
31
|
+
};
|
|
32
|
+
if (options.adapter !== void 0 && options.dialect !== void 0 && (options.adapter.dialect.name !== options.dialect.name || options.adapter.dialect.schema.version !== options.dialect.schema.version)) return {
|
|
33
|
+
ok: false,
|
|
34
|
+
diagnostics: [{
|
|
35
|
+
code: "dialect-mismatch",
|
|
36
|
+
message: "Snapshot adapter and explicit dialect must agree",
|
|
37
|
+
path: ["dialect"],
|
|
38
|
+
relatedPaths: [["adapter", "dialect"]]
|
|
39
|
+
}]
|
|
40
|
+
};
|
|
41
|
+
const adapter = options.adapter;
|
|
42
|
+
const dialect = options.dialect ?? adapter?.dialect ?? neutralSchemaDialect;
|
|
43
|
+
const namingPolicy = options.namingPolicy ?? dialect.schema.namingPolicy ?? Object.freeze({
|
|
44
|
+
name: schema.namingPolicy.tableName === defaultSchemaNamingPolicy.tableName ? "snake-case" : "custom",
|
|
45
|
+
version: schema.namingPolicy.version ?? 1
|
|
46
|
+
});
|
|
47
|
+
const tableEntries = Object.entries(schema.registry);
|
|
48
|
+
const tableIds = /* @__PURE__ */ new Map();
|
|
49
|
+
const tablesById = /* @__PURE__ */ new Map();
|
|
50
|
+
const validate = adapter?.dialect.schema.validate ?? dialect.schema.validate;
|
|
51
|
+
if (validate !== void 0) try {
|
|
52
|
+
diagnostics.push(...validate(schema, {
|
|
53
|
+
path: [],
|
|
54
|
+
dialect
|
|
55
|
+
}));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
diagnostics.push({
|
|
58
|
+
code: "invalid-schema",
|
|
59
|
+
message: error instanceof Error ? error.message : String(error),
|
|
60
|
+
path: []
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
for (const [id, entry] of tableEntries) {
|
|
64
|
+
tableIds.set(entry.table, id);
|
|
65
|
+
tablesById.set(id, entry.table);
|
|
66
|
+
}
|
|
67
|
+
const tables = tableEntries.map(([id, entry]) => serializeTable(id, entry.table, entry.physicalName, tableIds, tablesById, dialect, options, diagnostics)).filter((table) => table !== void 0).sort(compareId);
|
|
68
|
+
if (diagnostics.length > 0) return {
|
|
69
|
+
ok: false,
|
|
70
|
+
diagnostics: Object.freeze(diagnostics)
|
|
71
|
+
};
|
|
72
|
+
const rawSnapshot = {
|
|
73
|
+
format: schemaSnapshotFormat,
|
|
74
|
+
version: 1,
|
|
75
|
+
dialect: Object.freeze({
|
|
76
|
+
name: dialect.name,
|
|
77
|
+
version: dialect.schema.version
|
|
78
|
+
}),
|
|
79
|
+
namingPolicy: Object.freeze({
|
|
80
|
+
name: namingPolicy.name,
|
|
81
|
+
version: namingPolicy.version ?? 1
|
|
82
|
+
}),
|
|
83
|
+
...schema.namespace === void 0 ? {} : { namespace: schema.namespace },
|
|
84
|
+
tables
|
|
85
|
+
};
|
|
86
|
+
try {
|
|
87
|
+
return {
|
|
88
|
+
ok: true,
|
|
89
|
+
value: assertSchemaSnapshot(rawSnapshot)
|
|
90
|
+
};
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (error instanceof SnapshotValidationError) return {
|
|
93
|
+
ok: false,
|
|
94
|
+
diagnostics: error.diagnostics
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
ok: false,
|
|
98
|
+
diagnostics: [{
|
|
99
|
+
code: "invalid-schema",
|
|
100
|
+
message: error instanceof Error ? error.message : String(error),
|
|
101
|
+
path: []
|
|
102
|
+
}]
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Encode a valid snapshot using fixed property order and canonical JSON. */
|
|
107
|
+
function encodeSchemaSnapshot(snapshot) {
|
|
108
|
+
const canonical = assertSchemaSnapshot(snapshot);
|
|
109
|
+
return encodeCanonicalSnapshot(canonical);
|
|
110
|
+
}
|
|
111
|
+
/** Alias used by tooling packages that call the operation serialization. */
|
|
112
|
+
const serializeSchema = createSchemaSnapshot;
|
|
113
|
+
/** Alias for the canonical snapshot encoder. */
|
|
114
|
+
const encodeSnapshot = encodeSchemaSnapshot;
|
|
115
|
+
/** Alias for the canonical snapshot digest helper. */
|
|
116
|
+
const digestSchemaSnapshot = schemaSnapshotDigest;
|
|
117
|
+
function serializeTable(id, table, physicalName, tableIds, tablesById, dialect, options, diagnostics) {
|
|
118
|
+
const definitions = table.definitions;
|
|
119
|
+
const tableMetadata = table;
|
|
120
|
+
return {
|
|
121
|
+
id,
|
|
122
|
+
physicalName,
|
|
123
|
+
columns: Object.entries(definitions).map(([fieldName, definition]) => serializeColumn(fieldName, definition, table.sqlNames[fieldName] ?? fieldName, dialect, options, diagnostics)).sort(compareId),
|
|
124
|
+
constraints: Object.entries(tableMetadata.constraints).map(([constraintId, constraint]) => serializeConstraint(constraintId, constraint, table, tableIds, tablesById, dialect, options, diagnostics)).filter((constraint) => constraint !== void 0).sort(compareId),
|
|
125
|
+
indexes: Object.entries(tableMetadata.indexes).map(([indexId, indexMetadata]) => serializeIndex(indexId, indexMetadata, table, dialect, options, diagnostics)).filter((index) => index !== void 0).sort(compareId)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function serializeColumn(id, definition, physicalName, dialect, options, diagnostics) {
|
|
129
|
+
const storage = definition.storage ? encodeStorage(definition.storage, dialect, [
|
|
130
|
+
"tables",
|
|
131
|
+
id,
|
|
132
|
+
"columns",
|
|
133
|
+
id,
|
|
134
|
+
"storage"
|
|
135
|
+
], options, diagnostics) : void 0;
|
|
136
|
+
const defaultValue = definition.default ? encodeDefault(definition.default, dialect, [
|
|
137
|
+
"columns",
|
|
138
|
+
id,
|
|
139
|
+
"default"
|
|
140
|
+
], options, diagnostics) : void 0;
|
|
141
|
+
const generatedColumn = definition.generatedColumn ? encodeGenerated(definition.generatedColumn, dialect, [
|
|
142
|
+
"columns",
|
|
143
|
+
id,
|
|
144
|
+
"generatedColumn"
|
|
145
|
+
], options, diagnostics) : void 0;
|
|
146
|
+
const identity = definition.identity ? encodeIdentity(definition.identity, dialect, [
|
|
147
|
+
"tables",
|
|
148
|
+
id,
|
|
149
|
+
"columns",
|
|
150
|
+
id,
|
|
151
|
+
"identity"
|
|
152
|
+
], options, diagnostics) : void 0;
|
|
153
|
+
const onUpdate = definition.onUpdate ? encodeExpression(definition.onUpdate, "default", dialect, [
|
|
154
|
+
"columns",
|
|
155
|
+
id,
|
|
156
|
+
"onUpdate"
|
|
157
|
+
], options, diagnostics) : void 0;
|
|
158
|
+
return {
|
|
159
|
+
id,
|
|
160
|
+
physicalName,
|
|
161
|
+
nullable: definition.nullable,
|
|
162
|
+
hasDefault: definition.hasDefault,
|
|
163
|
+
generated: definition.generated,
|
|
164
|
+
...storage === void 0 ? {} : { storage },
|
|
165
|
+
...defaultValue === void 0 ? {} : { default: defaultValue },
|
|
166
|
+
...generatedColumn === void 0 ? {} : { generatedColumn },
|
|
167
|
+
...identity === void 0 ? {} : { identity },
|
|
168
|
+
...onUpdate === void 0 ? {} : { onUpdate }
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function encodeStorage(storage, dialect, path, options, diagnostics) {
|
|
172
|
+
if (storage.kind === "native" && storage.dialect !== dialect.name) {
|
|
173
|
+
diagnostics.push({
|
|
174
|
+
code: "dialect-mismatch",
|
|
175
|
+
message: `Native storage belongs to "${storage.dialect}" but the snapshot dialect is "${dialect.name}"`,
|
|
176
|
+
path
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const encoder = options.storageEncoder ?? options.adapter?.dialect.schema.encodeStorage ?? dialect.schema.encodeStorage;
|
|
181
|
+
if (encoder !== void 0) try {
|
|
182
|
+
return encoder(storage, {
|
|
183
|
+
path,
|
|
184
|
+
dialect
|
|
185
|
+
});
|
|
186
|
+
} catch (error) {
|
|
187
|
+
diagnostics.push({
|
|
188
|
+
code: "invalid-schema",
|
|
189
|
+
message: error instanceof Error ? error.message : String(error),
|
|
190
|
+
path
|
|
191
|
+
});
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (storage.kind === "portable") return {
|
|
195
|
+
kind: "portable",
|
|
196
|
+
type: storage.type
|
|
197
|
+
};
|
|
198
|
+
return {
|
|
199
|
+
kind: "native",
|
|
200
|
+
dialect: storage.dialect,
|
|
201
|
+
type: storage.type
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function encodeDefault(value, dialect, path, options, diagnostics) {
|
|
205
|
+
if (value.kind === "external") return { kind: "external" };
|
|
206
|
+
if (value.kind === "literal") return {
|
|
207
|
+
kind: "literal",
|
|
208
|
+
value: value.value
|
|
209
|
+
};
|
|
210
|
+
const expression = encodeExpression(value.expression, "default", dialect, path, options, diagnostics);
|
|
211
|
+
return expression === void 0 ? void 0 : {
|
|
212
|
+
kind: "expression",
|
|
213
|
+
expression
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function encodeGenerated(value, dialect, path, options, diagnostics) {
|
|
217
|
+
if (value.kind === "external") return { kind: "external" };
|
|
218
|
+
const expression = encodeExpression(value.expression, "generated", dialect, path, options, diagnostics);
|
|
219
|
+
return expression === void 0 ? void 0 : {
|
|
220
|
+
kind: "expression",
|
|
221
|
+
expression,
|
|
222
|
+
mode: value.mode
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function encodeIdentity(value, dialect, path, options, diagnostics) {
|
|
226
|
+
const extension = encodeExtension(value.dialect, dialect, [...path, "dialect"], options, diagnostics);
|
|
227
|
+
return {
|
|
228
|
+
kind: "identity",
|
|
229
|
+
generation: value.generation,
|
|
230
|
+
...extension === void 0 ? {} : { dialect: extension }
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function serializeConstraint(id, constraint, table, tableIds, tablesById, dialect, options, diagnostics) {
|
|
234
|
+
const physicalName = constraint.physicalName ?? generatedSchemaObjectName(id);
|
|
235
|
+
const common = {
|
|
236
|
+
id,
|
|
237
|
+
kind: constraint.kind,
|
|
238
|
+
physicalName
|
|
239
|
+
};
|
|
240
|
+
if (constraint.kind === "primary-key" || constraint.kind === "unique" || constraint.kind === "unique-constraint") {
|
|
241
|
+
const columns = serializeColumns(constraint.columns, table, [
|
|
242
|
+
"constraints",
|
|
243
|
+
id,
|
|
244
|
+
"columns"
|
|
245
|
+
], diagnostics);
|
|
246
|
+
const extension = encodeExtension(constraint.dialect, dialect, [
|
|
247
|
+
"constraints",
|
|
248
|
+
id,
|
|
249
|
+
"dialect"
|
|
250
|
+
], options, diagnostics);
|
|
251
|
+
if (columns === void 0) return void 0;
|
|
252
|
+
const timing = serializeTiming(constraint);
|
|
253
|
+
if (constraint.kind === "unique-constraint") return {
|
|
254
|
+
...common,
|
|
255
|
+
kind: "unique-constraint",
|
|
256
|
+
columns,
|
|
257
|
+
nulls: constraint.nulls,
|
|
258
|
+
...timing,
|
|
259
|
+
...extension === void 0 ? {} : { dialect: extension }
|
|
260
|
+
};
|
|
261
|
+
return {
|
|
262
|
+
...common,
|
|
263
|
+
kind: constraint.kind,
|
|
264
|
+
columns,
|
|
265
|
+
...timing,
|
|
266
|
+
...extension === void 0 ? {} : { dialect: extension }
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
if (constraint.kind === "foreign-key") {
|
|
270
|
+
const columns = serializeColumns(constraint.columns, table, [
|
|
271
|
+
"constraints",
|
|
272
|
+
id,
|
|
273
|
+
"columns"
|
|
274
|
+
], diagnostics);
|
|
275
|
+
const target = resolveForeignKeyTarget(constraint, tableIds, tablesById, [
|
|
276
|
+
"constraints",
|
|
277
|
+
id,
|
|
278
|
+
"target"
|
|
279
|
+
], diagnostics);
|
|
280
|
+
const extension = encodeExtension(constraint.dialect, dialect, [
|
|
281
|
+
"constraints",
|
|
282
|
+
id,
|
|
283
|
+
"dialect"
|
|
284
|
+
], options, diagnostics);
|
|
285
|
+
if (columns === void 0 || target === void 0) return void 0;
|
|
286
|
+
return {
|
|
287
|
+
...common,
|
|
288
|
+
kind: "foreign-key",
|
|
289
|
+
columns,
|
|
290
|
+
target,
|
|
291
|
+
...constraint.onUpdate === void 0 ? {} : { onUpdate: constraint.onUpdate },
|
|
292
|
+
...constraint.onDelete === void 0 ? {} : { onDelete: constraint.onDelete },
|
|
293
|
+
...constraint.match === void 0 ? {} : { match: constraint.match },
|
|
294
|
+
...serializeTiming(constraint),
|
|
295
|
+
...extension === void 0 ? {} : { dialect: extension }
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
if (constraint.kind === "check") {
|
|
299
|
+
const expression = encodeExpression(constraint.expression, "check", dialect, [
|
|
300
|
+
"constraints",
|
|
301
|
+
id,
|
|
302
|
+
"expression"
|
|
303
|
+
], options, diagnostics);
|
|
304
|
+
const extension = encodeExtension(constraint.dialect, dialect, [
|
|
305
|
+
"constraints",
|
|
306
|
+
id,
|
|
307
|
+
"dialect"
|
|
308
|
+
], options, diagnostics);
|
|
309
|
+
if (expression === void 0) return void 0;
|
|
310
|
+
return {
|
|
311
|
+
...common,
|
|
312
|
+
kind: "check",
|
|
313
|
+
expression,
|
|
314
|
+
...serializeTiming(constraint),
|
|
315
|
+
...extension === void 0 ? {} : { dialect: extension }
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
diagnostics.push({
|
|
319
|
+
code: "invalid-schema",
|
|
320
|
+
message: `Unsupported constraint kind on "${id}"`,
|
|
321
|
+
path: ["constraints", id]
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
function serializeTiming(value) {
|
|
325
|
+
return {
|
|
326
|
+
...value.deferrable === void 0 ? {} : { deferrable: value.deferrable },
|
|
327
|
+
...value.initially === void 0 ? {} : { initially: value.initially }
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function serializeColumns(columns, table, path, diagnostics) {
|
|
331
|
+
const result = [];
|
|
332
|
+
for (const [index, column] of columns.entries()) {
|
|
333
|
+
if (!isColumnReference(column)) {
|
|
334
|
+
diagnostics.push({
|
|
335
|
+
code: "invalid-schema",
|
|
336
|
+
message: "Constraint columns must be column references",
|
|
337
|
+
path: [...path, index]
|
|
338
|
+
});
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (!(column.fieldName in table.definitions)) {
|
|
342
|
+
diagnostics.push({
|
|
343
|
+
code: "unresolved-reference",
|
|
344
|
+
message: `Column "${column.fieldName}" is not declared on table "${table.tableName}"`,
|
|
345
|
+
path: [...path, index]
|
|
346
|
+
});
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
result.push(column.fieldName);
|
|
350
|
+
}
|
|
351
|
+
return result.length === columns.length && result.length > 0 ? result : void 0;
|
|
352
|
+
}
|
|
353
|
+
function resolveForeignKeyTarget(constraint, tableIds, tablesById, path, diagnostics) {
|
|
354
|
+
let target;
|
|
355
|
+
try {
|
|
356
|
+
target = typeof constraint.target === "function" ? constraint.target() : constraint.target;
|
|
357
|
+
} catch (error) {
|
|
358
|
+
diagnostics.push({
|
|
359
|
+
code: "unresolved-reference",
|
|
360
|
+
message: `Foreign-key target could not be resolved: ${error instanceof Error ? error.message : String(error)}`,
|
|
361
|
+
path
|
|
362
|
+
});
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const targetId = tableIds.get(target.table);
|
|
366
|
+
if (targetId === void 0 || !tablesById.has(targetId)) {
|
|
367
|
+
diagnostics.push({
|
|
368
|
+
code: "unresolved-reference",
|
|
369
|
+
message: "Foreign-key target table is not registered in the schema",
|
|
370
|
+
path: [...path, "table"]
|
|
371
|
+
});
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const targetColumns = serializeColumns(target.columns, target.table, [...path, "columns"], diagnostics);
|
|
375
|
+
if (targetColumns === void 0) return void 0;
|
|
376
|
+
return {
|
|
377
|
+
table: targetId,
|
|
378
|
+
columns: targetColumns
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
function serializeIndex(id, indexMetadata, table, dialect, options, diagnostics) {
|
|
382
|
+
const terms = [];
|
|
383
|
+
for (const [termIndex, term] of indexMetadata.terms.entries()) {
|
|
384
|
+
const serialized = serializeIndexTerm(term, table, dialect, [
|
|
385
|
+
"indexes",
|
|
386
|
+
id,
|
|
387
|
+
"terms",
|
|
388
|
+
termIndex
|
|
389
|
+
], options, diagnostics);
|
|
390
|
+
if (serialized !== void 0) terms.push(serialized);
|
|
391
|
+
}
|
|
392
|
+
const predicate = indexMetadata.predicate === void 0 ? void 0 : encodeExpression(indexMetadata.predicate, "index", dialect, [
|
|
393
|
+
"indexes",
|
|
394
|
+
id,
|
|
395
|
+
"predicate"
|
|
396
|
+
], options, diagnostics);
|
|
397
|
+
const includedColumns = indexMetadata.includedColumns === void 0 ? void 0 : serializeColumns(indexMetadata.includedColumns, table, [
|
|
398
|
+
"indexes",
|
|
399
|
+
id,
|
|
400
|
+
"includedColumns"
|
|
401
|
+
], diagnostics);
|
|
402
|
+
const extension = encodeExtension(indexMetadata.dialect, dialect, [
|
|
403
|
+
"indexes",
|
|
404
|
+
id,
|
|
405
|
+
"dialect"
|
|
406
|
+
], options, diagnostics);
|
|
407
|
+
if (terms.length !== indexMetadata.terms.length || indexMetadata.includedColumns !== void 0 && includedColumns === void 0) return void 0;
|
|
408
|
+
return {
|
|
409
|
+
id,
|
|
410
|
+
kind: "index",
|
|
411
|
+
physicalName: indexMetadata.physicalName ?? generatedSchemaObjectName(id),
|
|
412
|
+
terms,
|
|
413
|
+
unique: indexMetadata.unique,
|
|
414
|
+
candidateKey: indexMetadata.candidateKey,
|
|
415
|
+
...predicate === void 0 ? {} : { predicate },
|
|
416
|
+
...includedColumns === void 0 ? {} : { includedColumns },
|
|
417
|
+
...extension === void 0 ? {} : { dialect: extension }
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function serializeIndexTerm(term, table, dialect, path, options, diagnostics) {
|
|
421
|
+
if (isOrderTerm(term)) {
|
|
422
|
+
const expression = serializeIndexTermExpression(term.expression, table, dialect, [...path, "expression"], options, diagnostics);
|
|
423
|
+
return expression === void 0 ? void 0 : {
|
|
424
|
+
kind: "order",
|
|
425
|
+
expression,
|
|
426
|
+
...term.direction === void 0 ? {} : { direction: term.direction },
|
|
427
|
+
...term.nulls === void 0 ? {} : { nulls: term.nulls }
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
return serializeIndexTermExpression(term, table, dialect, path, options, diagnostics);
|
|
431
|
+
}
|
|
432
|
+
function serializeIndexTermExpression(expression, table, dialect, path, options, diagnostics) {
|
|
433
|
+
if (isColumnReference(expression)) {
|
|
434
|
+
if (!(expression.fieldName in table.definitions)) {
|
|
435
|
+
diagnostics.push({
|
|
436
|
+
code: "unresolved-reference",
|
|
437
|
+
message: `Index column "${expression.fieldName}" is not declared on table "${table.tableName}"`,
|
|
438
|
+
path
|
|
439
|
+
});
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
return {
|
|
443
|
+
kind: "column",
|
|
444
|
+
column: expression.fieldName
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
const encoded = encodeExpression(expression, "index", dialect, path, options, diagnostics);
|
|
448
|
+
return encoded === void 0 ? void 0 : {
|
|
449
|
+
kind: "expression",
|
|
450
|
+
expression: encoded
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
function encodeExpression(expression, mode, dialect, path, options, diagnostics) {
|
|
454
|
+
const encoder = options.expressionEncoder ?? options.adapter?.dialect.schema.encodeExpression ?? dialect.schema.encodeExpression;
|
|
455
|
+
if (encoder !== void 0) try {
|
|
456
|
+
return encoder(expression, {
|
|
457
|
+
mode,
|
|
458
|
+
path,
|
|
459
|
+
dialect
|
|
460
|
+
});
|
|
461
|
+
} catch (error) {
|
|
462
|
+
const code = error instanceof Error && "code" in error && error.code === "dialect-mismatch" ? "dialect-mismatch" : "unsupported-expression";
|
|
463
|
+
diagnostics.push({
|
|
464
|
+
code,
|
|
465
|
+
message: error instanceof Error ? error.message : String(error),
|
|
466
|
+
path
|
|
467
|
+
});
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if (isUnsafeSchemaSql(expression)) {
|
|
471
|
+
if (expression.schemaSqlDialect !== dialect.name) {
|
|
472
|
+
diagnostics.push({
|
|
473
|
+
code: "dialect-mismatch",
|
|
474
|
+
message: `Schema SQL is tagged for "${expression.schemaSqlDialect}" but the snapshot dialect is "${dialect.name}"`,
|
|
475
|
+
path
|
|
476
|
+
});
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
return {
|
|
480
|
+
kind: "expression",
|
|
481
|
+
expressionKind: expression.expressionKind,
|
|
482
|
+
sql: expression.schemaSql,
|
|
483
|
+
dialect: expression.schemaSqlDialect
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
try {
|
|
487
|
+
const rendered = renderSchemaExpression(expression, {
|
|
488
|
+
mode,
|
|
489
|
+
dialect
|
|
490
|
+
});
|
|
491
|
+
return {
|
|
492
|
+
kind: "expression",
|
|
493
|
+
expressionKind: expression.expressionKind,
|
|
494
|
+
sql: rendered.text
|
|
495
|
+
};
|
|
496
|
+
} catch (error) {
|
|
497
|
+
diagnostics.push({
|
|
498
|
+
code: "unsupported-expression",
|
|
499
|
+
message: error instanceof Error ? error.message : String(error),
|
|
500
|
+
path
|
|
501
|
+
});
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
function encodeExtension(extension, dialect, path, options, diagnostics) {
|
|
506
|
+
if (extension === void 0) return void 0;
|
|
507
|
+
if (extension.dialect !== dialect.name) {
|
|
508
|
+
diagnostics.push({
|
|
509
|
+
code: "dialect-mismatch",
|
|
510
|
+
message: `Dialect extension belongs to "${extension.dialect}" but the snapshot dialect is "${dialect.name}"`,
|
|
511
|
+
path
|
|
512
|
+
});
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const encoder = options.extensionEncoder ?? options.adapter?.dialect.schema.encodeDialectExtension ?? dialect.schema.encodeDialectExtension;
|
|
516
|
+
if (encoder !== void 0) try {
|
|
517
|
+
return encoder(extension, {
|
|
518
|
+
path,
|
|
519
|
+
dialect
|
|
520
|
+
});
|
|
521
|
+
} catch (error) {
|
|
522
|
+
diagnostics.push({
|
|
523
|
+
code: "dialect-mismatch",
|
|
524
|
+
message: error instanceof Error ? error.message : String(error),
|
|
525
|
+
path
|
|
526
|
+
});
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
const data = {};
|
|
530
|
+
for (const [key, value] of Object.entries(extension)) if (key !== "dialect") data[key] = value;
|
|
531
|
+
try {
|
|
532
|
+
return {
|
|
533
|
+
dialect: extension.dialect,
|
|
534
|
+
version: dialect.schema.version,
|
|
535
|
+
data: toSnapshotJsonValue(data)
|
|
536
|
+
};
|
|
537
|
+
} catch (error) {
|
|
538
|
+
diagnostics.push({
|
|
539
|
+
code: "invalid-value",
|
|
540
|
+
message: error instanceof Error ? error.message : String(error),
|
|
541
|
+
path
|
|
542
|
+
});
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function isOrderTerm(value) {
|
|
547
|
+
return typeof value === "object" && value !== null && "orderKind" in value && value.orderKind === "term" && "expression" in value;
|
|
548
|
+
}
|
|
549
|
+
function isSchemaRoot(value) {
|
|
550
|
+
return typeof value === "object" && value !== null && value.schemaKind === "schema" && typeof value.registry === "object" && value.registry !== null;
|
|
551
|
+
}
|
|
552
|
+
function compareId(left, right) {
|
|
553
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
554
|
+
}
|
|
555
|
+
//#endregion
|
|
556
|
+
export { encodeSnapshot as a, encodeSchemaSnapshot as i, createSchemaSnapshot as n, serializeSchema as o, digestSchemaSnapshot as r, tryCreateSchemaSnapshot as s, SnapshotSerializationError as t };
|