@sequenceholdings/orm 2.3.0 → 2.5.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 (59) hide show
  1. package/dist/authoring.cjs +53 -7
  2. package/dist/authoring.cjs.map +1 -1
  3. package/dist/authoring.d.cts +11 -7
  4. package/dist/authoring.d.ts +11 -7
  5. package/dist/authoring.js +53 -7
  6. package/dist/authoring.js.map +1 -1
  7. package/dist/canonical.cjs +48 -2
  8. package/dist/canonical.cjs.map +1 -1
  9. package/dist/canonical.d.cts +72 -72
  10. package/dist/canonical.d.ts +72 -72
  11. package/dist/canonical.js +48 -2
  12. package/dist/canonical.js.map +1 -1
  13. package/dist/cli.cjs +337 -86
  14. package/dist/cli.cjs.map +1 -1
  15. package/dist/cli.js +337 -86
  16. package/dist/cli.js.map +1 -1
  17. package/dist/client.cjs +1 -1
  18. package/dist/client.cjs.map +1 -1
  19. package/dist/client.d.cts +1 -1
  20. package/dist/client.d.ts +1 -1
  21. package/dist/client.js +1 -1
  22. package/dist/client.js.map +1 -1
  23. package/dist/compiler.cjs +493 -52
  24. package/dist/compiler.cjs.map +1 -1
  25. package/dist/compiler.d.cts +22 -7
  26. package/dist/compiler.d.ts +22 -7
  27. package/dist/compiler.js +493 -53
  28. package/dist/compiler.js.map +1 -1
  29. package/dist/{constants-C6EG6Wq7.d.cts → constants-Dou1RkTo.d.cts} +7 -2
  30. package/dist/{constants-C6EG6Wq7.d.ts → constants-Dou1RkTo.d.ts} +7 -2
  31. package/dist/dynamic-input.d.cts +1 -1
  32. package/dist/dynamic-input.d.ts +1 -1
  33. package/dist/index.cjs +329 -130
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +66 -58
  36. package/dist/index.d.ts +66 -58
  37. package/dist/index.js +329 -131
  38. package/dist/index.js.map +1 -1
  39. package/dist/ir.cjs +50 -3
  40. package/dist/ir.cjs.map +1 -1
  41. package/dist/ir.d.cts +71 -71
  42. package/dist/ir.d.ts +71 -71
  43. package/dist/ir.js +50 -3
  44. package/dist/ir.js.map +1 -1
  45. package/dist/predicate-v2.cjs +145 -22
  46. package/dist/predicate-v2.cjs.map +1 -1
  47. package/dist/predicate-v2.d.cts +41 -4
  48. package/dist/predicate-v2.d.ts +41 -4
  49. package/dist/predicate-v2.js +145 -22
  50. package/dist/predicate-v2.js.map +1 -1
  51. package/dist/sdl.cjs +53 -3
  52. package/dist/sdl.cjs.map +1 -1
  53. package/dist/sdl.d.cts +3 -1
  54. package/dist/sdl.d.ts +3 -1
  55. package/dist/sdl.js +53 -3
  56. package/dist/sdl.js.map +1 -1
  57. package/package.json +1 -1
  58. package/dist/{definition-DjfC7Lll.d.cts → definition-B99BsOAO.d.cts} +4 -4
  59. package/dist/{definition-DjfC7Lll.d.ts → definition-B99BsOAO.d.ts} +4 -4
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import { realpath, stat, readdir, readFile, mkdir, writeFile } from 'fs/promises
7
7
  import { createRequire } from 'module';
8
8
  import { join, sep, extname } from 'path';
9
9
  import { generateDrizzleJson, upPgSnapshot, generateMigration, pushSchema } from 'drizzle-kit/api';
10
+ import { PgParser } from '@supabase/pg-parser';
10
11
  import { load } from 'js-yaml';
11
12
  import { capabilityPinsSchema, customRolesBlockSchema, validateCapabilityPins } from '@sequenceholdings/custom-roles-manifest';
12
13
  export { capabilityPinsSchema, customRolesBlockSchema, customRolesDeclared, parseCapabilityPin, validateCapabilityPins } from '@sequenceholdings/custom-roles-manifest';
@@ -155,20 +156,24 @@ var t = {
155
156
  };
156
157
 
157
158
  // src/constants.ts
158
- var NAMESPACE_PATTERN = /^[a-z][a-z0-9_]{0,40}$/;
159
+ var NAMESPACE_PATTERN = /^(?!(?:events|native_sources)$)[a-z][a-z0-9_]{0,40}$/;
159
160
  var ORM_DATA_TOKEN_HEADER = "x-sequence-data-token";
160
161
  var ORM_SERVICE_DATA_TOKEN_HEADER = "x-sequence-data-token-service";
161
162
  var IDENTIFIER_PATTERN = /^[a-z][a-z0-9_]*$/;
162
163
  var COLUMN_IDENTIFIER_PATTERN = /^_?[a-z][a-z0-9_]*$/;
163
164
  var MAX_IDENTIFIER_LENGTH = 63;
164
165
  var CAPABILITY_KEY_PATTERN = /^(?:org\/|app\/[a-z][a-z0-9-]{0,63}\/)?[a-z0-9-]{1,64}$/;
166
+ var MAX_PERSISTED_READ_ROWS = 50001;
165
167
  var CLAIM_KEY_PATTERN = /^[a-z][a-z0-9_]*$/;
166
168
  var QUALIFIED_TABLE_PATTERN = /^[a-z][a-z0-9_]{0,62}\.[a-z][a-z0-9_]{0,62}$/;
167
169
  var SYNCED_SOURCE_PATTERN = QUALIFIED_TABLE_PATTERN;
168
170
  var ORM_SCHEMA_PREFIX = "orm_";
169
171
  var CONSUMER_ROLE_SUFFIX = "_consumer";
170
- var ormSchemaName = (namespace) => `${ORM_SCHEMA_PREFIX}${namespace}`;
171
- var consumerRoleName = (namespace) => `${ORM_SCHEMA_PREFIX}${namespace}${CONSUMER_ROLE_SUFFIX}`;
172
+ var ormSchemaName = (namespace) => {
173
+ if (!NAMESPACE_PATTERN.test(namespace)) throw new Error(`invalid or reserved ORM namespace '${namespace}'`);
174
+ return `${ORM_SCHEMA_PREFIX}${namespace}`;
175
+ };
176
+ var consumerRoleName = (namespace) => `${ormSchemaName(namespace)}${CONSUMER_ROLE_SUFFIX}`;
172
177
  var DEFINITION_FILE_EXTENSIONS = [".yml", ".yaml"];
173
178
  var NAMESPACE_CONFIG_FILENAMES = /* @__PURE__ */ new Set(["namespace.yaml", "namespace.yml"]);
174
179
  var HASH_DOMAIN = "sequence-orm-definitions\0";
@@ -397,10 +402,10 @@ function defineSyncedTable(name2, columnsOrConfig, maybeConfig) {
397
402
  if (builder.isPrimaryKey) columnLevelPk.push(propertyName);
398
403
  }
