qubu 0.6.1 → 0.6.2

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.
Files changed (84) hide show
  1. package/dist/{complete-DP7pliuY.mjs → canonical-B5_ouh-c.mjs} +466 -241
  2. package/dist/codegen.d.mts +2 -2
  3. package/dist/codegen.mjs +180 -90
  4. package/dist/column-Cyc2CMnG.mjs +116 -0
  5. package/dist/column-DDRvD7SF.mjs +721 -0
  6. package/dist/{constraints-DM_tarXc.mjs → constraints-CAmi18Uk.mjs} +8 -3
  7. package/dist/core.d.mts +3 -3
  8. package/dist/core.mjs +4 -4
  9. package/dist/diff.d.mts +9 -9
  10. package/dist/diff.mjs +152 -102
  11. package/dist/{explain-CkIK13L_.mjs → explain-BIqEmZha.mjs} +1 -1
  12. package/dist/{expressions-BCjc08zw.mjs → expressions-_6JF_J77.mjs} +2 -1
  13. package/dist/index-CaxrMD1A.d.mts +1 -0
  14. package/dist/index.d.mts +2 -2
  15. package/dist/index.mjs +368 -74
  16. package/dist/introspection/mysql.d.mts +1 -1
  17. package/dist/introspection/mysql.mjs +156 -23
  18. package/dist/introspection/postgres.d.mts +6 -3
  19. package/dist/introspection/postgres.mjs +388 -53
  20. package/dist/introspection/sqlite.d.mts +1 -1
  21. package/dist/introspection/sqlite.mjs +198 -12
  22. package/dist/introspection.d.mts +26 -12
  23. package/dist/introspection.mjs +2 -672
  24. package/dist/mysql.d.mts +3 -3
  25. package/dist/mysql.mjs +6 -5
  26. package/dist/{errors-Dxv73YJu.mjs → omit-VEr9Ydux.mjs} +5 -1
  27. package/dist/{on-conflict-CnaY5qso.mjs → on-conflict-B2rFyHGF.mjs} +6 -8
  28. package/dist/on-duplicate-key-update-Czsw1Yq-.mjs +95 -0
  29. package/dist/{postgres-Dey7QXPL.mjs → postgres-hFhd0I9n.mjs} +4 -5
  30. package/dist/postgres.d.mts +2 -2
  31. package/dist/postgres.mjs +2 -2
  32. package/dist/{registry-oWDiqD7i.mjs → registry-BXE_4M9P.mjs} +1 -1
  33. package/dist/{relational-DSAJ-l58.mjs → relational-CoPBETjI.mjs} +3 -2
  34. package/dist/schema.d.mts +2 -2
  35. package/dist/schema.mjs +8 -8
  36. package/dist/{serialize-CE-gw5_s.mjs → serialize-CyobNEx-.mjs} +174 -30
  37. package/dist/serialize-Du2UPZMt.d.mts +92 -0
  38. package/dist/snapshot/mysql.d.mts +5 -5
  39. package/dist/snapshot/mysql.mjs +8 -8
  40. package/dist/snapshot/postgres.d.mts +3 -3
  41. package/dist/snapshot/postgres.mjs +9 -9
  42. package/dist/snapshot/sqlite.d.mts +3 -3
  43. package/dist/snapshot/sqlite.mjs +7 -7
  44. package/dist/snapshot-mIb-Zzb5.mjs +1489 -0
  45. package/dist/snapshot.d.mts +4 -5
  46. package/dist/snapshot.mjs +3 -4
  47. package/dist/{source-BDuUXmAk.mjs → source-DYSUqzvb.mjs} +2 -2
  48. package/dist/sqlite.d.mts +2 -2
  49. package/dist/sqlite.mjs +6 -6
  50. package/dist/{table-C1QGNe4P.mjs → table-B8zEq0az.mjs} +4 -4
  51. package/dist/{types-BLNRatG_.mjs → types-CYHpSPwj.mjs} +10 -5
  52. package/dist/{types-BEn0N_al.d.mts → types-CiMvKi5V.d.mts} +14 -4
  53. package/dist/{types-DUe6eeI0.d.mts → types-Dqr4o2I1.d.mts} +590 -168
  54. package/dist/value-CpaUFtjw.mjs +45 -0
  55. package/dist/vite/ambient.d.ts +2 -0
  56. package/dist/vite.d.mts +1 -1
  57. package/dist/vite.mjs +2 -0
  58. package/docs/dialects-and-execution.md +61 -11
  59. package/docs/getting-started.md +1 -1
  60. package/docs/guides/extensions/typed-expressions.md +5 -3
  61. package/docs/guides/json.md +95 -2
  62. package/docs/guides/mutations.md +36 -0
  63. package/docs/index.md +1 -1
  64. package/docs/migrations/adapters.md +58 -21
  65. package/docs/migrations/recovery.md +7 -1
  66. package/docs/query-model/fragments.md +21 -1
  67. package/docs/reference/introspection-support.md +16 -18
  68. package/docs/reference/supported-surface.md +8 -7
  69. package/docs/schema/catalog-model.md +20 -7
  70. package/docs/schema/code-generation.md +1 -1
  71. package/docs/schema/diff.md +2 -2
  72. package/docs/schema/introspection.md +21 -14
  73. package/docs/schema/snapshots.md +18 -8
  74. package/docs/schema/storage-and-schema-sql.md +7 -2
  75. package/package.json +2 -1
  76. package/dist/canonical-DMvR9yBe.mjs +0 -972
  77. package/dist/column-BzN8KFJa.mjs +0 -364
  78. package/dist/column-CFvSbil0.mjs +0 -309
  79. package/dist/complete-types-CNMWBWap.d.mts +0 -371
  80. package/dist/index-CGui70hi.d.mts +0 -32
  81. package/dist/json-Db7XRD91.mjs +0 -169
  82. package/dist/omit-OxV58AwX.mjs +0 -5
  83. package/dist/serialize-OvXCLzjm.d.mts +0 -66
  84. package/dist/snapshot-DgsOhf_8.mjs +0 -354
@@ -1,17 +1,31 @@
1
- import { n as canonicalJson } from "./canonical-DMvR9yBe.mjs";
1
+ //#region src/snapshot/types.ts
2
+ /** The JSON object tag used by Qubu schema snapshots. */
3
+ const schemaSnapshotFormat = "qubu-schema";
4
+ /** The current canonical schema snapshot format version. */
5
+ const schemaSnapshotVersion = 1;
6
+ /** The first version of the dialect-extension envelope. */
7
+ const schemaSnapshotDialectVersion = 1;
8
+ /** The first version of the built-in naming-policy description. */
9
+ const schemaSnapshotNamingPolicyVersion = 1;
10
+ /** The neutral dialect used when no SQL engine adapter is selected. */
11
+ const neutralSnapshotDialect = Object.freeze({
12
+ name: "neutral",
13
+ version: 1
14
+ });
15
+ //#endregion
2
16
  //#region src/snapshot/complete-types.ts
3
- /** The stable envelope tag shared by Snapshot v1 and the complete model. */
4
- const completeSchemaSnapshotFormat = "qubu-schema";
5
- /** The strict format version for the complete catalog/object model. */
6
- const completeSchemaSnapshotVersion = 2;
17
+ /** The canonical schema snapshot envelope tag. */
18
+ const completeSchemaSnapshotFormat = schemaSnapshotFormat;
19
+ /** The current strict format version for the complete catalog/object model. */
20
+ const completeSchemaSnapshotVersion = 1;
7
21
  /** Descriptive alias for consumers that select a numbered snapshot version. */
8
- const schemaSnapshotV2Version = 2;
22
+ const schemaSnapshotV1Version = completeSchemaSnapshotVersion;
9
23
  /** Explicit format-version aliases for generated tooling and fixtures. */
10
- const schemaSnapshotCompleteVersion = 2;
11
- const schemaSnapshotVersion2 = 2;
24
+ const schemaSnapshotCompleteVersion = completeSchemaSnapshotVersion;
25
+ const schemaSnapshotVersion1 = completeSchemaSnapshotVersion;
12
26
  //#endregion
13
27
  //#region src/snapshot/complete.ts
14
- /** Error raised by throwing APIs after collecting strict v2 diagnostics. */
28
+ /** Error raised by throwing APIs after collecting strict v1 diagnostics. */
15
29
  var CompleteSnapshotValidationError = class extends TypeError {
16
30
  name = "CompleteSnapshotValidationError";
17
31
  diagnostics;
@@ -27,7 +41,7 @@ var CompleteSnapshotValidationError = class extends TypeError {
27
41
  this.issues = frozen;
28
42
  }
29
43
  };
