@sequenceholdings/orm 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +57 -2
  2. package/dist/authoring.cjs +122 -15
  3. package/dist/authoring.cjs.map +1 -1
  4. package/dist/authoring.d.cts +20 -3
  5. package/dist/authoring.d.ts +20 -3
  6. package/dist/authoring.js +122 -15
  7. package/dist/authoring.js.map +1 -1
  8. package/dist/canonical.cjs +83 -9
  9. package/dist/canonical.cjs.map +1 -1
  10. package/dist/canonical.d.cts +47 -1
  11. package/dist/canonical.d.ts +47 -1
  12. package/dist/canonical.js +83 -10
  13. package/dist/canonical.js.map +1 -1
  14. package/dist/cli.cjs +721 -132
  15. package/dist/cli.cjs.map +1 -1
  16. package/dist/cli.js +723 -134
  17. package/dist/cli.js.map +1 -1
  18. package/dist/client.cjs.map +1 -1
  19. package/dist/client.js.map +1 -1
  20. package/dist/compiler.cjs +482 -96
  21. package/dist/compiler.cjs.map +1 -1
  22. package/dist/compiler.d.cts +34 -2
  23. package/dist/compiler.d.ts +34 -2
  24. package/dist/compiler.js +483 -97
  25. package/dist/compiler.js.map +1 -1
  26. package/dist/index.cjs +414 -70
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +266 -9
  29. package/dist/index.d.ts +266 -9
  30. package/dist/index.js +404 -72
  31. package/dist/index.js.map +1 -1
  32. package/dist/ir.cjs +146 -12
  33. package/dist/ir.cjs.map +1 -1
  34. package/dist/ir.d.cts +161 -5
  35. package/dist/ir.d.ts +161 -5
  36. package/dist/ir.js +144 -13
  37. package/dist/ir.js.map +1 -1
  38. package/dist/{naming-CTvWSRTf.d.ts → naming-DCn94LJ4.d.ts} +15 -1
  39. package/dist/{naming-DRyinU4u.d.cts → naming-DPglwzkB.d.cts} +15 -1
  40. package/dist/predicate-v2.cjs +130 -11
  41. package/dist/predicate-v2.cjs.map +1 -1
  42. package/dist/predicate-v2.js +130 -11
  43. package/dist/predicate-v2.js.map +1 -1
  44. package/dist/sdl.cjs +460 -13
  45. package/dist/sdl.cjs.map +1 -1
  46. package/dist/sdl.d.cts +1 -1
  47. package/dist/sdl.d.ts +1 -1
  48. package/dist/sdl.js +459 -14
  49. package/dist/sdl.js.map +1 -1
  50. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { sql, eq, notExists } from 'drizzle-orm';
1
+ import { sql, eq, notExists, is, SQL } from 'drizzle-orm';
2
2
  import { pgSchema, uniqueIndex, index, foreignKey, primaryKey, PgDialect, QueryBuilder, getViewConfig, extractUsedTable, jsonb, date, timestamp, boolean, doublePrecision, numeric, bigint, integer, text, uuid } from 'drizzle-orm/pg-core';
3
3
  import { createHash } from 'crypto';
4
4
  import { z } from 'zod';