399
404
  if (entries.length > 0) {
400
- const hasConfigPk = config.primaryKey !== void 0 && config.primaryKey.length > 0;
405
+ const hasConfigPk = config.primaryKey !== void 0;
401
406
  if (columnLevelPk.length === 0 && !hasConfigPk) {
402
407
  throw new OrmDefinitionError(
403
- `synced table "${name2}" declares columns but no primary key \u2014 use .primaryKey() or config.primaryKey`,
408
+ `synced table "${name2}" declares columns but no primary key \u2014 use .primaryKey(), config.primaryKey, or explicit primaryKey: [] for an unkeyed read-only source`,
404
409
  file
405
410
  );
406
411
  }
@@ -1253,10 +1258,10 @@ function validateResolvedView({ view, tables, views = [] }) {
1253
1258
  const resolved = view.resolved;
1254
1259
  if (!resolved) return [];
1255
1260
  const errors = [];
1256
- const fail = (message) => errors.push(`resolved table '${view.view}': ${message}`);
1261
+ const fail2 = (message) => errors.push(`resolved table '${view.view}': ${message}`);
1257
1262
  const pkColumn = view.primaryKey?.length === 1 ? view.columns.find((c) => c.columnName === view.primaryKey?.[0]) : void 0;
1258
1263
  if (!pkColumn) {
1259
- fail("requires exactly one primary-key column");
1264
+ fail2("requires exactly one primary-key column");
1260
1265
  return errors;
1261
1266
  }
1262
1267
  const systemNames = new Set(Object.values(RESOLVED_VIEW_SYSTEM_COLUMNS).map((c) => c.name));
@@ -1266,92 +1271,93 @@ function validateResolvedView({ view, tables, views = [] }) {
1266
1271
  pkColumn,
1267
1272
  dataColumns: new Map(view.columns.filter((c) => !systemNames.has(c.name) && c.cell === void 0).map((c) => [c.name, c])),
1268
1273
  sourceByName: /* @__PURE__ */ new Map(),
1269
- fail
1274
+ fail: fail2
1270
1275
  };
1271
- if (resolved.sources.filter((source) => source.kind === "manual").length !== 1) fail("requires exactly one manual source");
1276
+ if (resolved.sources.filter((source) => source.kind === "manual").length !== 1) fail2("requires exactly one manual source");
1272
1277
  const tableByName = new Map(tables.map((table) => [table.table, table]));
1273
1278
  for (const source of resolved.sources) {
1274
- if (scope.sourceByName.has(source.name)) fail(`duplicate source '${source.name}'`);
1279
+ if (scope.sourceByName.has(source.name)) fail2(`duplicate source '${source.name}'`);
1275
1280
  scope.sourceByName.set(source.name, source);
1276
1281
  const table = tableByName.get(source.table);
1277
- if (!table) fail(`source '${source.name}' references unknown table '${source.table}'`);
1282
+ if (!table) fail2(`source '${source.name}' references unknown table '${source.table}'`);
1278
1283
  else validateSource({ scope, source, table });
1279
1284
  }
1280
1285
  validateRules(scope);
1281
1286
  validateViewCells(scope);
1282
1287
  if (resolved.materialized) validateMaterialized({ scope, tableByName, views });
1283
1288
  for (const name2 of resolved.deletedBy) {
1284
- if (scope.sourceByName.get(name2)?.kind !== "manual") fail(`deletedBy '${name2}' must be the manual source`);
1289
+ if (scope.sourceByName.get(name2)?.kind !== "manual") fail2(`deletedBy '${name2}' must be the manual source`);
1285
1290
  }
1286
1291
  return errors;
1287
1292
  }
1288
1293
  function validateSource({ scope, source, table }) {
1289
- const { fail } = scope;
1290
- if (source.kind === "etl" && table.source === void 0) fail(`etl source '${source.name}' must reference a synced table`);
1294
+ const { fail: fail2 } = scope;
1295
+ if (source.kind === "etl" && table.source === void 0) fail2(`etl source '${source.name}' must reference a synced table`);
1296
+ if (source.kind === "etl" && table.primaryKey?.length === 0) fail2(`etl source '${source.name}' cannot use an unkeyed synced table for resolved row identity`);
1291
1297
  if (source.kind !== "etl" && (table.internal !== true || table.cellMetadata !== true)) {
1292
- fail(`${source.kind} source '${source.name}' must reference an internal table with cell metadata`);
1298
+ fail2(`${source.kind} source '${source.name}' must reference an internal table with cell metadata`);
1293
1299
  }
1294
1300
  const hasRev = table.columns.some((column) => column.cell?.part === "rev");
1295
- if (source.kind === "manual" && !hasRev) fail(`manual source '${source.name}' must carry '__rev' cell columns`);
1296
- if (source.kind === "prefetch" && hasRev) fail(`prefetch source '${source.name}' must not carry '__rev' cell columns`);
1301
+ if (source.kind === "manual" && !hasRev) fail2(`manual source '${source.name}' must carry '__rev' cell columns`);
1302
+ if (source.kind === "prefetch" && hasRev) fail2(`prefetch source '${source.name}' must not carry '__rev' cell columns`);
1297
1303
  const byName = new Map(table.columns.map((c) => [c.name, c]));
1298
1304
  validateSourceColumns({ scope, source, byName });
1299
1305
  if (source.kind === "etl") {
1300
1306
  const updatedAt = source.updatedAt === void 0 ? void 0 : byName.get(source.updatedAt);
1301
1307
  if (source.updatedAt !== void 0 && updatedAt?.type !== "timestamptz" && updatedAt?.type !== "date") {
1302
- fail(`etl source '${source.name}' updatedAt must name a timestamptz/date column on '${source.table}'`);
1308
+ fail2(`etl source '${source.name}' updatedAt must name a timestamptz/date column on '${source.table}'`);
1303
1309
  }
1304
1310
  }
1305
1311
  validatePrefetchFields({ scope, source });
1306
1312
  }
1307
1313
  function validatePrefetchFields({ scope, source }) {
1308
- const { fail, pkColumn } = scope;
1314
+ const { fail: fail2, pkColumn } = scope;
1309
1315
  if (source.kind !== "prefetch") {
1310
1316
  if (source.key || source.fetch || source.function || source.prefetchDefaults || source.writeback) {
1311
- fail(`only prefetch sources may declare key/fetch/function/prefetchDefaults/writeback ('${source.name}')`);
1317
+ fail2(`only prefetch sources may declare key/fetch/function/prefetchDefaults/writeback ('${source.name}')`);
1312
1318
  }
1313
1319
  return;
1314
1320
  }
1315
1321
  if (!source.key || !source.fetch || !source.function || !source.prefetchDefaults) {
1316
- fail(`prefetch source '${source.name}' requires key, fetch, function and prefetchDefaults`);
1322
+ fail2(`prefetch source '${source.name}' requires key, fetch, function and prefetchDefaults`);
1317
1323
  } else if (source.key !== pkColumn.name && !source.columns.includes(source.key)) {
1318
- fail(`prefetch source '${source.name}' key '${source.key}' must be the primary key or one of its columns`);
1324
+ fail2(`prefetch source '${source.name}' key '${source.key}' must be the primary key or one of its columns`);
1319
1325
  }
1320
1326
  for (const column of source.writeback?.columns ?? []) {
1321
- if (!source.columns.includes(column)) fail(`prefetch source '${source.name}' writes back '${column}', which it does not supply`);
1327
+ if (!source.columns.includes(column)) fail2(`prefetch source '${source.name}' writes back '${column}', which it does not supply`);
1322
1328
  }
1323
1329
  }
1324
1330
  function validateSourceColumns({ scope, source, byName }) {
1325
- const { fail, pkColumn, dataColumns } = scope;
1331
+ const { fail: fail2, pkColumn, dataColumns } = scope;
1326
1332
  for (const column of [pkColumn.name, ...source.columns]) {
1327
1333
  const own = column === pkColumn.name ? pkColumn : dataColumns.get(column);
1328
1334
  const theirs = byName.get(column);
1329
- if (!own) fail(`source '${source.name}' supplies unknown column '${column}'`);
1330
- else if (!theirs) fail(`source '${source.name}' table '${source.table}' has no column '${column}'`);
1331
- else if (JSON.stringify(theirs.type) !== JSON.stringify(own.type)) fail(`column '${column}' has a different type on source '${source.name}'`);
1335
+ if (!own) fail2(`source '${source.name}' supplies unknown column '${column}'`);
1336
+ else if (!theirs) fail2(`source '${source.name}' table '${source.table}' has no column '${column}'`);
1337
+ else if (JSON.stringify(theirs.type) !== JSON.stringify(own.type)) fail2(`column '${column}' has a different type on source '${source.name}'`);
1332
1338
  }
1333
1339
  }
1334
- function validateRules({ resolved, pkColumn, dataColumns, sourceByName, fail }) {
1340
+ function validateRules({ resolved, pkColumn, dataColumns, sourceByName, fail: fail2 }) {
1335
1341
  const ruled = /* @__PURE__ */ new Set();
1336
1342
  for (const rule of resolved.resolve) {
1337
1343
  if (!dataColumns.has(rule.column) || rule.column === pkColumn.name) {
1338
- fail(`resolve rule targets unknown column '${rule.column}'`);
1344
+ fail2(`resolve rule targets unknown column '${rule.column}'`);
1339
1345
  continue;
1340
1346
  }
1341
- if (ruled.has(rule.column)) fail(`column '${rule.column}' has more than one resolve rule`);
1347
+ if (ruled.has(rule.column)) fail2(`column '${rule.column}' has more than one resolve rule`);
1342
1348
  ruled.add(rule.column);
1343
1349
  if (rule.comparator === "custom" !== (rule.orderBy !== void 0)) {
1344
- fail(`column '${rule.column}': orderBy is required for custom comparators and only allowed there`);
1350
+ fail2(`column '${rule.column}': orderBy is required for custom comparators and only allowed there`);
1345
1351
  }
1346
- if (new Set(rule.candidates).size !== rule.candidates.length) fail(`column '${rule.column}' repeats a candidate`);
1352
+ if (new Set(rule.candidates).size !== rule.candidates.length) fail2(`column '${rule.column}' repeats a candidate`);
1347
1353
  for (const candidate of rule.candidates) {
1348
1354
  const source = sourceByName.get(candidate);
1349
- if (!source) fail(`column '${rule.column}' names unknown candidate source '${candidate}'`);
1350
- else if (!source.columns.includes(rule.column)) fail(`column '${rule.column}' candidate '${candidate}' does not supply it`);
1355
+ if (!source) fail2(`column '${rule.column}' names unknown candidate source '${candidate}'`);
1356
+ else if (!source.columns.includes(rule.column)) fail2(`column '${rule.column}' candidate '${candidate}' does not supply it`);
1351
1357
  }
1352
1358
  }
1353
1359
  for (const column of dataColumns.keys()) {
1354
- if (column !== pkColumn.name && !ruled.has(column)) fail(`column '${column}' has no resolve rule`);
1360
+ if (column !== pkColumn.name && !ruled.has(column)) fail2(`column '${column}' has no resolve rule`);
1355
1361
  }
1356
1362
  }
1357
1363
  var VIEW_CELL_TYPES = {
@@ -1360,7 +1366,7 @@ var VIEW_CELL_TYPES = {
1360
1366
  by: "text",
1361
1367
  conflicts: "jsonb"
1362
1368
  };
1363
- function validateViewCells({ view, dataColumns, pkColumn, fail }) {
1369
+ function validateViewCells({ view, dataColumns, pkColumn, fail: fail2 }) {
1364
1370
  const expected = /* @__PURE__ */ new Map();
1365
1371
  for (const column of dataColumns.values()) {
1366
1372
  if (column.name === pkColumn.name) continue;
@@ -1372,34 +1378,34 @@ function validateViewCells({ view, dataColumns, pkColumn, fail }) {
1372
1378
  if (!column.cell) continue;
1373
1379
  const want = expected.get(column.name);
1374
1380
  if (!want || want.part !== column.cell.part || want.columnName !== column.columnName || cellColumnName(column.cell.of, column.cell.part) !== column.name) {
1375
- fail(`unexpected cell column '${column.name}'`);
1381
+ fail2(`unexpected cell column '${column.name}'`);
1376
1382
  continue;
1377
1383
  }
1378
- if (column.type !== VIEW_CELL_TYPES[column.cell.part]) fail(`cell column '${column.name}' must be ${VIEW_CELL_TYPES[column.cell.part]}`);
1384
+ if (column.type !== VIEW_CELL_TYPES[column.cell.part]) fail2(`cell column '${column.name}' must be ${VIEW_CELL_TYPES[column.cell.part]}`);
1379
1385
  expected.delete(column.name);
1380
1386
  }
1381
- for (const name2 of expected.keys()) fail(`missing cell column '${name2}'`);
1387
+ for (const name2 of expected.keys()) fail2(`missing cell column '${name2}'`);
1382
1388
  }
1383
1389
  var columnSignature = (columns) => JSON.stringify(columns.map((column) => [column.name, column.columnName, column.type]));
1384
1390
  function validateMaterialized({ scope, tableByName, views }) {
1385
- const { view, resolved, fail } = scope;
1391
+ const { view, resolved, fail: fail2 } = scope;
1386
1392
  const { table: tableName, compute: computeName } = resolved.materialized;
1387
1393
  const table = tableByName.get(tableName);
1388
1394
  if (!table || table.internal !== true || table.materializes !== view.view) {
1389
- fail(`materialized table '${tableName}' must be an internal table that materializes '${view.view}'`);
1395
+ fail2(`materialized table '${tableName}' must be an internal table that materializes '${view.view}'`);
1390
1396
  } else {
1391
- if (columnSignature(table.columns) !== columnSignature(view.columns)) fail(`materialized table '${tableName}' must have exactly the view's columns`);
1392
- if (JSON.stringify(table.primaryKey ?? []) !== JSON.stringify(view.primaryKey ?? [])) fail(`materialized table '${tableName}' must share the view's primary key`);
1397
+ if (columnSignature(table.columns) !== columnSignature(view.columns)) fail2(`materialized table '${tableName}' must have exactly the view's columns`);
1398
+ if (JSON.stringify(table.primaryKey ?? []) !== JSON.stringify(view.primaryKey ?? [])) fail2(`materialized table '${tableName}' must share the view's primary key`);
1393
1399
  }
1394
1400
  const compute = views.find((candidate) => candidate.view === computeName);
1395
- if (!compute || compute.internal !== true) fail(`compute view '${computeName}' must be an internal view`);
1396
- else if (columnSignature(compute.columns) !== columnSignature(view.columns)) fail(`compute view '${computeName}' must have exactly the view's columns`);
1401
+ if (!compute || compute.internal !== true) fail2(`compute view '${computeName}' must be an internal view`);
1402
+ else if (columnSignature(compute.columns) !== columnSignature(view.columns)) fail2(`compute view '${computeName}' must have exactly the view's columns`);
1397
1403
  for (const source of resolved.sources) {
1398
1404
  if (source.kind !== "etl") continue;
1399
1405
  const read = tableByName.get(source.table)?.policies?.read;
1400
1406
  const unconditional = typeof read === "string" ? read.trim() === "true" : read !== void 0 && read.default.trim() === "true" && read.variants.length === 0;
1401
1407
  if (!unconditional) {
1402
- fail(`etl source '${source.name}' must have read policy 'true' to be materialized (the copy is shared by every caller)`);
1408
+ fail2(`etl source '${source.name}' must have read policy 'true' to be materialized (the copy is shared by every caller)`);
1403
1409
  }
1404
1410
  }
1405
1411
  }
@@ -1736,7 +1742,7 @@ var canonicalTableSchema = z.object({
1736
1742
  /** Synced/reflected read-only tables (`source: schema.table`) — v1 semantics. */
1737
1743
  source: z.string().regex(QUALIFIED_TABLE_PATTERN).optional(),
1738
1744
  columns: z.array(canonicalColumnSchema).default([]),
1739
- primaryKey: z.array(columnIdentifier).min(1).max(8).optional(),
1745
+ primaryKey: z.array(columnIdentifier).max(8).optional(),
1740
1746
  links: z.array(canonicalLinkSchema).default([]),
1741
1747
  indexes: z.array(canonicalIndexSchema).default([]),
1742
1748
  /** Omitted by old definitions, preserving their existing content hashes. */
@@ -1772,6 +1778,29 @@ var canonicalTableSchema = z.object({
1772
1778
  * data plane. Omitted otherwise.
1773
1779
  */
1774
1780
  materializes: identifier2.optional()
1781
+ }).superRefine((table, ctx) => {
1782
+ if (table.primaryKey?.length !== 0) return;
1783
+ const fail2 = (message, path = ["primaryKey"]) => ctx.addIssue({ code: "custom", path, message: `unkeyed table '${table.table}' ${message}` });
1784
+ if (table.source === void 0 || table.columns.length === 0) {
1785
+ fail2("requires a typed synced source");
1786
+ }
1787
+ if ([table.policies.write, table.policies.insert, table.policies.update].some((policy) => policy !== void 0)) {
1788
+ fail2("is read-only and cannot declare write policies", ["policies"]);
1789
+ }
1790
+ const ownedCollections = [table.indexes, table.actions, table.checks, table.foreignKeys, table.cowMutations];
1791
+ const ownedMetadata = [table.cellMetadata, table.internal, table.materializes, table.renamedFrom];
1792
+ if (ownedCollections.some((items) => items !== void 0 && items.length > 0) || ownedMetadata.some((value) => value !== void 0)) {
1793
+ fail2("cannot declare owned storage, constraints or identity operations");
1794
+ }
1795
+ for (const [index3, column] of table.columns.entries()) {
1796
+ const ownedColumnMetadata = [column.default, column.defaultFn, column.onUpdateFn, column.renamedFrom, column.cast, column.cell];
1797
+ if (column.unique || ownedColumnMetadata.some((value) => value !== void 0)) {
1798
+ fail2("cannot declare column uniqueness, mutation defaults or migration metadata", ["columns", index3]);
1799
+ }
1800
+ }
1801
+ for (const [index3, link] of table.links.entries()) {
1802
+ if (link.enforce || link.kind === "toMany") fail2("cannot provide an identity for this link", ["links", index3]);
1803
+ }
1775
1804
  });
1776
1805
  var MAX_VIEW_QUERY = 1e5;
1777
1806
  var MAX_RESOLVED_VIEW_QUERY = 5e6;
@@ -1828,6 +1857,26 @@ var canonicalViewSchema = z.object({
1828
1857
  }
1829
1858
  }
1830
1859
  });
1860
+ function validateUnkeyedLinkIdentities({ definition, ctx }) {
1861
+ const tables = new Map(definition.tables.map((table) => [table.table, table]));
1862
+ const relations = [
1863
+ ...definition.tables.map((table, index3) => ({ kind: "tables", index: index3, links: table.links })),
1864
+ ...(definition.views ?? []).map((view, index3) => ({ kind: "views", index: index3, links: view.links }))
1865
+ ];
1866
+ for (const relation of relations) {
1867
+ for (const [linkIndex, link] of relation.links.entries()) {
1868
+ if (link.kind !== "toOne" || link.namespace !== void 0 && link.namespace !== definition.namespace) continue;
1869
+ const target = link.target === void 0 ? void 0 : tables.get(link.target);
1870
+ if (target?.source !== void 0 && target.primaryKey?.length === 0) {
1871
+ ctx.addIssue({
1872
+ code: "custom",
1873
+ path: [relation.kind, relation.index, "links", linkIndex],
1874
+ message: `link '${link.name}' cannot use unkeyed table '${target.table}' as a to-one identity`
1875
+ });
1876
+ }
1877
+ }
1878
+ }
1879
+ }
1831
1880
  var CELL_PART_TYPES = {
1832
1881
  at: "timestamptz",
1833
1882
  by: "text",
@@ -1841,49 +1890,49 @@ function trackedCellColumns(table) {
1841
1890
  }
1842
1891
  var SUFFIXES = Object.values(CELL_PART_SUFFIX);
1843
1892
  function validateCellMetadata(table, index3, ctx) {
1844
- const fail = (message, path = ["tables", index3]) => ctx.addIssue({ code: "custom", path, message });
1893
+ const fail2 = (message, path = ["tables", index3]) => ctx.addIssue({ code: "custom", path, message });
1845
1894
  const cells = table.columns.flatMap((column, position) => column.cell ? [{ column, position, cell: column.cell }] : []);
1846
1895
  if (table.materializes !== void 0) return;
1847
1896
  if (table.cellMetadata !== true) {
1848
- for (const { position } of cells) fail(`cell-metadata columns require cellMetadata on table '${table.table}'`, ["tables", index3, "columns", position]);
1897
+ for (const { position } of cells) fail2(`cell-metadata columns require cellMetadata on table '${table.table}'`, ["tables", index3, "columns", position]);
1849
1898
  return;
1850
1899
  }
1851
1900
  if (table.source !== void 0) {
1852
- fail(`synced table '${table.table}' cannot track cell metadata`);
1901
+ fail2(`synced table '${table.table}' cannot track cell metadata`);
1853
1902
  return;
1854
1903
  }
1855
1904
  const tracked = trackedCellColumns(table);
1856
1905
  const byName = new Map(tracked.map((column) => [column.name, column]));
1857
1906
  const withRev = cells.some(({ cell }) => cell.part === "rev");
1858
- if (withRev && table.internal !== true) fail(`only a resolved table's internal sources carry '__rev' cell columns ('${table.table}')`);
1907
+ if (withRev && table.internal !== true) fail2(`only a resolved table's internal sources carry '__rev' cell columns ('${table.table}')`);
1859
1908
  const seen = /* @__PURE__ */ new Set();
1860
1909
  for (const { column, position, cell } of cells) {
1861
1910
  const path = ["tables", index3, "columns", position];
1862
1911
  const owner = byName.get(cell.of);
1863
1912
  if (!owner) {
1864
- fail(`cell column '${column.name}' belongs to '${cell.of}', which is not a tracked column`, path);
1913
+ fail2(`cell column '${column.name}' belongs to '${cell.of}', which is not a tracked column`, path);
1865
1914
  continue;
1866
1915
  }
1867
- if (cell.part !== "at" && cell.part !== "by" && cell.part !== "rev") fail(`a table cell column must be part at/by/rev, not '${cell.part}'`, path);
1916
+ if (cell.part !== "at" && cell.part !== "by" && cell.part !== "rev") fail2(`a table cell column must be part at/by/rev, not '${cell.part}'`, path);
1868
1917
  if (column.name !== cellColumnName(owner.name, cell.part) || column.columnName !== cellColumnName(owner.columnName, cell.part)) {
1869
- fail(`cell column for '${owner.name}' ${cell.part} must be named '${cellColumnName(owner.name, cell.part)}' / '${cellColumnName(owner.columnName, cell.part)}'`, path);
1918
+ fail2(`cell column for '${owner.name}' ${cell.part} must be named '${cellColumnName(owner.name, cell.part)}' / '${cellColumnName(owner.columnName, cell.part)}'`, path);
1870
1919
  }
1871
1920
  if (column.type !== CELL_PART_TYPES[cell.part] || !column.nullable || column.unique || column.default !== void 0 || column.defaultFn !== void 0) {
1872
- fail(`cell column '${column.name}' must be a nullable, default-less ${CELL_PART_TYPES[cell.part]}`, path);
1921
+ fail2(`cell column '${column.name}' must be a nullable, default-less ${CELL_PART_TYPES[cell.part]}`, path);
1873
1922
  }
1874
1923
  const key = `${cell.of}:${cell.part}`;
1875
- if (seen.has(key)) fail(`duplicate cell column '${column.name}'`, path);
1924
+ if (seen.has(key)) fail2(`duplicate cell column '${column.name}'`, path);
1876
1925
  seen.add(key);
1877
1926
  }
1878
1927
  for (const column of tracked) {
1879
1928
  if (column.columnName.length > MAX_TRACKED_COLUMN_NAME) {
1880
- fail(`column '${column.columnName}' is too long to track cell metadata (max ${MAX_TRACKED_COLUMN_NAME} characters)`);
1929
+ fail2(`column '${column.columnName}' is too long to track cell metadata (max ${MAX_TRACKED_COLUMN_NAME} characters)`);
1881
1930
  }
1882
1931
  if (SUFFIXES.some((suffix) => column.columnName.endsWith(suffix))) {
1883
- fail(`column '${column.columnName}' ends in a reserved cell-metadata suffix (${SUFFIXES.join(", ")})`);
1932
+ fail2(`column '${column.columnName}' ends in a reserved cell-metadata suffix (${SUFFIXES.join(", ")})`);
1884
1933
  }
1885
1934
  for (const part of withRev ? ["at", "by", "rev"] : ["at", "by"]) {
1886
- if (!seen.has(`${column.name}:${part}`)) fail(`tracked column '${column.name}' is missing its '${cellColumnName(column.columnName, part)}' cell column`);
1935
+ if (!seen.has(`${column.name}:${part}`)) fail2(`tracked column '${column.name}' is missing its '${cellColumnName(column.columnName, part)}' cell column`);
1887
1936
  }
1888
1937
  }
1889
1938
  }
@@ -1891,7 +1940,7 @@ var exportGateSchema = z.union([z.literal(true), z.object({ capability: z.string
1891
1940
  var relationExportSchema = z.object({ read: exportGateSchema, write: exportGateSchema.optional() }).strict();
1892
1941
  var localDefinitionSchema = z.object({
1893
1942
  definition_format: z.literal(CANONICAL_FORMAT),
1894
- namespace: identifier2.max(41),
1943
+ namespace: identifier2.max(41).regex(NAMESPACE_PATTERN, "invalid or reserved ORM namespace"),
1895
1944
  description: z.string().max(2e3).optional(),
1896
1945
  enums: z.array(canonicalEnumSchema).default([]),
1897
1946
  tables: z.array(canonicalTableSchema).min(0).max(500),
@@ -1925,6 +1974,7 @@ var localDefinitionSchema = z.object({
1925
1974
  }
1926
1975
  }
1927
1976
  const fkTables = new Map(definition.tables.map((table) => [table.table, table]));
1977
+ validateUnkeyedLinkIdentities({ definition, ctx });
1928
1978
  const relations = /* @__PURE__ */ new Set([...fkTables.keys(), ...(definition.views ?? []).map((view) => view.view)]);
1929
1979
  for (const name2 of Object.keys(definition.exports ?? {})) {
1930
1980
  if (!relations.has(name2)) ctx.addIssue({ code: "custom", path: ["exports", name2], message: `export '${name2}' is not a local object` });
@@ -1950,38 +2000,38 @@ var localDefinitionSchema = z.object({
1950
2000
  }
1951
2001
  }
1952
2002
  for (const [index3, check] of (table.checks ?? []).entries()) {
1953
- const fail = (message) => ctx.addIssue({ code: "custom", path: ["tables", tableIndex, "checks", index3], message });
1954
- if (table.source) fail("synced tables cannot declare checks");
1955
- if (names.has(check.name)) fail(`duplicate constraint '${check.name}'`);
2003
+ const fail2 = (message) => ctx.addIssue({ code: "custom", path: ["tables", tableIndex, "checks", index3], message });
2004
+ if (table.source) fail2("synced tables cannot declare checks");
2005
+ if (names.has(check.name)) fail2(`duplicate constraint '${check.name}'`);
1956
2006
  names.add(check.name);
1957
2007
  try {
1958
2008
  compileCheckExpression(check.expression, table.columns);
1959
2009
  } catch (error) {
1960
- fail(error instanceof Error ? error.message : String(error));
2010
+ fail2(error instanceof Error ? error.message : String(error));
1961
2011
  }
1962
2012
  }
1963
2013
  for (const [index3, fk] of (table.foreignKeys ?? []).entries()) {
1964
- const fail = (message) => ctx.addIssue({ code: "custom", path: ["tables", tableIndex, "foreignKeys", index3], message });
1965
- if (names.has(fk.name)) fail(`duplicate foreign key '${fk.name}'`);
2014
+ const fail2 = (message) => ctx.addIssue({ code: "custom", path: ["tables", tableIndex, "foreignKeys", index3], message });
2015
+ if (names.has(fk.name)) fail2(`duplicate foreign key '${fk.name}'`);
1966
2016
  names.add(fk.name);
1967
2017
  const target = fkTables.get(fk.target);
1968
2018
  if (table.source || !target || target.source) {
1969
- fail("foreign keys must connect owned tables in the same namespace");
2019
+ fail2("foreign keys must connect owned tables in the same namespace");
1970
2020
  continue;
1971
2021
  }
1972
- if (fk.columns.length !== fk.references.length) fail("foreign key columns and references must have the same number of columns");
1973
- if (new Set(fk.columns).size !== fk.columns.length || new Set(fk.references).size !== fk.references.length) fail("foreign key columns must not repeat");
2022
+ if (fk.columns.length !== fk.references.length) fail2("foreign key columns and references must have the same number of columns");
2023
+ if (new Set(fk.columns).size !== fk.columns.length || new Set(fk.references).size !== fk.references.length) fail2("foreign key columns must not repeat");
1974
2024
  for (const [position, name2] of fk.columns.entries()) {
1975
2025
  const sourceColumn = table.columns.find((column) => column.columnName === name2);
1976
2026
  const targetColumn = target.columns.find((column) => column.columnName === fk.references[position]);
1977
- if (!sourceColumn || !targetColumn) fail("foreign key references an unknown column");
1978
- else if (JSON.stringify(sourceColumn.type) !== JSON.stringify(targetColumn.type)) fail("foreign key column types must match");
2027
+ if (!sourceColumn || !targetColumn) fail2("foreign key references an unknown column");
2028
+ else if (JSON.stringify(sourceColumn.type) !== JSON.stringify(targetColumn.type)) fail2("foreign key column types must match");
1979
2029
  }
1980
2030
  if (fk.onDelete === "set null" || fk.onUpdate === "set null") {
1981
- if (fk.columns.some((name2) => table.columns.find((column) => column.columnName === name2)?.nullable === false || table.primaryKey?.includes(name2))) fail("SET NULL requires nullable source columns");
2031
+ if (fk.columns.some((name2) => table.columns.find((column) => column.columnName === name2)?.nullable === false || table.primaryKey?.includes(name2))) fail2("SET NULL requires nullable source columns");
1982
2032
  }
1983
2033
  const uniqueKeys = [target.primaryKey ?? [], ...target.indexes.filter((index4) => index4.unique).map((index4) => index4.columns), ...target.columns.filter((column) => column.unique).map((column) => [column.columnName])];
1984
- 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");
2034
+ if (!uniqueKeys.some((key) => key.length === fk.references.length && key.every((column) => fk.references.includes(column)))) fail2("foreign key target columns must form a unique key");
1985
2035
  }
1986
2036
  }
1987
2037
  for (const [viewIndex, view] of (definition.views ?? []).entries()) {
@@ -2169,8 +2219,8 @@ function cloneColumn({ builder, property, notNull, primaryKey: primaryKey2 }) {
2169
2219
  return clone;
2170
2220
  }
2171
2221
  function planSource(input) {
2172
- const { sourceName, input: source, fail } = input;
2173
- if (!IDENTIFIER_PATTERN.test(sourceName)) fail(`source name "${sourceName}" must match ${IDENTIFIER_PATTERN}`);
2222
+ const { sourceName, input: source, fail: fail2 } = input;
2223
+ if (!IDENTIFIER_PATTERN.test(sourceName)) fail2(`source name "${sourceName}" must match ${IDENTIFIER_PATTERN}`);
2174
2224
  switch (source.kind) {
2175
2225
  case "manual":
2176
2226
  return {
@@ -2206,30 +2256,31 @@ function internalTable(input, supplied, system, options = {}) {
2206
2256
  internal: true
2207
2257
  });
2208
2258
  }
2209
- function assertColumns(input, list, what) {
2210
- for (const column of list) if (!input.dataColumns.includes(column)) input.fail(`${what} names unknown column "${column}"`);
2259
+ function assertColumns(input, list2, what) {
2260
+ for (const column of list2) if (!input.dataColumns.includes(column)) input.fail(`${what} names unknown column "${column}"`);
2211
2261
  }
2212
2262
  function planEtl(input, source) {
2213
- const { sourceName, pk, dataColumns, fail } = input;
2263
+ const { sourceName, pk, dataColumns, fail: fail2 } = input;
2214
2264
  const table = typeof source.table === "function" ? source.table() : source.table;
2215
- if (!isSeqTable(table) || table.source === void 0) fail(`etl source "${sourceName}" must reference a defineSyncedTable`);
2265
+ if (!isSeqTable(table) || table.source === void 0) fail2(`etl source "${sourceName}" must reference a defineSyncedTable`);
2216
2266
  const synced = table;
2217
- if (!(pk in synced.columns)) fail(`etl source "${sourceName}" table "${synced.tableName}" has no "${pk}" column`);
2267
+ if (synced.config.primaryKey?.length === 0) fail2(`etl source "${sourceName}" cannot use an unkeyed synced table for resolved row identity`);
2268
+ if (!(pk in synced.columns)) fail2(`etl source "${sourceName}" table "${synced.tableName}" has no "${pk}" column`);
2218
2269
  const supplied = source.columns ? [...source.columns] : dataColumns.filter((column) => column in synced.columns);
2219
2270
  assertColumns(input, supplied, `etl source "${sourceName}"`);
2220
2271
  if (source.updatedAt !== void 0 && !(source.updatedAt in synced.columns)) {
2221
- fail(`etl source "${sourceName}" updatedAt "${source.updatedAt}" is not a column of "${synced.tableName}"`);
2272
+ fail2(`etl source "${sourceName}" updatedAt "${source.updatedAt}" is not a column of "${synced.tableName}"`);
2222
2273
  }
2223
2274
  return { name: sourceName, kind: "etl", table: synced, columns: supplied, ...source.updatedAt ? { updatedAt: source.updatedAt } : {} };
2224
2275
  }
2225
2276
  function planPrefetch(input, source) {
2226
- const { sourceName, pk, fail } = input;
2277
+ const { sourceName, pk, fail: fail2 } = input;
2227
2278
  assertColumns(input, source.columns, `prefetch source "${sourceName}"`);
2228
2279
  if (source.key !== pk && !source.columns.includes(source.key)) {
2229
- fail(`prefetch source "${sourceName}" key "${source.key}" must be the primary key or one of its columns`);
2280
+ fail2(`prefetch source "${sourceName}" key "${source.key}" must be the primary key or one of its columns`);
2230
2281
  }
2231
2282
  for (const column of source.writeback?.columns ?? []) {
2232
- if (!source.columns.includes(column)) fail(`prefetch source "${sourceName}" writes back "${column}", which it does not supply`);
2283
+ if (!source.columns.includes(column)) fail2(`prefetch source "${sourceName}" writes back "${column}", which it does not supply`);
2233
2284
  }
2234
2285
  const writeback = source.writeback;
2235
2286
  return {
@@ -2435,34 +2486,34 @@ var SYSTEM_VIEW_COLUMNS = {
2435
2486
  };
2436
2487
  function defineResolvedTable(name2, columns, config) {
2437
2488
  const file = activeAuthoringContext()?.currentFile;
2438
- const fail = (message) => {
2489
+ const fail2 = (message) => {
2439
2490
  throw new OrmDefinitionError(`resolved table "${name2}": ${message}`, file);
2440
2491
  };
2441
- if (!IDENTIFIER_PATTERN.test(name2)) fail(`name must match ${IDENTIFIER_PATTERN}`);
2492
+ if (!IDENTIFIER_PATTERN.test(name2)) fail2(`name must match ${IDENTIFIER_PATTERN}`);
2442
2493
  for (const property of Object.keys(columns)) {
2443
2494
  if (RESERVED_RESOLVED_COLUMN_NAMES.has(property) || RESERVED_RESOLVED_COLUMN_NAMES.has(columns[property].columnNameFor(property))) {
2444
- fail(`column "${property}" collides with a reserved system column`);
2495
+ fail2(`column "${property}" collides with a reserved system column`);
2445
2496
  }
2446
2497
  }
2447
2498
  for (const property of Object.keys(columns)) {
2448
2499
  if (columns[property].columnNameFor(property).length > MAX_TRACKED_COLUMN_NAME) {
2449
- fail(`column "${property}" is too long for a resolved table (max ${MAX_TRACKED_COLUMN_NAME} characters, room for cell parts)`);
2500
+ fail2(`column "${property}" is too long for a resolved table (max ${MAX_TRACKED_COLUMN_NAME} characters, room for cell parts)`);
2450
2501
  }
2451
2502
  }
2452
2503
  const pkEntries = Object.entries(columns).filter(([, builder]) => builder.isPrimaryKey);
2453
- if (pkEntries.length !== 1) fail("declare exactly one .primaryKey() column");
2504
+ if (pkEntries.length !== 1) fail2("declare exactly one .primaryKey() column");
2454
2505
  const [pk, pkBuilder] = pkEntries[0];
2455
2506
  const dataColumns = Object.keys(columns).filter((property) => property !== pk);
2456
- if (dataColumns.length === 0) fail("declare at least one non-key column");
2507
+ if (dataColumns.length === 0) fail2("declare at least one non-key column");
2457
2508
  const sourceEntries = Object.entries(config.sources);
2458
- if (sourceEntries.filter(([, source]) => source.kind === "manual").length !== 1) fail("declare exactly one manualSource()");
2509
+ if (sourceEntries.filter(([, source]) => source.kind === "manual").length !== 1) fail2("declare exactly one manualSource()");
2459
2510
  const plans = sourceEntries.map(
2460
- ([sourceName, input]) => planSource({ viewName: name2, sourceName, input, columns, pk, pkBuilder, dataColumns, fail })
2511
+ ([sourceName, input]) => planSource({ viewName: name2, sourceName, input, columns, pk, pkBuilder, dataColumns, fail: fail2 })
2461
2512
  );
2462
- const rules = planRules({ config, plans, dataColumns, fail });
2513
+ const rules = planRules({ config, plans, dataColumns, fail: fail2 });
2463
2514
  const deletedBy = [...config.rows?.deletedBy ?? []];
2464
2515
  for (const source of deletedBy) {
2465
- if (plans.find((plan) => plan.name === source)?.kind !== "manual") fail(`rows.deletedBy "${source}" must be the manual source`);
2516
+ if (plans.find((plan) => plan.name === source)?.kind !== "manual") fail2(`rows.deletedBy "${source}" must be the manual source`);
2466
2517
  }
2467
2518
  const partType = { source: t.text, at: t.timestamptz, by: t.text, conflicts: t.jsonb };
2468
2519
  const viewColumns = {};
@@ -2525,11 +2576,11 @@ function defineResolvedTable(name2, columns, config) {
2525
2576
  }
2526
2577
  });
2527
2578
  }
2528
- function planRules({ config, plans, dataColumns, fail }) {
2579
+ function planRules({ config, plans, dataColumns, fail: fail2 }) {
2529
2580
  const kindOrder = { manual: 0, prefetch: 1, etl: 2 };
2530
2581
  const fallback = config.default ?? priority([...plans].sort((a, b) => kindOrder[a.kind] - kindOrder[b.kind]).map((plan) => plan.name));
2531
2582
  for (const column of Object.keys(config.resolve ?? {})) {
2532
- if (!dataColumns.includes(column)) fail(`resolve names unknown column "${column}"`);
2583
+ if (!dataColumns.includes(column)) fail2(`resolve names unknown column "${column}"`);
2533
2584
  }
2534
2585
  return dataColumns.map((column) => {
2535
2586
  const explicit = config.resolve?.[column];
@@ -2537,11 +2588,11 @@ function planRules({ config, plans, dataColumns, fail }) {
2537
2588
  const candidates = explicit ? [...explicit.candidates] : comparator.candidates.filter((name2) => plans.find((plan) => plan.name === name2)?.columns.includes(column));
2538
2589
  for (const candidate of candidates) {
2539
2590
  const plan = plans.find((entry) => entry.name === candidate);
2540
- if (!plan) fail(`column "${column}" names unknown source "${candidate}"`);
2541
- else if (!plan.columns.includes(column)) fail(`column "${column}" candidate "${candidate}" does not supply it`);
2591
+ if (!plan) fail2(`column "${column}" names unknown source "${candidate}"`);
2592
+ else if (!plan.columns.includes(column)) fail2(`column "${column}" candidate "${candidate}" does not supply it`);
2542
2593
  }
2543
- if (candidates.length === 0) fail(`column "${column}" has no candidate source`);
2544
- if (comparator.kind === "custom") assertSafeOrderBy({ orderBy: comparator.orderBy ?? "", column, fail });
2594
+ if (candidates.length === 0) fail2(`column "${column}" has no candidate source`);
2595
+ if (comparator.kind === "custom") assertSafeOrderBy({ orderBy: comparator.orderBy ?? "", column, fail: fail2 });
2545
2596
  return {
2546
2597
  column,
2547
2598
  comparator: comparator.kind,
@@ -2592,18 +2643,18 @@ var ORDER_BY_KEYWORDS = /* @__PURE__ */ new Set([
2592
2643
  ]);
2593
2644
  var ALLOWED_FUNCTIONS = new Set(VIEW_QUERY_FUNCTION_ALLOWLIST);
2594
2645
  var ORDER_BY_TOKEN = /\s+|'(?:[^']|'')*'|\d+(?:\.\d+)?|[a-z_][a-z0-9_]*|::|<=|>=|<>|!=|[-+*/%<>=(),|]/giy;
2595
- function assertSafeOrderBy({ orderBy, column, fail }) {
2646
+ function assertSafeOrderBy({ orderBy, column, fail: fail2 }) {
2596
2647
  ORDER_BY_TOKEN.lastIndex = 0;
2597
2648
  let consumed = 0;
2598
2649
  for (let match = ORDER_BY_TOKEN.exec(orderBy); match; match = ORDER_BY_TOKEN.exec(orderBy)) {
2599
2650
  consumed = ORDER_BY_TOKEN.lastIndex;
2600
2651
  const token = match[0].toLowerCase();
2601
2652
  if (/^[a-z_]/.test(token) && !ORDER_BY_KEYWORDS.has(token) && !ALLOWED_FUNCTIONS.has(token)) {
2602
- fail(`column "${column}" custom orderBy uses "${match[0]}" \u2014 only value, updated_at, source, actor, ord, SQL keywords and allowlisted functions`);
2653
+ fail2(`column "${column}" custom orderBy uses "${match[0]}" \u2014 only value, updated_at, source, actor, ord, SQL keywords and allowlisted functions`);
2603
2654
  }
2604
2655
  }
2605
2656
  if (consumed !== orderBy.length || orderBy.trim() === "") {
2606
- fail(`column "${column}" custom orderBy contains an unsupported character near "${orderBy.slice(consumed, consumed + 10)}"`);
2657
+ fail2(`column "${column}" custom orderBy contains an unsupported character near "${orderBy.slice(consumed, consumed + 10)}"`);
2607
2658
  }
2608
2659
  }
2609
2660
  function stableJson(value) {
@@ -3131,17 +3182,17 @@ function buildCanonicalLink({
3131
3182
  }) {
3132
3183
  const ownerKind = relationKind(relation);
3133
3184
  const ownerName = relationName(relation);
3134
- const fail = (message) => {
3185
+ const fail2 = (message) => {
3135
3186
  throw new OrmDefinitionError(`${ownerKind} "${ownerName}": link "${linkName}" ${message}`, relation.file);
3136
3187
  };
3137
3188
  if (link.enforce && link.linkKind !== "toOne") {
3138
- return fail("sets enforce: true, which is only supported on toOne links");
3189
+ return fail2("sets enforce: true, which is only supported on toOne links");
3139
3190
  }
3140
3191
  if ((link.onDelete !== void 0 || link.onUpdate !== void 0) && !link.enforce) {
3141
- return fail("sets a referential action without enforce: true");
3192
+ return fail2("sets a referential action without enforce: true");
3142
3193
  }
3143
3194
  if (link.linkKind === "toPlatformUser") {
3144
- if (link.target !== void 0) return fail("is toPlatformUser and must not declare a target table");
3195
+ if (link.target !== void 0) return fail2("is toPlatformUser and must not declare a target table");
3145
3196
  return {
3146
3197
  name: linkName,
3147
3198
  kind: "toPlatformUser",
@@ -3152,7 +3203,7 @@ function buildCanonicalLink({
3152
3203
  };
3153
3204
  }
3154
3205
  if (typeof link.target === "object" && link.target?.kind === "seq-external-object") {
3155
- if (link.enforce) return fail("cannot enforce a cross-namespace physical foreign key; use an ORM link without enforce");
3206
+ if (link.enforce) return fail2("cannot enforce a cross-namespace physical foreign key; use an ORM link without enforce");
3156
3207
  return {
3157
3208
  name: linkName,
3158
3209
  kind: link.linkKind,
@@ -3164,13 +3215,13 @@ function buildCanonicalLink({
3164
3215
  ...link.description !== void 0 ? { description: link.description } : {}
3165
3216
  };
3166
3217
  }
3167
- const target = resolveRelationRef({ ref: link.target, fail });
3218
+ const target = resolveRelationRef({ ref: link.target, fail: fail2 });
3168
3219
  const targetName = relationName(target);
3169
3220
  if (!relationsByName.has(targetName)) {
3170
- return fail(`targets ${relationKind(target)} "${targetName}" which is not part of this namespace`);
3221
+ return fail2(`targets ${relationKind(target)} "${targetName}" which is not part of this namespace`);
3171
3222
  }
3172
3223
  if (link.enforce && (!isSeqTable(relation) || !isSeqTable(target))) {
3173
- return fail("cannot enforce a PostgreSQL foreign key involving a view");
3224
+ return fail2("cannot enforce a PostgreSQL foreign key involving a view");
3174
3225
  }
3175
3226
  const owningSide = link.linkKind === "toOne" ? relation : target;
3176
3227
  const referencedSide = link.linkKind === "toOne" ? target : relation;
@@ -3186,19 +3237,19 @@ function buildCanonicalLink({
3186
3237
  ...link.description !== void 0 ? { description: link.description } : {}
3187
3238
  };
3188
3239
  }
3189
- function resolveRelationRef({ ref, fail }) {
3190
- if (ref === void 0) return fail("declares no target relation");
3240
+ function resolveRelationRef({ ref, fail: fail2 }) {
3241
+ if (ref === void 0) return fail2("declares no target relation");
3191
3242
  if (typeof ref !== "function") return ref;
3192
3243
  let resolved;
3193
3244
  try {
3194
3245
  resolved = ref();
3195
3246
  } catch (error) {
3196
- return fail(
3247
+ return fail2(
3197
3248
  `target thunk threw (${error instanceof Error ? error.message : String(error)}) \u2014 lazy refs resolve at serialize time; make sure the target module ran`
3198
3249
  );
3199
3250
  }
3200
3251
  if (!isSeqTable(resolved) && !isSeqView(resolved)) {
3201
- return fail("target thunk did not return a relation defined with defineTable/defineView");
3252
+ return fail2("target thunk did not return a relation defined with defineTable/defineView");
3202
3253
  }
3203
3254
  return resolved;
3204
3255
  }
@@ -3301,9 +3352,9 @@ function extractOrmSyncedTableContract({
3301
3352
  );
3302
3353
  }
3303
3354
  const primaryKey2 = table.primaryKey;
3304
- if (primaryKey2 === void 0 || primaryKey2.length === 0) {
3355
+ if (primaryKey2 === void 0) {
3305
3356
  throw new OrmDefinitionError(
3306
- `synced table "${table.table}" has no primary key \u2014 typed synced contracts require a primary key`
3357
+ `synced table "${table.table}" has no primary key contract \u2014 declare a key or explicit primaryKey: []`
3307
3358
  );
3308
3359
  }
3309
3360
  const pkSet = new Set(primaryKey2);
@@ -4108,9 +4159,9 @@ function buildActionParamsSchema(action) {
4108
4159
  for (const [name2, param] of entries) {
4109
4160
  shape[name2] = param.optional ? PARAM_SCHEMAS[param.type].nullish() : PARAM_SCHEMAS[param.type];
4110
4161
  }
4111
- return z.strictObject(shape).superRefine((obj, ctx) => {
4162
+ return z.strictObject(shape).superRefine((obj2, ctx) => {
4112
4163
  for (const [name2, param] of entries) {
4113
- if (!param.optional && param.type === "jsonb" && obj[name2] === void 0) {
4164
+ if (!param.optional && param.type === "jsonb" && obj2[name2] === void 0) {
4114
4165
  ctx.addIssue({ code: "custom", message: "Required", path: [name2] });
4115
4166
  }
4116
4167
  }
@@ -4768,6 +4819,17 @@ function syncedViewStatements({
4768
4819
  const viewName = `${schema}.${quoteIdentifier(table.table)}`;
4769
4820
  const physical2 = splitPhysicalRelation(backing.physicalRelation);
4770
4821
  const physicalTarget = `${quoteIdentifier(physical2.schema)}.${quoteIdentifier(physical2.table)}`;
4822
+ const declaredColumns = Object.keys(table.columns ?? {});
4823
+ const projection = declaredColumns.length > 0 ? declaredColumns.map(quoteIdentifier).join(", ") : "*";
4824
+ if (backing.selectColumns) {
4825
+ if (declaredColumns.length === 0) {
4826
+ throw new OrmDefinitionError(`synced backing for "${table.table}" requires declared columns`);
4827
+ }
4828
+ const approved = new Set(backing.selectColumns);
4829
+ if (declaredColumns.some((column) => !approved.has(column))) {
4830
+ throw new OrmDefinitionError(`synced backing for "${table.table}" projects outside its approved column ceiling`);
4831
+ }
4832
+ }
4771
4833
  const columnTypes = mergeSyncedViewColumnTypes({
4772
4834
  table,
4773
4835
  canonicalColumnTypes: columnTypesByTable?.get(table.table),
@@ -4776,23 +4838,26 @@ function syncedViewStatements({
4776
4838
  });
4777
4839
  const readPolicyIr = readPolicyIrByTable?.get(table.table);
4778
4840
  const readPolicy = table.policies?.read;
4779
- const whereClause = readPolicyIr ? ` WHERE ${compilePredIrToSql(readPolicyIr, {
4841
+ const policyClause = readPolicyIr ? ` WHERE ${compilePredIrToSql(readPolicyIr, {
4780
4842
  namespace: definition.namespace,
4781
4843
  columnTypes,
4782
4844
  columnNames: columnNamesByTable?.get(table.table)
4783
4845
  })}` : readPolicy ? ` WHERE ${compilePredicate(readPolicy.ast, narrowToV1ColumnTypes(columnTypes))}` : " WHERE false";
4784
4846
  if (backingPrivileges === "grant") {
4847
+ const selectPrivilege = backing.selectColumns ? `SELECT (${backing.selectColumns.map(quoteIdentifier).join(", ")})` : "SELECT";
4848
+ const hasSelectPrivilege = backing.selectColumns ? backing.selectColumns.map((column) => `pg_catalog.has_column_privilege(${quoteLiteral(executionOwnerRole)}, ${quoteLiteral(physicalTarget)}, ${quoteLiteral(column)}, 'SELECT')`).join("\n AND ") : `pg_catalog.has_table_privilege(${quoteLiteral(executionOwnerRole)}, ${quoteLiteral(physicalTarget)}, 'SELECT')`;
4785
4849
  statements.push(`GRANT USAGE ON SCHEMA ${quoteIdentifier(physical2.schema)} TO ${owner}`);
4786
- statements.push(`GRANT SELECT ON ${physicalTarget} TO ${owner}`);
4850
+ statements.push(`GRANT ${selectPrivilege} ON ${physicalTarget} TO ${owner}`);
4787
4851
  statements.push(`DO ${quoteLiteral(`BEGIN
4788
4852
  IF NOT (pg_catalog.has_schema_privilege(${quoteLiteral(executionOwnerRole)}, ${quoteLiteral(physical2.schema)}, 'USAGE')
4789
- AND pg_catalog.has_table_privilege(${quoteLiteral(executionOwnerRole)}, ${quoteLiteral(physicalTarget)}, 'SELECT')) THEN
4853
+ AND ${hasSelectPrivilege}) THEN
4790
4854
  RAISE EXCEPTION 'Synced backing owner lacks effective USAGE/SELECT; repair managed serving reader access before ORM apply' USING ERRCODE = '42501';
4791
4855
  END IF;
4792
4856
  END`)}`);
4793
4857
  }
4858
+ const whereClause = backing.readGuard ? ` WHERE (SELECT orm_native_sources.require_read_guard(${quoteLiteral(backing.readGuard)})) AND (${policyClause.slice(" WHERE ".length)})` : policyClause;
4794
4859
  statements.push(
4795
- `CREATE OR REPLACE VIEW ${viewName} AS SELECT * FROM ${physicalTarget}${whereClause}`
4860
+ `CREATE OR REPLACE VIEW ${viewName} AS SELECT ${projection} FROM ${physicalTarget}${whereClause}`
4796
4861
  );
4797
4862
  statements.push(`GRANT SELECT ON ${viewName} TO ${role}`);
4798
4863
  }
@@ -5063,10 +5128,142 @@ function snapshotTableNames(snapshot, schema) {
5063
5128
  return Object.values(tables).filter((entry) => entry.schema === schema).map((entry) => entry.name);
5064
5129
  }
5065
5130
 
5131
+ // src/sql/ast.ts
5132
+ function obj(value) {
5133
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("unsupported SQL node");
5134
+ return value;
5135
+ }
5136
+ function list(value) {
5137
+ return value === void 0 ? [] : Array.isArray(value) ? value : fail("expected SQL list");
5138
+ }
5139
+ function str(value) {
5140
+ return typeof value === "string" ? value : fail("expected SQL name");
5141
+ }
5142
+ function fail(message) {
5143
+ throw new Error(message);
5144
+ }
5145
+ function strings(value) {
5146
+ return list(value).map((v) => str(obj(obj(v).String).sval));
5147
+ }
5148
+
5149
+ // src/canonical/view-query.ts
5150
+ var parser;
5151
+ var functions = new Set(VIEW_QUERY_FUNCTION_ALLOWLIST);
5152
+ var scalarTypes = /* @__PURE__ */ new Set([
5153
+ "bool",
5154
+ "boolean",
5155
+ "int2",
5156
+ "int4",
5157
+ "int8",
5158
+ "integer",
5159
+ "bigint",
5160
+ "smallint",
5161
+ "numeric",
5162
+ "decimal",
5163
+ "float4",
5164
+ "float8",
5165
+ "real",
5166
+ "text",
5167
+ "varchar",
5168
+ "bpchar",
5169
+ "uuid",
5170
+ "date",
5171
+ "timestamp",
5172
+ "timestamptz",
5173
+ "time",
5174
+ "timetz",
5175
+ "interval",
5176
+ "json",
5177
+ "jsonb",
5178
+ "bytea"
5179
+ ]);
5180
+ var sqlValues = /* @__PURE__ */ new Set([
5181
+ "SVFOP_CURRENT_DATE",
5182
+ "SVFOP_CURRENT_TIME",
5183
+ "SVFOP_CURRENT_TIME_N",
5184
+ "SVFOP_CURRENT_TIMESTAMP",
5185
+ "SVFOP_CURRENT_TIMESTAMP_N",
5186
+ "SVFOP_LOCALTIME",
5187
+ "SVFOP_LOCALTIME_N",
5188
+ "SVFOP_LOCALTIMESTAMP",
5189
+ "SVFOP_LOCALTIMESTAMP_N",
5190
+ "SVFOP_CURRENT_ROLE",
5191
+ "SVFOP_CURRENT_USER",
5192
+ "SVFOP_USER",
5193
+ "SVFOP_SESSION_USER",
5194
+ "SVFOP_CURRENT_CATALOG",
5195
+ "SVFOP_CURRENT_SCHEMA"
5196
+ ]);
5197
+ async function validateManagedViewQueries({ canonical }) {
5198
+ for (const definition of [canonical, ...canonical.imports ?? []]) {
5199
+ for (const view of definition.views ?? []) {
5200
+ const fail2 = (message) => {
5201
+ throw new OrmDefinitionError(`managed view '${definition.namespace}/${view.view}': ${message}`);
5202
+ };
5203
+ parser ??= new PgParser({ version: 17 });
5204
+ const parsed = await parser.parse(view.query);
5205
+ if (parsed.error || !parsed.tree) fail2("invalid SELECT query");
5206
+ const statements = list(obj(parsed.tree).stmts);
5207
+ if (statements.length !== 1 || !obj(obj(statements[0]).stmt).SelectStmt) fail2("one SELECT query is required");
5208
+ validateTree({ tree: parsed.tree, schema: ormSchemaName(definition.namespace), enums: definition.enums.map((entry) => entry.name), fail: fail2 });
5209
+ }
5210
+ }
5211
+ }
5212
+ function pgCatalogName(parts) {
5213
+ if (parts.length === 1) return parts[0];
5214
+ if (parts.length === 2 && parts[0] === "pg_catalog") return parts[1];
5215
+ return void 0;
5216
+ }
5217
+ function reviewedFunctionName({ parts, format }) {
5218
+ return format === "COERCE_SQL_SYNTAX" && parts.length === 2 && parts[0] === "pg_catalog" && parts[1] === "position" ? "strpos" : pgCatalogName(parts);
5219
+ }
5220
+ function validateTree({ tree, ...scope }) {
5221
+ const pending = [tree];
5222
+ while (pending.length) {
5223
+ const value = pending.pop();
5224
+ if (Array.isArray(value)) {
5225
+ pending.push(...value);
5226
+ continue;
5227
+ }
5228
+ if (!value || typeof value !== "object") continue;
5229
+ const node = obj(value);
5230
+ for (const [kind, child] of Object.entries(node)) {
5231
+ validateNode({ kind, child, scope });
5232
+ pending.push(child);
5233
+ }
5234
+ }
5235
+ }
5236
+ function validateNode({ kind, child, scope }) {
5237
+ const { fail: fail2 } = scope;
5238
+ if (kind.endsWith("Stmt") && kind !== "SelectStmt") fail2("only SELECT statements are permitted");
5239
+ if (kind === "FuncCall") {
5240
+ const call = obj(child);
5241
+ const parts = strings(call.funcname);
5242
+ const name2 = reviewedFunctionName({ parts, format: call.funcformat });
5243
+ if (!name2 || !functions.has(name2)) fail2(`only explicitly allowlisted pg_catalog functions are permitted (found '${parts.join(".")}')`);
5244
+ }
5245
+ if (kind === "typeName" || kind === "TypeName") validateType({ node: obj(child), ...scope });
5246
+ if (kind === "A_Expr" && pgCatalogName(strings(obj(child).name)) === void 0) fail2("only pg_catalog operators are permitted");
5247
+ if (kind === "SortBy" && list(obj(child).useOp).length && pgCatalogName(strings(obj(child).useOp)) === void 0) fail2("only pg_catalog sort operators are permitted");
5248
+ if (kind === "SQLValueFunction" && !sqlValues.has(String(obj(child).op))) fail2("unsupported SQL value expression");
5249
+ if (kind === "ParamRef") fail2("view queries cannot contain parameters");
5250
+ if (kind === "A_Indirection" && list(obj(child).indirection).some((entry) => !obj(entry).A_Indices)) {
5251
+ fail2("composite field notation is not permitted in managed views");
5252
+ }
5253
+ }
5254
+ function validateType({ node, schema, enums, fail: fail2 }) {
5255
+ const parts = strings(node.names);
5256
+ const builtin = pgCatalogName(parts);
5257
+ const managedEnum = parts.length === 1 && enums.includes(parts[0]) || parts.length === 2 && parts[0] === schema && enums.includes(parts[1]);
5258
+ if (node.setof || node.pct_type || !managedEnum && (!builtin || !scalarTypes.has(builtin))) {
5259
+ fail2(`casts may only use supported pg_catalog scalar types or declared enums (found '${parts.join(".")}')`);
5260
+ }
5261
+ }
5262
+
5066
5263
  // src/engine/materialized-refresh.ts
5067
5264
  function materializedRefreshFunctions(canonical) {
5068
5265
  const schema = ormSchemaName(canonical.namespace);
5069
- const functions = /* @__PURE__ */ new Map();
5266
+ const functions2 = /* @__PURE__ */ new Map();
5070
5267
  for (const view of canonical.views ?? []) {
5071
5268
  const materialized = view.resolved?.materialized;
5072
5269
  if (!materialized) continue;
@@ -5075,7 +5272,7 @@ function materializedRefreshFunctions(canonical) {
5075
5272
  if (!table || pk.length === 0) {
5076
5273
  throw new OrmDefinitionError(`materialized resolved table '${view.view}' needs its table and primary key`);
5077
5274
  }
5078
- functions.set(view.view, refreshFunctionSql({
5275
+ functions2.set(view.view, refreshFunctionSql({
5079
5276
  schema,
5080
5277
  name: view.view,
5081
5278
  table: materialized.table,
@@ -5084,13 +5281,13 @@ function materializedRefreshFunctions(canonical) {
5084
5281
  pk
5085
5282
  }));
5086
5283
  }
5087
- return functions;
5284
+ return functions2;
5088
5285
  }
5089
5286
  function refreshFunctionSql({ schema, name: name2, table, compute, columns, pk }) {
5090
5287
  const fn = `${quoteIdentifier(schema)}.${quoteIdentifier(materializedRefreshFunctionName(name2))}`;
5091
5288
  const target = `${quoteIdentifier(schema)}.${quoteIdentifier(table)}`;
5092
5289
  const source = `${quoteIdentifier(schema)}.${quoteIdentifier(compute)}`;
5093
- const list = columns.map(quoteIdentifier).join(", ");
5290
+ const list2 = columns.map(quoteIdentifier).join(", ");
5094
5291
  const others = columns.filter((column) => !pk.includes(column));
5095
5292
  const keys = pk.map(quoteIdentifier).join(", ");
5096
5293
  const matches = pk.map((column) => `c.${quoteIdentifier(column)} = m.${quoteIdentifier(column)}`).join(" AND ");
@@ -5116,8 +5313,8 @@ BEGIN
5116
5313
  PERFORM set_config('request.jwt.claims', ${quoteLiteral(MATERIALIZE_CLAIMS_JSON)}, true);
5117
5314
  RETURN QUERY
5118
5315
  WITH up AS (
5119
- INSERT INTO ${target} AS m (${list})
5120
- SELECT ${list} FROM ${source}
5316
+ INSERT INTO ${target} AS m (${list2})
5317
+ SELECT ${list2} FROM ${source}
5121
5318
  ON CONFLICT (${keys}) ${onConflict}
5122
5319
  RETURNING 1
5123
5320
  ), gone AS (
@@ -5728,6 +5925,7 @@ async function planWithViewRecreation({
5728
5925
  previousSnapshot,
5729
5926
  viewRecreation
5730
5927
  }) {
5928
+ await validateManagedViewQueries({ canonical });
5731
5929
  const schema = ormSchemaName(canonical.namespace);
5732
5930
  const previous = previousSnapshot ? normalizeSnapshot(previousSnapshot) : emptySnapshot(canonical.namespace);
5733
5931
  assertValidViewDependencies(canonical);
@@ -6426,7 +6624,7 @@ var limitIrSchema = z.object({
6426
6624
  variable: z.string().optional(),
6427
6625
  value: z.number().int().positive().optional(),
6428
6626
  default: z.number().int().positive(),
6429
- max: z.number().int().positive()
6627
+ max: z.number().int().positive().max(MAX_PERSISTED_READ_ROWS)
6430
6628
  });
6431
6629
  var selectionIrSchema = z.lazy(
6432
6630
  () => z.object({
@@ -8042,6 +8240,6 @@ function resumeArguments({
8042
8240
  return [literal2.sql];
8043
8241
  }
8044
8242
 
8045
- export { ACTION_REQUIRES_DENIED_SQLSTATE, ACTION_VALIDATES_FAILED_SQLSTATE, AUDIT_ACTIONS, CANONICAL_FORMAT, CAPABILITIES_CLAIM_KEY, CAPABILITY_KEY_PATTERN, CELLS_FIELD, CELL_PARTS, CELL_PART_SUFFIX, CLAIMS_CONTRACT, CLAIMS_SETTING, CLAIM_KEY_PATTERN, CMP_OPS, COLUMN_BRAND, COLUMN_DEFAULT_FNS, COLUMN_IDENTIFIER_PATTERN, COLUMN_TYPES2 as COLUMN_TYPES, COMPARE_OPS, COMPOSED_IR_VERSION, CONSUMER_ROLE_SUFFIX, ColumnBuilder, DATE_BUCKETS, DEFINITION_FILE_EXTENSIONS, ENUM_BRAND, EXTERNAL_POLICY_CLAIM_KEYS, GUARDED_IR_VERSION, HASH_DOMAIN, IDENTIFIER_PATTERN, IDENTIFIER_RE, IMPORT_CONFLICT_MODES, INPUT_REF_KINDS, IR_VERSION, IrVersionError, LEGACY_IR_VERSION, LINK_BRAND, MATERIALIZE_ACTOR, MATERIALIZE_CLAIMS_JSON, MAX_DEFINITION_FILE_BYTES, MAX_GENERATED_SDL_BYTES, MAX_IDENTIFIER_LENGTH, MAX_TRACKED_COLUMN_NAME, 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, RUNTIME_SQL_IR_VERSION, SCHEMA_DIR, SQL_IR_VERSION, 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, cellColumnName, checksumOf, claimExpression, classifyDestructive, columnSchema, columnTypeSchema2 as columnTypeSchema, compileActionRequires, compileActionStatements, compileNamespace, compilePredIrToSql, compilePredicate, compiledArtifactSchema, compiledOperationSchema, computeCanonicalHash, computeDefinitionHash, computeSyncedContractHash, consumerRoleName, convertV1DefinitionToCanonical, createOrmMigrationExport, custom, declaredCapabilityKeys, defineEnum, defineNamespace, defineOperation, defineResolvedTable, defineSyncedTable, defineTable, defineView, deriveColumnName, diffCommand, diffStatements, emptyJournal, emptySnapshot, endAuthoringContext, etlSource, extractNamedParams, extractOrmSyncedTableContract, generateNamespaceTypes, generateSnapshot, generateSnapshotV2, highest, identifierSchema, importSpecSchema, indexByHash, isColumnBuilder, isEnumRef, isExternalPolicyClaimKey, isFunctionDefault, isOwnedStatement, isOwnedStatementV2, isQualifiedReference, isSeqLink, isSeqNamespaceConfig, isSeqTable, isSeqView, latest, limitIrSchema, loadCommittedMigrations, loadCommittedTipMigration, loadNamespaceDefinition, loadNamespaceFromDir, lowest, managedFn, manualSource, materializeLockKey, materializedRefreshFunctionName, migrationName, namespaceConfigSchema, namespaceSchema, nonNullFirst, normalizeCanonical, normalizeIr, normalizeSnapshot, objectRef, ontologyContractSchema, orderIrSchema, ormMigrationExportSchema, ormSchemaName, overlayWinsUnion, overrideRowMutation, parseCanonicalDefinition, parseDefinitionSources, parseOrmMigrationExport, parsePredicate, parseTableFile, parsedPredicateSchema, pendingKitStatements, pendingKitStatementsV2, planCommittedMigrationV2, planMigration, planMigrationV2, planTableImport, policyExpressionSchema, policyVariantSchema, predIrSchema, predicateOperands, prefetchPlanIrSchema, prefetchSource, priority, quoteIdentifier, quoteLiteral, readMigrationSql, readMigrationWorkspace, readOntologyContract, readSnapshot, rebaseViolations, referencedCapabilities, referencedColumns, renderMigrationSql, renderOrmMigrationExport, requiredArtifactIrVersion, resolvedMetaIrSchema, resolvedSourceIrSchema, revertOverlayMutation, rewriteSyncedSourceRelationsInViewQuery, roleExpression, rootIrSchema, securityStatements, selectionIrSchema, serializeNamespace, sqlTypeName, stableJson, syncedBackingRevokeStatements, syncedContractSurface, syncedTables, syncedViewDropStatements, syncedViewStatements, t, tableFileSchema, tableMetaIrSchema, tableReferenceSchema, toMany, toOne, toPlatformUser, typesInterfaceName, validateNamespaceCatalog, validateViewCatalogStatement, valueIrSchema, variableDefaultIrSchema, variableIrSchema, verifyRebaseIsNoop, walkPredicate, writeMigration };
8243
+ export { ACTION_REQUIRES_DENIED_SQLSTATE, ACTION_VALIDATES_FAILED_SQLSTATE, AUDIT_ACTIONS, CANONICAL_FORMAT, CAPABILITIES_CLAIM_KEY, CAPABILITY_KEY_PATTERN, CELLS_FIELD, CELL_PARTS, CELL_PART_SUFFIX, CLAIMS_CONTRACT, CLAIMS_SETTING, CLAIM_KEY_PATTERN, CMP_OPS, COLUMN_BRAND, COLUMN_DEFAULT_FNS, COLUMN_IDENTIFIER_PATTERN, COLUMN_TYPES2 as COLUMN_TYPES, COMPARE_OPS, COMPOSED_IR_VERSION, CONSUMER_ROLE_SUFFIX, ColumnBuilder, DATE_BUCKETS, DEFINITION_FILE_EXTENSIONS, ENUM_BRAND, EXTERNAL_POLICY_CLAIM_KEYS, GUARDED_IR_VERSION, HASH_DOMAIN, IDENTIFIER_PATTERN, IDENTIFIER_RE, IMPORT_CONFLICT_MODES, INPUT_REF_KINDS, IR_VERSION, IrVersionError, LEGACY_IR_VERSION, LINK_BRAND, MATERIALIZE_ACTOR, MATERIALIZE_CLAIMS_JSON, MAX_DEFINITION_FILE_BYTES, MAX_GENERATED_SDL_BYTES, MAX_IDENTIFIER_LENGTH, MAX_PERSISTED_READ_ROWS, MAX_TRACKED_COLUMN_NAME, 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, RUNTIME_SQL_IR_VERSION, SCHEMA_DIR, SQL_IR_VERSION, 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, cellColumnName, checksumOf, claimExpression, classifyDestructive, columnSchema, columnTypeSchema2 as columnTypeSchema, compileActionRequires, compileActionStatements, compileNamespace, compilePredIrToSql, compilePredicate, compiledArtifactSchema, compiledOperationSchema, computeCanonicalHash, computeDefinitionHash, computeSyncedContractHash, consumerRoleName, convertV1DefinitionToCanonical, createOrmMigrationExport, custom, declaredCapabilityKeys, defineEnum, defineNamespace, defineOperation, defineResolvedTable, defineSyncedTable, defineTable, defineView, deriveColumnName, diffCommand, diffStatements, emptyJournal, emptySnapshot, endAuthoringContext, etlSource, extractNamedParams, extractOrmSyncedTableContract, generateNamespaceTypes, generateSnapshot, generateSnapshotV2, highest, identifierSchema, importSpecSchema, indexByHash, isColumnBuilder, isEnumRef, isExternalPolicyClaimKey, isFunctionDefault, isOwnedStatement, isOwnedStatementV2, isQualifiedReference, isSeqLink, isSeqNamespaceConfig, isSeqTable, isSeqView, latest, limitIrSchema, loadCommittedMigrations, loadCommittedTipMigration, loadNamespaceDefinition, loadNamespaceFromDir, lowest, managedFn, manualSource, materializeLockKey, materializedRefreshFunctionName, migrationName, namespaceConfigSchema, namespaceSchema, nonNullFirst, normalizeCanonical, normalizeIr, normalizeSnapshot, objectRef, ontologyContractSchema, orderIrSchema, ormMigrationExportSchema, ormSchemaName, overlayWinsUnion, overrideRowMutation, parseCanonicalDefinition, parseDefinitionSources, parseOrmMigrationExport, parsePredicate, parseTableFile, parsedPredicateSchema, pendingKitStatements, pendingKitStatementsV2, planCommittedMigrationV2, planMigration, planMigrationV2, planTableImport, policyExpressionSchema, policyVariantSchema, predIrSchema, predicateOperands, prefetchPlanIrSchema, prefetchSource, priority, quoteIdentifier, quoteLiteral, readMigrationSql, readMigrationWorkspace, readOntologyContract, readSnapshot, rebaseViolations, referencedCapabilities, referencedColumns, renderMigrationSql, renderOrmMigrationExport, requiredArtifactIrVersion, resolvedMetaIrSchema, resolvedSourceIrSchema, revertOverlayMutation, rewriteSyncedSourceRelationsInViewQuery, roleExpression, rootIrSchema, securityStatements, selectionIrSchema, serializeNamespace, sqlTypeName, stableJson, syncedBackingRevokeStatements, syncedContractSurface, syncedTables, syncedViewDropStatements, syncedViewStatements, t, tableFileSchema, tableMetaIrSchema, tableReferenceSchema, toMany, toOne, toPlatformUser, typesInterfaceName, validateNamespaceCatalog, validateViewCatalogStatement, valueIrSchema, variableDefaultIrSchema, variableIrSchema, verifyRebaseIsNoop, walkPredicate, writeMigration };
8046
8244
  //# sourceMappingURL=index.js.map
8047
8245
  //# sourceMappingURL=index.js.map