30
- /** Decode and strictly validate a complete Snapshot v2 JSON value. */
44
+ /** Decode and strictly validate a complete Snapshot v1 JSON value. */
31
45
  function decodeCompleteSchemaSnapshot(input) {
32
46
  let value = input;
33
47
  if (typeof input === "string") try {
@@ -65,10 +79,9 @@ function canonicalizeCompleteSchemaSnapshot(input) {
65
79
  }
66
80
  /** Encode a complete snapshot with deterministic property and array order. */
67
81
  function encodeCompleteSchemaSnapshot(snapshot) {
68
- const canonical = assertCompleteSchemaSnapshot(snapshot);
69
- return canonicalJson(canonical);
82
+ return canonicalJson(assertCompleteSchemaSnapshot(snapshot));
70
83
  }
71
- /** Compute the deterministic content fingerprint for a complete Snapshot v2. */
84
+ /** Compute the deterministic content fingerprint for a complete Snapshot v1. */
72
85
  function completeSchemaSnapshotFingerprint(snapshot) {
73
86
  const source = encodeCompleteSchemaSnapshot(snapshot);
74
87
  let hash = 14695981039346656037n;
@@ -84,12 +97,12 @@ function completeSchemaSnapshotFingerprint(snapshot) {
84
97
  }
85
98
  return `fnv1a64:${hash.toString(16).padStart(16, "0")}`;
86
99
  }
87
- /** Numbered aliases for tooling that keeps v1 and v2 side by side. */
88
- const decodeSchemaSnapshotV2 = decodeCompleteSchemaSnapshot;
89
- const assertSchemaSnapshotV2 = assertCompleteSchemaSnapshot;
90
- const encodeSchemaSnapshotV2 = encodeCompleteSchemaSnapshot;
91
- const canonicalizeSchemaSnapshotV2 = canonicalizeCompleteSchemaSnapshot;
92
- const schemaSnapshotV2Fingerprint = completeSchemaSnapshotFingerprint;
100
+ /** Numbered aliases for tooling that prefers explicit Snapshot v1 names. */
101
+ const decodeSchemaSnapshotV1 = decodeCompleteSchemaSnapshot;
102
+ const assertSchemaSnapshotV1 = assertCompleteSchemaSnapshot;
103
+ const encodeSchemaSnapshotV1 = encodeCompleteSchemaSnapshot;
104
+ const canonicalizeSchemaSnapshotV1 = canonicalizeCompleteSchemaSnapshot;
105
+ const schemaSnapshotV1Fingerprint = completeSchemaSnapshotFingerprint;
93
106
  const decodeCompleteSnapshot = decodeCompleteSchemaSnapshot;
94
107
  const assertCompleteSnapshot = assertCompleteSchemaSnapshot;
95
108
  const encodeCompleteSnapshot = encodeCompleteSchemaSnapshot;
@@ -118,31 +131,32 @@ function validateCompleteSnapshot(value, diagnostics) {
118
131
  "comments",
119
132
  "ownership"
120
133
  ], [], diagnostics);
121
- if (value.format !== "qubu-schema") diagnostics.push(issue("invalid-snapshot", `Snapshot format must be "${completeSchemaSnapshotFormat}"`, ["format"]));
122
- if (value.version !== 2) diagnostics.push(issue(typeof value.version === "number" && value.version > 2 ? "future-version" : "invalid-snapshot", `Unsupported complete schema snapshot version: ${String(value.version)}`, ["version"]));
134
+ if (value.format !== completeSchemaSnapshotFormat) diagnostics.push(issue("invalid-snapshot", `Snapshot format must be "${completeSchemaSnapshotFormat}"`, ["format"]));
135
+ if (value.version !== completeSchemaSnapshotVersion) diagnostics.push(issue(typeof value.version === "number" && value.version > completeSchemaSnapshotVersion ? "future-version" : "invalid-snapshot", `Unsupported complete schema snapshot version: ${String(value.version)}`, ["version"]));
123
136
  const dialect = validateDialect(value.dialect, ["dialect"], diagnostics);
137
+ const snapshotDialect = dialect?.name;
124
138
  const namingPolicy = validateNamingPolicy(value.namingPolicy, ["namingPolicy"], diagnostics);
125
139
  const namespace = validateNamespace(value.namespace, ["namespace"], diagnostics, dialect?.name);
126
140
  const capabilities = validateCapabilities(value.capabilities, ["capabilities"], diagnostics);
127
- const tables = validateObjects(value.tables, ["tables"], diagnostics, validateTable);
128
- const views = validateObjects(value.views, ["views"], diagnostics, validateView);
129
- const sequences = validateObjects(value.sequences, ["sequences"], diagnostics, validateSequence);
130
- const enums = validateObjects(value.enums, ["enums"], diagnostics, validateEnum);
131
- const domains = validateObjects(value.domains, ["domains"], diagnostics, validateDomain);
132
- const collations = validateObjects(value.collations, ["collations"], diagnostics, validateCollation);
133
- const triggers = validateObjects(value.triggers, ["triggers"], diagnostics, validateTrigger);
134
- const routines = validateObjects(value.routines, ["routines"], diagnostics, validateRoutine);
135
- const partitions = validateObjects(value.partitions, ["partitions"], diagnostics, validatePartition);
136
- const policies = validateObjects(value.policies, ["policies"], diagnostics, validatePolicy);
137
- const extensions = validateObjects(value.extensions, ["extensions"], diagnostics, validateExtensionObject);
138
- const deferredObjects = validateObjects(value.deferredObjects, ["deferredObjects"], diagnostics, validateDeferredObject);
139
- const opaqueObjects = validateObjects(value.opaqueObjects, ["opaqueObjects"], diagnostics, validateOpaqueObject);
140
- const comments = validateObjects(value.comments, ["comments"], diagnostics, validateComment);
141
- const ownership = validateObjects(value.ownership, ["ownership"], diagnostics, validateOwnership);
141
+ const tables = validateObjects(value.tables, ["tables"], diagnostics, validateTable, snapshotDialect);
142
+ const views = validateObjects(value.views, ["views"], diagnostics, validateView, snapshotDialect);
143
+ const sequences = validateObjects(value.sequences, ["sequences"], diagnostics, validateSequence, snapshotDialect);
144
+ const enums = validateObjects(value.enums, ["enums"], diagnostics, validateEnum, snapshotDialect);
145
+ const domains = validateObjects(value.domains, ["domains"], diagnostics, validateDomain, snapshotDialect);
146
+ const collations = validateObjects(value.collations, ["collations"], diagnostics, validateCollation, snapshotDialect);
147
+ const triggers = validateObjects(value.triggers, ["triggers"], diagnostics, validateTrigger, snapshotDialect);
148
+ const routines = validateObjects(value.routines, ["routines"], diagnostics, validateRoutine, snapshotDialect);
149
+ const partitions = validateObjects(value.partitions, ["partitions"], diagnostics, validatePartition, snapshotDialect);
150
+ const policies = validateObjects(value.policies, ["policies"], diagnostics, validatePolicy, snapshotDialect);
151
+ const extensions = validateObjects(value.extensions, ["extensions"], diagnostics, validateExtensionObject, snapshotDialect);
152
+ const deferredObjects = validateObjects(value.deferredObjects, ["deferredObjects"], diagnostics, validateDeferredObject, snapshotDialect);
153
+ const opaqueObjects = validateObjects(value.opaqueObjects, ["opaqueObjects"], diagnostics, validateOpaqueObject, snapshotDialect);
154
+ const comments = validateObjects(value.comments, ["comments"], diagnostics, validateComment, snapshotDialect);
155
+ const ownership = validateObjects(value.ownership, ["ownership"], diagnostics, validateOwnership, snapshotDialect);
142
156
  if (dialect === void 0 || namingPolicy === void 0 || namespace === void 0 || capabilities === void 0 || tables === void 0 || views === void 0 || sequences === void 0 || enums === void 0 || domains === void 0 || collations === void 0 || triggers === void 0 || routines === void 0 || partitions === void 0 || policies === void 0 || extensions === void 0 || deferredObjects === void 0 || opaqueObjects === void 0 || comments === void 0 || ownership === void 0) return;
143
157
  const snapshot = {
144
158
  format: completeSchemaSnapshotFormat,
145
- version: 2,
159
+ version: completeSchemaSnapshotVersion,
146
160
  dialect,
147
161
  namingPolicy,
148
162
  namespace,
@@ -163,7 +177,6 @@ function validateCompleteSnapshot(value, diagnostics) {
163
177
  comments,
164
178
  ownership
165
179
  };
166
- validateCompleteDialectMetadata(snapshot, diagnostics);
167
180
  validateCompleteCrossReferences(snapshot, diagnostics);
168
181
  return diagnostics.length === 0 ? snapshot : void 0;
169
182
  }
@@ -214,7 +227,7 @@ function validateNamespace(value, path, diagnostics, dialect) {
214
227
  "dialect"
215
228
  ]);
216
229
  const kind = value.kind;
217
- if (kind !== "postgres-schema" && kind !== "sqlite-database" && kind !== "mysql-database") diagnostics.push(issue("invalid-snapshot", "Snapshot namespace kind is invalid", [...path, "kind"]));
230
+ if (kind !== "generic" && kind !== "postgres-schema" && kind !== "sqlite-database" && kind !== "mysql-database") diagnostics.push(issue("invalid-snapshot", "Snapshot namespace kind is invalid", [...path, "kind"]));
218
231
  const name = stringValue(value.name, [...path, "name"], diagnostics, true);
219
232
  const metadata = validateObjectMetadata(value, path, dialect, diagnostics);