@@ -34,6 +34,7 @@ var ColumnBuilder = class {
34
34
  hasDefault: false,
35
35
  defaultValue: void 0,
36
36
  defaultFn: void 0,
37
+ onUpdateFn: void 0,
37
38
  description: void 0,
38
39
  renamedFrom: void 0,
39
40
  cast: void 0,
@@ -69,6 +70,15 @@ var ColumnBuilder = class {
69
70
  this.state.defaultFn = void 0;
70
71
  return this;
71
72
  }
73
+ /**
74
+ * Stamp this column with Postgres `now()` on every UPDATE. Only valid on
75
+ * timestamptz/date; the compiler drops it from SetInput so callers cannot
76
+ * supply a value.
77
+ */
78
+ onUpdate(value) {
79
+ this.state.onUpdateFn = value;
80
+ return this;
81
+ }
72
82
  description(text4) {
73
83
  this.state.description = text4;
74
84
  return this;
@@ -112,6 +122,7 @@ var ColumnBuilder = class {
112
122
  };
113
123
  if (this.state.hasDefault) column.default = this.state.defaultValue ?? null;
114
124
  if (this.state.defaultFn !== void 0) column.defaultFn = this.state.defaultFn;
125
+ if (this.state.onUpdateFn !== void 0) column.onUpdateFn = this.state.onUpdateFn;
115
126
  if (this.state.description !== void 0) column.description = this.state.description;
116
127
  if (this.state.renamedFrom !== void 0) column.renamedFrom = this.state.renamedFrom;
117
128
  if (this.state.cast !== void 0) column.cast = this.state.cast;
@@ -139,6 +150,7 @@ var t = {
139
150
  // src/constants.ts
140
151
  var NAMESPACE_PATTERN = /^[a-z][a-z0-9_]{0,40}$/;
141
152
  var IDENTIFIER_PATTERN = /^[a-z][a-z0-9_]*$/;
153
+ var COLUMN_IDENTIFIER_PATTERN = /^_?[a-z][a-z0-9_]*$/;
142
154
  var MAX_IDENTIFIER_LENGTH = 63;
143
155
  var ORM_DATA_TOKEN_HEADER = "x-sequence-data-token";
144
156
  var ORM_SERVICE_DATA_TOKEN_HEADER = "x-sequence-data-token-service";
@@ -154,6 +166,8 @@ var DEFINITION_FILE_EXTENSIONS = [".yml", ".yaml"];
154
166
  var NAMESPACE_CONFIG_FILENAMES = /* @__PURE__ */ new Set(["namespace.yaml", "namespace.yml"]);
155
167
  var HASH_DOMAIN = "sequence-orm-definitions\0";
156
168
  var MAX_DEFINITION_FILE_BYTES = 1024 * 1024;
169
+ var MAX_GENERATED_SDL_BYTES = 16 * 1024 * 1024;
170
+ var ORM_REGISTRATION_MAX_BYTES = 64 * 1024 * 1024;
157
171
  var RESERVED_TABLE_NAMES = /* @__PURE__ */ new Set(["actions", "query"]);
158
172
  var RESERVED_COLUMN_NAMES = /* @__PURE__ */ new Set(["select", "order", "limit", "offset"]);
159
173
 
@@ -262,10 +276,10 @@ function isSeqLink(value) {
262
276
  function isSeqTable(value) {
263
277
  return typeof value === "object" && value !== null && value.kind === TABLE_BRAND;
264
278
  }
265
- function assertIdentifier({ value, what, file }) {
266
- if (!IDENTIFIER_PATTERN.test(value) || value.length > MAX_IDENTIFIER_LENGTH) {
279
+ function assertIdentifier({ value, what, file, pattern = IDENTIFIER_PATTERN }) {
280
+ if (!pattern.test(value) || value.length > MAX_IDENTIFIER_LENGTH) {
267
281
  throw new OrmDefinitionError(
268
- `${what} "${value}" must match ${IDENTIFIER_PATTERN} and be at most ${MAX_IDENTIFIER_LENGTH} characters`,
282
+ `${what} "${value}" must match ${pattern} and be at most ${MAX_IDENTIFIER_LENGTH} characters`,
269
283
  file
270
284
  );
271
285
  }
@@ -286,7 +300,7 @@ function defineTable(name, columns, config = {}) {
286
300
  );
287
301
  }
288
302
  const columnName = builder.columnNameFor(propertyName);
289
- assertIdentifier({ value: columnName, what: `table "${name}": column "${propertyName}" column name`, file });
303
+ assertIdentifier({ value: columnName, what: `table "${name}": column "${propertyName}" column name`, file, pattern: COLUMN_IDENTIFIER_PATTERN });
290
304
  const existing = seenColumnNames.get(columnName);
291
305
  if (existing !== void 0) {
292
306
  throw new OrmDefinitionError(
@@ -326,7 +340,8 @@ function defineSyncedTable(name, columnsOrConfig, maybeConfig) {
326
340
  assertIdentifier({
327
341
  value: columnName,
328
342
  what: `synced table "${name}": column "${propertyName}" column name`,
329
- file
343
+ file,
344
+ pattern: COLUMN_IDENTIFIER_PATTERN
330
345
  });
331
346
  const existing = seenColumnNames.get(columnName);
332
347
  if (existing !== void 0) {
@@ -415,7 +430,7 @@ function defineView(name, columns, config) {
415
430
  );
416
431
  }
417
432
  const columnName = builder.columnNameFor(propertyName);
418
- if (!IDENTIFIER_PATTERN.test(columnName) || columnName.length > MAX_IDENTIFIER_LENGTH) {
433
+ if (!COLUMN_IDENTIFIER_PATTERN.test(columnName) || columnName.length > MAX_IDENTIFIER_LENGTH) {
419
434
  throw new OrmDefinitionError(`view "${name}": column "${propertyName}" has invalid column name "${columnName}"`, file);
420
435
  }
421
436
  const existing = seenColumnNames.get(columnName);
@@ -864,6 +879,7 @@ function scalarColumnType(table, property, helper) {
864
879
  var CANONICAL_FORMAT = 2;
865
880
  var IDENTIFIER_RE = /^[a-z][a-z0-9_]*$/;
866
881
  var identifier = z.string().min(1).max(63).regex(IDENTIFIER_RE);
882
+ var columnIdentifier = z.string().min(1).max(63).regex(COLUMN_IDENTIFIER_PATTERN);
867
883
  var COLUMN_TYPES = [
868
884
  "uuid",
869
885
  "text",
@@ -884,18 +900,33 @@ var canonicalEnumSchema = z.object({
884
900
  var canonicalColumnSchema = z.object({
885
901
  /** Property name in TS (camelCase); columnName is the Postgres name. */
886
902
  name: z.string().min(1).max(63),
887
- columnName: identifier,
903
+ columnName: columnIdentifier,
888
904
  type: z.union([columnTypeSchema, z.object({ enum: identifier })]),
889
905
  nullable: z.boolean().default(true),
890
906
  unique: z.boolean().default(false),
891
907
  /** Literal default, or one of the allowlisted SQL functions. */
892
908
  default: z.union([z.string(), z.number(), z.boolean(), z.null()]).optional(),
893
909
  defaultFn: z.enum(["gen_random_uuid()", "now()"]).optional(),
910
+ /**
911
+ * Stamp this column from the database clock on UPDATE (`now()`). The
912
+ * column stays insertable (defaults fill gaps) but is omitted from
913
+ * SetInput / settable so callers cannot backdate it.
914
+ */
915
+ onUpdateFn: z.enum(["now()"]).optional(),
894
916
  description: z.string().max(500).optional(),
895
917
  /** Migration hints — same semantics as v1. */
896
- renamedFrom: identifier.optional(),
918
+ renamedFrom: columnIdentifier.optional(),
897
919
  cast: z.string().max(200).optional(),
898
920
  deprecated: z.boolean().default(false)
921
+ }).superRefine((column, ctx) => {
922
+ if (column.onUpdateFn === void 0) return;
923
+ if (typeof column.type !== "string" || column.type !== "timestamptz" && column.type !== "date") {
924
+ ctx.addIssue({
925
+ code: "custom",
926
+ path: ["onUpdateFn"],
927
+ message: `onUpdateFn '${column.onUpdateFn}' is only valid on timestamptz/date columns`
928
+ });
929
+ }
899
930
  });
900
931
  var canonicalLinkSchema = z.object({
901
932
  name: z.string().min(1).max(63),
@@ -903,15 +934,15 @@ var canonicalLinkSchema = z.object({
903
934
  /** Target table name (namespace-local). Absent for toPlatformUser. */
904
935
  target: identifier.optional(),
905
936
  /** FK column on the owning side (toOne/toPlatformUser: on this table; toMany: on the target). */
906
- on: identifier,
937
+ on: columnIdentifier,
907
938
  /** Referenced column on the target (default: target's PK / platform user `sub`). */
908
- references: identifier.optional(),
939
+ references: columnIdentifier.optional(),
909
940
  /** enforce: true emits a real FK constraint (same-namespace toOne only). */
910
941
  enforce: z.boolean().default(false),
911
942
  description: z.string().max(500).optional()
912
943
  });
913
944
  var canonicalIndexSchema = z.object({
914
- columns: z.array(identifier).min(1),
945
+ columns: z.array(columnIdentifier).min(1),
915
946
  unique: z.boolean().default(false),
916
947
  name: identifier.optional()
917
948
  });
@@ -1159,6 +1190,13 @@ var canonicalCowMutationSchema = z.object({
1159
1190
  }
1160
1191
  }
1161
1192
  });
1193
+ var canonicalForeignKeySchema = z.object({
1194
+ name: identifier,
1195
+ columns: z.array(columnIdentifier).min(1).max(8),
1196
+ target: identifier,
1197
+ references: z.array(columnIdentifier).min(1).max(8),
1198
+ deferrable: z.enum(["initially-immediate", "initially-deferred"]).optional()
1199
+ }).strict();
1162
1200
  var canonicalTableSchema = z.object({
1163
1201
  table: identifier,
1164
1202
  description: z.string().max(2e3).optional(),
@@ -1167,7 +1205,7 @@ var canonicalTableSchema = z.object({
1167
1205
  /** Synced/reflected read-only tables (`source: gold.*`) — v1 semantics. */
1168
1206
  source: z.string().regex(/^gold\.[a-z][a-z0-9_]*$/).optional(),
1169
1207
  columns: z.array(canonicalColumnSchema).default([]),
1170
- primaryKey: z.array(identifier).min(1).max(8).optional(),
1208
+ primaryKey: z.array(columnIdentifier).min(1).max(8).optional(),
1171
1209
  links: z.array(canonicalLinkSchema).default([]),
1172
1210
  indexes: z.array(canonicalIndexSchema).default([]),
1173
1211
  policies: canonicalPoliciesSchema.default({}),
@@ -1178,14 +1216,16 @@ var canonicalTableSchema = z.object({
1178
1216
  */
1179
1217
  actions: z.array(canonicalActionSchema).default([]),
1180
1218
  /** Optional (not defaulted) so pre-CoW canonical documents keep byte-identical hashes. */
1181
- cowMutations: z.array(canonicalCowMutationSchema).optional()
1219
+ cowMutations: z.array(canonicalCowMutationSchema).optional(),
1220
+ /** Omitted by old definitions, preserving their existing content hashes. */
1221
+ foreignKeys: z.array(canonicalForeignKeySchema).max(100).optional()
1182
1222
  });
1183
1223
  var canonicalViewSchema = z.object({
1184
1224
  view: identifier,
1185
1225
  description: z.string().max(2e3).optional(),
1186
1226
  columns: z.array(canonicalColumnSchema).min(1),
1187
1227
  /** Logical identity for GraphQL only; PostgreSQL views have no PK constraint. */
1188
- primaryKey: z.array(identifier).min(1).max(8).optional(),
1228
+ primaryKey: z.array(columnIdentifier).min(1).max(8).optional(),
1189
1229
  links: z.array(canonicalLinkSchema).default([]),
1190
1230
  policies: z.object({ read: policyExpressionSchema }).strict(),
1191
1231
  query: z.string().min(1).max(1e5).refine(isSingleViewQuerySql, {
@@ -1198,6 +1238,9 @@ var canonicalViewSchema = z.object({
1198
1238
  if (column.default !== void 0 || column.defaultFn !== void 0) {
1199
1239
  ctx.addIssue({ code: "custom", path: ["columns", index3], message: `view column '${column.name}' cannot declare a default` });
1200
1240
  }
1241
+ if (column.onUpdateFn !== void 0) {
1242
+ ctx.addIssue({ code: "custom", path: ["columns", index3], message: `view column '${column.name}' cannot declare onUpdateFn` });
1243
+ }
1201
1244
  if (column.unique) {
1202
1245
  ctx.addIssue({ code: "custom", path: ["columns", index3], message: `view column '${column.name}' cannot declare unique` });
1203
1246
  }
@@ -1231,6 +1274,45 @@ var canonicalDefinitionSchema = z.object({
1231
1274
  ctx.addIssue({ code: "custom", path: ["tables", index3, "table"], message: `duplicate relation '${table.table}'` });
1232
1275
  }
1233
1276
  seen.add(table.table);
1277
+ if (table.source !== void 0) {
1278
+ for (const [columnIndex, column] of table.columns.entries()) {
1279
+ if (column.onUpdateFn !== void 0) {
1280
+ ctx.addIssue({
1281
+ code: "custom",
1282
+ path: ["tables", index3, "columns", columnIndex],
1283
+ message: `synced table '${table.table}' column '${column.name}' cannot declare onUpdateFn`
1284
+ });
1285
+ }
1286
+ }
1287
+ }
1288
+ }
1289
+ const fkTables = new Map(definition.tables.map((table) => [table.table, table]));
1290
+ for (const [tableIndex, table] of definition.tables.entries()) {
1291
+ const names = /* @__PURE__ */ new Set([
1292
+ ...table.primaryKey?.length ? [`${table.table}_pkey`] : [],
1293
+ ...table.columns.filter((column) => column.unique && !(table.primaryKey?.length === 1 && table.primaryKey[0] === column.columnName)).map((column) => `${table.table}_${column.columnName}_unique`),
1294
+ ...table.links.filter((link) => link.enforce).map((link) => `fk_${table.table}_${link.name}`)
1295
+ ]);
1296
+ for (const [index3, fk] of (table.foreignKeys ?? []).entries()) {
1297
+ const fail = (message) => ctx.addIssue({ code: "custom", path: ["tables", tableIndex, "foreignKeys", index3], message });
1298
+ if (names.has(fk.name)) fail(`duplicate foreign key '${fk.name}'`);
1299
+ names.add(fk.name);
1300
+ const target = fkTables.get(fk.target);
1301
+ if (table.source || !target || target.source) {
1302
+ fail("foreign keys must connect owned tables in the same namespace");
1303
+ continue;
1304
+ }
1305
+ if (fk.columns.length !== fk.references.length) fail("foreign key columns and references must have the same number of columns");
1306
+ if (new Set(fk.columns).size !== fk.columns.length || new Set(fk.references).size !== fk.references.length) fail("foreign key columns must not repeat");
1307
+ for (const [position, name] of fk.columns.entries()) {
1308
+ const sourceColumn = table.columns.find((column) => column.columnName === name);
1309
+ const targetColumn = target.columns.find((column) => column.columnName === fk.references[position]);
1310
+ if (!sourceColumn || !targetColumn) fail("foreign key references an unknown column");
1311
+ else if (JSON.stringify(sourceColumn.type) !== JSON.stringify(targetColumn.type)) fail("foreign key column types must match");
1312
+ }
1313
+ const uniqueKeys = [target.primaryKey ?? [], ...target.indexes.filter((index4) => index4.unique).map((index4) => index4.columns), ...target.columns.filter((column) => column.unique).map((column) => [column.columnName])];
1314
+ if (!uniqueKeys.some((key) => key.length === fk.references.length && key.every((column) => fk.references.includes(column)))) fail("foreign key target columns must form a unique key");
1315
+ }
1234
1316
  }
1235
1317
  const tableByName = new Map(definition.tables.map((table) => [table.table, table]));
1236
1318
  for (const [tableIndex, table] of definition.tables.entries()) {
@@ -1366,12 +1448,13 @@ function normalizeCanonical(definition) {
1366
1448
  ...definition,
1367
1449
  enums: sortByName(definition.enums),
1368
1450
  tables: [...definition.tables].sort((a, b) => a.table.localeCompare(b.table)).map((t2) => {
1369
- const { cowMutations, ...rest } = t2;
1451
+ const { cowMutations, foreignKeys, ...rest } = t2;
1370
1452
  return {
1371
1453
  ...rest,
1372
1454
  links: sortByName(t2.links),
1373
1455
  indexes: [...t2.indexes].sort((a, b) => (a.name ?? a.columns.join("_")).localeCompare(b.name ?? b.columns.join("_"))),
1374
1456
  actions: sortByName(t2.actions),
1457
+ ...foreignKeys?.length ? { foreignKeys: sortByName(foreignKeys) } : {},
1375
1458
  // Omitted entirely when absent/empty so pre-CoW documents hash unchanged.
1376
1459
  ...cowMutations !== void 0 && cowMutations.length > 0 ? { cowMutations: sortByName(cowMutations) } : {}
1377
1460
  };
@@ -1645,6 +1728,22 @@ function buildCanonicalTable({ table, relationsByName, enumsByName }) {
1645
1728
  } else if (columnLevelPk.length > 0) {
1646
1729
  candidate.primaryKey = columnLevelPk;
1647
1730
  }
1731
+ if (table.config.foreignKeys?.length) {
1732
+ if (table.source) throw new OrmDefinitionError(`synced table "${table.tableName}" cannot enforce foreign keys`, table.file);
1733
+ candidate.foreignKeys = table.config.foreignKeys.map((fk) => {
1734
+ const target = resolveRelationRef({ ref: fk.target, fail: (message) => {
1735
+ throw new OrmDefinitionError(message, table.file);
1736
+ } });
1737
+ if (!isSeqTable(target) || !relationsByName.has(target.tableName)) throw new OrmDefinitionError("foreign key target must be a table in this namespace", table.file);
1738
+ return {
1739
+ name: fk.name,
1740
+ columns: fk.columns.map((ref) => resolveColumnRef({ relation: table, ref, role: `foreign key "${fk.name}" column` })),
1741
+ target: target.tableName,
1742
+ references: fk.references.map((ref) => resolveColumnRef({ relation: target, ref, role: `foreign key "${fk.name}" reference` })),
1743
+ ...fk.deferrable ? { deferrable: fk.deferrable } : {}
1744
+ };
1745
+ });
1746
+ }
1648
1747
  for (const index3 of table.config.indexes ?? []) {
1649
1748
  const entry = {
1650
1749
  columns: index3.columns.map((ref) => resolveColumnRef({ relation: table, ref, role: "index" }))
@@ -1697,6 +1796,12 @@ function buildCanonicalView({
1697
1796
  if (column.default !== void 0 || column.defaultFn !== void 0) {
1698
1797
  throw new OrmDefinitionError(`view "${view.viewName}": column "${propertyName}" cannot declare a default`, view.file);
1699
1798
  }
1799
+ if (column.onUpdateFn !== void 0) {
1800
+ throw new OrmDefinitionError(
1801
+ `view "${view.viewName}": column "${propertyName}" cannot declare onUpdateFn`,
1802
+ view.file
1803
+ );
1804
+ }
1700
1805
  if (column.unique) {
1701
1806
  throw new OrmDefinitionError(`view "${view.viewName}": column "${propertyName}" cannot declare unique`, view.file);
1702
1807
  }
@@ -1957,6 +2062,10 @@ async function loadNamespaceFromDir(dir, options = {}) {
1957
2062
  fsCache: false,
1958
2063
  ...options.ormModulePath !== void 0 ? {
1959
2064
  alias: {
2065
+ // The public /drizzle barrel re-exports this pinned dependency.
2066
+ // Explicitly map it before the root alias: otherwise jiti appends
2067
+ // "/drizzle" to the overridden module's filename.
2068
+ "@sequenceholdings/orm/drizzle": createRequire(import.meta.url).resolve("drizzle-orm"),
1960
2069
  "@sequenceholdings/orm": options.ormModulePath,
1961
2070
  "@sequenceholdings/orm/authoring": options.ormModulePath
1962
2071
  }
@@ -2519,8 +2628,8 @@ var actionSchema = z.strictObject({
2519
2628
  }
2520
2629
  }
2521
2630
  });
2522
- function extractNamedParams(sql4) {
2523
- const withoutStrings = sql4.replace(QUOTED_STRING_PATTERN, "''");
2631
+ function extractNamedParams(sql5) {
2632
+ const withoutStrings = sql5.replace(QUOTED_STRING_PATTERN, "''");
2524
2633
  const names = [...withoutStrings.matchAll(NAMED_PARAM_PATTERN)].map((match) => match[1]);
2525
2634
  return [...new Set(names)];
2526
2635
  }
@@ -2677,8 +2786,8 @@ var actionParamArg = (name) => `p_${name}`;
2677
2786
  function compileActionStatements(action, renderParam = actionParamArg) {
2678
2787
  return actionStatementSources(action.executes).map((statement) => compileStatement(statement, renderParam));
2679
2788
  }
2680
- function compileStatement(sql4, renderParam) {
2681
- const compiled = sql4.replace(TOKEN_PATTERN, (token, claimKey, capabilityKey, paramName) => {
2789
+ function compileStatement(sql5, renderParam) {
2790
+ const compiled = sql5.replace(TOKEN_PATTERN, (token, claimKey, capabilityKey, paramName) => {
2682
2791
  if (claimKey !== void 0) {
2683
2792
  if (!CLAIM_KEY_PATTERN.test(claimKey)) throw new OrmDefinitionError(`invalid claim key in executes: ${token}`);
2684
2793
  return claimExpression(claimKey);
@@ -2843,8 +2952,8 @@ function actionPrepareChecks(definition) {
2843
2952
  const order = actionParamOrder(action);
2844
2953
  const signature = order.length > 0 ? ` (${order.map((param) => sqlTypeName(action.params[param].type)).join(", ")})` : "";
2845
2954
  const compiled = compileActionStatements(action, (param) => `$${order.indexOf(param) + 1}`);
2846
- compiled.forEach((sql4, index3) => {
2847
- const checked = action.returns && index3 === compiled.length - 1 ? returnProjection(action.returns, sql4) : sql4;
2955
+ compiled.forEach((sql5, index3) => {
2956
+ const checked = action.returns && index3 === compiled.length - 1 ? returnProjection(action.returns, sql5) : sql5;
2848
2957
  statements.push(`PREPARE ${quoteIdentifier(`orm_check_${name}_${index3}`)}${signature} AS ${checked}`);
2849
2958
  });
2850
2959
  }
@@ -3298,7 +3407,8 @@ function syncedViewStatements({
3298
3407
  readPolicyIrByTable,
3299
3408
  columnNamesByTable,
3300
3409
  columnTypesByTable,
3301
- executionOwnerRole = SYNCED_VIEW_EXECUTION_OWNER_ROLE
3410
+ executionOwnerRole = SYNCED_VIEW_EXECUTION_OWNER_ROLE,
3411
+ backingPrivileges = "grant"
3302
3412
  }) {
3303
3413
  const schema = quoteIdentifier(ormSchemaName(definition.namespace));
3304
3414
  const role = quoteIdentifier(consumerRoleName(definition.namespace));
@@ -3332,8 +3442,10 @@ function syncedViewStatements({
3332
3442
  columnTypes,
3333
3443
  columnNames: columnNamesByTable?.get(table.table)
3334
3444
  })}` : readPolicy ? ` WHERE ${compilePredicate(readPolicy.ast, narrowToV1ColumnTypes(columnTypes))}` : " WHERE false";
3335
- statements.push(`GRANT USAGE ON SCHEMA ${quoteIdentifier(physical.schema)} TO ${owner}`);
3336
- statements.push(`GRANT SELECT ON ${physicalTarget} TO ${owner}`);
3445
+ if (backingPrivileges === "grant") {
3446
+ statements.push(`GRANT USAGE ON SCHEMA ${quoteIdentifier(physical.schema)} TO ${owner}`);
3447
+ statements.push(`GRANT SELECT ON ${physicalTarget} TO ${owner}`);
3448
+ }
3337
3449
  statements.push(
3338
3450
  `CREATE OR REPLACE VIEW ${viewName} AS SELECT * FROM ${physicalTarget}${whereClause}`
3339
3451
  );
@@ -3622,7 +3734,7 @@ var FACTORIES2 = {
3622
3734
  var SCHEMA_IMPORT_KEY2 = "$schema";
3623
3735
  var enumImportKey = (name) => `$enum_${name}`;
3624
3736
  var columnTablesV2 = (definition) => definition.tables.filter((table) => !table.source);
3625
- function buildDrizzleEntitiesV2(definition) {
3737
+ function buildDrizzleEntitiesV2(definition, options = {}) {
3626
3738
  const schemaName = ormSchemaName(definition.namespace);
3627
3739
  const schema = pgSchema(schemaName);
3628
3740
  const imports = { [SCHEMA_IMPORT_KEY2]: schema };
@@ -3637,11 +3749,19 @@ function buildDrizzleEntitiesV2(definition) {
3637
3749
  }
3638
3750
  const byName = new Map(definition.tables.map((table) => [table.table, table]));
3639
3751
  for (const table of sortByEnforcedLinks2(columnTablesV2(definition))) {
3640
- const drizzleTable = buildTable2(schema, table, built, enums, byName);
3752
+ const drizzleTable = buildTable2(schema, table, built, enums, byName, options.introspection ?? false);
3641
3753
  built.set(table.table, drizzleTable);
3642
3754
  imports[table.table] = drizzleTable;
3643
3755
  tables[table.table] = drizzleTable;
3644
3756
  }
3757
+ if (options.introspection) {
3758
+ for (const table of definition.tables.filter((table2) => table2.source)) {
3759
+ const columns = Object.fromEntries(
3760
+ table.columns.map((column) => [column.columnName, buildViewColumnV2({ view: table.table, column, enums })])
3761
+ );
3762
+ imports[table.table] = schema.view(table.table, columns).existing();
3763
+ }
3764
+ }
3645
3765
  for (const view of definition.views ?? []) {
3646
3766
  const columns = Object.fromEntries(
3647
3767
  view.columns.map((column) => [column.columnName, buildViewColumnV2({ view: view.view, column, enums })])
@@ -3709,18 +3829,18 @@ function rewriteSyncedSourceRelationsInViewQuery({
3709
3829
  return rewritten;
3710
3830
  });
3711
3831
  }
3712
- function transformSqlOutsideLiterals(sql4, transform) {
3832
+ function transformSqlOutsideLiterals(sql5, transform) {
3713
3833
  const out = [];
3714
3834
  let state = { kind: "normal" };
3715
3835
  let i = 0;
3716
3836
  let codeStart = 0;
3717
3837
  const emitCode = (end) => {
3718
- if (end > codeStart) out.push(transform(sql4.slice(codeStart, end)));
3838
+ if (end > codeStart) out.push(transform(sql5.slice(codeStart, end)));
3719
3839
  codeStart = end;
3720
3840
  };
3721
- while (i < sql4.length) {
3722
- const c = sql4[i];
3723
- const next = i + 1 < sql4.length ? sql4[i + 1] : "";
3841
+ while (i < sql5.length) {
3842
+ const c = sql5[i];
3843
+ const next = i + 1 < sql5.length ? sql5[i + 1] : "";
3724
3844
  switch (state.kind) {
3725
3845
  case "normal": {
3726
3846
  if (c === "-" && next === "-") {
@@ -3740,7 +3860,7 @@ function transformSqlOutsideLiterals(sql4, transform) {
3740
3860
  break;
3741
3861
  }
3742
3862
  if ((c === "E" || c === "e") && next === "'") {
3743
- const prev = i > 0 ? sql4[i - 1] : "";
3863
+ const prev = i > 0 ? sql5[i - 1] : "";
3744
3864
  if (!/[A-Za-z0-9_]/.test(prev)) {
3745
3865
  emitCode(i);
3746
3866
  state = { kind: "e-single" };
@@ -3759,9 +3879,9 @@ function transformSqlOutsideLiterals(sql4, transform) {
3759
3879
  break;
3760
3880
  }
3761
3881
  if (c === "$") {
3762
- const prev = i > 0 ? sql4[i - 1] : "";
3882
+ const prev = i > 0 ? sql5[i - 1] : "";
3763
3883
  if (!/[A-Za-z0-9_$]/.test(prev)) {
3764
- const tagMatch = /^\$([A-Za-z_][A-Za-z0-9_]*)?\$/.exec(sql4.slice(i));
3884
+ const tagMatch = /^\$([A-Za-z_][A-Za-z0-9_]*)?\$/.exec(sql5.slice(i));
3765
3885
  if (tagMatch) {
3766
3886
  emitCode(i);
3767
3887
  state = { kind: "dollar", tag: tagMatch[1] ?? "" };
@@ -3793,8 +3913,8 @@ function transformSqlOutsideLiterals(sql4, transform) {
3793
3913
  break;
3794
3914
  }
3795
3915
  case "e-single": {
3796
- if (c === "\\" && i + 1 < sql4.length) {
3797
- out.push(c, sql4[i + 1]);
3916
+ if (c === "\\" && i + 1 < sql5.length) {
3917
+ out.push(c, sql5[i + 1]);
3798
3918
  i += 2;
3799
3919
  break;
3800
3920
  }
@@ -3816,7 +3936,7 @@ function transformSqlOutsideLiterals(sql4, transform) {
3816
3936
  }
3817
3937
  case "dollar": {
3818
3938
  const closer = `$${state.tag}$`;
3819
- if (sql4.startsWith(closer, i)) {
3939
+ if (sql5.startsWith(closer, i)) {
3820
3940
  out.push(closer);
3821
3941
  state = { kind: "normal" };
3822
3942
  i += closer.length;
@@ -3860,15 +3980,15 @@ function transformSqlOutsideLiterals(sql4, transform) {
3860
3980
  }
3861
3981
  }
3862
3982
  }
3863
- emitCode(sql4.length);
3983
+ emitCode(sql5.length);
3864
3984
  return out.join("");
3865
3985
  }
3866
3986
  function escapeRegExp(value) {
3867
3987
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3868
3988
  }
3869
- function sqlReferencesQualifiedRelation(sql4, sourceSchema, sourceName) {
3989
+ function sqlReferencesQualifiedRelation(sql5, sourceSchema, sourceName) {
3870
3990
  let referenced = false;
3871
- transformSqlOutsideLiterals(sql4, (segment) => {
3991
+ transformSqlOutsideLiterals(sql5, (segment) => {
3872
3992
  if (qualifiedRelationPattern(sourceSchema, sourceName).test(segment)) referenced = true;
3873
3993
  return segment;
3874
3994
  });
@@ -3879,15 +3999,16 @@ function qualifiedRelationPattern(sourceSchema, sourceName) {
3879
3999
  const namePattern = `(?:"${escapeRegExp(sourceName)}"|${escapeRegExp(sourceName)})`;
3880
4000
  return new RegExp(`(?<![\\w."])${schemaPattern}\\.${namePattern}(?![\\w"])`, "g");
3881
4001
  }
3882
- function replaceQualifiedRelation(sql4, sourceSchema, sourceName, boundSchema, boundTable) {
3883
- return sql4.replace(qualifiedRelationPattern(sourceSchema, sourceName), `"${boundSchema}"."${boundTable}"`);
4002
+ function replaceQualifiedRelation(sql5, sourceSchema, sourceName, boundSchema, boundTable) {
4003
+ return sql5.replace(qualifiedRelationPattern(sourceSchema, sourceName), `"${boundSchema}"."${boundTable}"`);
3884
4004
  }
3885
4005
  function generateSnapshotV2(definition, previousId3) {
3886
4006
  const { imports, schemaName } = buildDrizzleEntitiesV2(definition);
3887
4007
  const snapshot = generateDrizzleJson(imports, previousId3, [schemaName]);
3888
- if ((definition.views?.length ?? 0) > 0) {
4008
+ if ((definition.views?.length ?? 0) > 0 || definition.tables.some((table) => table.foreignKeys?.length)) {
3889
4009
  const extended = snapshot;
3890
4010
  extended._sequenceOrm = {
4011
+ ...definition.tables.some((table) => table.foreignKeys?.length) ? { foreignKeys: Object.fromEntries(definition.tables.flatMap((table) => (table.foreignKeys ?? []).map((fk) => [`${table.table}.${fk.name}`, structuredClone(fk)]))) } : {},
3891
4012
  viewDependencies: Object.fromEntries(
3892
4013
  (definition.views ?? []).map((view) => [view.view, [...view.dependencies].sort()])
3893
4014
  )
@@ -3905,7 +4026,7 @@ function buildViewColumnV2({
3905
4026
  if (!column.nullable) builder = builder.notNull();
3906
4027
  return builder;
3907
4028
  }
3908
- function buildTable2(schema, table, built, enums, byName) {
4029
+ function buildTable2(schema, table, built, enums, byName, introspection) {
3909
4030
  const primaryKeyColumns = table.primaryKey ?? [];
3910
4031
  if (primaryKeyColumns.length === 0) {
3911
4032
  throw new OrmDefinitionError(`table '${table.table}' declares no primaryKey`);
@@ -3921,13 +4042,22 @@ function buildTable2(schema, table, built, enums, byName) {
3921
4042
  const columns = Object.fromEntries(
3922
4043
  table.columns.map((column) => [
3923
4044
  column.columnName,
3924
- buildColumnV2({ table: table.table, column, singlePrimaryKey, compositeMembers, enums })
4045
+ buildColumnV2({ table: table.table, column, singlePrimaryKey, compositeMembers, enums, introspection })
3925
4046
  ])
3926
4047
  );
3927
4048
  const drizzleTable = schema.table(table.table, columns, (self) => [
3928
4049
  ...buildCompositePrimaryKey(table, primaryKeyColumns, self),
3929
4050
  ...buildIndexes2(table, self),
3930
- ...buildForeignKeys2(table, self, built, byName)
4051
+ ...buildForeignKeys2(table, self, built, byName),
4052
+ ...(table.foreignKeys ?? []).map((fk) => {
4053
+ const target = fk.target === table.table ? self : built.get(fk.target);
4054
+ if (!target) throw new OrmDefinitionError(`foreign key '${fk.name}' has no target '${fk.target}'`);
4055
+ return foreignKey({
4056
+ name: fk.name,
4057
+ columns: fk.columns.map((column) => self[column]),
4058
+ foreignColumns: fk.references.map((column) => target[column])
4059
+ });
4060
+ })
3931
4061
  ]);
3932
4062
  return drizzleTable.enableRLS();
3933
4063
  }
@@ -3944,7 +4074,8 @@ function buildColumnV2({
3944
4074
  column,
3945
4075
  singlePrimaryKey,
3946
4076
  compositeMembers,
3947
- enums
4077
+ enums,
4078
+ introspection
3948
4079
  }) {
3949
4080
  const factory = resolveColumnFactory(table, column, enums);
3950
4081
  let builder = factory(column.columnName);
@@ -3965,7 +4096,7 @@ function buildColumnV2({
3965
4096
  }
3966
4097
  builder = builder.default(sql.raw(column.defaultFn));
3967
4098
  } else if (column.default !== void 0 && column.default !== null) {
3968
- builder = builder.default(column.default);
4099
+ builder = introspection && column.type === "jsonb" && typeof column.default === "string" ? builder.default(sql.raw(`${quoteLiteral(column.default)}::jsonb`)) : builder.default(column.default);
3969
4100
  }
3970
4101
  return builder;
3971
4102
  }
@@ -4150,7 +4281,8 @@ async function planMigrationV2({
4150
4281
  assertValidViewDependencies(canonical);
4151
4282
  const hints = applyMigrationHintsV2(previous, canonical);
4152
4283
  const snapshot = generateSnapshotV2(canonical, previousId(previous));
4153
- const baseDdl = await diffStatements(withoutViews(hints.adjusted), withoutViews(snapshot));
4284
+ const generatedBaseDdl = await diffStatements(withoutViews(hints.adjusted), withoutViews(snapshot));
4285
+ const baseDdl = orderForeignKeyAdditions(canonical, generatedBaseDdl);
4154
4286
  const previousViews = snapshotViews(hints.adjusted);
4155
4287
  const currentViews = snapshotViews(snapshot);
4156
4288
  const previousDependencies = snapshotViewDependencies(hints.adjusted);
@@ -4187,6 +4319,7 @@ async function planMigrationV2({
4187
4319
  ...dropOrder.map((name) => ({ kind: "ddl", sql: requiredViewStatement(dropDdl, name, schema, "DROP") })),
4188
4320
  ...hints.statements.map((statement) => ({ kind: "hint", sql: statement })),
4189
4321
  ...baseDdl.map((statement) => ({ kind: "ddl", sql: statement.replace(/;\s*$/, "") })),
4322
+ ...foreignKeyTimingStatements(canonical, previous, baseDdl).map((sql5) => ({ kind: "ddl", sql: sql5 })),
4190
4323
  ...createOrder.map((name) => ({ kind: "ddl", sql: requiredViewStatement(createDdl, name, schema, "CREATE") })),
4191
4324
  ...createOrder.map((name) => {
4192
4325
  const view = currentViewDefinitions.get(name);
@@ -4196,6 +4329,29 @@ async function planMigrationV2({
4196
4329
  ];
4197
4330
  return { namespace: canonical.namespace, schema, statements, snapshot };
4198
4331
  }
4332
+ function orderForeignKeyAdditions(canonical, statements) {
4333
+ if (!canonical.tables.some((table) => table.foreignKeys?.length)) return [...statements];
4334
+ const addsForeignKey = (statement) => /^ALTER TABLE[\s\S]* ADD CONSTRAINT[\s\S]* FOREIGN KEY\b/.test(statement);
4335
+ return [...statements.filter((statement) => !addsForeignKey(statement)), ...statements.filter(addsForeignKey)];
4336
+ }
4337
+ function foreignKeyTimingStatements(canonical, previous, baseDdl) {
4338
+ const prior = previous._sequenceOrm?.foreignKeys ?? {};
4339
+ const result = [];
4340
+ for (const table of canonical.tables) {
4341
+ for (const fk of table.foreignKeys ?? []) {
4342
+ const before = prior[`${table.table}.${fk.name}`];
4343
+ const recreated = baseDdl.some((statement) => statement.includes(`ALTER TABLE ${quoteIdentifier(ormSchemaName(canonical.namespace))}.${quoteIdentifier(table.table)} ADD CONSTRAINT ${quoteIdentifier(fk.name)}`));
4344
+ if (fk.deferrable ? !before || before.deferrable !== fk.deferrable || recreated : before?.deferrable && !recreated) {
4345
+ result.push(foreignKeyTimingSql(ormSchemaName(canonical.namespace), table.table, fk.name, fk.deferrable));
4346
+ }
4347
+ }
4348
+ }
4349
+ return result;
4350
+ }
4351
+ function foreignKeyTimingSql(schema, table, name, timing) {
4352
+ const clause = timing === void 0 ? "NOT DEFERRABLE" : timing === "initially-deferred" ? "DEFERRABLE INITIALLY DEFERRED" : "DEFERRABLE INITIALLY IMMEDIATE";
4353
+ return `ALTER TABLE ${quoteIdentifier(schema)}.${quoteIdentifier(table)} ALTER CONSTRAINT ${quoteIdentifier(name)} ${clause}`;
4354
+ }
4199
4355
  function validateViewCatalogStatement({
4200
4356
  canonical,
4201
4357
  view,
@@ -4450,7 +4606,63 @@ async function pendingKitStatementsV2({
4450
4606
  canonical,
4451
4607
  db
4452
4608
  }) {
4453
- return pendingStatements({ entities: buildDrizzleEntitiesV2(canonical), db, owned: V2_OWNED_STATEMENT });
4609
+ const { desired, defaultDrift } = await normalizeJsonDefaultsForIntrospection(canonical, db);
4610
+ const entities = buildDrizzleEntitiesV2(desired, { introspection: true });
4611
+ const pending = await pendingStatements({ entities, db, owned: V2_OWNED_STATEMENT });
4612
+ return [...orderForeignKeyAdditions(canonical, pending), ...defaultDrift, ...await pendingForeignKeyTimingStatements(canonical, db)];
4613
+ }
4614
+ async function normalizeJsonDefaultsForIntrospection(canonical, db) {
4615
+ const defaults = canonical.tables.flatMap((table, tableIndex) => table.source ? [] : table.columns.flatMap((column, columnIndex) => column.type === "jsonb" && typeof column.default === "string" ? [{ tableIndex, columnIndex, table: table.table, column: column.columnName, value: column.default }] : []));
4616
+ if (defaults.length === 0) return { desired: canonical, defaultDrift: [] };
4617
+ const array = (values) => sql`ARRAY[${sql.join(values.map((value) => sql`${value}`), sql`, `)}]::text[]`;
4618
+ const schema = ormSchemaName(canonical.namespace);
4619
+ const result = await shimExecute(db).execute(sql`
4620
+ SELECT desired.ordinal, desired.value::jsonb::text AS normalized,
4621
+ attribute.attnum IS NOT NULL AS column_exists,
4622
+ coalesce(pg_get_expr(ad.adbin, ad.adrelid) = quote_literal(desired.value::jsonb::text) || '::jsonb', false) AS matches
4623
+ FROM unnest(${array(defaults.map((item) => item.table))}, ${array(defaults.map((item) => item.column))}, ${array(defaults.map((item) => item.value))})
4624
+ WITH ORDINALITY AS desired(table_name, column_name, value, ordinal)
4625
+ LEFT JOIN pg_catalog.pg_namespace namespace ON namespace.nspname = ${schema}
4626
+ LEFT JOIN pg_catalog.pg_class relation ON relation.relnamespace = namespace.oid AND relation.relname = desired.table_name
4627
+ LEFT JOIN pg_catalog.pg_attribute attribute ON attribute.attrelid = relation.oid AND attribute.attname = desired.column_name AND NOT attribute.attisdropped
4628
+ LEFT JOIN pg_catalog.pg_attrdef ad ON ad.adrelid = relation.oid AND ad.adnum = attribute.attnum
4629
+ ORDER BY desired.ordinal
4630
+ `);
4631
+ const rows = result.rows;
4632
+ if (!Array.isArray(rows) || rows.length !== defaults.length || rows.some((row, index3) => Number(row.ordinal) !== index3 + 1 || typeof row.normalized !== "string" || typeof row.column_exists !== "boolean" || typeof row.matches !== "boolean")) {
4633
+ throw new Error("invalid JSON default introspection result");
4634
+ }
4635
+ const desired = structuredClone(canonical);
4636
+ const defaultDrift = [];
4637
+ defaults.forEach((item, index3) => {
4638
+ const row = rows[index3];
4639
+ desired.tables[item.tableIndex].columns[item.columnIndex].default = JSON.stringify(JSON.parse(row.normalized));
4640
+ if (row.column_exists && !row.matches) defaultDrift.push(
4641
+ `ALTER TABLE ${quoteIdentifier(schema)}.${quoteIdentifier(item.table)} ALTER COLUMN ${quoteIdentifier(item.column)} SET DEFAULT ${quoteLiteral(item.value)}::jsonb;`
4642
+ );
4643
+ });
4644
+ return { desired, defaultDrift };
4645
+ }
4646
+ async function pendingForeignKeyTimingStatements(canonical, db) {
4647
+ const keys = canonical.tables.flatMap((table) => (table.foreignKeys ?? []).map((fk) => ({ table: table.table, fk })));
4648
+ if (keys.length === 0) return [];
4649
+ const schema = ormSchemaName(canonical.namespace);
4650
+ const result = await shimExecute(db).execute(sql`
4651
+ SELECT relation.relname AS table_name, constraint_row.conname AS name,
4652
+ constraint_row.condeferrable AS deferrable, constraint_row.condeferred AS deferred
4653
+ FROM pg_catalog.pg_constraint AS constraint_row
4654
+ JOIN pg_catalog.pg_class AS relation ON relation.oid = constraint_row.conrelid
4655
+ JOIN pg_catalog.pg_namespace AS namespace ON namespace.oid = relation.relnamespace
4656
+ WHERE namespace.nspname = ${schema} AND constraint_row.contype = 'f'
4657
+ `);
4658
+ const rows = result.rows;
4659
+ return keys.flatMap(({ table, fk }) => {
4660
+ const actual = rows.find((row) => row.table_name === table && row.name === fk.name);
4661
+ const deferrable = fk.deferrable !== void 0;
4662
+ const deferred = fk.deferrable === "initially-deferred";
4663
+ if (actual ? actual.deferrable === deferrable && actual.deferred === deferred : !deferrable) return [];
4664
+ return [foreignKeyTimingSql(schema, table, fk.name, fk.deferrable)];
4665
+ });
4454
4666
  }
4455
4667
  async function pendingStatements({
4456
4668
  entities,
@@ -4463,11 +4675,31 @@ async function pendingStatements({
4463
4675
  );
4464
4676
  return statementsToExecute.filter((statement) => !owned.test(statement));
4465
4677
  }
4678
+ function correctIntrospectionQuery(query) {
4679
+ if (!is(query, SQL)) return query;
4680
+ const compiled = new PgDialect().sqlToQuery(query);
4681
+ let text4 = compiled.sql;
4682
+ const indexJoin = "pg_constraint con ON con.conindid = idx.indexrelid";
4683
+ if (text4.includes("AS generated_by_constraint") && text4.includes(indexJoin)) {
4684
+ text4 = text4.replace(indexJoin, `${indexJoin} AND con.contype IN ('p', 'u', 'x')`);
4685
+ }
4686
+ const sourceJoin = "LEFT JOIN pg_catalog.pg_attribute att ON att.attnum = ANY (con.conkey)";
4687
+ const targetJoin = "LEFT JOIN pg_catalog.pg_attribute fatt ON fatt.attnum = ANY (con.confkey)";
4688
+ if (text4.includes(sourceJoin) && text4.includes(targetJoin) && text4.includes("AND con.contype IN ('f')")) {
4689
+ text4 = text4.replace(
4690
+ sourceJoin,
4691
+ "JOIN LATERAL unnest(con.conkey, con.confkey) WITH ORDINALITY AS fk_key(source_num, target_num, ordinal) ON true LEFT JOIN pg_catalog.pg_attribute att ON att.attnum = fk_key.source_num"
4692
+ ).replace(targetJoin, "LEFT JOIN pg_catalog.pg_attribute fatt ON fatt.attnum = fk_key.target_num").replace(/;\s*$/, "") + " ORDER BY con.conname, fk_key.ordinal";
4693
+ }
4694
+ if (text4 === compiled.sql) return query;
4695
+ if (compiled.params.length !== 0) throw new Error("parameterized Drizzle catalog query cannot be normalized");
4696
+ return sql.raw(text4);
4697
+ }
4466
4698
  function shimExecute(db) {
4467
4699
  const execute = db.execute.bind(db);
4468
4700
  return {
4469
4701
  execute: async (query) => {
4470
- const result = await execute(query);
4702
+ const result = await execute(correctIntrospectionQuery(query));
4471
4703
  if (result && typeof result === "object" && "rows" in result) return result;
4472
4704
  return { rows: result };
4473
4705
  }
@@ -4507,21 +4739,73 @@ async function planMigration({
4507
4739
  const ddl = await diffStatements(hints.adjusted, snapshot);
4508
4740
  const policyDrops = policyDropStatements(schema, snapshotTableNames(previous, schema));
4509
4741
  const statements = [
4510
- ...policyDrops.map((sql4) => ({ kind: "security", sql: sql4 })),
4511
- ...hints.statements.map((sql4) => ({ kind: "hint", sql: sql4 })),
4512
- ...ddl.map((sql4) => ({ kind: "ddl", sql: sql4.replace(/;\s*$/, "") })),
4513
- ...securityStatements(definition).map((sql4) => ({ kind: "security", sql: sql4 })),
4742
+ ...policyDrops.map((sql5) => ({ kind: "security", sql: sql5 })),
4743
+ ...hints.statements.map((sql5) => ({ kind: "hint", sql: sql5 })),
4744
+ ...ddl.map((sql5) => ({ kind: "ddl", sql: sql5.replace(/;\s*$/, "") })),
4745
+ ...securityStatements(definition).map((sql5) => ({ kind: "security", sql: sql5 })),
4514
4746
  // PREPARE each action's executes first (plpgsql bodies don't check columns
4515
4747
  // at CREATE), then create the functions. Both reference the tables the DDL
4516
4748
  // above creates, so they close the plan.
4517
- ...actionPrepareChecks(definition).map((sql4) => ({ kind: "function", sql: sql4 })),
4518
- ...actionFunctionStatements(definition).map((sql4) => ({ kind: "function", sql: sql4 }))
4749
+ ...actionPrepareChecks(definition).map((sql5) => ({ kind: "function", sql: sql5 })),
4750
+ ...actionFunctionStatements(definition).map((sql5) => ({ kind: "function", sql: sql5 }))
4519
4751
  ];
4520
4752
  return { namespace: definition.namespace, schema, statements, snapshot };
4521
4753
  }
4522
4754
  var compileNamespace = (definition) => planMigration({ definition });
4523
4755
  var previousId2 = (snapshot) => snapshot.id;
4524
- var IR_VERSION = 1;
4756
+ var ORM_MIGRATION_EXPORT_FILE = "orm.migration.json";
4757
+ var ORM_MIGRATION_EXPORT_MAX_BYTES = ORM_REGISTRATION_MAX_BYTES;
4758
+ var hash = z.string().regex(/^sha256:[0-9a-f]{64}$/);
4759
+ var ormMigrationPayloadSchema = z.object({
4760
+ canonical_definition: canonicalDefinitionSchema,
4761
+ documents: z.array(z.object({ path: z.string().min(1).max(2048), contents: z.string().max(1e6) }).strict()).max(5e3),
4762
+ client_manifest: z.object({ ops_hash: hash, operations: z.record(z.string(), hash) }).strict(),
4763
+ sdl: z.string().refine((value) => Buffer.byteLength(value, "utf8") <= MAX_GENERATED_SDL_BYTES, {
4764
+ message: `sdl exceeds ${MAX_GENERATED_SDL_BYTES} bytes`
4765
+ }),
4766
+ schema_snapshot: z.json(),
4767
+ // The existing ORM committed-migration validator and replay engine remain
4768
+ // authoritative. This envelope hashes the provenance, never authorizes SQL.
4769
+ migration: z.json().optional()
4770
+ }).strict();
4771
+ var ormMigrationExportSchema = z.object({
4772
+ schema_version: z.literal(1),
4773
+ schema_hash: hash,
4774
+ payload: ormMigrationPayloadSchema,
4775
+ checksum: z.string().regex(/^[0-9a-f]{64}$/)
4776
+ }).strict();
4777
+ function checksum(value) {
4778
+ return createHash("sha256").update(stableJson(value)).digest("hex");
4779
+ }
4780
+ function createOrmMigrationExport({ schemaHash, payload }) {
4781
+ const contents = { schema_version: 1, schema_hash: hash.parse(schemaHash), payload: ormMigrationPayloadSchema.parse(payload) };
4782
+ return { ...contents, checksum: checksum(contents) };
4783
+ }
4784
+ function parseOrmMigrationExport(text4) {
4785
+ if (Buffer.byteLength(text4, "utf8") > ORM_MIGRATION_EXPORT_MAX_BYTES) throw new Error("ORM migration export exceeds the size limit");
4786
+ const exported = ormMigrationExportSchema.parse(JSON.parse(text4));
4787
+ const { checksum: expected, ...contents } = exported;
4788
+ if (checksum(contents) !== expected) throw new Error("ORM migration export checksum mismatch; regenerate and commit it");
4789
+ return exported;
4790
+ }
4791
+ function renderOrmMigrationExport(exported) {
4792
+ const text4 = `${JSON.stringify(exported, null, 2)}
4793
+ `;
4794
+ if (Buffer.byteLength(text4, "utf8") > ORM_MIGRATION_EXPORT_MAX_BYTES) throw new Error("ORM migration export exceeds the size limit");
4795
+ return text4;
4796
+ }
4797
+ var IR_VERSION = 2;
4798
+ var LEGACY_IR_VERSION = 1;
4799
+ var irVersionSchema = z.union([z.literal(LEGACY_IR_VERSION), z.literal(IR_VERSION)]);
4800
+ var operationVersionSchema = z.object({ irVersion: irVersionSchema });
4801
+ function requiredArtifactIrVersion(operations) {
4802
+ let required = LEGACY_IR_VERSION;
4803
+ for (const operation of operations) {
4804
+ const { irVersion } = operationVersionSchema.parse(operation);
4805
+ if (irVersion > required) required = irVersion;
4806
+ }
4807
+ return required;
4808
+ }
4525
4809
  var CLAIMS_CONTRACT = {
4526
4810
  sub: "string",
4527
4811
  org: "string?",
@@ -4648,6 +4932,33 @@ var aggregateRootSchema = z.object({
4648
4932
  nodes: selectionIrSchema.optional(),
4649
4933
  includeIf: includeIfSchema.optional()
4650
4934
  });
4935
+ var DATE_BUCKETS = ["year", "quarter", "month", "week", "day", "hour"];
4936
+ var groupByKeyIrSchema = z.object({
4937
+ column: z.string(),
4938
+ bucket: z.enum(DATE_BUCKETS).optional()
4939
+ });
4940
+ var aggregateGroupsRootSchema = z.object({
4941
+ kind: z.literal("aggregateGroups"),
4942
+ alias: z.string(),
4943
+ table: z.string(),
4944
+ /** Composed at compile time: AND(policy, documentWhere?, dynamicFilter?). */
4945
+ where: predIrSchema,
4946
+ groupBy: z.array(groupByKeyIrSchema).min(1),
4947
+ /**
4948
+ * The `key { … }` projection: which group columns appear in each entry's key
4949
+ * object, in selection order. A subset of `groupBy` (the compiler rejects a
4950
+ * key field that is not a group key — it would be indeterminate within the
4951
+ * group). Empty when the document selects only `aggregate`.
4952
+ */
4953
+ key: z.array(z.object({ alias: z.string(), column: z.string() })).default([]),
4954
+ count: z.object({ columns: z.array(z.string()).optional(), distinct: z.boolean().optional() }).optional(),
4955
+ sum: z.array(z.string()).optional(),
4956
+ avg: z.array(z.string()).optional(),
4957
+ /** Bounds the GROUP count, not the scanned rows — see MAX_GROUPS. */
4958
+ limit: limitIrSchema,
4959
+ offset: z.object({ variable: z.string().optional(), value: z.number().int().optional() }).optional(),
4960
+ includeIf: includeIfSchema.optional()
4961
+ });
4651
4962
  var writeValuesSchema = z.union([
4652
4963
  z.object({ slot: z.string() }),
4653
4964
  z.object({ entries: z.array(z.object({ column: z.string(), value: valueIrSchema })) })
@@ -4693,12 +5004,15 @@ var mutationRootSchema = z.object({
4693
5004
  insertCheck: predIrSchema.optional(),
4694
5005
  returning: selectionIrSchema.nullable(),
4695
5006
  affectedRows: z.boolean().default(false),
5007
+ /** v2: abort the transaction when the actual write count differs, regardless of selection. */
5008
+ assertAffectedRows: z.number().int().min(0).max(2147483647).optional(),
4696
5009
  includeIf: includeIfSchema.optional()
4697
5010
  });
4698
5011
  var rootIrSchema = z.discriminatedUnion("kind", [
4699
5012
  selectRootSchema,
4700
5013
  byPkRootSchema,
4701
5014
  aggregateRootSchema,
5015
+ aggregateGroupsRootSchema,
4702
5016
  mutationRootSchema
4703
5017
  ]);
4704
5018
  var INPUT_REF_KINDS = [
@@ -4728,7 +5042,7 @@ var variableIrSchema = z.object({
4728
5042
  defaultValue: variableDefaultIrSchema.optional()
4729
5043
  });
4730
5044
  var compiledOperationSchema = z.object({
4731
- irVersion: z.literal(IR_VERSION),
5045
+ irVersion: irVersionSchema,
4732
5046
  name: z.string(),
4733
5047
  opHash: z.string().regex(/^sha256:[0-9a-f]{64}$/),
4734
5048
  kind: z.enum(["query", "mutation"]),
@@ -4740,6 +5054,13 @@ var compiledOperationSchema = z.object({
4740
5054
  /** Every table the op touches — data-token scoping + audit. */
4741
5055
  tableSet: z.array(z.string()).min(1),
4742
5056
  roots: z.array(rootIrSchema).min(1)
5057
+ }).superRefine((operation, ctx) => {
5058
+ for (const [index3, root] of operation.roots.entries()) {
5059
+ if (root.kind !== "mutation" || root.assertAffectedRows === void 0) continue;
5060
+ if (operation.irVersion < 2 || operation.kind !== "mutation" || root.includeIf !== void 0) {
5061
+ ctx.addIssue({ code: "custom", path: ["roots", index3], message: "affected-row assertions require unconditional mutation roots and IR v2" });
5062
+ }
5063
+ }
4743
5064
  });
4744
5065
  var tableMetaIrSchema = z.object({
4745
5066
  table: z.string(),
@@ -4776,18 +5097,29 @@ var tableMetaIrSchema = z.object({
4776
5097
  insertable: z.array(z.string()),
4777
5098
  settable: z.array(z.string()),
4778
5099
  appendable: z.array(z.string()),
5100
+ /**
5101
+ * Logical columns stamped with Postgres `now()` on UPDATE (canonical
5102
+ * `onUpdateFn`). Omitted when empty so pre-onUpdate artifacts still parse.
5103
+ */
5104
+ touchOnUpdate: z.array(z.string()).optional(),
4779
5105
  constraints: z.array(z.object({ name: z.string(), columns: z.array(z.string()) })),
4780
5106
  /** Depth/node caps for dynamic filter trees on this table. */
4781
5107
  dynamicFilterMaxDepth: z.number().int().positive().default(6),
4782
5108
  dynamicFilterMaxNodes: z.number().int().positive().default(64)
4783
5109
  });
4784
5110
  var compiledArtifactSchema = z.object({
4785
- irVersion: z.literal(IR_VERSION),
5111
+ irVersion: irVersionSchema,
4786
5112
  namespace: z.string(),
4787
5113
  schemaHash: z.string(),
4788
5114
  opsHash: z.string(),
4789
5115
  tables: z.record(z.string(), tableMetaIrSchema),
4790
5116
  operations: z.record(z.string(), compiledOperationSchema)
5117
+ }).superRefine((artifact, ctx) => {
5118
+ for (const [name, operation] of Object.entries(artifact.operations)) {
5119
+ if (operation.irVersion > artifact.irVersion) {
5120
+ ctx.addIssue({ code: "custom", path: ["operations", name, "irVersion"], message: "operation requires a newer IR version than its artifact" });
5121
+ }
5122
+ }
4791
5123
  });
4792
5124
  var IrVersionError = class extends Error {
4793
5125
  constructor(found) {
@@ -4798,7 +5130,7 @@ var IrVersionError = class extends Error {
4798
5130
  function normalizeIr(raw) {
4799
5131
  if (!raw || typeof raw !== "object") throw new IrVersionError(void 0);
4800
5132
  const version = raw.irVersion;
4801
- if (version !== IR_VERSION) throw new IrVersionError(version);
5133
+ if (version !== LEGACY_IR_VERSION && version !== IR_VERSION) throw new IrVersionError(version);
4802
5134
  return compiledArtifactSchema.parse(raw);
4803
5135
  }
4804
5136
  function indexByHash(artifact) {
@@ -5114,12 +5446,12 @@ async function writeMigration({
5114
5446
  const tip = workspace.journal.entries.at(-1);
5115
5447
  const ordinal = (tip?.ordinal ?? 0) + 1;
5116
5448
  const name = migrationName(ordinal, contentHash);
5117
- const sql4 = renderMigrationSql({ name, namespace: workspace.journal.namespace, contentHash, plan });
5449
+ const sql5 = renderMigrationSql({ name, namespace: workspace.journal.namespace, contentHash, plan });
5118
5450
  const metaDir = join(dir, MIGRATIONS_DIRNAME, META_DIRNAME);
5119
5451
  await mkdir(metaDir, { recursive: true });
5120
5452
  const snapshotText = `${JSON.stringify(plan.snapshot, null, 2)}
5121
5453
  `;
5122
- await writeFile(join(dir, MIGRATIONS_DIRNAME, `${name}.sql`), sql4);
5454
+ await writeFile(join(dir, MIGRATIONS_DIRNAME, `${name}.sql`), sql5);
5123
5455
  await writeFile(join(metaDir, `${pad(ordinal)}.snapshot.json`), snapshotText);
5124
5456
  const journal = {
5125
5457
  ...workspace.journal,
@@ -5130,7 +5462,7 @@ async function writeMigration({
5130
5462
  name,
5131
5463
  content_hash: contentHash,
5132
5464
  previous_content_hash: tip?.content_hash ?? null,
5133
- checksum: checksumOf(sql4),
5465
+ checksum: checksumOf(sql5),
5134
5466
  snapshot_checksum: checksumOf(snapshotText),
5135
5467
  destructive
5136
5468
  }
@@ -5245,8 +5577,8 @@ async function checkWorkspace({
5245
5577
  let previousId3;
5246
5578
  let previousHash = null;
5247
5579
  for (const entry of workspace.journal.entries) {
5248
- const sql4 = await readMigrationSql(dir, entry);
5249
- if (checksumOf(sql4) !== entry.checksum) {
5580
+ const sql5 = await readMigrationSql(dir, entry);
5581
+ if (checksumOf(sql5) !== entry.checksum) {
5250
5582
  log(`${MIGRATIONS_DIRNAME}/${entry.name}.sql does not match its journal checksum \u2014 committed migrations must not be edited`);
5251
5583
  return 1;
5252
5584
  }
@@ -5286,7 +5618,7 @@ async function checkWorkspace({
5286
5618
  log(`migrations in sync \u2014 ${workspace.journal.entries.length} committed, tip ${tip.name}`);
5287
5619
  return 0;
5288
5620
  }
5289
- var firstLine = (sql4) => sql4.split("\n")[0] ?? sql4;
5621
+ var firstLine = (sql5) => sql5.split("\n")[0] ?? sql5;
5290
5622
 
5291
5623
  // src/migrations/from-yaml.ts
5292
5624
  function convertV1DefinitionToCanonical(definition) {
@@ -5392,7 +5724,7 @@ function buildRebaseJournalEntry({ namespace, previousHash, newHash, ordinal, sn
5392
5724
  throw new OrmDefinitionError(`rebase ordinal must be an integer \u2265 2 (a rebase sits on an existing journal tip); got ${ordinal}`);
5393
5725
  }
5394
5726
  const name = migrationName(ordinal, newHash);
5395
- const sql4 = renderRebaseMigrationSql({ name, namespace, previousHash, newHash });
5727
+ const sql5 = renderRebaseMigrationSql({ name, namespace, previousHash, newHash });
5396
5728
  const snapshotText = `${JSON.stringify(snapshot, null, 2)}
5397
5729
  `;
5398
5730
  const entry = {
@@ -5400,11 +5732,11 @@ function buildRebaseJournalEntry({ namespace, previousHash, newHash, ordinal, sn
5400
5732
  name,
5401
5733
  content_hash: newHash,
5402
5734
  previous_content_hash: previousHash,
5403
- checksum: checksumOf(sql4),
5735
+ checksum: checksumOf(sql5),
5404
5736
  snapshot_checksum: checksumOf(snapshotText),
5405
5737
  destructive: false
5406
5738
  };
5407
- return { name, entry, sql: sql4, snapshotText };
5739
+ return { name, entry, sql: sql5, snapshotText };
5408
5740
  }
5409
5741
  function renderRebaseMigrationSql({
5410
5742
  name,
@@ -5502,6 +5834,6 @@ function canonicalActions(value) {
5502
5834
  );
5503
5835
  }
5504
5836
 
5505
- export { ACTION_REQUIRES_DENIED_SQLSTATE, ACTION_VALIDATES_FAILED_SQLSTATE, AUDIT_ACTIONS, CANONICAL_FORMAT, CAPABILITIES_CLAIM_KEY, CAPABILITY_KEY_PATTERN, CLAIMS_CONTRACT, CLAIMS_SETTING, CLAIM_KEY_PATTERN, CMP_OPS, COLUMN_BRAND, COLUMN_DEFAULT_FNS, COLUMN_TYPES2 as COLUMN_TYPES, COMPARE_OPS, CONSUMER_ROLE_SUFFIX, ColumnBuilder, DEFINITION_FILE_EXTENSIONS, ENUM_BRAND, HASH_DOMAIN, IDENTIFIER_PATTERN, IDENTIFIER_RE, INPUT_REF_KINDS, IR_VERSION, IrVersionError, LINK_BRAND, MAX_DEFINITION_FILE_BYTES, MAX_IDENTIFIER_LENGTH, MIGRATIONS_DIRNAME, NAMESPACE_CONFIG_BRAND, NAMESPACE_CONFIG_FILE, NAMESPACE_CONFIG_FILENAMES, NAMESPACE_PATTERN, ORM_DATA_TOKEN_HEADER, ORM_SCHEMA_PREFIX, ORM_SERVICE_DATA_TOKEN_HEADER, ORM_TO_PIPELINE_TYPE, OrmDefinitionError, PredicateParseError, QUALIFIED_TABLE_PATTERN, RESERVED_COLUMN_NAMES, RESERVED_TABLE_NAMES, ROLES_CLAIM_KEY, SCHEMA_DIR, STATEMENT_KINDS, SYNCED_CONTRACT_HASH_DOMAIN, SYNCED_SOURCE_PATTERN, SYNCED_VIEW_EXECUTION_OWNER_ROLE, TABLE_BRAND, VIEW_BRAND, actionFunctionName, actionFunctionStatements, actionParamArg, actionParamOrder, actionParamSchema, actionPrepareChecks, actionSchema, actionWriteTargets, actionsInterfaceName, activeAuthoringContext, applyMigrationHints, applyMigrationHintsV2, beginAuthoringContext, buildActionParamsSchema, buildDrizzleEntities, buildDrizzleEntitiesV2, buildNamespaceDefinition, buildRebaseJournalEntry, canonicalActionSchema, canonicalColumnSchema, canonicalDefinitionSchema, canonicalEnumSchema, canonicalIndexSchema, canonicalLinkSchema, canonicalPoliciesSchema, canonicalRelations, canonicalTableSchema, canonicalViewSchema, canonicalizeDefinition, capabilityExpression, castParts, checksumOf, claimExpression, classifyDestructive, columnSchema, columnTypeSchema2 as columnTypeSchema, compileActionRequires, compileActionStatements, compileNamespace, compilePredIrToSql, compilePredicate, compiledArtifactSchema, compiledOperationSchema, computeCanonicalHash, computeDefinitionHash, computeSyncedContractHash, consumerRoleName, convertV1DefinitionToCanonical, declaredCapabilityKeys, defineEnum, defineNamespace, defineSyncedTable, defineTable, defineView, deriveColumnName, diffCommand, diffStatements, emptyJournal, emptySnapshot, endAuthoringContext, extractNamedParams, extractOrmSyncedTableContract, generateNamespaceTypes, generateSnapshot, generateSnapshotV2, identifierSchema, indexByHash, isColumnBuilder, isEnumRef, isFunctionDefault, isOwnedStatement, isOwnedStatementV2, isQualifiedReference, isSeqLink, isSeqNamespaceConfig, isSeqTable, isSeqView, limitIrSchema, loadCommittedMigrations, loadCommittedTipMigration, loadNamespaceDefinition, loadNamespaceFromDir, migrationName, namespaceConfigSchema, namespaceSchema, normalizeCanonical, normalizeIr, normalizeSnapshot, orderIrSchema, ormSchemaName, overlayWinsUnion, overrideRowMutation, parseCanonicalDefinition, parseDefinitionSources, parsePredicate, parseTableFile, parsedPredicateSchema, pendingKitStatements, pendingKitStatementsV2, planMigration, planMigrationV2, policyExpressionSchema, policyVariantSchema, predIrSchema, predicateOperands, quoteIdentifier, quoteLiteral, readMigrationSql, readMigrationWorkspace, readSnapshot, rebaseViolations, referencedCapabilities, referencedColumns, renderMigrationSql, revertOverlayMutation, rewriteSyncedSourceRelationsInViewQuery, roleExpression, rootIrSchema, securityStatements, selectionIrSchema, serializeNamespace, sqlTypeName, stableJson, syncedBackingRevokeStatements, syncedContractSurface, syncedTables, syncedViewDropStatements, syncedViewStatements, t, tableFileSchema, tableMetaIrSchema, tableReferenceSchema, toMany, toOne, toPlatformUser, typesInterfaceName, validateViewCatalogStatement, valueIrSchema, variableDefaultIrSchema, variableIrSchema, verifyRebaseIsNoop, walkPredicate, writeMigration };
5837
+ export { ACTION_REQUIRES_DENIED_SQLSTATE, ACTION_VALIDATES_FAILED_SQLSTATE, AUDIT_ACTIONS, CANONICAL_FORMAT, CAPABILITIES_CLAIM_KEY, CAPABILITY_KEY_PATTERN, CLAIMS_CONTRACT, CLAIMS_SETTING, CLAIM_KEY_PATTERN, CMP_OPS, COLUMN_BRAND, COLUMN_DEFAULT_FNS, COLUMN_IDENTIFIER_PATTERN, COLUMN_TYPES2 as COLUMN_TYPES, COMPARE_OPS, CONSUMER_ROLE_SUFFIX, ColumnBuilder, DATE_BUCKETS, DEFINITION_FILE_EXTENSIONS, ENUM_BRAND, HASH_DOMAIN, IDENTIFIER_PATTERN, IDENTIFIER_RE, INPUT_REF_KINDS, IR_VERSION, IrVersionError, LEGACY_IR_VERSION, LINK_BRAND, MAX_DEFINITION_FILE_BYTES, MAX_GENERATED_SDL_BYTES, MAX_IDENTIFIER_LENGTH, MIGRATIONS_DIRNAME, NAMESPACE_CONFIG_BRAND, NAMESPACE_CONFIG_FILE, NAMESPACE_CONFIG_FILENAMES, NAMESPACE_PATTERN, ORM_DATA_TOKEN_HEADER, ORM_MIGRATION_EXPORT_FILE, ORM_MIGRATION_EXPORT_MAX_BYTES, ORM_REGISTRATION_MAX_BYTES, ORM_SCHEMA_PREFIX, ORM_SERVICE_DATA_TOKEN_HEADER, ORM_TO_PIPELINE_TYPE, OrmDefinitionError, PredicateParseError, QUALIFIED_TABLE_PATTERN, RESERVED_COLUMN_NAMES, RESERVED_TABLE_NAMES, ROLES_CLAIM_KEY, SCHEMA_DIR, STATEMENT_KINDS, SYNCED_CONTRACT_HASH_DOMAIN, SYNCED_SOURCE_PATTERN, SYNCED_VIEW_EXECUTION_OWNER_ROLE, TABLE_BRAND, VIEW_BRAND, actionFunctionName, actionFunctionStatements, actionParamArg, actionParamOrder, actionParamSchema, actionPrepareChecks, actionSchema, actionWriteTargets, actionsInterfaceName, activeAuthoringContext, applyMigrationHints, applyMigrationHintsV2, beginAuthoringContext, buildActionParamsSchema, buildDrizzleEntities, buildDrizzleEntitiesV2, buildNamespaceDefinition, buildRebaseJournalEntry, canonicalActionSchema, canonicalColumnSchema, canonicalDefinitionSchema, canonicalEnumSchema, canonicalIndexSchema, canonicalLinkSchema, canonicalPoliciesSchema, canonicalRelations, canonicalTableSchema, canonicalViewSchema, canonicalizeDefinition, capabilityExpression, castParts, checksumOf, claimExpression, classifyDestructive, columnSchema, columnTypeSchema2 as columnTypeSchema, compileActionRequires, compileActionStatements, compileNamespace, compilePredIrToSql, compilePredicate, compiledArtifactSchema, compiledOperationSchema, computeCanonicalHash, computeDefinitionHash, computeSyncedContractHash, consumerRoleName, convertV1DefinitionToCanonical, createOrmMigrationExport, declaredCapabilityKeys, defineEnum, defineNamespace, defineSyncedTable, defineTable, defineView, deriveColumnName, diffCommand, diffStatements, emptyJournal, emptySnapshot, endAuthoringContext, extractNamedParams, extractOrmSyncedTableContract, generateNamespaceTypes, generateSnapshot, generateSnapshotV2, identifierSchema, indexByHash, isColumnBuilder, isEnumRef, isFunctionDefault, isOwnedStatement, isOwnedStatementV2, isQualifiedReference, isSeqLink, isSeqNamespaceConfig, isSeqTable, isSeqView, limitIrSchema, loadCommittedMigrations, loadCommittedTipMigration, loadNamespaceDefinition, loadNamespaceFromDir, migrationName, namespaceConfigSchema, namespaceSchema, normalizeCanonical, normalizeIr, normalizeSnapshot, orderIrSchema, ormMigrationExportSchema, ormSchemaName, overlayWinsUnion, overrideRowMutation, parseCanonicalDefinition, parseDefinitionSources, parseOrmMigrationExport, parsePredicate, parseTableFile, parsedPredicateSchema, pendingKitStatements, pendingKitStatementsV2, planMigration, planMigrationV2, policyExpressionSchema, policyVariantSchema, predIrSchema, predicateOperands, quoteIdentifier, quoteLiteral, readMigrationSql, readMigrationWorkspace, readSnapshot, rebaseViolations, referencedCapabilities, referencedColumns, renderMigrationSql, renderOrmMigrationExport, requiredArtifactIrVersion, revertOverlayMutation, rewriteSyncedSourceRelationsInViewQuery, roleExpression, rootIrSchema, securityStatements, selectionIrSchema, serializeNamespace, sqlTypeName, stableJson, syncedBackingRevokeStatements, syncedContractSurface, syncedTables, syncedViewDropStatements, syncedViewStatements, t, tableFileSchema, tableMetaIrSchema, tableReferenceSchema, toMany, toOne, toPlatformUser, typesInterfaceName, validateViewCatalogStatement, valueIrSchema, variableDefaultIrSchema, variableIrSchema, verifyRebaseIsNoop, walkPredicate, writeMigration };
5506
5838
  //# sourceMappingURL=index.js.map
5507
5839
  //# sourceMappingURL=index.js.map