220
233
  return name === void 0 || typeof kind !== "string" ? void 0 : {
@@ -245,7 +258,7 @@ function validateCapabilities(value, path, diagnostics) {
245
258
  for (const key of Object.keys(value).sort()) {
246
259
  const child = value[key];
247
260
  if (typeof child !== "boolean" && typeof child !== "string") diagnostics.push(issue("invalid-value", "Capability values must be boolean or string", [...path, key]));
248
- else result[key] = child;
261
+ else setOwn$1(result, key, child);
249
262
  }
250
263
  const enforcement = value.checkConstraintEnforcement;
251
264
  if (enforcement !== "enforced" && enforcement !== "metadata-only" && enforcement !== "unknown") diagnostics.push(issue("invalid-snapshot", "Check-constraint enforcement is invalid", [...path, "checkConstraintEnforcement"]));
@@ -255,7 +268,7 @@ function validateCapabilities(value, path, diagnostics) {
255
268
  if (diagnostics.some((diagnostic) => diagnostic.path.length === path.length + 1 && diagnostic.path.slice(0, path.length).every((part, i) => part === path[i]))) return;
256
269
  return result;
257
270
  }
258
- function validateObjects(value, path, diagnostics, validate) {
271
+ function validateObjects(value, path, diagnostics, validate, dialect) {
259
272
  if (!Array.isArray(value)) {
260
273
  diagnostics.push(issue("invalid-snapshot", "Value must be an array", path));
261
274
  return;
@@ -263,7 +276,7 @@ function validateObjects(value, path, diagnostics, validate) {
263
276
  validateSortedIds(value, path, diagnostics);
264
277
  const result = [];
265
278
  for (const [index, item] of value.entries()) {
266
- const valid = validate(item, [...path, index], diagnostics);
279
+ const valid = validate(item, [...path, index], diagnostics, dialect);
267
280
  if (valid !== void 0) result.push(valid);
268
281
  }
269
282
  return result;
@@ -307,17 +320,18 @@ function validateBase(value, path, kind, dialect, diagnostics, allowed = []) {
307
320
  metadata
308
321
  };
309
322
  }
310
- function validateTable(value, path, diagnostics) {
311
- const base = validateBase(value, path, "table", void 0, diagnostics, [
323
+ function validateTable(value, path, diagnostics, dialect) {
324
+ const base = validateBase(value, path, "table", dialect, diagnostics, [
312
325
  "columns",
313
326
  "constraints",
314
327
  "indexes"
315
328
  ]);
316
329
  if (!isRecord(value) || base === void 0) return;
317
- const columns = validateObjects(value.columns, [...path, "columns"], diagnostics, validateColumn);
318
- const constraints = validateObjects(value.constraints, [...path, "constraints"], diagnostics, validateConstraint);
319
- const indexes = validateObjects(value.indexes, [...path, "indexes"], diagnostics, validateIndex);
330
+ const columns = validateObjects(value.columns, [...path, "columns"], diagnostics, validateColumn, dialect);
331
+ const constraints = validateObjects(value.constraints, [...path, "constraints"], diagnostics, validateConstraint, dialect);
332
+ const indexes = validateObjects(value.indexes, [...path, "indexes"], diagnostics, validateIndex, dialect);
320
333
  if (columns === void 0 || constraints === void 0 || indexes === void 0) return;
334
+ validateUniqueOrdinalPositions(columns, [...path, "columns"], diagnostics);
321
335
  return {
322
336
  kind: "table",
323
337
  id: base.id,
@@ -328,8 +342,8 @@ function validateTable(value, path, diagnostics) {
328
342
  ...base.metadata
329
343
  };
330
344
  }
331
- function validateColumn(value, path, diagnostics) {
332
- const base = validateBase(value, path, "column", void 0, diagnostics, [
345
+ function validateColumn(value, path, diagnostics, dialect) {
346
+ const base = validateBase(value, path, "column", dialect, diagnostics, [
333
347
  "ordinalPosition",
334
348
  "nullable",
335
349
  "hasDefault",
@@ -345,11 +359,11 @@ function validateColumn(value, path, diagnostics) {
345
359
  const nullable = booleanValue(value.nullable, [...path, "nullable"], diagnostics);
346
360
  const hasDefault = booleanValue(value.hasDefault, [...path, "hasDefault"], diagnostics);
347
361
  const generated = booleanValue(value.generated, [...path, "generated"], diagnostics);
348
- const storage = value.storage === void 0 ? void 0 : validateStorage(value.storage, [...path, "storage"], diagnostics);
349
- const defaultValue = value.default === void 0 ? void 0 : validateDefault(value.default, [...path, "default"], diagnostics);
350
- const generatedColumn = value.generatedColumn === void 0 ? void 0 : validateGenerated(value.generatedColumn, [...path, "generatedColumn"], diagnostics);
351
- const identity = value.identity === void 0 ? void 0 : validateIdentity(value.identity, [...path, "identity"], diagnostics);
352
- const onUpdate = value.onUpdate === void 0 ? void 0 : validateExpression(value.onUpdate, [...path, "onUpdate"], diagnostics);
362
+ const storage = value.storage === void 0 ? void 0 : validateStorage(value.storage, [...path, "storage"], diagnostics, dialect);
363
+ const defaultValue = value.default === void 0 ? void 0 : validateDefault(value.default, [...path, "default"], diagnostics, dialect);
364
+ const generatedColumn = value.generatedColumn === void 0 ? void 0 : validateGenerated(value.generatedColumn, [...path, "generatedColumn"], diagnostics, dialect);
365
+ const identity = value.identity === void 0 ? void 0 : validateIdentity(value.identity, [...path, "identity"], diagnostics, dialect);
366
+ const onUpdate = value.onUpdate === void 0 ? void 0 : validateExpression(value.onUpdate, [...path, "onUpdate"], diagnostics, dialect);
353
367
  if (ordinalPosition === void 0 || nullable === void 0 || hasDefault === void 0 || generated === void 0) return;
354
368
  return {
355
369
  kind: "column",
@@ -367,13 +381,13 @@ function validateColumn(value, path, diagnostics) {
367
381
  ...base.metadata
368
382
  };
369
383
  }
370
- function validateConstraint(value, path, diagnostics) {
384
+ function validateConstraint(value, path, diagnostics, dialect) {
371
385
  if (!isRecord(value)) {
372
386
  diagnostics.push(issue("invalid-snapshot", "Constraint must be an object", path));
373
387
  return;
374
388
  }
375
389
  const kind = value.kind;
376
- const base = validateBase(value, path, String(kind), void 0, diagnostics, kind === "foreign-key" ? [
390
+ const base = validateBase(value, path, String(kind), dialect, diagnostics, kind === "foreign-key" ? [
377
391
  "columns",
378
392
  "target",
379
393
  "onUpdate",
@@ -397,7 +411,7 @@ function validateConstraint(value, path, diagnostics) {
397
411
  ]);
398
412
  if (base === void 0) return;
399
413
  if (kind === "check") {
400
- const expression = validateExpression(value.expression, [...path, "expression"], diagnostics);
414
+ const expression = validateExpression(value.expression, [...path, "expression"], diagnostics, dialect);
401
415
  const timing = validateTiming(value, path, diagnostics);
402
416
  const validated = optionalBoolean(value.validated, [...path, "validated"], diagnostics);
403
417
  if (expression === void 0) return;
@@ -460,8 +474,8 @@ function validateConstraint(value, path, diagnostics) {
460
474
  ...base.metadata
461
475
  };
462
476
  }
463
- function validateIndex(value, path, diagnostics) {
464
- const base = validateBase(value, path, "index", void 0, diagnostics, [
477
+ function validateIndex(value, path, diagnostics, dialect) {
478
+ const base = validateBase(value, path, "index", dialect, diagnostics, [
465
479
  "terms",
466
480
  "unique",
467
481
  "candidateKey",
@@ -471,11 +485,14 @@ function validateIndex(value, path, diagnostics) {
471
485
  "method"
472
486
  ]);
473
487
  if (!isRecord(value) || base === void 0) return;
474
- const terms = validateArray(value.terms, [...path, "terms"], diagnostics, validateIndexTerm);
475
- if (terms !== void 0) validateSortedPositions(terms, [...path, "terms"], diagnostics);
488
+ const terms = validateArray(value.terms, [...path, "terms"], diagnostics, validateIndexTerm, dialect);
489
+ if (terms !== void 0) {
490
+ if (terms.length === 0) diagnostics.push(issue("invalid-snapshot", "Indexes must contain at least one term", [...path, "terms"]));
491
+ validateSortedPositions(terms, [...path, "terms"], diagnostics);
492
+ }
476
493
  const unique = booleanValue(value.unique, [...path, "unique"], diagnostics);
477
494
  const candidateKey = booleanValue(value.candidateKey, [...path, "candidateKey"], diagnostics);
478
- const predicate = value.predicate === void 0 ? void 0 : validateExpression(value.predicate, [...path, "predicate"], diagnostics);
495
+ const predicate = value.predicate === void 0 ? void 0 : validateExpression(value.predicate, [...path, "predicate"], diagnostics, dialect);
479
496
  const includedColumns = value.includedColumns === void 0 ? void 0 : validateIds(value.includedColumns, [...path, "includedColumns"], diagnostics, false);
480
497
  const backingConstraint = value.backingConstraint === void 0 ? void 0 : validateObjectReference(value.backingConstraint, [...path, "backingConstraint"], diagnostics);
481
498
  const method = value.method === void 0 ? void 0 : stringValue(value.method, [...path, "method"], diagnostics, true);
@@ -494,7 +511,7 @@ function validateIndex(value, path, diagnostics) {
494
511
  ...base.metadata
495
512
  };
496
513
  }
497
- function validateIndexTerm(value, path, diagnostics) {
514
+ function validateIndexTerm(value, path, diagnostics, dialect) {
498
515
  if (!isRecord(value)) {
499
516
  diagnostics.push(issue("invalid-snapshot", "Index term must be an object", path));
500
517
  return;
@@ -519,7 +536,7 @@ function validateIndexTerm(value, path, diagnostics) {
519
536
  const operatorClass = value.operatorClass === void 0 ? void 0 : stringValue(value.operatorClass, [...path, "operatorClass"], diagnostics, true);
520
537
  if (kind === "column") {
521
538
  const column = stringValue(value.column, [...path, "column"], diagnostics, true);
522
- const prefixLength = value.prefixLength === void 0 ? void 0 : validateValueFact(value.prefixLength, [...path, "prefixLength"], diagnostics);
539
+ const prefixLength = value.prefixLength === void 0 ? void 0 : validateValueFact(value.prefixLength, [...path, "prefixLength"], diagnostics, dialect);
523
540
  if (column === void 0 || position === void 0) return;
524
541
  return {
525
542
  kind: "column",
@@ -532,7 +549,7 @@ function validateIndexTerm(value, path, diagnostics) {
532
549
  };
533
550
  }
534
551
  if (kind === "expression") {
535
- const expression = validateExpression(value.expression, [...path, "expression"], diagnostics);
552
+ const expression = validateExpression(value.expression, [...path, "expression"], diagnostics, dialect);
536
553
  if (expression === void 0 || position === void 0) return;
537
554
  return {
538
555
  kind: "expression",
@@ -545,8 +562,8 @@ function validateIndexTerm(value, path, diagnostics) {
545
562
  }
546
563
  diagnostics.push(issue("invalid-snapshot", "Index term kind is invalid", [...path, "kind"]));
547
564
  }
548
- function validateView(value, path, diagnostics) {
549
- const base = validateBase(value, path, "view", void 0, diagnostics, [
565
+ function validateView(value, path, diagnostics, dialect) {
566
+ const base = validateBase(value, path, "view", dialect, diagnostics, [
550
567
  "columns",
551
568
  "definition",
552
569
  "dependencies",
@@ -555,8 +572,8 @@ function validateView(value, path, diagnostics) {
555
572
  "securityInvoker"
556
573
  ]);
557
574
  if (!isRecord(value) || base === void 0) return;
558
- const columns = validateObjects(value.columns, [...path, "columns"], diagnostics, validateColumn);
559
- const definition = validateExpression(value.definition, [...path, "definition"], diagnostics);
575
+ const columns = validateObjects(value.columns, [...path, "columns"], diagnostics, validateColumn, dialect);
576
+ const definition = validateExpression(value.definition, [...path, "definition"], diagnostics, dialect);
560
577
  const dependencies = value.dependencies === void 0 ? void 0 : validateReferences(value.dependencies, [...path, "dependencies"], diagnostics);
561
578
  const checkOption = validateCheckOption(value.checkOption, [...path, "checkOption"], diagnostics);
562
579
  const securityBarrier = optionalBoolean(value.securityBarrier, [...path, "securityBarrier"], diagnostics);
@@ -575,8 +592,8 @@ function validateView(value, path, diagnostics) {
575
592
  ...base.metadata
576
593
  };
577
594
  }
578
- function validateSequence(value, path, diagnostics) {
579
- const base = validateBase(value, path, "sequence", void 0, diagnostics, [
595
+ function validateSequence(value, path, diagnostics, dialect) {
596
+ const base = validateBase(value, path, "sequence", dialect, diagnostics, [
580
597
  "storage",
581
598
  "start",
582
599
  "increment",
@@ -588,15 +605,15 @@ function validateSequence(value, path, diagnostics) {
588
605
  "identity"
589
606
  ]);
590
607
  if (!isRecord(value) || base === void 0) return;
591
- const storage = value.storage === void 0 ? void 0 : validateStorage(value.storage, [...path, "storage"], diagnostics);
592
- const start = value.start === void 0 ? void 0 : validateValueFact(value.start, [...path, "start"], diagnostics);
593
- const increment = value.increment === void 0 ? void 0 : validateValueFact(value.increment, [...path, "increment"], diagnostics);
594
- const minimum = value.minimum === void 0 ? void 0 : validateValueFact(value.minimum, [...path, "minimum"], diagnostics);
595
- const maximum = value.maximum === void 0 ? void 0 : validateValueFact(value.maximum, [...path, "maximum"], diagnostics);
596
- const cache = value.cache === void 0 ? void 0 : validateValueFact(value.cache, [...path, "cache"], diagnostics);
608
+ const storage = value.storage === void 0 ? void 0 : validateStorage(value.storage, [...path, "storage"], diagnostics, dialect);
609
+ const start = value.start === void 0 ? void 0 : validateValueFact(value.start, [...path, "start"], diagnostics, dialect);
610
+ const increment = value.increment === void 0 ? void 0 : validateValueFact(value.increment, [...path, "increment"], diagnostics, dialect);
611
+ const minimum = value.minimum === void 0 ? void 0 : validateValueFact(value.minimum, [...path, "minimum"], diagnostics, dialect);
612
+ const maximum = value.maximum === void 0 ? void 0 : validateValueFact(value.maximum, [...path, "maximum"], diagnostics, dialect);
613
+ const cache = value.cache === void 0 ? void 0 : validateValueFact(value.cache, [...path, "cache"], diagnostics, dialect);
597
614
  const cycle = optionalBoolean(value.cycle, [...path, "cycle"], diagnostics);
598
615
  const ownedBy = value.ownedBy === void 0 ? void 0 : validateObjectReference(value.ownedBy, [...path, "ownedBy"], diagnostics);
599
- const identity = value.identity === void 0 ? void 0 : validateIdentity(value.identity, [...path, "identity"], diagnostics);
616
+ const identity = value.identity === void 0 ? void 0 : validateIdentity(value.identity, [...path, "identity"], diagnostics, dialect);
600
617
  return {
601
618
  kind: "sequence",
602
619
  id: base.id,
@@ -613,10 +630,10 @@ function validateSequence(value, path, diagnostics) {
613
630
  ...base.metadata
614
631
  };
615
632
  }
616
- function validateEnum(value, path, diagnostics) {
617
- const base = validateBase(value, path, "enum", void 0, diagnostics, ["values"]);
633
+ function validateEnum(value, path, diagnostics, dialect) {
634
+ const base = validateBase(value, path, "enum", dialect, diagnostics, ["values"]);
618
635
  if (!isRecord(value) || base === void 0) return;
619
- const values = validateArray(value.values, [...path, "values"], diagnostics, validateEnumValue);
636
+ const values = validateArray(value.values, [...path, "values"], diagnostics, validateEnumValue, dialect);
620
637
  if (values === void 0) return;
621
638
  let previous = -1;
622
639
  for (const [index, item] of values.entries()) {
@@ -636,7 +653,7 @@ function validateEnum(value, path, diagnostics) {
636
653
  ...base.metadata
637
654
  };
638
655
  }
639
- function validateEnumValue(value, path, diagnostics) {
656
+ function validateEnumValue(value, path, diagnostics, dialect) {
640
657
  if (!isRecord(value)) {
641
658
  diagnostics.push(issue("invalid-snapshot", "Enum value must be an object", path));
642
659
  return;
@@ -648,25 +665,26 @@ function validateEnumValue(value, path, diagnostics) {
648
665
  ], path, diagnostics, ["provenance"]);
649
666
  const label = stringValue(value.value, [...path, "value"], diagnostics);
650
667
  const ordinalPosition = integerValue(value.ordinalPosition, [...path, "ordinalPosition"], diagnostics);
651
- const provenance = value.provenance === void 0 ? void 0 : validateProvenance(value.provenance, [...path, "provenance"], void 0, diagnostics);
668
+ const provenance = value.provenance === void 0 ? void 0 : validateProvenance(value.provenance, [...path, "provenance"], dialect, diagnostics);
652
669
  return label === void 0 || ordinalPosition === void 0 ? void 0 : {
653
670
  value: label,
654
671
  ordinalPosition,
655
672
  ...provenance === void 0 ? {} : { provenance }
656
673
  };
657
674
  }
658
- function validateDomain(value, path, diagnostics) {
659
- const base = validateBase(value, path, "domain", void 0, diagnostics, [
675
+ function validateDomain(value, path, diagnostics, dialect) {
676
+ const base = validateBase(value, path, "domain", dialect, diagnostics, [
660
677
  "storage",
661
678
  "nullable",
662
679
  "default",
663
680
  "constraints"
664
681
  ]);
665
682
  if (!isRecord(value) || base === void 0) return;
666
- const storage = validateStorage(value.storage, [...path, "storage"], diagnostics);
683
+ const storage = validateStorage(value.storage, [...path, "storage"], diagnostics, dialect);
667
684
  const nullable = optionalBoolean(value.nullable, [...path, "nullable"], diagnostics);
668
- const defaultValue = value.default === void 0 ? void 0 : validateValueFact(value.default, [...path, "default"], diagnostics);
669
- const constraints = value.constraints === void 0 ? void 0 : validateArray(value.constraints, [...path, "constraints"], diagnostics, validateCheckConstraint);
685
+ const defaultValue = value.default === void 0 ? void 0 : validateValueFact(value.default, [...path, "default"], diagnostics, dialect);
686
+ if (value.constraints !== void 0) validateSortedIds(value.constraints, [...path, "constraints"], diagnostics);
687
+ const constraints = value.constraints === void 0 ? void 0 : validateArray(value.constraints, [...path, "constraints"], diagnostics, validateCheckConstraint, dialect);
670
688
  if (storage === void 0) return;
671
689
  return {
672
690
  kind: "domain",
@@ -679,16 +697,16 @@ function validateDomain(value, path, diagnostics) {
679
697
  ...base.metadata
680
698
  };
681
699
  }
682
- function validateCheckConstraint(value, path, diagnostics) {
683
- const constraint = validateConstraint(value, path, diagnostics);
700
+ function validateCheckConstraint(value, path, diagnostics, dialect) {
701
+ const constraint = validateConstraint(value, path, diagnostics, dialect);
684
702
  if (constraint?.kind !== "check") {
685
703
  diagnostics.push(issue("invalid-snapshot", "Domain constraints must be check constraints", path));
686
704
  return;
687
705
  }
688
706
  return constraint;
689
707
  }
690
- function validateCollation(value, path, diagnostics) {
691
- const base = validateBase(value, path, "collation", void 0, diagnostics, [
708
+ function validateCollation(value, path, diagnostics, dialect) {
709
+ const base = validateBase(value, path, "collation", dialect, diagnostics, [
692
710
  "provider",
693
711
  "locale",
694
712
  "deterministic",
@@ -710,8 +728,8 @@ function validateCollation(value, path, diagnostics) {
710
728
  ...base.metadata
711
729
  };
712
730
  }
713
- function validateTrigger(value, path, diagnostics) {
714
- const base = validateBase(value, path, "trigger", void 0, diagnostics, [
731
+ function validateTrigger(value, path, diagnostics, dialect) {
732
+ const base = validateBase(value, path, "trigger", dialect, diagnostics, [
715
733
  "table",
716
734
  "timing",
717
735
  "events",
@@ -725,8 +743,8 @@ function validateTrigger(value, path, diagnostics) {
725
743
  const timing = validateTimingKind(value.timing, [...path, "timing"], diagnostics);
726
744
  const events = validateEvents(value.events, [...path, "events"], diagnostics);
727
745
  const orientation = validateOrientation(value.orientation, [...path, "orientation"], diagnostics);
728
- const condition = value.condition === void 0 ? void 0 : validateExpression(value.condition, [...path, "condition"], diagnostics);
729
- const body = validateExpression(value.body, [...path, "body"], diagnostics);
746
+ const condition = value.condition === void 0 ? void 0 : validateExpression(value.condition, [...path, "condition"], diagnostics, dialect);
747
+ const body = validateExpression(value.body, [...path, "body"], diagnostics, dialect);
730
748
  const enabled = optionalBoolean(value.enabled, [...path, "enabled"], diagnostics);
731
749
  if (table === void 0 || timing === void 0 || events === void 0 || body === void 0) return;
732
750
  return {
@@ -743,8 +761,8 @@ function validateTrigger(value, path, diagnostics) {
743
761
  ...base.metadata
744
762
  };
745
763
  }
746
- function validateRoutine(value, path, diagnostics) {
747
- const base = validateBase(value, path, "routine", void 0, diagnostics, [
764
+ function validateRoutine(value, path, diagnostics, dialect) {
765
+ const base = validateBase(value, path, "routine", dialect, diagnostics, [
748
766
  "routineKind",
749
767
  "parameters",
750
768
  "returnType",
@@ -757,11 +775,11 @@ function validateRoutine(value, path, diagnostics) {
757
775
  ]);
758
776
  if (!isRecord(value) || base === void 0) return;
759
777
  const routineKind = validateRoutineKind(value.routineKind, [...path, "routineKind"], diagnostics);
760
- const parameters = validateArray(value.parameters, [...path, "parameters"], diagnostics, validateRoutineParameter);
778
+ const parameters = validateArray(value.parameters, [...path, "parameters"], diagnostics, validateRoutineParameter, dialect);
761
779
  if (parameters !== void 0) validateSortedPositions(parameters, [...path, "parameters"], diagnostics);
762
- const returnType = value.returnType === void 0 ? void 0 : validateStorage(value.returnType, [...path, "returnType"], diagnostics);
780
+ const returnType = value.returnType === void 0 ? void 0 : validateStorage(value.returnType, [...path, "returnType"], diagnostics, dialect);
763
781
  const language = value.language === void 0 ? void 0 : stringValue(value.language, [...path, "language"], diagnostics, true);
764
- const body = value.body === void 0 ? void 0 : validateExpression(value.body, [...path, "body"], diagnostics);
782
+ const body = value.body === void 0 ? void 0 : validateExpression(value.body, [...path, "body"], diagnostics, dialect);
765
783
  const volatility = validateChoice(value.volatility, [
766
784
  "immutable",
767
785
  "stable",
@@ -797,7 +815,7 @@ function validateRoutine(value, path, diagnostics) {
797
815
  ...base.metadata
798
816
  };
799
817
  }
800
- function validateRoutineParameter(value, path, diagnostics) {
818
+ function validateRoutineParameter(value, path, diagnostics, dialect) {
801
819
  if (!isRecord(value)) {
802
820
  diagnostics.push(issue("invalid-snapshot", "Routine parameter must be an object", path));
803
821
  return;
@@ -811,7 +829,8 @@ function validateRoutineParameter(value, path, diagnostics) {
811
829
  ], path, diagnostics, [
812
830
  "name",
813
831
  "mode",
814
- "default"
832
+ "default",
833
+ "provenance"
815
834
  ]);
816
835
  const name = value.name === void 0 ? void 0 : stringValue(value.name, [...path, "name"], diagnostics);
817
836
  const mode = validateChoice(value.mode, [
@@ -821,19 +840,21 @@ function validateRoutineParameter(value, path, diagnostics) {
821
840
  "variadic",
822
841
  "table"
823
842
  ], [...path, "mode"], diagnostics);
824
- const storage = validateStorage(value.storage, [...path, "storage"], diagnostics);
825
- const defaultValue = value.default === void 0 ? void 0 : validateValueFact(value.default, [...path, "default"], diagnostics);
843
+ const storage = validateStorage(value.storage, [...path, "storage"], diagnostics, dialect);
844
+ const defaultValue = value.default === void 0 ? void 0 : validateValueFact(value.default, [...path, "default"], diagnostics, dialect);
845
+ const provenance = value.provenance === void 0 ? void 0 : validateProvenance(value.provenance, [...path, "provenance"], dialect, diagnostics);
826
846
  const ordinalPosition = integerValue(value.ordinalPosition, [...path, "ordinalPosition"], diagnostics);
827
847
  return storage === void 0 || ordinalPosition === void 0 ? void 0 : {
828
848
  ...name === void 0 ? {} : { name },
829
849
  ...mode === void 0 ? {} : { mode },
830
850
  storage,
831
851
  ...defaultValue === void 0 ? {} : { default: defaultValue },
832
- ordinalPosition
852
+ ordinalPosition,
853
+ ...provenance === void 0 ? {} : { provenance }
833
854
  };
834
855
  }
835
- function validatePartition(value, path, diagnostics) {
836
- const base = validateBase(value, path, "partition", void 0, diagnostics, [
856
+ function validatePartition(value, path, diagnostics, dialect) {
857
+ const base = validateBase(value, path, "partition", dialect, diagnostics, [
837
858
  "parent",
838
859
  "strategy",
839
860
  "keyColumns",
@@ -850,7 +871,7 @@ function validatePartition(value, path, diagnostics) {
850
871
  "unknown"
851
872
  ], [...path, "strategy"], diagnostics);
852
873
  const keyColumns = value.keyColumns === void 0 ? void 0 : validateIds(value.keyColumns, [...path, "keyColumns"], diagnostics, false);
853
- const bound = value.bound === void 0 ? void 0 : validateExpression(value.bound, [...path, "bound"], diagnostics);
874
+ const bound = value.bound === void 0 ? void 0 : validateExpression(value.bound, [...path, "bound"], diagnostics, dialect);
854
875
  const defaultValue = optionalBoolean(value.default, [...path, "default"], diagnostics);
855
876
  if (parent === void 0 || strategy === void 0) return;
856
877
  return {
@@ -865,8 +886,8 @@ function validatePartition(value, path, diagnostics) {
865
886
  ...base.metadata
866
887
  };
867
888
  }
868
- function validatePolicy(value, path, diagnostics) {
869
- const base = validateBase(value, path, "policy", void 0, diagnostics, [
889
+ function validatePolicy(value, path, diagnostics, dialect) {
890
+ const base = validateBase(value, path, "policy", dialect, diagnostics, [
870
891
  "table",
871
892
  "command",
872
893
  "roles",
@@ -886,8 +907,8 @@ function validatePolicy(value, path, diagnostics) {
886
907
  ], [...path, "command"], diagnostics);
887
908
  const roles = value.roles === void 0 ? void 0 : validateStrings(value.roles, [...path, "roles"], diagnostics, false);
888
909
  const permissive = optionalBoolean(value.permissive, [...path, "permissive"], diagnostics);
889
- const using = value.using === void 0 ? void 0 : validateExpression(value.using, [...path, "using"], diagnostics);
890
- const check = value.check === void 0 ? void 0 : validateExpression(value.check, [...path, "check"], diagnostics);
910
+ const using = value.using === void 0 ? void 0 : validateExpression(value.using, [...path, "using"], diagnostics, dialect);
911
+ const check = value.check === void 0 ? void 0 : validateExpression(value.check, [...path, "check"], diagnostics, dialect);
891
912
  if (table === void 0 || command === void 0) return;
892
913
  return {
893
914
  kind: "policy",
@@ -902,8 +923,8 @@ function validatePolicy(value, path, diagnostics) {
902
923
  ...base.metadata
903
924
  };
904
925
  }
905
- function validateExtensionObject(value, path, diagnostics) {
906
- const base = validateBase(value, path, "extension", void 0, diagnostics, [
926
+ function validateExtensionObject(value, path, diagnostics, dialect) {
927
+ const base = validateBase(value, path, "extension", dialect, diagnostics, [
907
928
  "extensionName",
908
929
  "extensionVersion",
909
930
  "schema",
@@ -929,8 +950,8 @@ function validateExtensionObject(value, path, diagnostics) {
929
950
  ...base.metadata
930
951
  };
931
952
  }
932
- function validateDeferredObject(value, path, diagnostics) {
933
- const base = validateBase(value, path, "deferred-object", void 0, diagnostics, [
953
+ function validateDeferredObject(value, path, diagnostics, dialect) {
954
+ const base = validateBase(value, path, "deferred-object", dialect, diagnostics, [
934
955
  "objectKind",
935
956
  "reason",
936
957
  "data"
@@ -950,8 +971,8 @@ function validateDeferredObject(value, path, diagnostics) {
950
971
  ...base.metadata
951
972
  };
952
973
  }
953
- function validateOpaqueObject(value, path, diagnostics) {
954
- const base = validateBase(value, path, "opaque-object", void 0, diagnostics, [
974
+ function validateOpaqueObject(value, path, diagnostics, dialect) {
975
+ const base = validateBase(value, path, "opaque-object", dialect, diagnostics, [
955
976
  "objectKind",
956
977
  "data",
957
978
  "sql"
@@ -959,7 +980,7 @@ function validateOpaqueObject(value, path, diagnostics) {
959
980
  if (!isRecord(value) || base === void 0) return;
960
981
  const objectKind = stringValue(value.objectKind, [...path, "objectKind"], diagnostics, true);
961
982
  const data = validateJsonValue(value.data, [...path, "data"], diagnostics);
962
- const sql = value.sql === void 0 ? void 0 : validateExpression(value.sql, [...path, "sql"], diagnostics);
983
+ const sql = value.sql === void 0 ? void 0 : validateExpression(value.sql, [...path, "sql"], diagnostics, dialect);
963
984
  if (objectKind === void 0 || data === void 0) return;
964
985
  return {
965
986
  kind: "opaque-object",
@@ -971,8 +992,8 @@ function validateOpaqueObject(value, path, diagnostics) {
971
992
  ...base.metadata
972
993
  };
973
994
  }
974
- function validateComment(value, path, diagnostics) {
975
- const base = validateBase(value, path, "comment", void 0, diagnostics, ["object", "text"]);
995
+ function validateComment(value, path, diagnostics, dialect) {
996
+ const base = validateBase(value, path, "comment", dialect, diagnostics, ["object", "text"]);
976
997
  if (!isRecord(value) || base === void 0) return;
977
998
  const object = validateObjectReference(value.object, [...path, "object"], diagnostics);
978
999
  const text = stringValue(value.text, [...path, "text"], diagnostics);
@@ -986,8 +1007,8 @@ function validateComment(value, path, diagnostics) {
986
1007
  ...base.metadata
987
1008
  };
988
1009
  }
989
- function validateOwnership(value, path, diagnostics) {
990
- const base = validateBase(value, path, "ownership", void 0, diagnostics, ["object", "owner"]);
1010
+ function validateOwnership(value, path, diagnostics, dialect) {
1011
+ const base = validateBase(value, path, "ownership", dialect, diagnostics, ["object", "owner"]);
991
1012
  if (!isRecord(value) || base === void 0) return;
992
1013
  const object = validateObjectReference(value.object, [...path, "object"], diagnostics);
993
1014
  const owner = stringValue(value.owner, [...path, "owner"], diagnostics, true);
@@ -1001,7 +1022,7 @@ function validateOwnership(value, path, diagnostics) {
1001
1022
  ...base.metadata
1002
1023
  };
1003
1024
  }
1004
- function validateStorage(value, path, diagnostics) {
1025
+ function validateStorage(value, path, diagnostics, dialect) {
1005
1026
  if (!isRecord(value)) {
1006
1027
  diagnostics.push(issue("invalid-snapshot", "Storage must be an object", path));
1007
1028
  return;
@@ -1021,7 +1042,7 @@ function validateStorage(value, path, diagnostics) {
1021
1042
  "type",
1022
1043
  "affinity"
1023
1044
  ], path, diagnostics, ["affinity"]);
1024
- const dialect = stringValue(value.dialect, [...path, "dialect"], diagnostics, true);
1045
+ const storageDialect = stringValue(value.dialect, [...path, "dialect"], diagnostics, true);
1025
1046
  const type = stringValue(value.type, [...path, "type"], diagnostics, true);
1026
1047
  const affinity = value.affinity === void 0 ? void 0 : validateChoice(value.affinity, [
1027
1048
  "blob",
@@ -1030,17 +1051,18 @@ function validateStorage(value, path, diagnostics) {
1030
1051
  "real",
1031
1052
  "text"
1032
1053
  ], [...path, "affinity"], diagnostics);
1033
- if (dialect === void 0 || type === void 0) return;
1054
+ if (storageDialect === void 0 || type === void 0) return;
1055
+ if (dialect !== void 0 && storageDialect !== dialect) diagnostics.push(issue("dialect-mismatch", `Native storage belongs to "${storageDialect}" but snapshot dialect is "${dialect}"`, [...path, "dialect"]));
1034
1056
  return {
1035
1057
  kind: "native",
1036
- dialect,
1058
+ dialect: storageDialect,
1037
1059
  type,
1038
1060
  ...affinity === void 0 ? {} : { affinity }
1039
1061
  };
1040
1062
  }
1041
1063
  diagnostics.push(issue("invalid-snapshot", "Storage kind is invalid", [...path, "kind"]));
1042
1064
  }
1043
- function validateDefault(value, path, diagnostics) {
1065
+ function validateDefault(value, path, diagnostics, dialect) {
1044
1066
  if (!isRecord(value)) {
1045
1067
  diagnostics.push(issue("invalid-snapshot", "Default must be an object", path));
1046
1068
  return;
@@ -1059,7 +1081,7 @@ function validateDefault(value, path, diagnostics) {
1059
1081
  }
1060
1082
  if (value.kind === "expression") {
1061
1083
  requireKeys(value, ["kind", "expression"], path, diagnostics);
1062
- const expression = validateExpression(value.expression, [...path, "expression"], diagnostics);
1084
+ const expression = validateExpression(value.expression, [...path, "expression"], diagnostics, dialect);
1063
1085
  return expression === void 0 ? void 0 : {
1064
1086
  kind: "expression",
1065
1087
  expression
@@ -1067,7 +1089,7 @@ function validateDefault(value, path, diagnostics) {
1067
1089
  }
1068
1090
  diagnostics.push(issue("invalid-snapshot", "Default kind is invalid", [...path, "kind"]));
1069
1091
  }
1070
- function validateGenerated(value, path, diagnostics) {
1092
+ function validateGenerated(value, path, diagnostics, dialect) {
1071
1093
  if (!isRecord(value)) {
1072
1094
  diagnostics.push(issue("invalid-snapshot", "Generated-column metadata must be an object", path));
1073
1095
  return;
@@ -1082,7 +1104,7 @@ function validateGenerated(value, path, diagnostics) {
1082
1104
  "expression",
1083
1105
  "mode"
1084
1106
  ], path, diagnostics);
1085
- const expression = validateExpression(value.expression, [...path, "expression"], diagnostics);
1107
+ const expression = validateExpression(value.expression, [...path, "expression"], diagnostics, dialect);
1086
1108
  const mode = validateChoice(value.mode, ["stored", "virtual"], [...path, "mode"], diagnostics);
1087
1109
  return expression === void 0 || mode === void 0 ? void 0 : {
1088
1110
  kind: "expression",
@@ -1092,7 +1114,7 @@ function validateGenerated(value, path, diagnostics) {
1092
1114
  }
1093
1115
  diagnostics.push(issue("invalid-snapshot", "Generated-column kind is invalid", [...path, "kind"]));
1094
1116
  }
1095
- function validateIdentity(value, path, diagnostics) {
1117
+ function validateIdentity(value, path, diagnostics, dialect) {
1096
1118
  if (!isRecord(value)) {
1097
1119
  diagnostics.push(issue("invalid-snapshot", "Identity must be an object", path));
1098
1120
  return;
@@ -1111,8 +1133,8 @@ function validateIdentity(value, path, diagnostics) {
1111
1133
  ]);
1112
1134
  if (value.kind !== "identity") diagnostics.push(issue("invalid-snapshot", "Identity kind must be identity", [...path, "kind"]));
1113
1135
  const generation = validateChoice(value.generation, ["always", "by-default"], [...path, "generation"], diagnostics);
1114
- const options = validateValueFactRecord(value.options, [...path, "options"], diagnostics);
1115
- const metadata = validateObjectMetadata(value, path, void 0, diagnostics);
1136
+ const options = validateValueFactRecord(value.options, [...path, "options"], diagnostics, dialect);
1137
+ const metadata = validateObjectMetadata(value, path, dialect, diagnostics);
1116
1138
  if (generation === void 0 || options === void 0 || value.kind !== "identity") return;
1117
1139
  return {
1118
1140
  kind: "identity",
@@ -1121,7 +1143,7 @@ function validateIdentity(value, path, diagnostics) {
1121
1143
  ...metadata
1122
1144
  };
1123
1145
  }
1124
- function validateExpression(value, path, diagnostics) {
1146
+ function validateExpression(value, path, diagnostics, dialect) {
1125
1147
  if (!isRecord(value)) {
1126
1148
  diagnostics.push(issue("invalid-snapshot", "Expression must be an object", path));
1127
1149
  return;
@@ -1134,17 +1156,18 @@ function validateExpression(value, path, diagnostics) {
1134
1156
  ], path, diagnostics, ["dialect"]);
1135
1157
  const expressionKind = stringValue(value.expressionKind, [...path, "expressionKind"], diagnostics, true);
1136
1158
  const sql = stringValue(value.sql, [...path, "sql"], diagnostics);
1137
- const dialect = value.dialect === void 0 ? void 0 : stringValue(value.dialect, [...path, "dialect"], diagnostics, true);
1159
+ const expressionDialect = value.dialect === void 0 ? void 0 : stringValue(value.dialect, [...path, "dialect"], diagnostics, true);
1138
1160
  if (value.kind !== "expression") diagnostics.push(issue("invalid-snapshot", "Expression kind must be expression", [...path, "kind"]));
1139
1161
  if (sql !== void 0 && sql !== sql.replace(/\r\n?/g, "\n")) diagnostics.push(issue("non-canonical", "Expression SQL must use LF line endings", [...path, "sql"]));
1140
- if (expressionKind === "unsafe" && dialect === void 0) diagnostics.push(issue("invalid-snapshot", "Unsafe expressions must carry a dialect tag", [...path, "dialect"]));
1141
- if (expressionKind !== void 0 && expressionKind !== "unsafe" && dialect !== void 0) diagnostics.push(issue("invalid-snapshot", "Only unsafe expressions may carry a dialect tag", [...path, "dialect"]));
1162
+ if (expressionKind === "unsafe" && expressionDialect === void 0) diagnostics.push(issue("invalid-snapshot", "Unsafe expressions must carry a dialect tag", [...path, "dialect"]));
1163
+ if (expressionKind !== void 0 && expressionKind !== "unsafe" && expressionDialect !== void 0) diagnostics.push(issue("invalid-snapshot", "Only unsafe expressions may carry a dialect tag", [...path, "dialect"]));
1164
+ if (dialect !== void 0 && expressionDialect !== void 0 && expressionDialect !== dialect) diagnostics.push(issue("dialect-mismatch", `Expression belongs to "${expressionDialect}" but snapshot dialect is "${dialect}"`, [...path, "dialect"]));
1142
1165
  if (expressionKind === void 0 || sql === void 0 || value.kind !== "expression") return;
1143
1166
  return {
1144
1167
  kind: "expression",
1145
1168
  expressionKind,
1146
1169
  sql,
1147
- ...dialect === void 0 ? {} : { dialect }
1170
+ ...expressionDialect === void 0 ? {} : { dialect: expressionDialect }
1148
1171
  };
1149
1172
  }
1150
1173
  function validateLiteral(value, path, diagnostics) {
@@ -1177,7 +1200,7 @@ function validateLiteral(value, path, diagnostics) {
1177
1200
  }
1178
1201
  diagnostics.push(issue("invalid-snapshot", "Literal kind is invalid", [...path, "kind"]));
1179
1202
  }
1180
- function validateValueFact(value, path, diagnostics) {
1203
+ function validateValueFact(value, path, diagnostics, dialect) {
1181
1204
  if (!isRecord(value)) {
1182
1205
  diagnostics.push(issue("invalid-snapshot", "Value fact must be an object", path));
1183
1206
  return;
@@ -1192,7 +1215,7 @@ function validateValueFact(value, path, diagnostics) {
1192
1215
  }
1193
1216
  if (value.kind === "expression") {
1194
1217
  requireKeys(value, ["kind", "expression"], path, diagnostics);
1195
- const expression = validateExpression(value.expression, [...path, "expression"], diagnostics);
1218
+ const expression = validateExpression(value.expression, [...path, "expression"], diagnostics, dialect);
1196
1219
  return expression === void 0 ? void 0 : {
1197
1220
  kind: "expression",
1198
1221
  expression
@@ -1200,15 +1223,15 @@ function validateValueFact(value, path, diagnostics) {
1200
1223
  }
1201
1224
  diagnostics.push(issue("invalid-snapshot", "Value fact kind is invalid", [...path, "kind"]));
1202
1225
  }
1203
- function validateValueFactRecord(value, path, diagnostics) {
1226
+ function validateValueFactRecord(value, path, diagnostics, dialect) {
1204
1227
  if (!isRecord(value)) {
1205
1228
  diagnostics.push(issue("invalid-snapshot", "Value-fact options must be an object", path));
1206
1229
  return;
1207
1230
  }
1208
1231
  const result = {};
1209
1232
  for (const key of Object.keys(value).sort()) {
1210
- const fact = validateValueFact(value[key], [...path, key], diagnostics);
1211
- if (fact !== void 0) result[key] = fact;
1233
+ const fact = validateValueFact(value[key], [...path, key], diagnostics, dialect);
1234
+ if (fact !== void 0) setOwn$1(result, key, fact);
1212
1235
  }
1213
1236
  return result;
1214
1237
  }
@@ -1322,7 +1345,7 @@ function validateJsonValue(value, path, diagnostics, seen = /* @__PURE__ */ new
1322
1345
  const result = {};
1323
1346
  for (const key of Object.keys(value).sort()) {
1324
1347
  const child = validateJsonValue(value[key], [...path, key], diagnostics, seen);
1325
- if (child !== void 0) result[key] = child;
1348
+ if (child !== void 0) setOwn$1(result, key, child);
1326
1349
  }
1327
1350
  return result;
1328
1351
  } finally {
@@ -1334,12 +1357,28 @@ function validateObjectReference(value, path, diagnostics) {
1334
1357
  diagnostics.push(issue("invalid-snapshot", "Object reference must be an object", path));
1335
1358
  return;
1336
1359
  }
1337
- requireKeys(value, ["kind", "id"], path, diagnostics);
1360
+ requireKeys(value, ["kind", "id"], path, diagnostics, ["owner"]);
1338
1361
  const kind = stringValue(value.kind, [...path, "kind"], diagnostics, true);
1339
1362
  const id = stringValue(value.id, [...path, "id"], diagnostics, true);
1363
+ const owner = value.owner === void 0 ? void 0 : validateObjectOwner(value.owner, [...path, "owner"], diagnostics);
1340
1364
  if (kind === "namespace") diagnostics.push(issue("invalid-snapshot", "Object references cannot target a namespace", [...path, "kind"]));
1341
1365
  if (kind !== void 0 && !completeObjectKinds.has(kind)) diagnostics.push(issue("invalid-snapshot", `Unknown object reference kind: ${kind}`, [...path, "kind"]));
1342
- return kind === void 0 || id === void 0 || !completeObjectKinds.has(kind) || kind === "namespace" ? void 0 : {
1366
+ return kind === void 0 || id === void 0 || !completeObjectKinds.has(kind) || kind === "namespace" || value.owner !== void 0 && owner === void 0 ? void 0 : {
1367
+ kind,
1368
+ id,
1369
+ ...owner === void 0 ? {} : { owner }
1370
+ };
1371
+ }
1372
+ function validateObjectOwner(value, path, diagnostics) {
1373
+ if (!isRecord(value)) {
1374
+ diagnostics.push(issue("invalid-snapshot", "Object reference owner must be an object", path));
1375
+ return;
1376
+ }
1377
+ requireKeys(value, ["kind", "id"], path, diagnostics);
1378
+ const kind = stringValue(value.kind, [...path, "kind"], diagnostics, true);
1379
+ const id = stringValue(value.id, [...path, "id"], diagnostics, true);
1380
+ if (kind !== void 0 && !completeObjectOwnerKinds.has(kind)) diagnostics.push(issue("invalid-snapshot", `Unknown object reference owner kind: ${kind}`, [...path, "kind"]));
1381
+ return kind === void 0 || id === void 0 || !completeObjectOwnerKinds.has(kind) ? void 0 : {
1343
1382
  kind,
1344
1383
  id
1345
1384
  };
@@ -1383,14 +1422,14 @@ function validateStrings(value, path, diagnostics, nonEmpty) {
1383
1422
  if (nonEmpty && result.length === 0) diagnostics.push(issue("invalid-snapshot", "Array cannot be empty", path));
1384
1423
  return result;
1385
1424
  }
1386
- function validateArray(value, path, diagnostics, validate) {
1425
+ function validateArray(value, path, diagnostics, validate, dialect) {
1387
1426
  if (!Array.isArray(value)) {
1388
1427
  diagnostics.push(issue("invalid-snapshot", "Value must be an array", path));
1389
1428
  return;
1390
1429
  }
1391
1430
  const result = [];
1392
1431
  for (const [index, item] of value.entries()) {
1393
- const child = validate(item, [...path, index], diagnostics);
1432
+ const child = validate(item, [...path, index], diagnostics, dialect);
1394
1433
  if (child !== void 0) result.push(child);
1395
1434
  }
1396
1435
  return result;
@@ -1510,7 +1549,7 @@ function optionalBoolean(value, path, diagnostics) {
1510
1549
  return value === void 0 ? void 0 : booleanValue(value, path, diagnostics);
1511
1550
  }
1512
1551
  function isCanonicalNumber(value, integer) {
1513
- return integer ? /^(?:0|-[1-9]\d*|[1-9]\d*)$/u.test(value) : /^(?:0|-?(?:[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?|0(?:\.\d+)?(?:[eE][+-]?\d+)?)$/u.test(value);
1552
+ return integer ? /^(?:0|-[1-9]\d*|[1-9]\d*)$/u.test(value) : /^(?:(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?(?:0|[1-9]\d*))?|-[1-9]\d*(?:\.\d+)?(?:[eE][+-]?(?:0|[1-9]\d*))?|-0\.\d*[1-9]\d*(?:[eE][+-]?(?:0|[1-9]\d*))?)$/u.test(value);
1514
1553
  }
1515
1554
  const completeObjectKinds = /* @__PURE__ */ new Set([
1516
1555
  "table",
@@ -1533,91 +1572,135 @@ const completeObjectKinds = /* @__PURE__ */ new Set([
1533
1572
  "deferred-object",
1534
1573
  "opaque-object"
1535
1574
  ]);
1536
- function validateCompleteDialectMetadata(snapshot, diagnostics) {
1537
- const dialect = snapshot.dialect.name;
1538
- const objects = [
1539
- ...snapshot.tables,
1540
- ...snapshot.views,
1541
- ...snapshot.sequences,
1542
- ...snapshot.enums,
1543
- ...snapshot.domains,
1544
- ...snapshot.collations,
1545
- ...snapshot.triggers,
1546
- ...snapshot.routines,
1547
- ...snapshot.partitions,
1548
- ...snapshot.policies,
1549
- ...snapshot.extensions,
1550
- ...snapshot.deferredObjects,
1551
- ...snapshot.opaqueObjects,
1552
- ...snapshot.comments,
1553
- ...snapshot.ownership
1554
- ];
1555
- for (const object of objects) {
1556
- if (object.dialect?.dialect !== void 0 && object.dialect.dialect !== dialect) diagnostics.push(issue("dialect-mismatch", `Dialect extension belongs to "${object.dialect.dialect}" but snapshot dialect is "${dialect}"`, [
1557
- object.kind,
1558
- object.id,
1559
- "dialect",
1560
- "dialect"
1561
- ]));
1562
- if (object.provenance?.dialect !== void 0 && object.provenance.dialect !== dialect) diagnostics.push(issue("dialect-mismatch", `Provenance belongs to "${object.provenance.dialect}" but snapshot dialect is "${dialect}"`, [
1563
- object.kind,
1564
- object.id,
1565
- "provenance",
1566
- "dialect"
1567
- ]));
1568
- }
1569
- walkCompleteMetadata(snapshot, [], dialect, diagnostics);
1570
- }
1571
- function walkCompleteMetadata(value, path, dialect, diagnostics, seen = /* @__PURE__ */ new WeakSet()) {
1572
- if (value === null || typeof value !== "object") return;
1573
- if (seen.has(value)) return;
1574
- seen.add(value);
1575
- try {
1576
- if (Array.isArray(value)) {
1577
- for (const [index, child] of value.entries()) walkCompleteMetadata(child, [...path, index], dialect, diagnostics, seen);
1578
- return;
1579
- }
1580
- if (!isRecord(value)) return;
1581
- if (value.kind === "expression" && typeof value.dialect === "string" && value.dialect !== dialect) diagnostics.push(issue("dialect-mismatch", `Expression belongs to "${value.dialect}" but snapshot dialect is "${dialect}"`, [...path, "dialect"]));
1582
- if (value.kind === "native" && typeof value.dialect === "string" && value.dialect !== dialect) diagnostics.push(issue("dialect-mismatch", `Native storage belongs to "${value.dialect}" but snapshot dialect is "${dialect}"`, [...path, "dialect"]));
1583
- for (const [key, child] of Object.entries(value)) if (key !== "data") walkCompleteMetadata(child, [...path, key], dialect, diagnostics, seen);
1584
- } finally {
1585
- seen.delete(value);
1586
- }
1575
+ const completeObjectOwnerKinds = /* @__PURE__ */ new Set([
1576
+ "table",
1577
+ "view",
1578
+ "materialized-view",
1579
+ "domain"
1580
+ ]);
1581
+ const nestedReferenceOwnerKinds = /* @__PURE__ */ new Map([
1582
+ ["column", [
1583
+ "table",
1584
+ "view",
1585
+ "materialized-view"
1586
+ ]],
1587
+ ["constraint", ["table", "domain"]],
1588
+ ["index", ["table"]]
1589
+ ]);
1590
+ const constraintObjectKinds = /* @__PURE__ */ new Set([
1591
+ "primary-key",
1592
+ "unique",
1593
+ "unique-constraint",
1594
+ "foreign-key",
1595
+ "check"
1596
+ ]);
1597
+ function referenceKind(kind) {
1598
+ return constraintObjectKinds.has(kind) ? "constraint" : kind;
1587
1599
  }
1588
1600
  function validateCompleteCrossReferences(snapshot, diagnostics) {
1589
1601
  const objects = /* @__PURE__ */ new Map();
1590
- const add = (object) => {
1591
- const kind = object.kind;
1592
- objects.set(referenceKey(kind, object.id), object);
1593
- if (kind === "primary-key" || kind === "unique" || kind === "unique-constraint" || kind === "foreign-key" || kind === "check") objects.set(referenceKey("constraint", object.id), object);
1602
+ const add = (object, path, owner) => {
1603
+ const kind = referenceKind(object.kind);
1604
+ const key = referenceKey(owner, kind, object.id);
1605
+ if (objects.has(key)) {
1606
+ diagnostics.push(issue("invalid-cross-reference", `Duplicate ${kind} "${object.id}" in the same owner scope`, path));
1607
+ return;
1608
+ }
1609
+ objects.set(key, {
1610
+ object,
1611
+ path
1612
+ });
1594
1613
  };
1595
- for (const table of snapshot.tables) {
1596
- add(table);
1597
- for (const column of table.columns) add(column);
1598
- for (const constraint of table.constraints) add(constraint);
1599
- for (const index of table.indexes) add(index);
1600
- }
1601
- for (const group of [
1602
- snapshot.views,
1603
- snapshot.sequences,
1604
- snapshot.enums,
1605
- snapshot.domains,
1606
- snapshot.collations,
1607
- snapshot.triggers,
1608
- snapshot.routines,
1609
- snapshot.partitions,
1610
- snapshot.policies,
1611
- snapshot.extensions,
1612
- snapshot.deferredObjects,
1613
- snapshot.opaqueObjects,
1614
- snapshot.comments,
1615
- snapshot.ownership
1616
- ]) for (const object of group) add(object);
1617
- for (const view of snapshot.views) for (const column of view.columns) add(column);
1618
- const requireReference = (reference, path, expected) => {
1614
+ for (const [tableIndex, table] of snapshot.tables.entries()) {
1615
+ const tablePath = ["tables", tableIndex];
1616
+ const owner = {
1617
+ kind: "table",
1618
+ id: table.id
1619
+ };
1620
+ add(table, tablePath);
1621
+ for (const [columnIndex, column] of table.columns.entries()) add(column, [
1622
+ ...tablePath,
1623
+ "columns",
1624
+ columnIndex
1625
+ ], owner);
1626
+ for (const [constraintIndex, constraint] of table.constraints.entries()) add(constraint, [
1627
+ ...tablePath,
1628
+ "constraints",
1629
+ constraintIndex
1630
+ ], owner);
1631
+ for (const [indexIndex, index] of table.indexes.entries()) add(index, [
1632
+ ...tablePath,
1633
+ "indexes",
1634
+ indexIndex
1635
+ ], owner);
1636
+ }
1637
+ for (const [viewIndex, view] of snapshot.views.entries()) {
1638
+ const viewPath = ["views", viewIndex];
1639
+ const owner = {
1640
+ kind: view.kind,
1641
+ id: view.id
1642
+ };
1643
+ add(view, viewPath);
1644
+ for (const [columnIndex, column] of view.columns.entries()) add(column, [
1645
+ ...viewPath,
1646
+ "columns",
1647
+ columnIndex
1648
+ ], owner);
1649
+ }
1650
+ for (const [index, object] of snapshot.sequences.entries()) add(object, ["sequences", index]);
1651
+ for (const [index, object] of snapshot.enums.entries()) add(object, ["enums", index]);
1652
+ for (const [domainIndex, domain] of snapshot.domains.entries()) {
1653
+ const domainPath = ["domains", domainIndex];
1654
+ const owner = {
1655
+ kind: "domain",
1656
+ id: domain.id
1657
+ };
1658
+ add(domain, domainPath);
1659
+ for (const [constraintIndex, constraint] of (domain.constraints ?? []).entries()) add(constraint, [
1660
+ ...domainPath,
1661
+ "constraints",
1662
+ constraintIndex
1663
+ ], owner);
1664
+ }
1665
+ for (const [name, group] of [
1666
+ ["collations", snapshot.collations],
1667
+ ["triggers", snapshot.triggers],
1668
+ ["routines", snapshot.routines],
1669
+ ["partitions", snapshot.partitions],
1670
+ ["policies", snapshot.policies],
1671
+ ["extensions", snapshot.extensions],
1672
+ ["deferredObjects", snapshot.deferredObjects],
1673
+ ["opaqueObjects", snapshot.opaqueObjects],
1674
+ ["comments", snapshot.comments],
1675
+ ["ownership", snapshot.ownership]
1676
+ ]) for (const [index, object] of group.entries()) add(object, [name, index]);
1677
+ const requireReference = (reference, path, expected, requiredOwner) => {
1619
1678
  if (expected !== void 0 && reference.kind !== expected) diagnostics.push(issue("invalid-cross-reference", `Reference must target a ${expected}`, path));
1620
- if (!objects.has(referenceKey(reference.kind, reference.id))) diagnostics.push(issue("invalid-cross-reference", `Referenced ${reference.kind} "${reference.id}" does not exist`, path));
1679
+ const allowedOwnerKinds = nestedReferenceOwnerKinds.get(reference.kind);
1680
+ if (allowedOwnerKinds !== void 0) {
1681
+ if (reference.owner === void 0) {
1682
+ diagnostics.push(issue("invalid-cross-reference", `Reference to nested ${reference.kind} "${reference.id}" must include an owner scope`, [...path, "owner"]));
1683
+ return;
1684
+ }
1685
+ if (!allowedOwnerKinds.includes(reference.owner.kind)) {
1686
+ diagnostics.push(issue("invalid-cross-reference", `Owner kind "${reference.owner.kind}" cannot contain ${reference.kind} objects`, [
1687
+ ...path,
1688
+ "owner",
1689
+ "kind"
1690
+ ]));
1691
+ return;
1692
+ }
1693
+ } else if (reference.owner !== void 0) {
1694
+ diagnostics.push(issue("invalid-cross-reference", `Top-level ${reference.kind} references cannot include an owner scope`, [...path, "owner"]));
1695
+ return;
1696
+ }
1697
+ if (requiredOwner !== void 0 && (reference.owner === void 0 || reference.owner.kind !== requiredOwner.kind || reference.owner.id !== requiredOwner.id)) {
1698
+ diagnostics.push(issue("invalid-cross-reference", `Reference scope must target ${requiredOwner.kind} "${requiredOwner.id}"`, [...path, "owner"]));
1699
+ return;
1700
+ }
1701
+ const indexed = objects.get(referenceKey(reference.owner, reference.kind, reference.id));
1702
+ if (indexed === void 0) diagnostics.push(issue("invalid-cross-reference", `Referenced ${reference.kind} "${reference.id}" does not exist`, path));
1703
+ return indexed;
1621
1704
  };
1622
1705
  for (const [tableIndex, table] of snapshot.tables.entries()) {
1623
1706
  const columns = new Set(table.columns.map((column) => column.id));
@@ -1633,7 +1716,7 @@ function validateCompleteCrossReferences(snapshot, diagnostics) {
1633
1716
  ]));
1634
1717
  }
1635
1718
  if (constraint.kind === "foreign-key") {
1636
- requireReference(constraint.target.table, [
1719
+ const target = requireReference(constraint.target.table, [
1637
1720
  "tables",
1638
1721
  tableIndex,
1639
1722
  "constraints",
@@ -1641,10 +1724,9 @@ function validateCompleteCrossReferences(snapshot, diagnostics) {
1641
1724
  "target",
1642
1725
  "table"
1643
1726
  ], "table");
1644
- const target = objects.get(referenceKey(constraint.target.table.kind, constraint.target.table.id));
1645
- if (target?.kind === "table") {
1646
- const targetColumns = new Set(target.columns.map((column) => column.id));
1647
- for (const [columnIndex, column] of constraint.target.columns.entries()) if (!targetColumns.has(column)) diagnostics.push(issue("invalid-cross-reference", `Foreign-key target column "${column}" is not declared on table "${target.id}"`, [
1727
+ if (target?.object.kind === "table") {
1728
+ const targetColumns = new Set(target.object.columns.map((column) => column.id));
1729
+ for (const [columnIndex, column] of constraint.target.columns.entries()) if (!targetColumns.has(column)) diagnostics.push(issue("invalid-cross-reference", `Foreign-key target column "${column}" is not declared on table "${target.object.id}"`, [
1648
1730
  "tables",
1649
1731
  tableIndex,
1650
1732
  "constraints",
@@ -1661,7 +1743,10 @@ function validateCompleteCrossReferences(snapshot, diagnostics) {
1661
1743
  "constraints",
1662
1744
  constraintIndex,
1663
1745
  "backingIndex"
1664
- ], "index");
1746
+ ], "index", {
1747
+ kind: "table",
1748
+ id: table.id
1749
+ });
1665
1750
  }
1666
1751
  for (const [indexIndex, index] of table.indexes.entries()) {
1667
1752
  for (const [termIndex, term] of index.terms.entries()) if (term.kind === "column" && !columns.has(term.column)) diagnostics.push(issue("invalid-cross-reference", `Index column "${term.column}" is not declared on table "${table.id}"`, [
@@ -1687,7 +1772,10 @@ function validateCompleteCrossReferences(snapshot, diagnostics) {
1687
1772
  "indexes",
1688
1773
  indexIndex,
1689
1774
  "backingConstraint"
1690
- ], "constraint");
1775
+ ], "constraint", {
1776
+ kind: "table",
1777
+ id: table.id
1778
+ });
1691
1779
  }
1692
1780
  }
1693
1781
  for (const [index, sequence] of snapshot.sequences.entries()) if (sequence.ownedBy !== void 0) requireReference(sequence.ownedBy, [
@@ -1733,8 +1821,13 @@ function validateCompleteCrossReferences(snapshot, diagnostics) {
1733
1821
  "object"
1734
1822
  ]);
1735
1823
  }
1736
- function referenceKey(kind, id) {
1737
- return `${kind}\u0000${id}`;
1824
+ function referenceKey(owner, kind, id) {
1825
+ return JSON.stringify([
1826
+ owner?.kind ?? null,
1827
+ owner?.id ?? null,
1828
+ kind,
1829
+ id
1830
+ ]);
1738
1831
  }
1739
1832
  function validateSortedIds(value, path, diagnostics) {
1740
1833
  if (!Array.isArray(value)) return;
@@ -1761,6 +1854,15 @@ function validateSortedPositions(value, path, diagnostics) {
1761
1854
  if (position !== void 0) previous = position;
1762
1855
  }
1763
1856
  }
1857
+ function validateUniqueOrdinalPositions(value, path, diagnostics) {
1858
+ const positions = /* @__PURE__ */ new Map();
1859
+ for (const [index, item] of value.entries()) if (positions.get(item.ordinalPosition) !== void 0) diagnostics.push(issue("invalid-snapshot", `Column ordinal position ${item.ordinalPosition} is duplicated`, [
1860
+ ...path,
1861
+ index,
1862
+ "ordinalPosition"
1863
+ ]));
1864
+ else positions.set(item.ordinalPosition, index);
1865
+ }
1764
1866
  function requireKeys(value, required, path, diagnostics, optional = []) {
1765
1867
  const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
1766
1868
  for (const key of required) if (!optional.includes(key) && !(key in value)) diagnostics.push(issue("invalid-snapshot", `Missing required field "${key}"`, [...path, key]));
@@ -1776,6 +1878,14 @@ function issue(code, message, path) {
1776
1878
  path: Object.freeze([...path])
1777
1879
  };
1778
1880
  }
1881
+ function setOwn$1(target, key, value) {
1882
+ Object.defineProperty(target, key, {
1883
+ configurable: true,
1884
+ enumerable: true,
1885
+ value,
1886
+ writable: true
1887
+ });
1888
+ }
1779
1889
  function deepFreeze(value, seen = /* @__PURE__ */ new WeakSet()) {
1780
1890
  if (value === null || typeof value !== "object") return value;
1781
1891
  if (seen.has(value)) return value;
@@ -1785,4 +1895,119 @@ function deepFreeze(value, seen = /* @__PURE__ */ new WeakSet()) {
1785
1895
  return Object.freeze(value);
1786
1896
  }
1787
1897
  //#endregion
1788
- export { completeSchemaSnapshotVersion as _, canonicalizeCompleteSchemaSnapshot as a, schemaSnapshotVersion2 as b, decodeCompleteSchemaSnapshot as c, encodeCompleteSchemaSnapshot as d, encodeCompleteSnapshot as f, completeSchemaSnapshotFormat as g, schemaSnapshotV2Fingerprint as h, assertSchemaSnapshotV2 as i, decodeCompleteSnapshot as l, fingerprintCompleteSchemaSnapshot as m, assertCompleteSchemaSnapshot as n, canonicalizeSchemaSnapshotV2 as o, encodeSchemaSnapshotV2 as p, assertCompleteSnapshot as r, completeSchemaSnapshotFingerprint as s, CompleteSnapshotValidationError as t, decodeSchemaSnapshotV2 as u, schemaSnapshotCompleteVersion as v, schemaSnapshotV2Version as y };
1898
+ //#region src/snapshot/decode.ts
1899
+ /** Error raised by throwing snapshot APIs after collecting diagnostics. */
1900
+ var SnapshotValidationError = class extends CompleteSnapshotValidationError {
1901
+ name = "SnapshotValidationError";
1902
+ };
1903
+ /** Decode and strictly validate the canonical Snapshot v1 JSON value. */
1904
+ function decodeSchemaSnapshot(input) {
1905
+ return decodeCompleteSchemaSnapshot(input);
1906
+ }
1907
+ /** Validate a Snapshot v1 value and throw one structured error if it is malformed. */
1908
+ function assertSchemaSnapshot(input) {
1909
+ const result = decodeSchemaSnapshot(input);
1910
+ if (!result.ok) throw new SnapshotValidationError(result.diagnostics);
1911
+ return result.value;
1912
+ }
1913
+ /** Return a fixed-order, deeply immutable copy of a valid Snapshot v1 value. */
1914
+ function canonicalizeSchemaSnapshot(input) {
1915
+ return canonicalizeCompleteSchemaSnapshot(input);
1916
+ }
1917
+ //#endregion
1918
+ //#region src/snapshot/canonical.ts
1919
+ /** Error raised when a value cannot cross the canonical JSON boundary. */
1920
+ var SnapshotCanonicalError = class extends TypeError {
1921
+ path;
1922
+ constructor(message, path = []) {
1923
+ super(message);
1924
+ this.name = "SnapshotCanonicalError";
1925
+ this.path = Object.freeze([...path]);
1926
+ }
1927
+ };
1928
+ /** Convert a JavaScript value to the explicit JSON-safe snapshot domain. */
1929
+ function toSnapshotJsonValue(value, path = [], seen = /* @__PURE__ */ new WeakSet()) {
1930
+ if (value === null) return null;
1931
+ switch (typeof value) {
1932
+ case "string":
1933
+ case "boolean": return value;
1934
+ case "number":
1935
+ if (Number.isNaN(value)) return { $number: "NaN" };
1936
+ if (value === Infinity) return { $number: "Infinity" };
1937
+ if (value === -Infinity) return { $number: "-Infinity" };
1938
+ return Object.is(value, -0) ? 0 : value;
1939
+ case "bigint": return { $bigint: value.toString() };
1940
+ case "undefined":
1941
+ case "function":
1942
+ case "symbol": throw new SnapshotCanonicalError(`Snapshot values cannot contain ${typeof value}`, path);
1943
+ case "object": break;
1944
+ default: throw new SnapshotCanonicalError("Unsupported snapshot value", path);
1945
+ }
1946
+ if (seen.has(value)) throw new SnapshotCanonicalError("Snapshot values cannot be cyclic", path);
1947
+ seen.add(value);
1948
+ try {
1949
+ if (Array.isArray(value)) return Object.freeze(value.map((item, index) => toSnapshotJsonValue(item, [...path, index], seen)));
1950
+ const prototype = Object.getPrototypeOf(value);
1951
+ if (prototype !== Object.prototype && prototype !== null) throw new SnapshotCanonicalError("Snapshot values must be plain objects, arrays, or scalar values", path);
1952
+ const result = {};
1953
+ for (const key of Object.keys(value).sort()) setOwn(result, key, toSnapshotJsonValue(value[key], [...path, key], seen));
1954
+ return Object.freeze(result);
1955
+ } finally {
1956
+ seen.delete(value);
1957
+ }
1958
+ }
1959
+ /** Render a JSON-safe value with deterministic scalar and object handling. */
1960
+ function canonicalJson(value) {
1961
+ if (value === null) return "null";
1962
+ if (typeof value === "string") return JSON.stringify(value);
1963
+ if (typeof value === "boolean") return value ? "true" : "false";
1964
+ if (typeof value === "number") {
1965
+ if (!Number.isFinite(value)) throw new SnapshotCanonicalError("Non-finite numbers must use a tagged snapshot number");
1966
+ return Object.is(value, -0) ? "0" : JSON.stringify(value);
1967
+ }
1968
+ if (Array.isArray(value)) return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
1969
+ if (isSpecialNumber(value)) return `{"$number":${JSON.stringify(value.$number)}}`;
1970
+ if (isBigInt(value)) return `{"$bigint":${JSON.stringify(value.$bigint)}}`;
1971
+ const objectValue = value;
1972
+ return `{${Object.keys(objectValue).map((key) => `${JSON.stringify(key)}:${canonicalJson(objectValue[key])}`).join(",")}}`;
1973
+ }
1974
+ /** Canonical JSON for a schema snapshot after fixed-order reconstruction. */
1975
+ function encodeCanonicalSnapshot(snapshot) {
1976
+ return canonicalJson(assertSchemaSnapshot(snapshot));
1977
+ }
1978
+ /**
1979
+ * Compute a small deterministic content fingerprint for cache keys and diagnostics. It is
1980
+ * deliberately not an entity identity, signature, or migration lineage.
1981
+ */
1982
+ function schemaSnapshotFingerprint(snapshot) {
1983
+ const source = encodeCanonicalSnapshot(assertSchemaSnapshot(snapshot));
1984
+ let hash = 14695981039346656037n;
1985
+ const prime = 1099511628211n;
1986
+ const mask = 18446744073709551615n;
1987
+ for (let index = 0; index < source.length; index += 1) {
1988
+ const codePoint = source.codePointAt(index) ?? 0;
1989
+ if (codePoint > 65535) index += 1;
1990
+ const bytes = new TextEncoder().encode(String.fromCodePoint(codePoint));
1991
+ for (const byte of bytes) {
1992
+ hash ^= BigInt(byte);
1993
+ hash = hash * prime & mask;
1994
+ }
1995
+ }
1996
+ return `fnv1a64:${hash.toString(16).padStart(16, "0")}`;
1997
+ }
1998
+ function isSpecialNumber(value) {
1999
+ return Object.keys(value).length === 1 && "$number" in value && value.$number !== void 0;
2000
+ }
2001
+ function isBigInt(value) {
2002
+ return Object.keys(value).length === 1 && "$bigint" in value && typeof value.$bigint === "string";
2003
+ }
2004
+ function setOwn(target, key, value) {
2005
+ Object.defineProperty(target, key, {
2006
+ configurable: true,
2007
+ enumerable: true,
2008
+ value,
2009
+ writable: true
2010
+ });
2011
+ }
2012
+ //#endregion
2013
+ export { neutralSnapshotDialect as A, fingerprintCompleteSchemaSnapshot as C, schemaSnapshotCompleteVersion as D, completeSchemaSnapshotVersion as E, schemaSnapshotFormat as M, schemaSnapshotNamingPolicyVersion as N, schemaSnapshotV1Version as O, schemaSnapshotVersion as P, encodeSchemaSnapshotV1 as S, completeSchemaSnapshotFormat as T, decodeCompleteSchemaSnapshot as _, toSnapshotJsonValue as a, encodeCompleteSchemaSnapshot as b, canonicalizeSchemaSnapshot as c, assertCompleteSchemaSnapshot as d, assertCompleteSnapshot as f, completeSchemaSnapshotFingerprint as g, canonicalizeSchemaSnapshotV1 as h, schemaSnapshotFingerprint as i, schemaSnapshotDialectVersion as j, schemaSnapshotVersion1 as k, decodeSchemaSnapshot as l, canonicalizeCompleteSchemaSnapshot as m, canonicalJson as n, SnapshotValidationError as o, assertSchemaSnapshotV1 as p, encodeCanonicalSnapshot as r, assertSchemaSnapshot as s, SnapshotCanonicalError as t, CompleteSnapshotValidationError as u, decodeCompleteSnapshot as v, schemaSnapshotV1Fingerprint as w, encodeCompleteSnapshot as x, decodeSchemaSnapshotV1 as y };