@vibeorm/runtime 2.4.1 → 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 (42) hide show
  1. package/README.md +7 -0
  2. package/dist/adapter-kit/index.d.ts +2 -1
  3. package/dist/adapter-kit/index.d.ts.map +1 -1
  4. package/dist/adapter-kit/index.js +53 -3
  5. package/dist/adapter-kit/index.js.map +5 -4
  6. package/dist/adapter-kit/row-changes.d.ts +29 -0
  7. package/dist/adapter-kit/row-changes.d.ts.map +1 -0
  8. package/dist/adapter-kit/savepoint-gate.d.ts +8 -0
  9. package/dist/adapter-kit/savepoint-gate.d.ts.map +1 -1
  10. package/dist/adapter.d.ts +14 -0
  11. package/dist/adapter.d.ts.map +1 -1
  12. package/dist/advisory-key.d.ts +10 -0
  13. package/dist/advisory-key.d.ts.map +1 -0
  14. package/dist/advisory-lock.d.ts +3 -3
  15. package/dist/client.d.ts +3 -0
  16. package/dist/client.d.ts.map +1 -1
  17. package/dist/codecs.d.ts.map +1 -1
  18. package/dist/database-module.d.ts.map +1 -1
  19. package/dist/find-page.d.ts +35 -0
  20. package/dist/find-page.d.ts.map +1 -0
  21. package/dist/index.d.ts +6 -3
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +541 -274
  24. package/dist/index.js.map +26 -22
  25. package/dist/keyset-iterator.d.ts.map +1 -1
  26. package/dist/keyset-projection.d.ts +12 -0
  27. package/dist/keyset-projection.d.ts.map +1 -0
  28. package/dist/model-meta.d.ts +5 -1
  29. package/dist/model-meta.d.ts.map +1 -1
  30. package/dist/policy.d.ts.map +1 -1
  31. package/dist/query-builder.d.ts +8 -1
  32. package/dist/query-builder.d.ts.map +1 -1
  33. package/dist/read-only.d.ts +17 -1
  34. package/dist/read-only.d.ts.map +1 -1
  35. package/dist/relation-plan.d.ts +1 -0
  36. package/dist/relation-plan.d.ts.map +1 -1
  37. package/dist/render-cache.d.ts.map +1 -1
  38. package/dist/rls-readiness.d.ts.map +1 -1
  39. package/dist/scoped.d.ts.map +1 -1
  40. package/dist/transaction-row-changes.d.ts +28 -0
  41. package/dist/transaction-row-changes.d.ts.map +1 -0
  42. package/package.json +6 -3
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ function createSqlModel(params) {
30
30
  if (model === undefined)
31
31
  throw new VibeError({ code: "VIBE_VALIDATION", message: "Unknown SQL model" });
32
32
  const tableName = model.dbName ?? model.name;
33
- const table = sql.ident({ parts: [tableName] });
33
+ const table = sql.ident({ parts: model.namespace === undefined ? [tableName] : [model.namespace, tableName] });
34
34
  const fields = Object.fromEntries(model.fields.filter((field) => field.isUnsupported !== true).map((field) => {
35
35
  let decoder;
36
36
  if (isEnumType(field.type)) {
@@ -199,8 +199,62 @@ function statementFor(params) {
199
199
  key: params.key
200
200
  };
201
201
  }
202
+ // packages/runtime/src/advisory-key.ts
203
+ import { createHash } from "crypto";
204
+ import { VibeError as VibeError5 } from "@vibeorm/schema";
205
+ function advisoryKeyOf(params) {
206
+ const { text } = params;
207
+ const refuse = () => new VibeError5({
208
+ code: "VIBE_VALIDATION",
209
+ message: "advisoryKeyOf text must be a well-formed UTF-16 string",
210
+ meta: { reason: "advisory-key-text" }
211
+ });
212
+ if (typeof text !== "string")
213
+ throw refuse();
214
+ for (let index = 0;index < text.length; index++) {
215
+ const unit = text.charCodeAt(index);
216
+ if (unit >= 55296 && unit <= 56319) {
217
+ const next = text.charCodeAt(index + 1);
218
+ if (!(next >= 56320 && next <= 57343))
219
+ throw refuse();
220
+ index++;
221
+ } else if (unit >= 56320 && unit <= 57343) {
222
+ throw refuse();
223
+ }
224
+ }
225
+ return createHash("sha256").update(text, "utf8").digest().readBigInt64BE(0);
226
+ }
227
+ // packages/runtime/src/transaction-row-changes.ts
228
+ import { VibeError as VibeError6 } from "@vibeorm/schema";
229
+ var observations = new WeakMap;
230
+ function registerTransactionObservation(params) {
231
+ observations.set(params.db, params.observation);
232
+ }
233
+ function inheritTransactionObservation(params) {
234
+ const observation = observations.get(params.from);
235
+ if (observation !== undefined)
236
+ observations.set(params.to, observation);
237
+ }
238
+ function transactionRowChanges(params) {
239
+ const observation = observations.get(params.db);
240
+ if (observation === undefined)
241
+ throw new VibeError6({
242
+ code: "VIBE_CONFIG",
243
+ message: "transactionRowChanges requires a registered handle from this VibeORM runtime installation",
244
+ meta: { reason: "transaction-observation-handle" }
245
+ });
246
+ if (!observation.inTransaction)
247
+ throw new VibeError6({
248
+ code: "VIBE_TRANSACTION",
249
+ message: "transactionRowChanges requires an active transaction handle",
250
+ meta: { reason: "transaction-observation-context" }
251
+ });
252
+ observation.assertActive();
253
+ const count = observation.read();
254
+ return typeof count === "number" && Number.isSafeInteger(count) && count >= 0 ? count : "unknown";
255
+ }
202
256
  // packages/runtime/src/model-meta.ts
203
- import { VibeError as VibeError5, enumStorageOf, isEnumType as isEnumType2, validateComputedConfig } from "@vibeorm/schema";
257
+ import { VibeError as VibeError7, enumStorageOf, isEnumType as isEnumType2, validateComputedConfig } from "@vibeorm/schema";
204
258
  import { enumMembershipCodec } from "@vibeorm/sql";
205
259
  function toClientName(params) {
206
260
  const { name } = params;
@@ -308,6 +362,7 @@ function buildFieldMeta(params) {
308
362
  type: field.type,
309
363
  scalarType: enumName === null ? field.type : null,
310
364
  enumName,
365
+ ...enumStorage !== "database" || enumDef === undefined || enumDef.namespace === undefined && (!isEnumType2(field.type) || field.type.namespace === undefined) ? {} : { enumSqlName: { namespace: enumDef.namespace ?? (isEnumType2(field.type) ? field.type.namespace : undefined) ?? "public", name: enumDef.dbName ?? enumDef.name } },
311
366
  enumStorage,
312
367
  enumCodec: enumStorage === "string" && enumDef !== undefined ? enumMembershipCodec({ model, field: field.name, enum: enumDef.name, members: enumDef.values }) : null,
313
368
  isList: field.isList,
@@ -329,7 +384,7 @@ function buildModelMeta(params) {
329
384
  for (const name of model.primaryKey.fields) {
330
385
  const field = fieldByName.get(name);
331
386
  if (field === undefined) {
332
- throw new VibeError5({
387
+ throw new VibeError7({
333
388
  code: "VIBE_SCHEMA_INVALID",
334
389
  message: `model "${model.name}" declares composite primary-key field "${name}", which does not exist`,
335
390
  meta: { model: model.name, field: name }
@@ -396,6 +451,7 @@ function buildModelMeta(params) {
396
451
  name: model.name,
397
452
  clientName: toClientName({ name: model.name }),
398
453
  tableName: model.dbName ?? model.name,
454
+ ...model.namespace === undefined ? {} : { namespace: model.namespace },
399
455
  fields,
400
456
  fieldByName,
401
457
  fieldByColumn,
@@ -435,7 +491,7 @@ function getModelMeta(params) {
435
491
  const { meta, model } = params;
436
492
  const found = meta.modelByName.get(model);
437
493
  if (found === undefined) {
438
- throw new VibeError5({
494
+ throw new VibeError7({
439
495
  code: "VIBE_VALIDATION",
440
496
  message: `unknown model "${model}"`,
441
497
  meta: { model, known: [...new Set(meta.models.map((entry) => entry.name))] }
@@ -448,20 +504,20 @@ function getFieldMeta(params) {
448
504
  const found = model.fieldByName.get(field);
449
505
  if (found === undefined) {
450
506
  if (model.computed !== null && model.computed.has(field)) {
451
- throw new VibeError5({
507
+ throw new VibeError7({
452
508
  code: "VIBE_VALIDATION",
453
509
  message: `"${field}" on model "${model.name}" is a computed field \u2014 computed fields appear in results (select/omit) only, not in ${context}`,
454
510
  meta: { model: model.name, field, context, computed: true }
455
511
  });
456
512
  }
457
513
  if (model.relationByName.has(field)) {
458
- throw new VibeError5({
514
+ throw new VibeError7({
459
515
  code: "VIBE_VALIDATION",
460
516
  message: `"${field}" on model "${model.name}" is a relation \u2014 not valid in ${context} here (relation writes use nested-write verbs, relation reads use select/include)`,
461
517
  meta: { model: model.name, field, context }
462
518
  });
463
519
  }
464
- throw new VibeError5({
520
+ throw new VibeError7({
465
521
  code: "VIBE_VALIDATION",
466
522
  message: `unknown field "${field}" on model "${model.name}" in ${context}`,
467
523
  meta: { model: model.name, field, context }
@@ -471,8 +527,8 @@ function getFieldMeta(params) {
471
527
  }
472
528
  // packages/runtime/src/codecs.ts
473
529
  import { JSON_TRANSPORT, projectionOutputName, parsePgArrayLiteral, toPgArrayLiteral } from "@vibeorm/sql";
474
- import { VibeError as VibeError6, isEnumType as isEnumType3 } from "@vibeorm/schema";
475
- import { DIALECT_CODECS, decodeIsNoop } from "@vibeorm/sql";
530
+ import { VibeError as VibeError8, isEnumType as isEnumType3 } from "@vibeorm/schema";
531
+ import { DIALECT_CODECS, decodeIsNoop, nativeEnumArrayParameter } from "@vibeorm/sql";
476
532
  import {
477
533
  DIALECT_CODECS as DIALECT_CODECS2,
478
534
  MYSQL_CODECS,
@@ -500,7 +556,10 @@ function encodeValue(params) {
500
556
  const codec = fieldCodec({ dialect, field });
501
557
  if (field.isList && Array.isArray(value)) {
502
558
  const elements = value.map((element) => element === null || element === undefined ? element : codec.encode(element));
503
- return isPostgresEnumList({ dialect, field }) ? toPgArrayLiteral({ values: elements }) : elements;
559
+ if (!isPostgresEnumList({ dialect, field }))
560
+ return elements;
561
+ const literal = toPgArrayLiteral({ values: elements });
562
+ return field.enumSqlName === undefined ? literal : nativeEnumArrayParameter({ value: literal, type: field.enumSqlName });
504
563
  }
505
564
  return codec.encode(value);
506
565
  }
@@ -533,7 +592,7 @@ function validateAtomicOperand(params) {
533
592
  } else if (typeof value === "number" && Number.isFinite(value)) {
534
593
  return value;
535
594
  }
536
- throw new VibeError6({
595
+ throw new VibeError8({
537
596
  code: "VIBE_VALIDATION",
538
597
  message: `Invalid arithmetic operand for ${field.scalarType} field "${field.name}"`,
539
598
  meta: { field: field.name, value }
@@ -542,7 +601,7 @@ function validateAtomicOperand(params) {
542
601
  function toRealNumber(params) {
543
602
  const { field, value } = params;
544
603
  const refuse = () => {
545
- throw new VibeError6({
604
+ throw new VibeError8({
546
605
  code: "VIBE_VALIDATION",
547
606
  message: `"${String(value)}" is not a numeric value for the Decimal field "${field.name}"`,
548
607
  meta: { field: field.name, value }
@@ -782,7 +841,7 @@ function positionalMaterializer(params) {
782
841
  const output = projectionOutputName({ column });
783
842
  const entry = plan.byColumn.get(output);
784
843
  if (entry === undefined)
785
- throw new VibeError6({ code: "VIBE_INTERNAL", message: "positional projection has no schema field", meta: { model: model.name, column: output } });
844
+ throw new VibeError8({ code: "VIBE_INTERNAL", message: "positional projection has no schema field", meta: { model: model.name, column: output } });
786
845
  return entry;
787
846
  });
788
847
  const width = slots.length;
@@ -790,7 +849,7 @@ function positionalMaterializer(params) {
790
849
  const chunked = width > chunkSize;
791
850
  const count = Math.ceil(width / chunkSize);
792
851
  const invalid = () => {
793
- throw new VibeError6({ code: "VIBE_INTERNAL", message: "positional relation payload does not match its SQL projection", meta: { model: model.name, expectedColumns: width } });
852
+ throw new VibeError8({ code: "VIBE_INTERNAL", message: "positional relation payload does not match its SQL projection", meta: { model: model.name, expectedColumns: width } });
794
853
  };
795
854
  if (width === 0 || new Set(slots.map((slot) => slot.name)).size !== width)
796
855
  return invalid();
@@ -832,7 +891,7 @@ function decodeAggregateValue(params) {
832
891
  return field === null ? value : decodeValue({ dialect, field, value });
833
892
  }
834
893
  // packages/runtime/src/lateral-projection.ts
835
- import { VibeError as VibeError7, unsupportedCapability as unsupportedCapability2 } from "@vibeorm/schema";
894
+ import { VibeError as VibeError9, unsupportedCapability as unsupportedCapability2 } from "@vibeorm/schema";
836
895
  function isPlainObject(value) {
837
896
  return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
838
897
  }
@@ -849,7 +908,7 @@ function lateralProjection(params) {
849
908
  const columns = names.map((name) => {
850
909
  const field = model.fieldByName.get(name);
851
910
  if (field === undefined)
852
- throw new VibeError7({ code: "VIBE_INTERNAL", message: "lateral projection references an unknown field", meta: { model: model.name, field: name } });
911
+ throw new VibeError9({ code: "VIBE_INTERNAL", message: "lateral projection references an unknown field", meta: { model: model.name, field: name } });
853
912
  return Object.freeze(applyLateralTransform({ model, column: { table: LATERAL_CHILD_ALIAS, name: field.columnName } }));
854
913
  });
855
914
  const descriptor = Object.freeze({ columns: Object.freeze(columns), hiddenOrder: Object.freeze(hiddenOrder) });
@@ -898,7 +957,7 @@ function applyLateralTransform(params) {
898
957
 
899
958
  // packages/runtime/src/query-builder.ts
900
959
  import { isSqlFragment, mapConflictColumns } from "@vibeorm/sql";
901
- import { VibeError as VibeError11, unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
960
+ import { VibeError as VibeError13, unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
902
961
  import {
903
962
  SQL_DEFAULT_CELL,
904
963
  containsPattern,
@@ -912,9 +971,9 @@ import {
912
971
  import { describeRowLock } from "@vibeorm/sql";
913
972
 
914
973
  // packages/runtime/src/bulk-upsert.ts
915
- import { VibeError as VibeError8, unsupportedCapability as unsupportedCapability3 } from "@vibeorm/schema";
974
+ import { VibeError as VibeError10, unsupportedCapability as unsupportedCapability3 } from "@vibeorm/schema";
916
975
  function validationError2(params) {
917
- return new VibeError8({
976
+ return new VibeError10({
918
977
  code: "VIBE_VALIDATION",
919
978
  message: params.message,
920
979
  ...params.meta === undefined ? {} : { meta: params.meta }
@@ -1238,7 +1297,7 @@ function assertConflictKeysAreComparable(params) {
1238
1297
  }
1239
1298
 
1240
1299
  // packages/runtime/src/keyset.ts
1241
- import { VibeError as VibeError9 } from "@vibeorm/schema";
1300
+ import { VibeError as VibeError11 } from "@vibeorm/schema";
1242
1301
  var KEYSET_TOKEN_VERSION = 1;
1243
1302
  var KEYSET_TOKEN_PREFIX = "vk1.";
1244
1303
  var KEYSET_MAX_PAGE_SIZE = 1e4;
@@ -1248,10 +1307,10 @@ var DATETIME_NEEDS_PRECISION_ASSERTION = Object.freeze({
1248
1307
  sqlite: false
1249
1308
  });
1250
1309
  function keysetValidation(params) {
1251
- return new VibeError9({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
1310
+ return new VibeError11({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
1252
1311
  }
1253
1312
  function keysetUnsupported(params) {
1254
- return new VibeError9({
1313
+ return new VibeError11({
1255
1314
  code: "VIBE_UNSUPPORTED_CAPABILITY",
1256
1315
  message: params.message,
1257
1316
  meta: params.meta
@@ -1371,7 +1430,7 @@ function compileKeysetOrderPlan(params) {
1371
1430
  meta: { model: model.name, orderFields: [...seen], feature: "keysetTieBreaker" }
1372
1431
  });
1373
1432
  }
1374
- return { model: model.name, keys, signature: signatureOf2({ model: model.name, keys }) };
1433
+ return { model: model.name, keys, signature: signatureOf2({ model: model.name, keys, ...model.namespace === undefined ? {} : { namespace: model.namespace, table: model.tableName } }) };
1375
1434
  }
1376
1435
  function signatureOf2(params) {
1377
1436
  const { model, keys } = params;
@@ -1379,7 +1438,7 @@ function signatureOf2(params) {
1379
1438
  const base = `${key.field.name}:${key.direction}`;
1380
1439
  return key.field.isOptional ? `${base}:nulls=${key.nulls}` : base;
1381
1440
  });
1382
- return [model, ...parts].join("|");
1441
+ return [model, ...params.namespace === undefined ? [] : [`physical=${JSON.stringify([params.namespace, params.table])}`], ...parts].join("|");
1383
1442
  }
1384
1443
  function encodeValueFor(params) {
1385
1444
  const { key, value, model } = params;
@@ -1634,9 +1693,9 @@ function decodeKeysetToken(params) {
1634
1693
  }
1635
1694
 
1636
1695
  // packages/runtime/src/relation-plan.ts
1637
- import { VibeError as VibeError10, implicitJoinTable } from "@vibeorm/schema";
1696
+ import { VibeError as VibeError12, implicitJoinTable, qualifiedSqlName, unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
1638
1697
  function validationError3(params) {
1639
- return new VibeError10({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
1698
+ return new VibeError12({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
1640
1699
  }
1641
1700
  function isPlainObject2(value) {
1642
1701
  return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date);
@@ -1661,7 +1720,7 @@ function keyFields(params) {
1661
1720
  return names.map((name) => {
1662
1721
  const field = model.fieldByName.get(name);
1663
1722
  if (field === undefined) {
1664
- throw new VibeError10({
1723
+ throw new VibeError12({
1665
1724
  code: "VIBE_SCHEMA_INVALID",
1666
1725
  message: `relation "${relation.name}" on ${relation.model} names unknown ${what} field "${name}"`,
1667
1726
  meta: { model: relation.model, relation: relation.name }
@@ -1673,7 +1732,7 @@ function keyFields(params) {
1673
1732
  function singleKeyPair(params) {
1674
1733
  const { link, what } = params;
1675
1734
  if (link.parentKeys.length !== 1 || link.childKeys.length !== 1) {
1676
- throw new VibeError10({
1735
+ throw new VibeError12({
1677
1736
  code: "VIBE_UNSUPPORTED_CAPABILITY",
1678
1737
  message: `${what} on relation "${link.relation.name}" of ${link.relation.model} needs a single-column relation key \u2014 this relation links ${link.parentKeys.length} columns; use an explicit junction model`,
1679
1738
  meta: { model: link.relation.model, relation: link.relation.name, arity: link.parentKeys.length }
@@ -1717,12 +1776,15 @@ function resolveRelationLinkUncached(params) {
1717
1776
  const target = getModelMeta({ meta, model: relation.targetModel });
1718
1777
  if (relation.type === "manyToMany") {
1719
1778
  if (relation.model === relation.targetModel) {
1720
- throw new VibeError10({
1779
+ throw new VibeError12({
1721
1780
  code: "VIBE_SCHEMA_INVALID",
1722
1781
  message: `relation "${relation.name}" on ${relation.model} is an implicit self many-to-many: both sides own the ` + `same join-table column, so this field and its inverse would read the same rows. Model each direction ` + `with an explicit junction model.`,
1723
1782
  meta: { model: relation.model, relation: relation.name, targetModel: relation.targetModel }
1724
1783
  });
1725
1784
  }
1785
+ const namespace = qualifiedSqlName({ name: model.tableName, namespace: model.namespace }).namespace;
1786
+ if (namespace !== qualifiedSqlName({ name: target.tableName, namespace: target.namespace }).namespace)
1787
+ throw unsupportedCapability4({ dialect: "postgres", feature: "implicitJoinNamespaces", hint: "Implicit join parents must share one physical namespace" });
1726
1788
  const join = implicitJoinTable({
1727
1789
  modelA: relation.model,
1728
1790
  modelB: relation.targetModel,
@@ -1737,6 +1799,7 @@ function resolveRelationLinkUncached(params) {
1737
1799
  childKeys: [singlePrimaryKey({ model: target, relation })],
1738
1800
  join: {
1739
1801
  tableName: join.tableName,
1802
+ ...model.namespace === undefined && target.namespace === undefined ? {} : { namespace },
1740
1803
  parentColumn: parentIsA ? "A" : "B",
1741
1804
  childColumn: parentIsA ? "B" : "A"
1742
1805
  }
@@ -1759,7 +1822,7 @@ function resolveRelationLinkUncached(params) {
1759
1822
  }
1760
1823
  const reverse = findReverseRelation({ relation, target });
1761
1824
  if (reverse === null || reverse.fields === undefined || reverse.fields.length === 0) {
1762
- throw new VibeError10({
1825
+ throw new VibeError12({
1763
1826
  code: "VIBE_SCHEMA_INVALID",
1764
1827
  message: `relation "${relation.name}" on ${relation.model} has no foreign-key counterpart on ${relation.targetModel}`,
1765
1828
  meta: { model: relation.model, relation: relation.name, target: relation.targetModel }
@@ -1784,7 +1847,7 @@ function pairedKeys(params) {
1784
1847
  const parentKeys = keyFields({ model, names: parentNames, relation, what: "fields" });
1785
1848
  const childKeys = keyFields({ model: target, names: childNames, relation, what: "references" });
1786
1849
  if (parentKeys.length !== childKeys.length) {
1787
- throw new VibeError10({
1850
+ throw new VibeError12({
1788
1851
  code: "VIBE_SCHEMA_INVALID",
1789
1852
  message: `relation "${relation.name}" on ${relation.model} links ${parentKeys.length} field(s) to ${childKeys.length} reference(s) \u2014 a foreign key must pair every column`,
1790
1853
  meta: { model: relation.model, relation: relation.name }
@@ -2134,7 +2197,7 @@ var AGG_FN_BY_KEY = {
2134
2197
  _max: "max"
2135
2198
  };
2136
2199
  function validationError4(params) {
2137
- return new VibeError11({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
2200
+ return new VibeError13({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
2138
2201
  }
2139
2202
  function isPlainObject3(value) {
2140
2203
  return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date) && !(value instanceof Uint8Array);
@@ -2238,21 +2301,21 @@ function assertLockIsExpressible(params) {
2238
2301
  if (rowLockStrengths.length === 0) {
2239
2302
  if (lock.strength === "update" && lock.wait === "wait")
2240
2303
  return;
2241
- throw unsupportedCapability4({
2304
+ throw unsupportedCapability5({
2242
2305
  dialect: dialect.name,
2243
2306
  feature: site,
2244
2307
  hint: `${dialect.name} has no locking-read clause at all. Only lock: "update" is accepted there, ` + `as the documented no-op its single-writer transactions already provide`
2245
2308
  });
2246
2309
  }
2247
2310
  if (!rowLockStrengths.includes(lock.strength)) {
2248
- throw unsupportedCapability4({
2311
+ throw unsupportedCapability5({
2249
2312
  dialect: dialect.name,
2250
2313
  feature: site,
2251
2314
  hint: `${dialect.name} has these lock strengths: ${rowLockStrengths.join(", ")}`
2252
2315
  });
2253
2316
  }
2254
2317
  if (!rowLockWaitPolicies.includes(lock.wait)) {
2255
- throw unsupportedCapability4({
2318
+ throw unsupportedCapability5({
2256
2319
  dialect: dialect.name,
2257
2320
  feature: site,
2258
2321
  hint: `${dialect.name} has these lock wait policies: ${rowLockWaitPolicies.join(", ")}`
@@ -2262,7 +2325,7 @@ function assertLockIsExpressible(params) {
2262
2325
  function compileConflictTarget(params) {
2263
2326
  const { dialect, meta, model, method, target, where } = params;
2264
2327
  if ((target !== undefined || where !== undefined) && dialect.doNothingForm === "insertIgnore") {
2265
- throw unsupportedCapability4({
2328
+ throw unsupportedCapability5({
2266
2329
  dialect: dialect.name,
2267
2330
  feature: `a conflict target on ${model.clientName}.${method}()`,
2268
2331
  hint: "mysql's INSERT IGNORE / ON DUPLICATE KEY fire on ANY duplicate key \u2014 no target can be named; gate the call per dialect"
@@ -2280,7 +2343,7 @@ function compileConflictTarget(params) {
2280
2343
  out.columns = target.map((name) => getFieldMeta({ model, field: String(name), context: "onConflict target" }).columnName);
2281
2344
  } else if (isPlainObject3(target) && typeof target.constraint === "string" && target.constraint.length > 0 && Object.keys(target).length === 1) {
2282
2345
  if (!dialect.capabilities.conflictTargetConstraint) {
2283
- throw unsupportedCapability4({
2346
+ throw unsupportedCapability5({
2284
2347
  dialect: dialect.name,
2285
2348
  feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
2286
2349
  hint: "only postgres supports ON CONSTRAINT targets \u2014 name the indexed columns instead"
@@ -2302,7 +2365,7 @@ function compileConflictTarget(params) {
2302
2365
  });
2303
2366
  }
2304
2367
  if (!dialect.capabilities.partialIndexes) {
2305
- throw unsupportedCapability4({
2368
+ throw unsupportedCapability5({
2306
2369
  dialect: dialect.name,
2307
2370
  feature: "a partial-index conflict target",
2308
2371
  hint: "this dialect has no partial indexes to target"
@@ -2388,7 +2451,7 @@ function assertListFilterable(params) {
2388
2451
  const { dialect, model, field, operator } = params;
2389
2452
  if (dialect.capabilities.scalarArrays)
2390
2453
  return;
2391
- throw unsupportedCapability4({
2454
+ throw unsupportedCapability5({
2392
2455
  dialect: dialect.name,
2393
2456
  feature: `scalar list filter "${operator}" on ${model.name}.${field.name}`,
2394
2457
  hint: "only postgres has native array columns \u2014 model the list as a related table instead"
@@ -2398,7 +2461,7 @@ function assertListWritable(params) {
2398
2461
  const { dialect, model, field } = params;
2399
2462
  if (!field.isList || dialect.capabilities.scalarArrays)
2400
2463
  return;
2401
- throw unsupportedCapability4({
2464
+ throw unsupportedCapability5({
2402
2465
  dialect: dialect.name,
2403
2466
  feature: `writing the scalar list ${model.name}.${field.name}`,
2404
2467
  hint: "only postgres has native array columns \u2014 model the list as a related table instead"
@@ -2515,7 +2578,7 @@ function compileJsonFieldFilter(params) {
2515
2578
  const requireOp = (op) => {
2516
2579
  if (dialect.supportedJsonOps.includes(op))
2517
2580
  return;
2518
- throw unsupportedCapability4({
2581
+ throw unsupportedCapability5({
2519
2582
  dialect: dialect.name,
2520
2583
  feature: `json filter "${op}" on ${model.name}.${field.name}`,
2521
2584
  hint: `this dialect can express: ${dialect.supportedJsonOps.join(", ")}`
@@ -2836,7 +2899,7 @@ function buildRelationExists(params) {
2836
2899
  kind: "exists",
2837
2900
  select: {
2838
2901
  kind: "select",
2839
- table: { name: target.tableName, alias: childAlias },
2902
+ table: { name: target.tableName, ...target.namespace === undefined ? {} : { namespace: target.namespace }, alias: childAlias },
2840
2903
  columns: [],
2841
2904
  selectExpr: { kind: "one" },
2842
2905
  where: correlated({
@@ -2852,7 +2915,7 @@ function buildRelationExists(params) {
2852
2915
  ...negate ? { negate: true } : {},
2853
2916
  select: {
2854
2917
  kind: "select",
2855
- table: { name: join.tableName, alias: jtAlias },
2918
+ table: { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace }, alias: jtAlias },
2856
2919
  columns: [],
2857
2920
  selectExpr: { kind: "one" },
2858
2921
  where: {
@@ -2875,7 +2938,7 @@ function buildRelationExists(params) {
2875
2938
  ...negate ? { negate: true } : {},
2876
2939
  select: {
2877
2940
  kind: "select",
2878
- table: { name: target.tableName, alias: childAlias },
2941
+ table: { name: target.tableName, ...target.namespace === undefined ? {} : { namespace: target.namespace }, alias: childAlias },
2879
2942
  columns: [],
2880
2943
  selectExpr: { kind: "one" },
2881
2944
  where: correlated(correlateLink({ link, childTable: childAlias, outerTable: outer }))
@@ -3149,7 +3212,7 @@ function compileRelationOrderTerms(params) {
3149
3212
  const alias = `__ord${++aliasSeq.n}`;
3150
3213
  const select = link.kind === "manyToMany" ? {
3151
3214
  kind: "select",
3152
- table: { name: link.join.tableName, alias },
3215
+ table: { name: link.join.tableName, ...link.join?.namespace === undefined ? {} : { namespace: link.join.namespace }, alias },
3153
3216
  columns: [],
3154
3217
  selectExpr: { kind: "countAll" },
3155
3218
  where: {
@@ -3163,7 +3226,7 @@ function compileRelationOrderTerms(params) {
3163
3226
  }
3164
3227
  } : {
3165
3228
  kind: "select",
3166
- table: { name: link.target.tableName, alias },
3229
+ table: { name: link.target.tableName, ...link.target.namespace === undefined ? {} : { namespace: link.target.namespace }, alias },
3167
3230
  columns: [],
3168
3231
  selectExpr: { kind: "countAll" },
3169
3232
  where: correlateLink({ link, childTable: alias, outerTable: outer })
@@ -3183,7 +3246,7 @@ function compileRelationOrderTerms(params) {
3183
3246
  terms.push({
3184
3247
  select: {
3185
3248
  kind: "select",
3186
- table: { name: link.target.tableName, alias },
3249
+ table: { name: link.target.tableName, ...link.target.namespace === undefined ? {} : { namespace: link.target.namespace }, alias },
3187
3250
  columns: [compareColumnRef({ dialect, field, table: alias })],
3188
3251
  where: correlateLink({ link, childTable: alias, outerTable: outer })
3189
3252
  },
@@ -3737,7 +3800,7 @@ function parseCursor(params) {
3737
3800
  function keysetFieldOfTerm(params) {
3738
3801
  const { dialect, model, term } = params;
3739
3802
  if (!("column" in term)) {
3740
- throw unsupportedCapability4({
3803
+ throw unsupportedCapability5({
3741
3804
  dialect: dialect.name,
3742
3805
  feature: `keyset pagination over a relation or aggregate orderBy on model "${model.name}"`,
3743
3806
  hint: "order by scalar columns plus a unique tie-breaker; a correlated subquery value is not on the row, so no position can describe it"
@@ -3745,7 +3808,7 @@ function keysetFieldOfTerm(params) {
3745
3808
  }
3746
3809
  const field = model.fieldByColumn.get(term.column.name);
3747
3810
  if (field === undefined) {
3748
- throw unsupportedCapability4({
3811
+ throw unsupportedCapability5({
3749
3812
  dialect: dialect.name,
3750
3813
  feature: `keyset pagination over a computed order key on model "${model.name}"`,
3751
3814
  hint: "order by scalar columns plus a unique tie-breaker"
@@ -4125,7 +4188,7 @@ function buildFindShape(params) {
4125
4188
  const outerOrder = distinctOuterOrder ?? arranged.slice(0, distinctLeadCount);
4126
4189
  const inner = {
4127
4190
  kind: "select",
4128
- table: { name: model.tableName },
4191
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4129
4192
  columns: withOuterOrderKeys(columns, outerOrder),
4130
4193
  rowNumber: {
4131
4194
  partitionBy: distinctPartition,
@@ -4149,7 +4212,7 @@ function buildFindShape(params) {
4149
4212
  if (distinctOuterOrder !== null) {
4150
4213
  const inner = {
4151
4214
  kind: "select",
4152
- table: { name: model.tableName },
4215
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4153
4216
  columns: withOuterOrderKeys(columns, distinctOuterOrder),
4154
4217
  ...lateralJoins.length > 0 ? { lateralJoins } : {},
4155
4218
  ...where === undefined ? {} : { where },
@@ -4177,7 +4240,7 @@ function buildFindShape(params) {
4177
4240
  const innerColumns = withOuterOrderKeys(withKeyColumns(projected, correlationKeys), orderTerms);
4178
4241
  const inner = {
4179
4242
  kind: "select",
4180
- table: { name: model.tableName },
4243
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4181
4244
  columns: innerColumns,
4182
4245
  ...where === undefined ? {} : { where },
4183
4246
  ...distinctOn === undefined ? {} : { distinctOn },
@@ -4187,7 +4250,7 @@ function buildFindShape(params) {
4187
4250
  };
4188
4251
  const statement = {
4189
4252
  kind: "select",
4190
- table: { name: model.tableName },
4253
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4191
4254
  columns,
4192
4255
  fromSelect: inner,
4193
4256
  lateralJoins,
@@ -4197,7 +4260,7 @@ function buildFindShape(params) {
4197
4260
  }
4198
4261
  const statement = {
4199
4262
  kind: "select",
4200
- table: { name: model.tableName },
4263
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4201
4264
  columns,
4202
4265
  ...lateralJoins.length > 0 ? { lateralJoins } : {},
4203
4266
  ...where === undefined ? {} : { where },
@@ -4241,12 +4304,12 @@ function buildLateralCount(params) {
4241
4304
  };
4242
4305
  select = {
4243
4306
  kind: "select",
4244
- table: filter === undefined ? { name: join.tableName, alias: joinAlias } : { name: link.target.tableName, alias: childAlias },
4307
+ table: filter === undefined ? { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace }, alias: joinAlias } : { name: link.target.tableName, ...link.target.namespace === undefined ? {} : { namespace: link.target.namespace }, alias: childAlias },
4245
4308
  columns: [],
4246
4309
  selectExpr: { kind: "countAll", alias: columnAlias },
4247
4310
  where: filter === undefined ? correlation : { kind: "and", operands: [correlation, filter] },
4248
4311
  ...filter === undefined ? {} : { innerJoins: [{
4249
- table: { name: join.tableName, alias: joinAlias },
4312
+ table: { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace }, alias: joinAlias },
4250
4313
  on: [{ left: { table: joinAlias, name: join.childColumn }, right: { table: childAlias, name: pair.child.columnName } }]
4251
4314
  }] }
4252
4315
  };
@@ -4254,7 +4317,7 @@ function buildLateralCount(params) {
4254
4317
  const correlation = correlateLink({ link, childTable: childAlias, outerTable: model.tableName });
4255
4318
  select = {
4256
4319
  kind: "select",
4257
- table: { name: link.target.tableName, alias: childAlias },
4320
+ table: { name: link.target.tableName, ...link.target.namespace === undefined ? {} : { namespace: link.target.namespace }, alias: childAlias },
4258
4321
  columns: [],
4259
4322
  selectExpr: { kind: "countAll", alias: columnAlias },
4260
4323
  where: filter === undefined ? correlation : { kind: "and", operands: [correlation, filter] }
@@ -4277,7 +4340,7 @@ function buildLateralJoinClause(params) {
4277
4340
  kind: "exists",
4278
4341
  select: {
4279
4342
  kind: "select",
4280
- table: { name: join.tableName, alias: jtAlias },
4343
+ table: { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace }, alias: jtAlias },
4281
4344
  columns: [],
4282
4345
  selectExpr: { kind: "one" },
4283
4346
  where: {
@@ -4329,7 +4392,7 @@ function buildLateralJoinClause(params) {
4329
4392
  rowFormat: "positional",
4330
4393
  select: {
4331
4394
  kind: "select",
4332
- table: { name: target.tableName, alias: LATERAL_CHILD_ALIAS },
4395
+ table: { name: target.tableName, ...target.namespace === undefined ? {} : { namespace: target.namespace }, alias: LATERAL_CHILD_ALIAS },
4333
4396
  columns,
4334
4397
  where,
4335
4398
  ...orderBy === undefined || orderBy.length === 0 ? {} : { orderBy },
@@ -4685,7 +4748,7 @@ function resolveStrategy(params) {
4685
4748
  const strategy = explicit ?? defaultRelationStrategy ?? "query";
4686
4749
  if (strategy === "join" && !dialect.capabilities.lateralJoin) {
4687
4750
  if (explicit !== undefined || hasRelations) {
4688
- throw unsupportedCapability4({
4751
+ throw unsupportedCapability5({
4689
4752
  dialect: dialect.name,
4690
4753
  feature: 'relationStrategy "join"',
4691
4754
  hint: 'lateral joins are postgres-only \u2014 use the portable "query" strategy on this dialect'
@@ -4856,7 +4919,7 @@ function buildQuery(params) {
4856
4919
  const bounded = countTake !== undefined || countSkip !== undefined;
4857
4920
  const boundedInner = (innerFields) => ({
4858
4921
  kind: "select",
4859
- table: { name: model.tableName },
4922
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4860
4923
  columns: projectionColumns({ model, selectedFields: innerFields }),
4861
4924
  ...where === undefined ? {} : { where },
4862
4925
  ...countOrder === undefined || countOrder.length === 0 ? {} : { orderBy: countOrder },
@@ -4915,7 +4978,7 @@ function buildQuery(params) {
4915
4978
  aggregateSpec: { selections, countShorthand: false },
4916
4979
  statement: {
4917
4980
  kind: "select",
4918
- table: { name: model.tableName },
4981
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4919
4982
  columns: [],
4920
4983
  aggregates: aggSelects,
4921
4984
  ...where === undefined ? {} : { where }
@@ -4940,7 +5003,7 @@ function buildQuery(params) {
4940
5003
  countAlias: COUNT_ALIAS,
4941
5004
  statement: {
4942
5005
  kind: "select",
4943
- table: { name: model.tableName },
5006
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4944
5007
  columns: [],
4945
5008
  selectExpr: { kind: "countAll", alias: COUNT_ALIAS },
4946
5009
  ...where === undefined ? {} : { where }
@@ -4960,7 +5023,7 @@ function buildQuery(params) {
4960
5023
  aggregateSpec: spec,
4961
5024
  statement: {
4962
5025
  kind: "select",
4963
- table: { name: model.tableName },
5026
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4964
5027
  columns: [],
4965
5028
  aggregates: aggSelects,
4966
5029
  ...where === undefined ? {} : { where }
@@ -4970,7 +5033,7 @@ function buildQuery(params) {
4970
5033
  const innerFields = referenced.length > 0 ? referenced : model.primaryKey.map((field) => field.name);
4971
5034
  const inner = {
4972
5035
  kind: "select",
4973
- table: { name: model.tableName },
5036
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
4974
5037
  columns: projectionColumns({ model, selectedFields: innerFields }),
4975
5038
  ...where === undefined ? {} : { where },
4976
5039
  ...orderBy === undefined || orderBy.length === 0 ? {} : { orderBy },
@@ -5023,7 +5086,7 @@ function buildQuery(params) {
5023
5086
  groupByFields: byFields.map((field) => field.name),
5024
5087
  statement: {
5025
5088
  kind: "select",
5026
- table: { name: model.tableName },
5089
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
5027
5090
  columns: byColumns,
5028
5091
  ...aggSelects.length === 0 ? {} : { aggregates: aggSelects },
5029
5092
  ...where === undefined ? {} : { where },
@@ -5065,7 +5128,7 @@ function buildQuery(params) {
5065
5128
  throw validationError4({ message: "DO NOTHING cannot carry update expressions" });
5066
5129
  if (spec.action === "update") {
5067
5130
  if (!dialect.capabilities.returning)
5068
- throw unsupportedCapability4({ dialect: dialect.name, feature: "create onConflict update returning", hint: "use upsertMany for a count-only conflict update" });
5131
+ throw unsupportedCapability5({ dialect: dialect.name, feature: "create onConflict update returning", hint: "use upsertMany for a count-only conflict update" });
5069
5132
  if (compiled.columns === undefined && compiled.constraint === undefined)
5070
5133
  throw validationError4({ message: "A conflict update requires an explicit target" });
5071
5134
  const updates = requireObject({ value: spec.update, what: "onConflict.update", model });
@@ -5103,7 +5166,7 @@ function buildQuery(params) {
5103
5166
  refetchWhere: row.knownKey,
5104
5167
  statement: {
5105
5168
  kind: "insert",
5106
- table: { name: model.tableName },
5169
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
5107
5170
  columns,
5108
5171
  rows: [columns.map((column) => row.values[column])],
5109
5172
  ...conflictClause === undefined ? {} : { onConflict: conflictClause },
@@ -5114,7 +5177,7 @@ function buildQuery(params) {
5114
5177
  case "createMany":
5115
5178
  case "createManyAndReturn": {
5116
5179
  if (method === "createManyAndReturn" && !dialect.capabilities.createManyAndReturn) {
5117
- throw unsupportedCapability4({
5180
+ throw unsupportedCapability5({
5118
5181
  dialect: dialect.name,
5119
5182
  feature: "createManyAndReturn",
5120
5183
  hint: "this dialect cannot RETURNING multiple inserted rows \u2014 use createMany then findMany"
@@ -5151,7 +5214,7 @@ function buildQuery(params) {
5151
5214
  }
5152
5215
  const statements = groups.map((group) => ({
5153
5216
  kind: "insert",
5154
- table: { name: model.tableName },
5217
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
5155
5218
  columns: group.columns,
5156
5219
  rows: group.rows,
5157
5220
  ...manyConflict === undefined ? {} : { onConflict: manyConflict },
@@ -5237,7 +5300,7 @@ function buildQuery(params) {
5237
5300
  };
5238
5301
  const upsertStatements = upsertGroups.map((group) => ({
5239
5302
  kind: "insert",
5240
- table: { name: model.tableName },
5303
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
5241
5304
  columns: group.columns,
5242
5305
  rows: group.rows,
5243
5306
  onConflict
@@ -5254,7 +5317,7 @@ function buildQuery(params) {
5254
5317
  case "updateManyAndReturn": {
5255
5318
  const isUnique = method === "update";
5256
5319
  if (method === "updateManyAndReturn" && !dialect.capabilities.returning) {
5257
- throw unsupportedCapability4({
5320
+ throw unsupportedCapability5({
5258
5321
  dialect: dialect.name,
5259
5322
  feature: "updateManyAndReturn",
5260
5323
  hint: "this dialect has no RETURNING \u2014 use updateMany then findMany, accepting that the read is a separate, unprotected statement"
@@ -5276,7 +5339,7 @@ function buildQuery(params) {
5276
5339
  refetchWhere: isUnique ? uniqueRefetchWhere({ model, where, data: args.data }) : null,
5277
5340
  statement: {
5278
5341
  kind: "update",
5279
- table: { name: model.tableName },
5342
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
5280
5343
  set: compileUpdateSet({
5281
5344
  dialect,
5282
5345
  model,
@@ -5299,7 +5362,7 @@ function buildQuery(params) {
5299
5362
  });
5300
5363
  }
5301
5364
  if (!dialect.capabilities.conflictTargetConstraint) {
5302
- throw unsupportedCapability4({
5365
+ throw unsupportedCapability5({
5303
5366
  dialect: dialect.name,
5304
5367
  feature: "a named-constraint conflict target on upsert",
5305
5368
  hint: "only postgres supports ON CONFLICT ON CONSTRAINT \u2014 rely on the where-derived column target instead"
@@ -5317,7 +5380,7 @@ function buildQuery(params) {
5317
5380
  const targetFields = conflictTargetGroup({ model, where }).fields;
5318
5381
  for (const field of targetFields) {
5319
5382
  if (!(field.columnName in row.values)) {
5320
- throw new VibeError11({
5383
+ throw new VibeError13({
5321
5384
  code: "VIBE_INTERNAL",
5322
5385
  message: `upsert on ${model.name}: create data does not bind conflict-target column "${field.columnName}" \u2014 this shape must run the find-then-write fallback flow`,
5323
5386
  meta: { model: model.name, column: field.columnName }
@@ -5328,7 +5391,7 @@ function buildQuery(params) {
5328
5391
  for (const [key, value] of Object.entries(where)) {
5329
5392
  if (value === undefined || nativeTargetNames.has(key))
5330
5393
  continue;
5331
- throw new VibeError11({
5394
+ throw new VibeError13({
5332
5395
  code: "VIBE_INTERNAL",
5333
5396
  message: `upsert on ${model.name}: where field "${key}" is not part of the conflict target \u2014 guarded upserts must run the find-then-write fallback flow`,
5334
5397
  meta: { model: model.name, field: key }
@@ -5343,7 +5406,7 @@ function buildQuery(params) {
5343
5406
  refetchWhereBase: { ...where },
5344
5407
  statement: {
5345
5408
  kind: "insert",
5346
- table: { name: model.tableName },
5409
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
5347
5410
  columns,
5348
5411
  rows: [columns.map((column) => row.values[column])],
5349
5412
  onConflict: {
@@ -5369,7 +5432,7 @@ function buildQuery(params) {
5369
5432
  refetchWhere: isUnique ? where : null,
5370
5433
  statement: {
5371
5434
  kind: "delete",
5372
- table: { name: model.tableName },
5435
+ table: { name: model.tableName, ...model.namespace === undefined ? {} : { namespace: model.namespace } },
5373
5436
  ...compiled === undefined ? {} : { where: compiled },
5374
5437
  ...isUnique ? { returning: returningColumns({ model, selectedFields }) } : {}
5375
5438
  }
@@ -5381,7 +5444,7 @@ function buildQuery(params) {
5381
5444
  import { getSqlDialect, renderStatement } from "@vibeorm/sql";
5382
5445
 
5383
5446
  // packages/runtime/src/extensions.ts
5384
- import { VibeError as VibeError12, extensionManifestEntry } from "@vibeorm/schema";
5447
+ import { VibeError as VibeError14, extensionManifestEntry } from "@vibeorm/schema";
5385
5448
  function assertExtensionManifest(params) {
5386
5449
  const { manifest } = params;
5387
5450
  const instances = params.instances ?? [];
@@ -5404,7 +5467,7 @@ function assertExtensionManifest(params) {
5404
5467
  problems.push(`"${name}" is configured but missing from the generated client`);
5405
5468
  }
5406
5469
  if (problems.length > 0) {
5407
- throw new VibeError12({
5470
+ throw new VibeError14({
5408
5471
  code: "VIBE_STALE_CLIENT",
5409
5472
  message: `extension list changed since generate; run vibeorm generate \u2014 ${problems.join("; ")}`,
5410
5473
  meta: { manifest, problems }
@@ -5419,7 +5482,7 @@ function buildExtensionOperatorMap(params) {
5419
5482
  for (const operator of extension.sql?.whereOperators ?? []) {
5420
5483
  const existing = owner.get(operator.name);
5421
5484
  if (existing !== undefined) {
5422
- throw new VibeError12({
5485
+ throw new VibeError14({
5423
5486
  code: "VIBE_CONFIG",
5424
5487
  message: `where operator "${operator.name}" is claimed by both "${existing}" and "${extension.name}"`,
5425
5488
  meta: { operator: operator.name }
@@ -5435,7 +5498,7 @@ function buildExtensionOperatorMap(params) {
5435
5498
  options: extension.options
5436
5499
  });
5437
5500
  if ("error" in compiled) {
5438
- throw new VibeError12({
5501
+ throw new VibeError14({
5439
5502
  code: "VIBE_VALIDATION",
5440
5503
  message: `"${operator.name}" on ${model}.${field}: ${compiled.error}`,
5441
5504
  meta: { model, field, operator: operator.name, extension: extension.name }
@@ -5468,7 +5531,7 @@ function buildConnectHooks(params) {
5468
5531
  }
5469
5532
 
5470
5533
  // packages/runtime/src/relation-key.ts
5471
- import { VibeError as VibeError13 } from "@vibeorm/schema";
5534
+ import { VibeError as VibeError15 } from "@vibeorm/schema";
5472
5535
  function relationValueKey(params) {
5473
5536
  const { value } = params;
5474
5537
  if (value === null || value === undefined)
@@ -5501,7 +5564,7 @@ function relationTupleKey(params) {
5501
5564
  if (value === null || value === undefined)
5502
5565
  return null;
5503
5566
  if (typeof value === "object" && !(value instanceof Date) && !(value instanceof Uint8Array)) {
5504
- throw new VibeError13({
5567
+ throw new VibeError15({
5505
5568
  code: "VIBE_UNSUPPORTED_CAPABILITY",
5506
5569
  message: "a relation key of this type cannot be compared faithfully in memory \u2014 relation links support String, Int, BigInt, Boolean, DateTime and Bytes keys",
5507
5570
  meta: { received: Object.prototype.toString.call(value) }
@@ -5527,7 +5590,7 @@ function assertWriteScope(params) {
5527
5590
  }
5528
5591
 
5529
5592
  // packages/runtime/src/nested-writes.ts
5530
- import { VibeError as VibeError14 } from "@vibeorm/schema";
5593
+ import { VibeError as VibeError16 } from "@vibeorm/schema";
5531
5594
  function parentTupleOf(params) {
5532
5595
  const { link, row } = params;
5533
5596
  return link.parentKeys.map((field) => row[field.name]);
@@ -5574,10 +5637,10 @@ function detachAssignment(params) {
5574
5637
  return out;
5575
5638
  }
5576
5639
  function validationError5(params) {
5577
- return new VibeError14({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
5640
+ return new VibeError16({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
5578
5641
  }
5579
5642
  function notFound(params) {
5580
- return new VibeError14({ code: "VIBE_NOT_FOUND", message: params.message, meta: params.meta });
5643
+ return new VibeError16({ code: "VIBE_NOT_FOUND", message: params.message, meta: params.meta });
5581
5644
  }
5582
5645
  function isPlainObject4(value) {
5583
5646
  return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date) && !(value instanceof Uint8Array);
@@ -5744,7 +5807,7 @@ async function insertJoinRows(params) {
5744
5807
  await run.statement({
5745
5808
  statement: {
5746
5809
  kind: "insert",
5747
- table: { name: join.tableName },
5810
+ table: { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace } },
5748
5811
  columns: ["A", "B"],
5749
5812
  rows: rows.slice(start, start + perChunk),
5750
5813
  onConflict: { columns: ["A", "B"], doNothing: true }
@@ -5764,7 +5827,7 @@ async function deleteJoinRows(params) {
5764
5827
  await run.statement({
5765
5828
  statement: {
5766
5829
  kind: "delete",
5767
- table: { name: join.tableName },
5830
+ table: { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace } },
5768
5831
  where: {
5769
5832
  kind: "and",
5770
5833
  operands: [
@@ -5813,7 +5876,7 @@ async function deleteJoinRowsForChildren(params) {
5813
5876
  await run.statement({
5814
5877
  statement: {
5815
5878
  kind: "delete",
5816
- table: { name: join.tableName },
5879
+ table: { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace } },
5817
5880
  where: isSelf ? {
5818
5881
  kind: "or",
5819
5882
  operands: [
@@ -6193,7 +6256,7 @@ async function loadMemberKeys(params) {
6193
6256
  const rows = await run.statement({
6194
6257
  statement: {
6195
6258
  kind: "select",
6196
- table: { name: join.tableName },
6259
+ table: { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace } },
6197
6260
  columns: [{ name: join.childColumn }],
6198
6261
  where: narrow === null ? parentMatch : {
6199
6262
  kind: "and",
@@ -6794,7 +6857,7 @@ function previewOperation(params) {
6794
6857
  };
6795
6858
  }
6796
6859
  // packages/runtime/src/diagnostics/plan.ts
6797
- import { VibeError as VibeError15, unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
6860
+ import { VibeError as VibeError17, unsupportedCapability as unsupportedCapability6 } from "@vibeorm/schema";
6798
6861
  import { NATIVE_RLS, getSqlDialect as getSqlDialect2, renderPostgresExplain, renderPostgresWorkload, renderStatement as renderStatement2 } from "@vibeorm/sql";
6799
6862
  var PLAN_DEFAULTS = Object.freeze({ maxNodes: 200, maxConditionLength: 2000 });
6800
6863
  var CONDITION_KEYS = [
@@ -6813,7 +6876,7 @@ var CONDITION_KEYS = [
6813
6876
  "Output"
6814
6877
  ];
6815
6878
  function planError(params) {
6816
- return new VibeError15({ code: "VIBE_ADAPTER", message: params.message, meta: {} });
6879
+ return new VibeError17({ code: "VIBE_ADAPTER", message: params.message, meta: {} });
6817
6880
  }
6818
6881
  function asRecord(value) {
6819
6882
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
@@ -6846,14 +6909,14 @@ function parsePostgresPlan(params) {
6846
6909
  const maxNodes = params.maxNodes ?? PLAN_DEFAULTS.maxNodes;
6847
6910
  const includeLiterals = params.includeLiterals === true;
6848
6911
  if (!Number.isInteger(maxNodes) || maxNodes < 1) {
6849
- throw new VibeError15({ code: "VIBE_CONFIG", message: `maxNodes must be a positive integer, got ${String(maxNodes)}`, meta: { maxNodes } });
6912
+ throw new VibeError17({ code: "VIBE_CONFIG", message: `maxNodes must be a positive integer, got ${String(maxNodes)}`, meta: { maxNodes } });
6850
6913
  }
6851
6914
  let parsed = payload;
6852
6915
  if (typeof payload === "string") {
6853
6916
  try {
6854
6917
  parsed = JSON.parse(payload);
6855
6918
  } catch {
6856
- throw new VibeError15({
6919
+ throw new VibeError17({
6857
6920
  code: "VIBE_ADAPTER",
6858
6921
  message: "EXPLAIN returned malformed JSON",
6859
6922
  meta: { reason: "malformed-plan-json", mode }
@@ -6921,7 +6984,7 @@ function parsePostgresPlan(params) {
6921
6984
  var WRITE_LEADERS = ["INSERT", "UPDATE", "DELETE", "MERGE", "TRUNCATE", "CREATE", "DROP", "ALTER", "GRANT", "REVOKE", "COPY", "CALL", "DO"];
6922
6985
  var SIDE_EFFECT_CALLS = /\bpg_(?:try_)?advisory_(?:xact_)?lock(?:_shared)?\s*\(/i;
6923
6986
  function refuse(params) {
6924
- return new VibeError15({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta ?? {} });
6987
+ return new VibeError17({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta ?? {} });
6925
6988
  }
6926
6989
  function executableReadRefusal(params) {
6927
6990
  const normalized = normalizeSql({ text: params.text });
@@ -6972,7 +7035,7 @@ async function readPlanContext(params) {
6972
7035
  }
6973
7036
  function requirePostgres(params) {
6974
7037
  if (params.dialect !== "postgres") {
6975
- throw unsupportedCapability5({
7038
+ throw unsupportedCapability6({
6976
7039
  dialect: params.dialect,
6977
7040
  feature: "query plan inspection",
6978
7041
  hint: "plan inspection is PostgreSQL-shaped; operation tracing (telemetry) works on every dialect"
@@ -7051,7 +7114,7 @@ async function explainOnSession(params) {
7051
7114
  const context = await readPlanContext({ executor, dialect, rlsContextKeys: contextKeys });
7052
7115
  if (!context.representative) {
7053
7116
  if (params.requireRepresentativeContext === true) {
7054
- throw new VibeError15({
7117
+ throw new VibeError17({
7055
7118
  code: "VIBE_RLS_CONTEXT",
7056
7119
  message: `refusing to report a plan taken under a non-representative identity: ${context.reason ?? "role bypasses row policies"}`,
7057
7120
  meta: { currentUser: context.currentUser, bypassRls: context.bypassRls, superuser: context.superuser }
@@ -7127,7 +7190,7 @@ async function explainOperation(params) {
7127
7190
  });
7128
7191
  }
7129
7192
  // packages/runtime/src/diagnostics/statement-diagnostics.ts
7130
- import { VibeError as VibeError16 } from "@vibeorm/schema";
7193
+ import { VibeError as VibeError18 } from "@vibeorm/schema";
7131
7194
  import { renderPostgresWorkload as renderPostgresWorkload2 } from "@vibeorm/sql";
7132
7195
  var STATEMENT_DIAGNOSTICS_DEFAULTS = Object.freeze({
7133
7196
  slowerThanMs: 0,
@@ -7139,7 +7202,7 @@ var STATEMENT_DIAGNOSTICS_DEFAULTS = Object.freeze({
7139
7202
  });
7140
7203
  var EXPLAIN_MODES = ["off", "estimate", "analyze"];
7141
7204
  function configError(params) {
7142
- return new VibeError16({ code: "VIBE_CONFIG", message: params.message, meta: params.meta ?? {} });
7205
+ return new VibeError18({ code: "VIBE_CONFIG", message: params.message, meta: params.meta ?? {} });
7143
7206
  }
7144
7207
  function isExplainMode(value) {
7145
7208
  return typeof value === "string" && EXPLAIN_MODES.includes(value);
@@ -7265,7 +7328,7 @@ function summarizePlan(params) {
7265
7328
  };
7266
7329
  }
7267
7330
  function errorCode(error) {
7268
- return error instanceof VibeError16 ? error.code : "VIBE_INTERNAL";
7331
+ return error instanceof VibeError18 ? error.code : "VIBE_INTERNAL";
7269
7332
  }
7270
7333
  function createStatementDiagnostics(params) {
7271
7334
  const { config, adapter, dialect } = params;
@@ -7376,7 +7439,7 @@ function createStatementDiagnostics(params) {
7376
7439
  };
7377
7440
  }
7378
7441
  // packages/runtime/src/diagnostics/workload.ts
7379
- import { unsupportedCapability as unsupportedCapability6 } from "@vibeorm/schema";
7442
+ import { unsupportedCapability as unsupportedCapability7 } from "@vibeorm/schema";
7380
7443
  import { getSqlDialect as getSqlDialect3, renderPostgresWorkload as renderPostgresWorkload3 } from "@vibeorm/sql";
7381
7444
  var STATEMENTS_INFO_MIN_VERSION = 140000;
7382
7445
  var STATEMENTS_MIN_VERSION = 130000;
@@ -7409,7 +7472,7 @@ async function readAvailability(params) {
7409
7472
  async function readWorkloadStatistics(params) {
7410
7473
  const { executor } = params;
7411
7474
  if (params.dialect !== "postgres") {
7412
- throw unsupportedCapability6({
7475
+ throw unsupportedCapability7({
7413
7476
  dialect: params.dialect,
7414
7477
  feature: "workload statistics (pg_stat_statements)",
7415
7478
  hint: "server workload statistics are PostgreSQL-only; operation telemetry works on every dialect"
@@ -7487,7 +7550,7 @@ async function readWorkloadStatistics(params) {
7487
7550
  };
7488
7551
  }
7489
7552
  // packages/runtime/src/diagnostics/insight.ts
7490
- import { VibeError as VibeError17 } from "@vibeorm/schema";
7553
+ import { VibeError as VibeError19 } from "@vibeorm/schema";
7491
7554
  var DIAGNOSTIC_THRESHOLDS = Object.freeze({
7492
7555
  repeatThreshold: 5,
7493
7556
  minRepeatThreshold: 2,
@@ -7505,7 +7568,7 @@ function bounded(params) {
7505
7568
  if (value === undefined)
7506
7569
  return fallback;
7507
7570
  if (!Number.isInteger(value) || value < min || value > max) {
7508
- throw new VibeError17({
7571
+ throw new VibeError19({
7509
7572
  code: "VIBE_CONFIG",
7510
7573
  message: `${name} must be an integer between ${min} and ${max}, got ${String(value)}`,
7511
7574
  meta: { [name]: value }
@@ -7728,11 +7791,11 @@ function recommendFromPlan(params) {
7728
7791
  return findings.slice(0, maxFindings);
7729
7792
  }
7730
7793
  // packages/runtime/src/relation-loader.ts
7731
- import { VibeError as VibeError19 } from "@vibeorm/schema";
7794
+ import { VibeError as VibeError21 } from "@vibeorm/schema";
7732
7795
  import { renderStatement as renderStatement3 } from "@vibeorm/sql";
7733
7796
 
7734
7797
  // packages/runtime/src/computed.ts
7735
- import { VibeError as VibeError18 } from "@vibeorm/schema";
7798
+ import { VibeError as VibeError20 } from "@vibeorm/schema";
7736
7799
  function sameNeeds(a, b) {
7737
7800
  if (a.length !== b.length)
7738
7801
  return false;
@@ -7768,7 +7831,7 @@ function assertComputedManifest(params) {
7768
7831
  problems.push(`"${key}" is configured but missing from the generated client`);
7769
7832
  }
7770
7833
  if (problems.length > 0) {
7771
- throw new VibeError18({
7834
+ throw new VibeError20({
7772
7835
  code: "VIBE_STALE_CLIENT",
7773
7836
  message: `computed-field config changed since generate; run vibeorm generate \u2014 ${problems.join("; ")}`,
7774
7837
  meta: { problems }
@@ -7796,7 +7859,7 @@ function resolveRelationConcurrency(params) {
7796
7859
  if (concurrency === undefined)
7797
7860
  return 1;
7798
7861
  if (!Number.isInteger(concurrency) || concurrency < 1) {
7799
- throw new VibeError19({
7862
+ throw new VibeError21({
7800
7863
  code: "VIBE_CONFIG",
7801
7864
  message: `relationLoading.concurrency must be a positive integer \u2014 got ${String(concurrency)}`,
7802
7865
  meta: { concurrency }
@@ -7944,7 +8007,7 @@ function buildChildStatement(params) {
7944
8007
  if (window === undefined) {
7945
8008
  return {
7946
8009
  kind: "select",
7947
- table: { name: target.tableName },
8010
+ table: { name: target.tableName, ...target.namespace === undefined ? {} : { namespace: target.namespace } },
7948
8011
  columns,
7949
8012
  where,
7950
8013
  ...orderBy === undefined || orderBy.length === 0 ? {} : { orderBy }
@@ -7952,7 +8015,7 @@ function buildChildStatement(params) {
7952
8015
  }
7953
8016
  const inner = {
7954
8017
  kind: "select",
7955
- table: { name: target.tableName },
8018
+ table: { name: target.tableName, ...target.namespace === undefined ? {} : { namespace: target.namespace } },
7956
8019
  columns,
7957
8020
  where,
7958
8021
  rowNumber: { partitionBy: [...window.partitionBy], orderBy: orderBy ?? [], alias: WINDOW_ROW_ALIAS }
@@ -7981,7 +8044,7 @@ function chunkKeys(params) {
7981
8044
  const rendered = renderStatement3({ dialect: ctx.dialect, statement: build(keys.slice(0, 1)) });
7982
8045
  fixed = rendered.values.length - (expands ? arity : 1);
7983
8046
  if (fixed + arity > budget) {
7984
- throw new VibeError19({
8047
+ throw new VibeError21({
7985
8048
  code: "VIBE_UNSUPPORTED_CAPABILITY",
7986
8049
  message: `relation "${relation}" needs ${fixed + arity} bound parameters for its own predicate, more than ${ctx.dialect.name}'s ${budget}-parameter statement budget \u2014 narrow the nested filter`,
7987
8050
  meta: { relation, dialect: ctx.dialect.name, required: fixed + arity, budget }
@@ -8111,7 +8174,7 @@ async function loadManyToMany(params) {
8111
8174
  const link = node.link;
8112
8175
  const join = link.join;
8113
8176
  if (join === null) {
8114
- throw new VibeError19({
8177
+ throw new VibeError21({
8115
8178
  code: "VIBE_INTERNAL",
8116
8179
  message: `manyToMany relation "${node.name}" resolved without join-table wiring`
8117
8180
  });
@@ -8156,11 +8219,11 @@ async function loadManyToMany(params) {
8156
8219
  const where = nestedWhere === undefined ? membership : { kind: "and", operands: [membership, nestedWhere] };
8157
8220
  const base = {
8158
8221
  kind: "select",
8159
- table: { name: target.tableName },
8222
+ table: { name: target.tableName, ...target.namespace === undefined ? {} : { namespace: target.namespace } },
8160
8223
  columns: [...childColumns, { table: M2M_JOIN_ALIAS, name: join.parentColumn, alias: M2M_PARENT_ALIAS }],
8161
8224
  innerJoins: [
8162
8225
  {
8163
- table: { name: join.tableName, alias: M2M_JOIN_ALIAS },
8226
+ table: { name: join.tableName, ...join.namespace === undefined ? {} : { namespace: join.namespace }, alias: M2M_JOIN_ALIAS },
8164
8227
  on: [
8165
8228
  {
8166
8229
  left: { table: M2M_JOIN_ALIAS, name: join.childColumn },
@@ -8270,7 +8333,7 @@ async function loadCounts(params) {
8270
8333
  const where = filter === undefined ? membership : { kind: "and", operands: [membership, filter] };
8271
8334
  const base = {
8272
8335
  kind: "select",
8273
- table: { name: joinsChildTable ? target.tableName : table },
8336
+ table: { name: joinsChildTable ? target.tableName : table, ...(joinsChildTable || join === null ? target.namespace : join.namespace) === undefined ? {} : { namespace: joinsChildTable || join === null ? target.namespace : join.namespace } },
8274
8337
  columns: projectedColumns,
8275
8338
  selectExpr: { kind: "countAll", alias: COUNT_VALUE_ALIAS },
8276
8339
  where,
@@ -8282,7 +8345,7 @@ async function loadCounts(params) {
8282
8345
  ...base,
8283
8346
  innerJoins: [
8284
8347
  {
8285
- table: { name: join.tableName, alias: M2M_JOIN_ALIAS },
8348
+ table: { name: join.tableName, ...join?.namespace === undefined ? {} : { namespace: join.namespace }, alias: M2M_JOIN_ALIAS },
8286
8349
  on: [
8287
8350
  {
8288
8351
  left: { table: M2M_JOIN_ALIAS, name: join.childColumn },
@@ -8408,7 +8471,7 @@ async function attachLateralRelations(params) {
8408
8471
  try {
8409
8472
  parsed = JSON.parse(raw);
8410
8473
  } catch (cause) {
8411
- throw new VibeError19({
8474
+ throw new VibeError21({
8412
8475
  code: "VIBE_INTERNAL",
8413
8476
  message: `relation column "${column}" returned text that is not valid JSON`,
8414
8477
  meta: { relation: node.name },
@@ -8418,7 +8481,7 @@ async function attachLateralRelations(params) {
8418
8481
  }
8419
8482
  if (isList) {
8420
8483
  if (!Array.isArray(parsed)) {
8421
- throw new VibeError19({ code: "VIBE_INTERNAL", message: "to-many relation payload must be an array", meta: { relation: node.name } });
8484
+ throw new VibeError21({ code: "VIBE_INTERNAL", message: "to-many relation payload must be an array", meta: { relation: node.name } });
8422
8485
  }
8423
8486
  const children = parsed.map(decodePosition);
8424
8487
  for (const child of children) {
@@ -8459,7 +8522,7 @@ async function attachLateralRelations(params) {
8459
8522
  const raw = row[column];
8460
8523
  const count = typeof raw === "number" || typeof raw === "bigint" || typeof raw === "string" && /^\d+$/.test(raw) ? Number(raw) : NaN;
8461
8524
  if (!Number.isSafeInteger(count) || count < 0) {
8462
- throw new VibeError19({ code: "VIBE_INTERNAL", message: "relation count payload must be a non-negative safe integer", meta: { relation: selection.counts[index]?.name } });
8525
+ throw new VibeError21({ code: "VIBE_INTERNAL", message: "relation count payload must be a non-negative safe integer", meta: { relation: selection.counts[index]?.name } });
8463
8526
  }
8464
8527
  counts[selection.counts[index].name] = count;
8465
8528
  delete row[column];
@@ -8468,11 +8531,11 @@ async function attachLateralRelations(params) {
8468
8531
  }
8469
8532
  }
8470
8533
  // packages/runtime/src/views.ts
8471
- import { VibeError as VibeError21 } from "@vibeorm/schema";
8534
+ import { VibeError as VibeError23 } from "@vibeorm/schema";
8472
8535
 
8473
8536
  // packages/runtime/src/sql-access.ts
8474
8537
  import { Buffer as Buffer2 } from "buffer";
8475
- import { VibeError as VibeError20 } from "@vibeorm/schema";
8538
+ import { VibeError as VibeError22 } from "@vibeorm/schema";
8476
8539
  import { isSqlFragment as isSqlFragment2 } from "@vibeorm/sql";
8477
8540
  function containsSqlFragment(value, seen = new Set) {
8478
8541
  if (isSqlFragment2(value))
@@ -8497,7 +8560,7 @@ function containsSqlFragment(value, seen = new Set) {
8497
8560
  return false;
8498
8561
  }
8499
8562
  function restrictedSqlArgs(params) {
8500
- const refuse = () => params.refusal?.() ?? new VibeError20({ code: "VIBE_VALIDATION", message: `SQL fragments are unavailable through ${params.path}; use the unrestricted client`, meta: { path: params.path } });
8563
+ const refuse = () => params.refusal?.() ?? new VibeError22({ code: "VIBE_VALIDATION", message: `SQL fragments are unavailable through ${params.path}; use the unrestricted client`, meta: { path: params.path } });
8501
8564
  if (containsSqlFragment(params.value))
8502
8565
  throw refuse();
8503
8566
  const seen = new Map;
@@ -8559,13 +8622,13 @@ function restrictConflictPredicates(params) {
8559
8622
  const target = spec.target;
8560
8623
  const declared = conflictSchemas.get(params.meta)?.get(params.model.name)?.some((index) => typeof spec.where === "string" && index.where === spec.where && Array.isArray(target) && target.length === index.fields.length && index.fields.every((field, position) => field === target[position]));
8561
8624
  if (declared !== true)
8562
- throw new VibeError20({ code: "VIBE_VALIDATION", message: `${params.path}: ${key}.where must match a declared unique index and its target fields; free-form SQL requires the unrestricted client`, meta: { model: params.model.name, path: params.path } });
8625
+ throw new VibeError22({ code: "VIBE_VALIDATION", message: `${params.path}: ${key}.where must match a declared unique index and its target fields; free-form SQL requires the unrestricted client`, meta: { model: params.model.name, path: params.path } });
8563
8626
  }
8564
8627
  }
8565
8628
 
8566
8629
  // packages/runtime/src/views.ts
8567
8630
  function validationError6(params) {
8568
- return new VibeError21({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
8631
+ return new VibeError23({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
8569
8632
  }
8570
8633
 
8571
8634
  class ViewResult {
@@ -8919,7 +8982,7 @@ function createView(params) {
8919
8982
  for (const [clientName, mask] of resolved) {
8920
8983
  const delegate = models[clientName];
8921
8984
  if (delegate === undefined) {
8922
- throw new VibeError21({
8985
+ throw new VibeError23({
8923
8986
  code: "VIBE_INTERNAL",
8924
8987
  message: `view "${name}": no delegate for model "${mask.model.name}"`,
8925
8988
  meta: { view: name, model: mask.model.name }
@@ -8935,9 +8998,9 @@ function attachDefineView(params) {
8935
8998
  Object.defineProperty(client, "$defineView", { value, enumerable: true });
8936
8999
  }
8937
9000
  // packages/runtime/src/validators.ts
8938
- import { VibeError as VibeError22 } from "@vibeorm/schema";
9001
+ import { VibeError as VibeError24 } from "@vibeorm/schema";
8939
9002
  function validationFailed(params) {
8940
- return new VibeError22({
9003
+ return new VibeError24({
8941
9004
  code: "VIBE_VALIDATION",
8942
9005
  message: `validation failed for ${params.model}.${params.field}: ${params.issues[0]?.message ?? "invalid value"}`,
8943
9006
  meta: { model: params.model, field: params.field, issues: params.issues }
@@ -8946,7 +9009,7 @@ function validationFailed(params) {
8946
9009
  function validateValue(params) {
8947
9010
  const result = params.schema["~standard"].validate(params.value);
8948
9011
  if (result instanceof Promise) {
8949
- throw new VibeError22({
9012
+ throw new VibeError24({
8950
9013
  code: "VIBE_VALIDATION",
8951
9014
  message: `async validator on ${params.model}.${params.field} \u2014 write validators must be synchronous (validate before calling the client for async rules)`,
8952
9015
  meta: { model: params.model, field: params.field }
@@ -9069,10 +9132,10 @@ function deferPolicyOperation(params) {
9069
9132
  }
9070
9133
 
9071
9134
  // packages/runtime/src/policy.ts
9072
- import { VibeError as VibeError24 } from "@vibeorm/schema";
9135
+ import { VibeError as VibeError27 } from "@vibeorm/schema";
9073
9136
 
9074
9137
  // packages/runtime/src/module-context.ts
9075
- import { VibeError as VibeError23 } from "@vibeorm/schema";
9138
+ import { VibeError as VibeError25 } from "@vibeorm/schema";
9076
9139
  var binders = new WeakMap;
9077
9140
  function registerModuleBinder(params) {
9078
9141
  binders.set(params.client, params.bind);
@@ -9085,7 +9148,7 @@ function inheritReadOnlyModuleBinder(params) {
9085
9148
  function bindModuleContext(params) {
9086
9149
  const bind = binders.get(params.db);
9087
9150
  if (bind === undefined)
9088
- throw new VibeError23({
9151
+ throw new VibeError25({
9089
9152
  code: "VIBE_CONFIG",
9090
9153
  message: `Module ${params.artifact.manifest.id} needs an unrestricted handle from the same VibeORM runtime installation; scoped and foreign handles cannot attach package models`,
9091
9154
  meta: { reason: "module_handle", moduleId: params.artifact.manifest.id, protocol: params.artifact.manifest.protocol }
@@ -9094,9 +9157,10 @@ function bindModuleContext(params) {
9094
9157
  }
9095
9158
 
9096
9159
  // packages/runtime/src/read-only.ts
9097
- import { ReadOnlyClientError } from "@vibeorm/schema";
9160
+ import { ReadOnlyClientError, VibeError as VibeError26 } from "@vibeorm/schema";
9098
9161
  var READ_DELEGATE_METHODS = Object.freeze([
9099
9162
  "findMany",
9163
+ "findPage",
9100
9164
  "findFirst",
9101
9165
  "findFirstOrThrow",
9102
9166
  "findUnique",
@@ -9124,6 +9188,42 @@ var DELEGATE_METHOD_ACCESS = Object.freeze(Object.fromEntries([
9124
9188
  function delegateMethodAccess(params) {
9125
9189
  return Object.hasOwn(DELEGATE_METHOD_ACCESS, params.method) ? DELEGATE_METHOD_ACCESS[params.method] : undefined;
9126
9190
  }
9191
+ function createDelegateMethodClassifier(params) {
9192
+ const context = contexts.get(params.db);
9193
+ if (context === undefined)
9194
+ throw new VibeError26({
9195
+ code: "VIBE_CONFIG",
9196
+ message: "Configured classification requires a registered VibeORM client handle",
9197
+ meta: { reason: "delegate-classifier-handle" }
9198
+ });
9199
+ context.assertActive?.();
9200
+ return ({ method, model }) => {
9201
+ context.assertActive?.();
9202
+ const target = model === undefined ? undefined : context.meta.models.find((entry) => entry.name === model || entry.clientName === model);
9203
+ if (model !== undefined && target === undefined)
9204
+ return;
9205
+ const core = delegateMethodAccess({ method });
9206
+ if (core !== undefined)
9207
+ return core;
9208
+ const parts = method.split(".");
9209
+ if (parts.length > 2)
9210
+ return;
9211
+ const [property, member] = parts;
9212
+ const mount = context.mounts.find((entry) => entry.property === property && (target === undefined ? entry.scope === "client" : entry.scope === "model" && entry.model === target.name));
9213
+ if (mount === undefined || mount.readOnly === undefined)
9214
+ return;
9215
+ const root = params.db;
9216
+ const owner = target === undefined ? root : root.$models?.[target.name];
9217
+ if (typeof owner !== "object" || owner === null || property === undefined)
9218
+ return;
9219
+ const value = owner[property];
9220
+ if (mount.readOnly === true)
9221
+ return member === undefined && typeof value === "function" ? "read" : undefined;
9222
+ if (member === undefined || !mount.readOnly.includes(member) || typeof value !== "object" || value === null)
9223
+ return;
9224
+ return typeof value[member] === "function" ? "read" : undefined;
9225
+ };
9226
+ }
9127
9227
  var CLIENT_MEMBER_ACCESS = Object.freeze({
9128
9228
  $models: "rebuilt",
9129
9229
  $on: "forwarded",
@@ -9323,8 +9423,11 @@ function readOnlyOver(params) {
9323
9423
  const existing = facades.get(params.client);
9324
9424
  if (existing !== undefined)
9325
9425
  return existing;
9326
- const built = buildReadOnly(params);
9426
+ const context = contexts.get(params.client) ?? params.context;
9427
+ const built = buildReadOnly({ client: params.client, context });
9327
9428
  inheritReadOnlyModuleBinder({ from: params.client, to: built });
9429
+ inheritTransactionObservation({ from: params.client, to: built });
9430
+ contexts.set(built, context);
9328
9431
  facades.set(params.client, built);
9329
9432
  return built;
9330
9433
  }
@@ -9332,7 +9435,8 @@ function attachReadOnly(params) {
9332
9435
  const context = {
9333
9436
  meta: params.meta,
9334
9437
  mounts: params.mounts ?? [],
9335
- operations: params.operations
9438
+ operations: params.operations,
9439
+ ...params.assertActive === undefined ? {} : { assertActive: params.assertActive }
9336
9440
  };
9337
9441
  contexts.set(params.client, context);
9338
9442
  Object.defineProperty(params.client, "$readOnly", {
@@ -9346,6 +9450,7 @@ function inheritReadOnly(params) {
9346
9450
  if (context === undefined)
9347
9451
  return;
9348
9452
  contexts.set(params.to, context);
9453
+ inheritTransactionObservation({ from: params.from, to: params.to });
9349
9454
  Object.defineProperty(params.to, "$readOnly", {
9350
9455
  value: () => readOnlyOver({ client: params.to, context }),
9351
9456
  enumerable: true,
@@ -9355,7 +9460,7 @@ function inheritReadOnly(params) {
9355
9460
 
9356
9461
  // packages/runtime/src/policy.ts
9357
9462
  function policyError(message, meta) {
9358
- return new VibeError24({ code: "VIBE_VALIDATION", message, meta: meta ?? {} });
9463
+ return new VibeError27({ code: "VIBE_VALIDATION", message, meta: meta ?? {} });
9359
9464
  }
9360
9465
  function policiedModels(meta) {
9361
9466
  return meta.models.filter((model) => model.policy !== undefined);
@@ -9705,9 +9810,10 @@ function scopedDelegate(params) {
9705
9810
  const pkWhere = pk.length === 1 ? { [pk[0]]: target[pk[0]] } : { [pkClientKey()]: Object.fromEntries(pk.map((name) => [name, target[name]])) };
9706
9811
  return write(raw, pkWhere);
9707
9812
  };
9708
- const notFound = (method) => new VibeError24({ code: "VIBE_NOT_FOUND", message: `${method} on ${model.name}: no row matches the unique where inside the bound policy context`, meta: { model: model.name, method } });
9813
+ const notFound = (method) => new VibeError27({ code: "VIBE_NOT_FOUND", message: `${method} on ${model.name}: no row matches the unique where inside the bound policy context`, meta: { model: model.name, method } });
9709
9814
  return {
9710
9815
  findMany: (args) => base.findMany(scopeFind(args)),
9816
+ findPage: (args) => base.findPage(scopeFind(args)),
9711
9817
  findFirst: (args) => base.findFirst(scopeFind(args)),
9712
9818
  findFirstOrThrow: (args) => base.findFirstOrThrow(scopeFind(args)),
9713
9819
  findUnique: (args) => base.findFirst(scopeUnique(args)),
@@ -9739,7 +9845,7 @@ function scopedDelegate(params) {
9739
9845
  })
9740
9846
  })),
9741
9847
  upsertMany: () => {
9742
- throw new VibeError24({
9848
+ throw new VibeError27({
9743
9849
  code: "VIBE_UNSUPPORTED_CAPABILITY",
9744
9850
  message: "upsertMany is not available on a policy-bound client: its conflict target is not policy-checked yet",
9745
9851
  meta: { model: model.name }
@@ -9748,7 +9854,7 @@ function scopedDelegate(params) {
9748
9854
  updateManyAndReturn: (args) => deferred(() => {
9749
9855
  const run = base.updateManyAndReturn;
9750
9856
  if (run === undefined) {
9751
- throw new VibeError24({
9857
+ throw new VibeError27({
9752
9858
  code: "VIBE_UNSUPPORTED_CAPABILITY",
9753
9859
  message: "updateManyAndReturn is not available on this delegate",
9754
9860
  meta: { model: model.name }
@@ -9807,6 +9913,7 @@ function globalDelegate(params) {
9807
9913
  const payload = (value, phase) => forceWriteData({ meta, model, data: value ?? {}, context, phase });
9808
9914
  const overrides = {
9809
9915
  findMany: (args) => base.findMany(readArgs(args)),
9916
+ findPage: (args) => base.findPage(readArgs(args)),
9810
9917
  findFirst: (args) => base.findFirst(readArgs(args)),
9811
9918
  findFirstOrThrow: (args) => base.findFirstOrThrow(readArgs(args)),
9812
9919
  findUnique: (args) => base.findUnique(readArgs(args)),
@@ -9822,7 +9929,7 @@ function globalDelegate(params) {
9822
9929
  updateManyAndReturn: (args) => deferred(() => {
9823
9930
  const run = base.updateManyAndReturn;
9824
9931
  if (run === undefined) {
9825
- throw new VibeError24({
9932
+ throw new VibeError27({
9826
9933
  code: "VIBE_UNSUPPORTED_CAPABILITY",
9827
9934
  message: "updateManyAndReturn is not available on this delegate"
9828
9935
  });
@@ -9833,7 +9940,7 @@ function globalDelegate(params) {
9833
9940
  upsertMany: (args) => deferred(() => {
9834
9941
  if (params.policyBound === false)
9835
9942
  return base.upsertMany(args);
9836
- throw new VibeError24({
9943
+ throw new VibeError27({
9837
9944
  code: "VIBE_UNSUPPORTED_CAPABILITY",
9838
9945
  message: "upsertMany is not available on a policy-bound client: its conflict target is not policy-checked yet"
9839
9946
  });
@@ -10004,7 +10111,7 @@ function attachPolicy(params) {
10004
10111
  });
10005
10112
  }
10006
10113
  // packages/runtime/src/scoped.ts
10007
- import { ScopedQueryError, VibeError as VibeError25 } from "@vibeorm/schema";
10114
+ import { ScopedQueryError, VibeError as VibeError28 } from "@vibeorm/schema";
10008
10115
  function refusal(params) {
10009
10116
  return new ScopedQueryError(params);
10010
10117
  }
@@ -10728,7 +10835,7 @@ function createScopeRewriter(params) {
10728
10835
  })
10729
10836
  };
10730
10837
  }
10731
- var FIND_LIKE = ["findMany", "findFirst", "findFirstOrThrow", "count", "aggregate", "groupBy"];
10838
+ var FIND_LIKE = ["findPage", "findMany", "findFirst", "findFirstOrThrow", "count", "aggregate", "groupBy"];
10732
10839
  function rewriteScopedCall(params) {
10733
10840
  const { meta, resolved, scope, preds, method } = params;
10734
10841
  const ctx = { meta, resolved, scope, preds };
@@ -10857,6 +10964,7 @@ function scopedDelegate2(params) {
10857
10964
  };
10858
10965
  return {
10859
10966
  findMany: (args) => run("findMany", args),
10967
+ findPage: (args) => run("findPage", args),
10860
10968
  findFirst: (args) => run("findFirst", args),
10861
10969
  findFirstOrThrow: (args) => run("findFirstOrThrow", args),
10862
10970
  findUnique: (args) => run("findUnique", args),
@@ -10960,7 +11068,7 @@ function attachScoped(params) {
10960
11068
  Object.defineProperty(client, "$scoped", {
10961
11069
  value: (config) => {
10962
11070
  if (!isPlainObject8(config) || !isPlainObject8(config.models)) {
10963
- throw new VibeError25({
11071
+ throw new VibeError28({
10964
11072
  code: "VIBE_VALIDATION",
10965
11073
  message: "$scoped takes { scope: string | number | bigint | null, models: { <Model>: \u2026 } }"
10966
11074
  });
@@ -10976,7 +11084,7 @@ function attachScoped(params) {
10976
11084
  }
10977
11085
  const scope = config.scope;
10978
11086
  if (scope !== null && typeof scope !== "string" && typeof scope !== "number" && typeof scope !== "bigint") {
10979
- throw new VibeError25({
11087
+ throw new VibeError28({
10980
11088
  code: "VIBE_VALIDATION",
10981
11089
  message: `$scoped: scope must be a string, number, bigint or null \u2014 got ${typeof scope}`
10982
11090
  });
@@ -10992,7 +11100,7 @@ function attachScoped(params) {
10992
11100
  });
10993
11101
  }
10994
11102
  // packages/runtime/src/rls-readiness.ts
10995
- import { VibeError as VibeError26, assertValidSchemaIR, unsupportedCapability as unsupportedCapability7 } from "@vibeorm/schema";
11103
+ import { VibeError as VibeError29, assertValidSchemaIR, unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
10996
11104
  import { NATIVE_RLS as NATIVE_RLS2, getSqlDialect as getSqlDialect4, renderRlsPolicy, renderRlsRole, NATIVE_RLS_PROBE_POLICY, renderRlsReadinessQuery, renderRlsProbeTable } from "@vibeorm/sql";
10997
11105
  import { RLS_READINESS_SQL, NATIVE_RLS_PROBE_POLICY as NATIVE_RLS_PROBE_POLICY2 } from "@vibeorm/sql";
10998
11106
  function textOf(params) {
@@ -11016,7 +11124,7 @@ function intOf(params) {
11016
11124
  return Number.parseInt(value, 10);
11017
11125
  }
11018
11126
  function unreadableCatalog(params) {
11019
- return new VibeError26({
11127
+ return new VibeError29({
11020
11128
  code: "VIBE_ADAPTER",
11021
11129
  message: `native RLS readiness could not read the "${params.key}" result of the folded catalog read: ${params.detail}. ` + "The inspection is refused rather than treated as an empty result set.",
11022
11130
  meta: { result: params.key }
@@ -11072,10 +11180,10 @@ function unprotectedTablesOf(params) {
11072
11180
  function requireNativeRls(params) {
11073
11181
  const dialect = getSqlDialect4({ dialect: params.adapter.dialect });
11074
11182
  if (!dialect.capabilities.nativeRowLevelSecurity) {
11075
- throw unsupportedCapability7({ dialect: dialect.name, feature: "nativeRowLevelSecurity" });
11183
+ throw unsupportedCapability8({ dialect: dialect.name, feature: "nativeRowLevelSecurity" });
11076
11184
  }
11077
11185
  if (params.schema.rls === undefined) {
11078
- throw new VibeError26({
11186
+ throw new VibeError29({
11079
11187
  code: "VIBE_CONFIG",
11080
11188
  message: "Native row-level security readiness requires a schema that declares native RLS"
11081
11189
  });
@@ -11092,24 +11200,27 @@ async function probeExpressions(params) {
11092
11200
  if (tables.length === 0)
11093
11201
  return { available: true, expressions: [] };
11094
11202
  return adapter.transaction(async (tx) => {
11095
- const current = await tx.execute(renderRlsReadinessQuery({ dialect, query: "readSearchPath" }));
11203
+ const current = await tx.execute({ ...renderRlsReadinessQuery({ dialect, query: "readSearchPath" }), effect: "read" });
11096
11204
  const searchPath = current[0] === undefined ? "" : textOf({ row: current[0], key: "searchPath" });
11097
- await tx.execute(renderRlsReadinessQuery({ dialect, query: "setSearchPath", searchPath: "" }));
11205
+ await tx.execute({ ...renderRlsReadinessQuery({ dialect, query: "setSearchPath", searchPath: "" }), effect: "read" });
11098
11206
  for (const entry of params.desired === undefined ? tables : []) {
11099
- await tx.executeUnsafe(renderRlsProbeTable({ dialect, table: entry.table, action: "create" }));
11100
- await tx.executeUnsafe(renderRlsPolicy({
11101
- dialect,
11102
- schema,
11103
- model: entry.model,
11104
- policyName: NATIVE_RLS_PROBE_POLICY,
11105
- targetSchema: "pg_temp"
11106
- }));
11207
+ await tx.executeUnsafe({ ...renderRlsProbeTable({ dialect, table: entry.table, action: "create" }), effect: "read" });
11208
+ await tx.executeUnsafe({
11209
+ ...renderRlsPolicy({
11210
+ dialect,
11211
+ schema,
11212
+ model: entry.model,
11213
+ policyName: NATIVE_RLS_PROBE_POLICY,
11214
+ targetSchema: "pg_temp"
11215
+ }),
11216
+ effect: "read"
11217
+ });
11107
11218
  }
11108
- const rows = await tx.execute(renderRlsReadinessQuery({ dialect, query: "expressions" }));
11219
+ const rows = await tx.execute({ ...renderRlsReadinessQuery({ dialect, query: "expressions" }), effect: "read" });
11109
11220
  for (const entry of params.desired === undefined ? tables : []) {
11110
- await tx.executeUnsafe(renderRlsProbeTable({ dialect, table: entry.table, action: "drop" }));
11221
+ await tx.executeUnsafe({ ...renderRlsProbeTable({ dialect, table: entry.table, action: "drop" }), effect: "read" });
11111
11222
  }
11112
- await tx.execute(renderRlsReadinessQuery({ dialect, query: "setSearchPath", searchPath }));
11223
+ await tx.execute({ ...renderRlsReadinessQuery({ dialect, query: "setSearchPath", searchPath }), effect: "read" });
11113
11224
  return {
11114
11225
  available: true,
11115
11226
  expressions: [...rows.filter((row) => params.desired === undefined || row.probe === false).map((row) => ({
@@ -11366,7 +11477,7 @@ async function inspectNativeRlsTransaction(params) {
11366
11477
  const dialect = requireNativeRls({ adapter, schema });
11367
11478
  const protectedTables = protectedTablesOf({ schema });
11368
11479
  const unprotected = unprotectedTablesOf({ schema });
11369
- const catalogRows = await adapter.execute(renderRlsReadinessQuery({ dialect, query: "catalog" }));
11480
+ const catalogRows = await adapter.execute({ ...renderRlsReadinessQuery({ dialect, query: "catalog" }), effect: "read" });
11370
11481
  const catalog = catalogRows[0] ?? {};
11371
11482
  const identityRow = catalogRowsOf({ row: catalog, key: "identity" })[0] ?? {};
11372
11483
  const identity = {
@@ -11476,7 +11587,7 @@ async function inspectNativeRls(params) {
11476
11587
  const embeddedRole = adapter.provider === "pglite" ? requireEmbeddedRole({ role: params.runtimeRole }) : undefined;
11477
11588
  return adapter.transaction(async (tx) => {
11478
11589
  if (embeddedRole !== undefined) {
11479
- await tx.executeUnsafe(renderRlsRole({ dialect: getSqlDialect4({ dialect: adapter.dialect }), role: embeddedRole }));
11590
+ await tx.executeUnsafe({ ...renderRlsRole({ dialect: getSqlDialect4({ dialect: adapter.dialect }), role: embeddedRole }), effect: "read" });
11480
11591
  }
11481
11592
  return inspectNativeRlsTransaction({
11482
11593
  adapter: tx,
@@ -11488,7 +11599,7 @@ async function inspectNativeRls(params) {
11488
11599
  function requireEmbeddedRole(params) {
11489
11600
  const { role } = params;
11490
11601
  if (typeof role !== "string" || role.length === 0 || role.includes("\x00")) {
11491
- throw new VibeError26({
11602
+ throw new VibeError29({
11492
11603
  code: "VIBE_CONFIG",
11493
11604
  message: "PGlite native row-level security requires a pre-existing restricted runtime role (nativeRls.runtimeRole) \u2014 its default embedded session is privileged and bypasses every policy",
11494
11605
  meta: { provider: "pglite" }
@@ -11500,7 +11611,7 @@ function assertNativeRlsReady(params) {
11500
11611
  const { report } = params;
11501
11612
  if (report.ready)
11502
11613
  return;
11503
- throw new VibeError26({
11614
+ throw new VibeError29({
11504
11615
  code: "VIBE_CONFIG",
11505
11616
  message: `Native row-level security is not ready on this database: ${report.problems.map((problem) => `${problem.name} (${problem.status})`).join(", ")}`,
11506
11617
  meta: {
@@ -11525,17 +11636,114 @@ function formatNativeRlsReport(params) {
11525
11636
  return lines;
11526
11637
  }
11527
11638
  // packages/runtime/src/database-module.ts
11528
- import { createHash } from "crypto";
11529
- import { VibeError as VibeError31, assertValidSchemaIR as assertValidSchemaIR3, providerToDialect } from "@vibeorm/schema";
11639
+ import { createHash as createHash2 } from "crypto";
11640
+ import { VibeError as VibeError35, assertValidSchemaIR as assertValidSchemaIR3, prepareDatabaseModuleSchema, providerToDialect } from "@vibeorm/schema";
11641
+
11642
+ // packages/runtime/src/client.ts
11643
+ import { AsyncLocalStorage } from "async_hooks";
11644
+
11645
+ // packages/runtime/src/find-page.ts
11646
+ import { VibeError as VibeError30 } from "@vibeorm/schema";
11647
+
11648
+ // packages/runtime/src/keyset-projection.ts
11649
+ function keysetProjection(params) {
11650
+ const { plan, select, omit } = params;
11651
+ const names = plan.keys.map((key) => key.field.name);
11652
+ if (select !== undefined) {
11653
+ const hidden = names.filter((name) => select[name] !== true);
11654
+ if (hidden.length === 0)
11655
+ return { select, hidden };
11656
+ const widened = { ...select };
11657
+ for (const name of hidden)
11658
+ widened[name] = true;
11659
+ return { select: widened, hidden };
11660
+ }
11661
+ if (omit !== undefined) {
11662
+ const hidden = names.filter((name) => omit[name] === true);
11663
+ if (hidden.length === 0)
11664
+ return { omit, hidden };
11665
+ const narrowed = { ...omit };
11666
+ for (const name of hidden)
11667
+ narrowed[name] = false;
11668
+ return { omit: narrowed, hidden };
11669
+ }
11670
+ return { hidden: [] };
11671
+ }
11672
+
11673
+ // packages/runtime/src/find-page.ts
11674
+ var PAGE_ARGUMENTS = new Set([
11675
+ "where",
11676
+ "orderBy",
11677
+ "take",
11678
+ "after",
11679
+ "select",
11680
+ "include",
11681
+ "omit",
11682
+ "relationStrategy",
11683
+ "keyset"
11684
+ ]);
11685
+ function validatePageArgs(params) {
11686
+ const { model, args } = params;
11687
+ if (typeof args !== "object" || args === null || Array.isArray(args)) {
11688
+ throw new VibeError30({ code: "VIBE_VALIDATION", message: `${model}.findPage requires an argument object`, meta: { model, reason: "keyset-page-args" } });
11689
+ }
11690
+ for (const key of Object.keys(args)) {
11691
+ if (!PAGE_ARGUMENTS.has(key)) {
11692
+ throw new VibeError30({ code: "VIBE_VALIDATION", message: `${model}.findPage does not accept ${key}`, meta: { model, argument: key, reason: "keyset-page-argument" } });
11693
+ }
11694
+ }
11695
+ const take = "take" in args ? args.take : undefined;
11696
+ if (typeof take !== "number" || !Number.isSafeInteger(take) || take < 1 || take > KEYSET_MAX_PAGE_SIZE) {
11697
+ throw new VibeError30({ code: "VIBE_VALIDATION", message: `findPage take must be an integer between 1 and ${KEYSET_MAX_PAGE_SIZE}`, meta: { model, reason: "keyset-page-size" } });
11698
+ }
11699
+ return args;
11700
+ }
11701
+ function preparePage(params) {
11702
+ const { meta, model, dialect, args } = params;
11703
+ const plan = compileKeysetOrderPlan({
11704
+ model,
11705
+ dialect,
11706
+ terms: compileKeysetOrderInputs({ meta, model, dialect, orderBy: args.orderBy }),
11707
+ ...parseKeysetOptions({ model, value: args.keyset })
11708
+ });
11709
+ const projection = keysetProjection({
11710
+ plan,
11711
+ select: args.select,
11712
+ omit: args.omit
11713
+ });
11714
+ return {
11715
+ plan,
11716
+ args: {
11717
+ ...args,
11718
+ take: args.take + 1,
11719
+ ...projection.select === undefined ? {} : { select: projection.select },
11720
+ ...projection.omit === undefined ? {} : { omit: projection.omit }
11721
+ }
11722
+ };
11723
+ }
11724
+ function pageContinuation(params) {
11725
+ const { plan, rows, take, after } = params;
11726
+ const first = rows[0];
11727
+ if (typeof after === "string" && first !== undefined && keysetRowIsAfter({
11728
+ keys: plan.keys,
11729
+ row: keysetRowValues({ plan, row: first }),
11730
+ position: decodeKeysetToken({ plan, token: after })
11731
+ }) === false) {
11732
+ throw new VibeError30({ code: "VIBE_DATA_INVALID", message: `keyset page for ${plan.model} is not advancing; check ordering precision`, meta: { model: plan.model, reason: "keyset-position-not-advancing" } });
11733
+ }
11734
+ const last = rows[take - 1];
11735
+ return rows.length > take && last !== undefined ? encodeKeysetToken({ plan, row: last }) : null;
11736
+ }
11530
11737
 
11531
11738
  // packages/runtime/src/client.ts
11532
11739
  import { compileSql } from "@vibeorm/sql";
11533
- import { RlsContextError as RlsContextError2, VibeError as VibeError30, assertValidSchemaIR as assertValidSchemaIR2, unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
11740
+ import { RlsContextError as RlsContextError2, VibeError as VibeError34, assertValidSchemaIR as assertValidSchemaIR2, unsupportedCapability as unsupportedCapability9 } from "@vibeorm/schema";
11534
11741
  import { ADVISORY_LOCK_RESULT_COLUMN, ParamCollector, getSqlDialect as getSqlDialect5, renderRlsContext, renderRlsPolicy as renderRlsPolicy2, renderRlsRole as renderRlsRole2, renderStatement as renderStatement5 } from "@vibeorm/sql";
11535
11742
 
11536
11743
  // packages/runtime/src/render-cache.ts
11537
11744
  import {
11538
11745
  isSqlFragment as isSqlFragment3,
11746
+ isNativeEnumArrayParameter,
11539
11747
  isDbNowMarker,
11540
11748
  isJsonParamCell,
11541
11749
  isListSetOperation,
@@ -11587,7 +11795,22 @@ function addCol(walk, column) {
11587
11795
  addIdent(walk, column.alias);
11588
11796
  }
11589
11797
  }
11798
+ function addParameter(walk, value) {
11799
+ if (isNativeEnumArrayParameter(value)) {
11800
+ walk.key += "enumArray";
11801
+ addIdent(walk, value.type.namespace);
11802
+ addIdent(walk, value.type.name);
11803
+ walk.values.push(value.value);
11804
+ return;
11805
+ }
11806
+ walk.key += "param";
11807
+ walk.values.push(value);
11808
+ }
11590
11809
  function addTable(walk, table) {
11810
+ if (table.namespace !== undefined) {
11811
+ walk.key += "namespace";
11812
+ addIdent(walk, table.namespace);
11813
+ }
11591
11814
  addIdent(walk, table.name);
11592
11815
  if (table.alias !== undefined) {
11593
11816
  walk.key += "@";
@@ -11609,7 +11832,7 @@ function addSetEntry(walk, name, value) {
11609
11832
  if (isSetOperation(value)) {
11610
11833
  walk.key += `=o${value.__op}`;
11611
11834
  addIdent(walk, name);
11612
- walk.values.push(value.value);
11835
+ addParameter(walk, value.value);
11613
11836
  return;
11614
11837
  }
11615
11838
  if (isDbNowMarker(value)) {
@@ -11622,12 +11845,12 @@ function addSetEntry(walk, name, value) {
11622
11845
  if (isListSetOperation(value)) {
11623
11846
  walk.key += `=l${value.__listOp}`;
11624
11847
  addIdent(walk, name);
11625
- walk.values.push(value.value);
11848
+ addParameter(walk, value.value);
11626
11849
  return;
11627
11850
  }
11628
11851
  walk.key += "=v";
11629
11852
  addIdent(walk, name);
11630
- walk.values.push(value);
11853
+ addParameter(walk, value);
11631
11854
  }
11632
11855
  function addReturning(walk, returning) {
11633
11856
  if (returning === undefined || returning.length === 0) {
@@ -11651,7 +11874,7 @@ function walkExpr(walk, dialect, expr) {
11651
11874
  }
11652
11875
  walk.key += `c${expr.op}`;
11653
11876
  addCol(walk, expr.column);
11654
- walk.values.push(expr.value);
11877
+ addParameter(walk, expr.value);
11655
11878
  return true;
11656
11879
  case "cmpCol":
11657
11880
  walk.key += `k${expr.op}`;
@@ -11670,7 +11893,7 @@ function walkExpr(walk, dialect, expr) {
11670
11893
  walk.key += expr.negate === true ? "i1" : "i0";
11671
11894
  addCol(walk, expr.column);
11672
11895
  if (dialect.inArrayStrategy === "any") {
11673
- walk.values.push([...expr.values]);
11896
+ addParameter(walk, Array.isArray(expr.values) ? [...expr.values] : expr.values);
11674
11897
  } else {
11675
11898
  walk.key += `#${expr.values.length}`;
11676
11899
  for (const value of expr.values)
@@ -11730,22 +11953,22 @@ function walkExpr(walk, dialect, expr) {
11730
11953
  case "aggCmp":
11731
11954
  walk.key += `g${expr.op}`;
11732
11955
  addAgg(walk, expr.agg);
11733
- walk.values.push(expr.value);
11956
+ addParameter(walk, expr.value);
11734
11957
  return true;
11735
11958
  case "arrayHas":
11736
11959
  walk.key += expr.negate === true ? "h1" : "h0";
11737
11960
  addCol(walk, expr.column);
11738
- walk.values.push(expr.value);
11961
+ addParameter(walk, expr.value);
11739
11962
  return true;
11740
11963
  case "arrayContainsAll":
11741
11964
  walk.key += "H";
11742
11965
  addCol(walk, expr.column);
11743
- walk.values.push([...expr.values]);
11966
+ addParameter(walk, Array.isArray(expr.values) ? [...expr.values] : expr.values);
11744
11967
  return true;
11745
11968
  case "arrayOverlaps":
11746
11969
  walk.key += "V";
11747
11970
  addCol(walk, expr.column);
11748
- walk.values.push([...expr.values]);
11971
+ addParameter(walk, Array.isArray(expr.values) ? [...expr.values] : expr.values);
11749
11972
  return true;
11750
11973
  case "arrayIsEmpty":
11751
11974
  walk.key += expr.empty ? "e1" : "e0";
@@ -12041,11 +12264,11 @@ function renderStatementCached(params) {
12041
12264
  }
12042
12265
 
12043
12266
  // packages/runtime/src/strict-args.ts
12044
- import { VibeError as VibeError27 } from "@vibeorm/schema";
12267
+ import { VibeError as VibeError31 } from "@vibeorm/schema";
12045
12268
  var SKIP = Symbol.for("vibeorm.skip");
12046
12269
  function explicitUndefined(params) {
12047
12270
  const { model, method, path } = params;
12048
- return new VibeError27({
12271
+ return new VibeError31({
12049
12272
  code: "VIBE_VALIDATION",
12050
12273
  message: `${model}.${method}(): explicit undefined at ${path} \u2014 an undefined value is refused ` + `because it would silently drop the property (widening a filter or losing a write). ` + `Omit the property, or pass SKIP to omit it deliberately; ` + `VibeClient({ strictArguments: false }) restores the legacy behaviour.`,
12051
12274
  meta: { model, method, path }
@@ -12251,10 +12474,10 @@ function bindRlsContext(params) {
12251
12474
  }
12252
12475
 
12253
12476
  // packages/runtime/src/telemetry/recorder.ts
12254
- import { VibeError as VibeError29 } from "@vibeorm/schema";
12477
+ import { VibeError as VibeError33 } from "@vibeorm/schema";
12255
12478
 
12256
12479
  // packages/runtime/src/telemetry/config.ts
12257
- import { VibeError as VibeError28 } from "@vibeorm/schema";
12480
+ import { VibeError as VibeError32 } from "@vibeorm/schema";
12258
12481
  var TELEMETRY_DEFAULTS = Object.freeze({
12259
12482
  captureSql: false,
12260
12483
  captureParameterValues: false,
@@ -12269,7 +12492,7 @@ var TELEMETRY_DEFAULTS = Object.freeze({
12269
12492
  latencyBucketsMs: Object.freeze([1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000])
12270
12493
  });
12271
12494
  function configError2(params) {
12272
- return new VibeError28({
12495
+ return new VibeError32({
12273
12496
  code: "VIBE_CONFIG",
12274
12497
  message: `telemetry: ${params.message}`,
12275
12498
  ...params.meta === undefined ? {} : { meta: params.meta }
@@ -12357,7 +12580,7 @@ function deriveStage(params) {
12357
12580
  return "decode";
12358
12581
  }
12359
12582
  function errorCodeOf(error) {
12360
- return error instanceof VibeError29 ? error.code : undefined;
12583
+ return error instanceof VibeError33 ? error.code : undefined;
12361
12584
  }
12362
12585
  function newHistogram(bounds) {
12363
12586
  return { counts: new Array(bounds.length + 1).fill(0), sum: 0, count: 0 };
@@ -12740,7 +12963,7 @@ async function instrumentStatement(params) {
12740
12963
  // packages/runtime/src/client.ts
12741
12964
  function notFound2(params) {
12742
12965
  const { model, method } = params;
12743
- return new VibeError30({
12966
+ return new VibeError34({
12744
12967
  code: "VIBE_NOT_FOUND",
12745
12968
  message: `no ${model} record matched the where clause of ${method}()`,
12746
12969
  meta: { model, method }
@@ -12748,7 +12971,7 @@ function notFound2(params) {
12748
12971
  }
12749
12972
  function transactionLifecycleRefusal(params) {
12750
12973
  const { method } = params;
12751
- return new VibeError30({
12974
+ return new VibeError34({
12752
12975
  code: "VIBE_VALIDATION",
12753
12976
  message: `${method}() is not available on a transaction client \u2014 the connection is owned by the open transaction; call it on the client that started the transaction`,
12754
12977
  meta: { method, inTransaction: true }
@@ -12756,7 +12979,7 @@ function transactionLifecycleRefusal(params) {
12756
12979
  }
12757
12980
  function viewIsReadOnly(params) {
12758
12981
  const { model, method } = params;
12759
- return new VibeError30({
12982
+ return new VibeError34({
12760
12983
  code: "VIBE_VALIDATION",
12761
12984
  message: `${model} is a view \u2014 ${method}() is not available on views (they are read-only); write to the underlying table instead`,
12762
12985
  meta: { model, method }
@@ -12863,7 +13086,7 @@ async function engineTransaction(params) {
12863
13086
  const support = engine.adapter.budgets?.transactionDeadline;
12864
13087
  const requested = options.deadline.enforcement ?? "between-statements";
12865
13088
  if (support === undefined || support === "unsupported" || requested === "cancel-running-statements" && support !== "cancel-running-statements") {
12866
- throw new VibeError30({
13089
+ throw new VibeError34({
12867
13090
  code: "VIBE_UNSUPPORTED_CAPABILITY",
12868
13091
  message: "the adapter does not declare support for the requested transaction deadline",
12869
13092
  meta: { provider: engine.adapter.provider, feature: "transactionDeadline", requested, supported: support ?? "undeclared" }
@@ -12876,10 +13099,10 @@ async function engineTransaction(params) {
12876
13099
  const execute = async () => {
12877
13100
  if (engine.rlsSchema !== undefined && engine.inTransaction !== true) {
12878
13101
  if (adapter.provider === "pglite") {
12879
- await adapter.executeUnsafe(renderRlsRole2({ dialect: engine.dialect, role: engine.options.nativeRls.runtimeRole }));
13102
+ await adapter.executeUnsafe({ ...renderRlsRole2({ dialect: engine.dialect, role: engine.options.nativeRls.runtimeRole }), effect: "read" });
12880
13103
  }
12881
13104
  if (engine.context !== undefined && Object.keys(engine.rlsSchema.rls.context).length > 0) {
12882
- await adapter.executeUnsafe(renderRlsContext({ dialect: engine.dialect, context: engine.rlsSchema.rls.context, values: engine.context.settings }));
13105
+ await adapter.executeUnsafe({ ...renderRlsContext({ dialect: engine.dialect, context: engine.rlsSchema.rls.context, values: engine.context.settings }), effect: "read" });
12883
13106
  }
12884
13107
  const readiness = await inspectNativeRlsTransaction({ adapter, schema: engine.rlsSchema, runtimeRole: engine.options.nativeRls?.runtimeRole, cacheKey: engine.rootIdentity });
12885
13108
  assertNativeRlsReady({ report: readiness });
@@ -13052,7 +13275,7 @@ class QueryPromise extends Promise {
13052
13275
  }
13053
13276
  #claim() {
13054
13277
  if (this.#started) {
13055
- throw new VibeError30({
13278
+ throw new VibeError34({
13056
13279
  code: "VIBE_VALIDATION",
13057
13280
  message: "$transaction([...]) needs operations that have not dispatched \u2014 pass delegate calls in the same tick they are created (this one was awaited or created earlier and already executed outside the transaction)"
13058
13281
  });
@@ -13097,6 +13320,21 @@ var LAZY_OPERATIONS = {
13097
13320
  refuseQueryPromise({ value: params.value, reason: params.reason });
13098
13321
  }
13099
13322
  };
13323
+ function statementEffect(params) {
13324
+ if (params.adapter.rowChanges === undefined)
13325
+ return;
13326
+ const { statement, dialect } = params;
13327
+ if (containsSqlFragment(statement))
13328
+ return "unknown";
13329
+ if (statement.kind === "select" || statement.kind === "advisoryLock" || statement.kind === "rlsContext" || statement.kind === "rlsRole")
13330
+ return "read";
13331
+ if (statement.kind === "insert") {
13332
+ if (dialect.upsertForm === "onDuplicateKey" && statement.onConflict !== undefined && !("doNothing" in statement.onConflict))
13333
+ return "unknown";
13334
+ return "write";
13335
+ }
13336
+ return statement.kind === "update" || statement.kind === "delete" ? "write" : "unknown";
13337
+ }
13100
13338
  async function runRows(params) {
13101
13339
  const { engine, plan } = params;
13102
13340
  const renderStarted = renderClock({ engine });
@@ -13116,17 +13354,19 @@ async function runRows(params) {
13116
13354
  rowCount: (value) => value.length,
13117
13355
  run: () => engine.adapter.execute({
13118
13356
  text: rendered.text,
13119
- values: bindValues({ adapter: engine.adapter, values: rendered.values })
13357
+ values: bindValues({ adapter: engine.adapter, values: rendered.values }),
13358
+ effect: statementEffect({ statement: plan.statement, dialect: engine.dialect, adapter: engine.adapter })
13120
13359
  })
13121
13360
  });
13122
13361
  return materializeRows({ dialect: engine.dialect.name, model: plan.model, rows, wire: engine.adapter.wire });
13123
13362
  }
13124
13363
  async function runBoundAffected(params) {
13125
- const { adapter, text, values } = params;
13364
+ const { adapter, text, values, effect } = params;
13365
+ const input = { text, values, ...effect === undefined ? {} : { effect } };
13126
13366
  const bound = adapter.executeAffected;
13127
13367
  if (bound !== undefined)
13128
- return await bound.call(adapter, { text, values });
13129
- return await adapter.executeUnsafe({ text, values });
13368
+ return await bound.call(adapter, input);
13369
+ return await adapter.executeUnsafe(input);
13130
13370
  }
13131
13371
  async function runAffected(params) {
13132
13372
  const { engine, plan } = params;
@@ -13159,7 +13399,8 @@ async function runAffected(params) {
13159
13399
  run: () => runBoundAffected({
13160
13400
  adapter: engine.adapter,
13161
13401
  text: rendered.text,
13162
- values: bindValues({ adapter: engine.adapter, values: rendered.values })
13402
+ values: bindValues({ adapter: engine.adapter, values: rendered.values }),
13403
+ effect: statementEffect({ statement: plan.statement, dialect: engine.dialect, adapter: engine.adapter })
13163
13404
  })
13164
13405
  });
13165
13406
  return result.affectedRows;
@@ -13170,14 +13411,14 @@ function plan(params) {
13170
13411
  const args = engine.readOnlySql === true ? restrictedSqlArgs({ value: params.args, path: "$readOnly", refusal: () => readOnlyRefusal({ path: `${model}.${method}`, reason: "raw" }) }) : params.args;
13171
13412
  if (args !== undefined && args["lock"] !== undefined) {
13172
13413
  if (engine.inTransaction !== true) {
13173
- throw new VibeError30({
13414
+ throw new VibeError34({
13174
13415
  code: "VIBE_VALIDATION",
13175
13416
  message: `lock on ${model}.${method}() requires a transaction \u2014 call it on the client $transaction hands its callback (outside one, the lock would release at statement end)`,
13176
13417
  meta: { model, method }
13177
13418
  });
13178
13419
  }
13179
13420
  if (!LOCKABLE_METHODS.includes(method)) {
13180
- throw new VibeError30({
13421
+ throw new VibeError34({
13181
13422
  code: "VIBE_VALIDATION",
13182
13423
  message: `lock on ${model}.${method}() is not supported \u2014 only ${LOCKABLE_METHODS.join(", ")} take a lock. ` + `Lock the rows with a find inside the transaction, then write them`,
13183
13424
  meta: { model, method }
@@ -13204,7 +13445,7 @@ function readAcquiredVerdict(params) {
13204
13445
  return true;
13205
13446
  if (value === false || value === 0 || value === "f" || value === "false" || value === "0")
13206
13447
  return false;
13207
- throw new VibeError30({
13448
+ throw new VibeError34({
13208
13449
  code: "VIBE_INTERNAL",
13209
13450
  message: `internal: ${params.method}() expected a boolean "${ADVISORY_LOCK_RESULT_COLUMN}" column, got ${String(value)}`,
13210
13451
  meta: { method: params.method, value: String(value) }
@@ -13246,7 +13487,7 @@ async function insertedKeyWhere(params) {
13246
13487
  const keyField = source.model.primaryKey[0];
13247
13488
  const lastInsertIdSql = engine.dialect.lastInsertIdSql;
13248
13489
  if (lastInsertIdSql === null || source.model.primaryKey.length !== 1 || keyField === undefined) {
13249
- throw unsupportedCapability8({
13490
+ throw unsupportedCapability9({
13250
13491
  dialect: engine.dialect.name,
13251
13492
  feature: `${source.method} on ${source.model.name} without RETURNING`,
13252
13493
  hint: "this model's key is assigned by the database and cannot be read back on this dialect"
@@ -13264,11 +13505,11 @@ async function insertedKeyWhere(params) {
13264
13505
  text: lastInsertIdSql,
13265
13506
  values: [],
13266
13507
  rowCount: (value) => value.rows.length,
13267
- run: () => engine.adapter.executeUnsafe({ text: lastInsertIdSql })
13508
+ run: () => engine.adapter.executeUnsafe({ text: lastInsertIdSql, effect: "read" })
13268
13509
  });
13269
13510
  const id = result.rows[0]?.id;
13270
13511
  if (id === undefined || id === null) {
13271
- throw new VibeError30({
13512
+ throw new VibeError34({
13272
13513
  code: "VIBE_INTERNAL",
13273
13514
  message: `could not read back the generated key for ${source.model.name}`,
13274
13515
  meta: { model: source.model.name }
@@ -13303,7 +13544,8 @@ async function runSingleMutation(params) {
13303
13544
  run: () => runBoundAffected({
13304
13545
  adapter: target.adapter,
13305
13546
  text: rendered.text,
13306
- values: bindValues({ adapter: target.adapter, values: rendered.values })
13547
+ values: bindValues({ adapter: target.adapter, values: rendered.values }),
13548
+ effect: statementEffect({ statement, dialect: target.dialect, adapter: target.adapter })
13307
13549
  })
13308
13550
  });
13309
13551
  return result;
@@ -13439,7 +13681,8 @@ function relationExecutor(params) {
13439
13681
  rowCount: (value) => value.length,
13440
13682
  run: () => engine.adapter.execute({
13441
13683
  text: rendered.text,
13442
- values: bindValues({ adapter: engine.adapter, values: rendered.values })
13684
+ values: bindValues({ adapter: engine.adapter, values: rendered.values }),
13685
+ effect: statementEffect({ statement, dialect: engine.dialect, adapter: engine.adapter })
13443
13686
  })
13444
13687
  });
13445
13688
  };
@@ -13521,7 +13764,8 @@ function makeRunner(params) {
13521
13764
  rowCount: (value) => value.length,
13522
13765
  run: () => engine.adapter.execute({
13523
13766
  text: rendered.text,
13524
- values: bindValues({ adapter: engine.adapter, values: rendered.values })
13767
+ values: bindValues({ adapter: engine.adapter, values: rendered.values }),
13768
+ effect: statementEffect({ statement, dialect: engine.dialect, adapter: engine.adapter })
13525
13769
  })
13526
13770
  });
13527
13771
  }
@@ -13575,6 +13819,16 @@ function createDelegate(params) {
13575
13819
  const rows = shapeRows({ plan: built, rows: await runRows({ engine: target, plan: built }) });
13576
13820
  return await finalizeRows({ engine: target, model: built.model, shape: shapeOf(built), rows });
13577
13821
  };
13822
+ const findPage = async (target, input) => {
13823
+ const args = validatePageArgs({ model, args: input });
13824
+ const original = plan({ engine: target, model, method: "findMany", args });
13825
+ const page = preparePage({ meta: target.meta, model: original.model, dialect: target.dialect, args });
13826
+ const built = plan({ engine: target, model, method: "findMany", args: page.args });
13827
+ const rows = await runRows({ engine: target, plan: built });
13828
+ const nextCursor = pageContinuation({ plan: page.plan, rows, take: args.take, after: args.after });
13829
+ const items = await finalizeRows({ engine: target, model: built.model, shape: shapeOf(original), rows: rows.slice(0, args.take) });
13830
+ return { items, nextCursor };
13831
+ };
13578
13832
  const findFirst = async (target, args) => {
13579
13833
  const built = plan({ engine: target, model, method: "findFirst", args });
13580
13834
  const rows = shapeRows({ plan: built, rows: await runRows({ engine: target, plan: built }) });
@@ -13596,7 +13850,7 @@ function createDelegate(params) {
13596
13850
  const skipping = args.onConflict !== undefined;
13597
13851
  if (hasNestedWrites({ model: modelMeta, data: args.data })) {
13598
13852
  if (skipping) {
13599
- throw new VibeError30({
13853
+ throw new VibeError34({
13600
13854
  code: "VIBE_VALIDATION",
13601
13855
  message: `onConflict cannot combine with nested writes on ${modelMeta.name}.create() \u2014 insert the parent row alone, then connect relations`,
13602
13856
  meta: { model: modelMeta.name }
@@ -13697,7 +13951,7 @@ function createDelegate(params) {
13697
13951
  const upsert = async (target, args) => {
13698
13952
  const modelMeta = getModelMeta({ meta: target.meta, model });
13699
13953
  if (hasNestedWrites({ model: modelMeta, data: args.create }) || hasNestedWrites({ model: modelMeta, data: args.update })) {
13700
- throw new VibeError30({
13954
+ throw new VibeError34({
13701
13955
  code: "VIBE_VALIDATION",
13702
13956
  message: `nested writes are not supported inside upsert arms on ${modelMeta.name} \u2014 use create()/update() with nested data`,
13703
13957
  meta: { model: modelMeta.name }
@@ -13705,7 +13959,7 @@ function createDelegate(params) {
13705
13959
  }
13706
13960
  if (!upsertUsesNativeStatement({ model: modelMeta, args })) {
13707
13961
  if (args.onConflict !== undefined) {
13708
- throw new VibeError30({
13962
+ throw new VibeError34({
13709
13963
  code: "VIBE_VALIDATION",
13710
13964
  message: `onConflict on ${modelMeta.name}.upsert() needs the native single-statement path \u2014 this shape (a guard field beyond the conflict target, or create data not binding the where's key) runs the find-then-write fallback, which cannot honor an explicit conflict target`,
13711
13965
  meta: { model: modelMeta.name }
@@ -13763,7 +14017,8 @@ function createDelegate(params) {
13763
14017
  rowCount: (value) => value.length,
13764
14018
  run: () => target.adapter.execute({
13765
14019
  text: rendered.text,
13766
- values: bindValues({ adapter: target.adapter, values: rendered.values })
14020
+ values: bindValues({ adapter: target.adapter, values: rendered.values }),
14021
+ effect: statementEffect({ statement: built.statement, dialect: target.dialect, adapter: target.adapter })
13767
14022
  })
13768
14023
  });
13769
14024
  if (built.aggregateSpec !== null) {
@@ -13803,6 +14058,7 @@ function createDelegate(params) {
13803
14058
  const lazy = (method, run) => createQueryPromise({ engine, run, model, method });
13804
14059
  const delegate = {
13805
14060
  findMany: (args) => lazy("findMany", (target) => findMany(target, args)),
14061
+ findPage: (args) => lazy("findPage", (target) => findPage(target, args)),
13806
14062
  findFirst: (args) => lazy("findFirst", (target) => findFirst(target, args)),
13807
14063
  findUnique: (args) => lazy("findUnique", (target) => findUnique(target, args)),
13808
14064
  findFirstOrThrow: (args) => lazy("findFirstOrThrow", async (target) => {
@@ -13954,7 +14210,8 @@ function buildClient(params) {
13954
14210
  run: () => runBoundAffected({
13955
14211
  adapter: target.adapter,
13956
14212
  text: rendered.text,
13957
- values: bindValues({ adapter: target.adapter, values: rendered.values })
14213
+ values: bindValues({ adapter: target.adapter, values: rendered.values }),
14214
+ effect: statementEffect({ statement, dialect: target.dialect, adapter: target.adapter })
13958
14215
  })
13959
14216
  });
13960
14217
  if (scope !== undefined)
@@ -13983,7 +14240,7 @@ function buildClient(params) {
13983
14240
  }
13984
14241
  for (const operation of operations) {
13985
14242
  if (!isQueryPromise(operation)) {
13986
- claimError = new VibeError30({
14243
+ claimError = new VibeError34({
13987
14244
  code: "VIBE_VALIDATION",
13988
14245
  message: "$transaction([...]) takes query promises from model delegate calls \u2014 a foreign promise is already running and cannot join the transaction"
13989
14246
  });
@@ -14048,7 +14305,7 @@ function buildClient(params) {
14048
14305
  $models: models,
14049
14306
  $on: (event, listener) => {
14050
14307
  if (event !== "query") {
14051
- throw new VibeError30({
14308
+ throw new VibeError34({
14052
14309
  code: "VIBE_VALIDATION",
14053
14310
  message: `unknown client event "${String(event)}" \u2014 supported: "query"`,
14054
14311
  meta: { event }
@@ -14063,7 +14320,7 @@ function buildClient(params) {
14063
14320
  $querySql: async ({ query, decoder }) => {
14064
14321
  assertEngineActive({ engine });
14065
14322
  if (decoder === null || typeof decoder !== "object" || typeof decoder.decode !== "function")
14066
- throw new VibeError30({ code: "VIBE_VALIDATION", message: "$querySql requires an explicit result decoder" });
14323
+ throw new VibeError34({ code: "VIBE_VALIDATION", message: "$querySql requires an explicit result decoder" });
14067
14324
  const statement = compileSql({ dialect: engine.dialect, query });
14068
14325
  let output = [];
14069
14326
  await runRaw("$querySql", statement, (rows) => {
@@ -14086,7 +14343,7 @@ function buildClient(params) {
14086
14343
  $connect: async () => {
14087
14344
  assertEngineActive({ engine, requireContext: false });
14088
14345
  if (engine.borrowedModule === true)
14089
- throw new VibeError30({ code: "VIBE_VALIDATION", message: "A package module borrows its adapter; the application owns connection lifecycle", meta: { reason: "module_borrowed_lifecycle", method: "$connect" } });
14346
+ throw new VibeError34({ code: "VIBE_VALIDATION", message: "A package module borrows its adapter; the application owns connection lifecycle", meta: { reason: "module_borrowed_lifecycle", method: "$connect" } });
14090
14347
  if (engine.inTransaction === true)
14091
14348
  throw transactionLifecycleRefusal({ method: "$connect" });
14092
14349
  if (engine.rlsSchema !== undefined) {
@@ -14108,7 +14365,7 @@ function buildClient(params) {
14108
14365
  $disconnect: async () => {
14109
14366
  assertEngineActive({ engine, requireContext: false });
14110
14367
  if (engine.borrowedModule === true)
14111
- throw new VibeError30({ code: "VIBE_VALIDATION", message: "A package module borrows its adapter; the application owns connection lifecycle", meta: { reason: "module_borrowed_lifecycle", method: "$disconnect" } });
14368
+ throw new VibeError34({ code: "VIBE_VALIDATION", message: "A package module borrows its adapter; the application owns connection lifecycle", meta: { reason: "module_borrowed_lifecycle", method: "$disconnect" } });
14112
14369
  if (engine.inTransaction === true)
14113
14370
  throw transactionLifecycleRefusal({ method: "$disconnect" });
14114
14371
  await engine.diagnostics?.flush();
@@ -14140,11 +14397,12 @@ function buildClient(params) {
14140
14397
  client,
14141
14398
  meta: engine.meta,
14142
14399
  ...engine.extensionMounts === undefined ? {} : { mounts: engine.extensionMounts },
14143
- operations: LAZY_OPERATIONS
14400
+ operations: LAZY_OPERATIONS,
14401
+ assertActive: () => assertEngineActive({ engine })
14144
14402
  });
14145
14403
  } else {
14146
14404
  const refuseLegacy = () => {
14147
- throw new VibeError30({ code: "VIBE_CONFIG", message: "Native row-level security cannot be combined with application policy or tenant scoping" });
14405
+ throw new VibeError34({ code: "VIBE_CONFIG", message: "Native row-level security cannot be combined with application policy or tenant scoping" });
14148
14406
  };
14149
14407
  Object.defineProperties(client, {
14150
14408
  $withContext: { enumerable: true, value: (context) => {
@@ -14162,7 +14420,8 @@ function buildClient(params) {
14162
14420
  client,
14163
14421
  meta: engine.meta,
14164
14422
  ...engine.extensionMounts === undefined ? {} : { mounts: engine.extensionMounts },
14165
- operations: LAZY_OPERATIONS
14423
+ operations: LAZY_OPERATIONS,
14424
+ assertActive: () => assertEngineActive({ engine })
14166
14425
  });
14167
14426
  }
14168
14427
  for (const delegate of Object.values(models))
@@ -14173,12 +14432,12 @@ function buildClient(params) {
14173
14432
  registerModuleBinder({ client, bind: ({ schema, manifest }) => {
14174
14433
  assertEngineActive({ engine, requireContext: false });
14175
14434
  if (engine.rlsSchema !== undefined || engine.meta.models.some((model) => model.policy !== undefined))
14176
- throw new VibeError30({ code: "VIBE_CONFIG", message: `Module ${manifest.id} cannot attach models to a policy or native-RLS context`, meta: { reason: "module_restricted_context", moduleId: manifest.id } });
14435
+ throw new VibeError34({ code: "VIBE_CONFIG", message: `Module ${manifest.id} cannot attach models to a policy or native-RLS context`, meta: { reason: "module_restricted_context", moduleId: manifest.id } });
14177
14436
  if (manifest.dialect !== engine.dialect.name)
14178
- throw new VibeError30({ code: "VIBE_UNSUPPORTED_CAPABILITY", message: `Module ${manifest.id} requires ${manifest.dialect}, received ${engine.dialect.name}`, meta: { reason: "module_dialect", moduleId: manifest.id } });
14437
+ throw new VibeError34({ code: "VIBE_UNSUPPORTED_CAPABILITY", message: `Module ${manifest.id} requires ${manifest.dialect}, received ${engine.dialect.name}`, meta: { reason: "module_dialect", moduleId: manifest.id } });
14179
14438
  const previous = engine.moduleManifests.get(manifest.id);
14180
14439
  if (previous !== undefined && (previous.schemaChecksum !== manifest.schemaChecksum || previous.revision !== manifest.revision || previous.contract !== manifest.contract))
14181
- throw new VibeError30({ code: "VIBE_CONFIG", message: `Module ${manifest.id} was already bound with a different manifest; use compatible package artifacts`, meta: { reason: "module_manifest_conflict", moduleId: manifest.id, revision: manifest.revision } });
14440
+ throw new VibeError34({ code: "VIBE_CONFIG", message: `Module ${manifest.id} was already bound with a different manifest; use compatible package artifacts`, meta: { reason: "module_manifest_conflict", moduleId: manifest.id, revision: manifest.revision } });
14182
14441
  let meta = moduleMetadata.get(schema);
14183
14442
  if (meta === undefined) {
14184
14443
  meta = buildRuntimeMeta({ schema });
@@ -14189,8 +14448,14 @@ function buildClient(params) {
14189
14448
  const { validate: _validate, ...options } = engine.options;
14190
14449
  return buildClient({ engine: { ...engine, meta, options, borrowedModule: true, extensionMounts: [], connectHooks: [], renderCache: new StatementRenderCache } });
14191
14450
  } });
14451
+ registerTransactionObservation({ db: client, observation: {
14452
+ inTransaction: engine.inTransaction === true,
14453
+ assertActive: () => assertEngineActive({ engine }),
14454
+ read: () => engine.adapter.rowChanges?.() ?? "unknown"
14455
+ } });
14192
14456
  return client;
14193
14457
  }
14458
+ var EXTENSION_EFFECT = new AsyncLocalStorage;
14194
14459
  function makeMountContext(params) {
14195
14460
  const { engine, extension, model } = params;
14196
14461
  return {
@@ -14220,7 +14485,8 @@ function makeMountContext(params) {
14220
14485
  rowCount: (value) => value.length,
14221
14486
  run: () => target.adapter.execute({
14222
14487
  text,
14223
- values: bindValues({ adapter: target.adapter, values: [...values] })
14488
+ values: bindValues({ adapter: target.adapter, values: [...values] }),
14489
+ effect: EXTENSION_EFFECT.getStore() ?? "unknown"
14224
14490
  })
14225
14491
  });
14226
14492
  return model === null ? rows : materializeRows({ dialect: target.dialect.name, model, rows, wire: target.adapter.wire });
@@ -14233,7 +14499,7 @@ function makeMountContext(params) {
14233
14499
  compileWhere: ({ where, model: modelName, qualify }) => {
14234
14500
  const target = modelName === undefined ? model : getModelMeta({ meta: engine.meta, model: modelName });
14235
14501
  if (target === null) {
14236
- throw new VibeError30({
14502
+ throw new VibeError34({
14237
14503
  code: "VIBE_INTERNAL",
14238
14504
  message: `extension "${extension}" compiled a where with no model in scope`,
14239
14505
  meta: { extension }
@@ -14253,8 +14519,27 @@ function makeMountContext(params) {
14253
14519
  function createMountSurface(params) {
14254
14520
  const { engine, mount, model } = params;
14255
14521
  const original = mount.create(makeMountContext({ engine, extension: mount.extension, model }));
14522
+ const effectOf = (path, args) => {
14523
+ if (containsSqlFragment(args))
14524
+ return "unknown";
14525
+ return mount.readOnly === true && path.length === 0 || Array.isArray(mount.readOnly) && path.length === 1 && mount.readOnly.includes(String(path[0])) ? "read" : "unknown";
14526
+ };
14527
+ const wrapEffects = (value, path) => {
14528
+ if (typeof value === "function")
14529
+ return function(...args) {
14530
+ return EXTENSION_EFFECT.run(effectOf(path, args), () => Reflect.apply(value, this, args));
14531
+ };
14532
+ if (value === null || typeof value !== "object" || Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
14533
+ return value;
14534
+ const result = Object.create(Object.getPrototypeOf(value));
14535
+ for (const key of Reflect.ownKeys(value)) {
14536
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
14537
+ Object.defineProperty(result, key, "value" in descriptor ? { ...descriptor, value: wrapEffects(descriptor.value, [...path, key]) } : descriptor);
14538
+ }
14539
+ return result;
14540
+ };
14256
14541
  if (engine.rlsSchema === undefined)
14257
- return original;
14542
+ return wrapEffects(original, []);
14258
14543
  const wrap = (value, path) => {
14259
14544
  if (typeof value === "function") {
14260
14545
  return (...args) => createQueryPromise({ engine, run: async (target) => {
@@ -14263,24 +14548,24 @@ function createMountSurface(params) {
14263
14548
  for (const key of path) {
14264
14549
  receiver = current;
14265
14550
  if (current === null || typeof current !== "object" && typeof current !== "function")
14266
- throw new VibeError30({ code: "VIBE_CONFIG", message: "Extension mount changed its method shape" });
14551
+ throw new VibeError34({ code: "VIBE_CONFIG", message: "Extension mount changed its method shape" });
14267
14552
  current = Reflect.get(current, key);
14268
14553
  }
14269
14554
  if (typeof current !== "function")
14270
- throw new VibeError30({ code: "VIBE_CONFIG", message: "Extension mount changed its method shape" });
14271
- return Reflect.apply(current, receiver, args);
14555
+ throw new VibeError34({ code: "VIBE_CONFIG", message: "Extension mount changed its method shape" });
14556
+ return EXTENSION_EFFECT.run(effectOf(path, args), () => Reflect.apply(current, receiver, args));
14272
14557
  } });
14273
14558
  }
14274
14559
  if (value === null || typeof value !== "object")
14275
14560
  return value;
14276
14561
  if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
14277
- throw new VibeError30({ code: "VIBE_CONFIG", message: "Native RLS extension mounts must expose plain objects and methods" });
14562
+ throw new VibeError34({ code: "VIBE_CONFIG", message: "Native RLS extension mounts must expose plain objects and methods" });
14278
14563
  }
14279
14564
  const result = {};
14280
14565
  for (const key of Reflect.ownKeys(value)) {
14281
14566
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
14282
14567
  if (!("value" in descriptor))
14283
- throw new VibeError30({ code: "VIBE_CONFIG", message: "Native RLS extension mount accessors are unsupported" });
14568
+ throw new VibeError34({ code: "VIBE_CONFIG", message: "Native RLS extension mount accessors are unsupported" });
14284
14569
  Object.defineProperty(result, key, { value: wrap(descriptor.value, [...path, key]), enumerable: descriptor.enumerable });
14285
14570
  }
14286
14571
  return Object.freeze(result);
@@ -14297,7 +14582,7 @@ function attachExtensionMounts(params) {
14297
14582
  const model = getModelMeta({ meta: engine.meta, model: mount.model ?? "" });
14298
14583
  const delegate = models[model.name];
14299
14584
  if (delegate === undefined || mount.property in delegate) {
14300
- throw new VibeError30({
14585
+ throw new VibeError34({
14301
14586
  code: "VIBE_CONFIG",
14302
14587
  message: `extension "${mount.extension}" cannot mount "${mount.property}" on ${model.name} \u2014 the name is taken`,
14303
14588
  meta: { extension: mount.extension, model: model.name, property: mount.property }
@@ -14308,7 +14593,7 @@ function attachExtensionMounts(params) {
14308
14593
  continue;
14309
14594
  }
14310
14595
  if (!mount.property.startsWith("$") || mount.property in client) {
14311
- throw new VibeError30({
14596
+ throw new VibeError34({
14312
14597
  code: "VIBE_CONFIG",
14313
14598
  message: `extension "${mount.extension}" cannot mount client property "${mount.property}" \u2014 root mounts are $-prefixed and must not collide`,
14314
14599
  meta: { extension: mount.extension, property: mount.property }
@@ -14334,7 +14619,7 @@ function createClient(params) {
14334
14619
  if (schema.rls !== undefined) {
14335
14620
  const dialect = getSqlDialect5({ dialect: dialectName });
14336
14621
  if (!dialect.capabilities.nativeRowLevelSecurity)
14337
- throw unsupportedCapability8({ dialect: dialectName, feature: "nativeRowLevelSecurity" });
14622
+ throw unsupportedCapability9({ dialect: dialectName, feature: "nativeRowLevelSecurity" });
14338
14623
  assertValidSchemaIR2({ schema });
14339
14624
  for (const model of schema.models) {
14340
14625
  if (model.rls !== "unprotected")
@@ -14343,9 +14628,9 @@ function createClient(params) {
14343
14628
  const role = options?.nativeRls?.runtimeRole;
14344
14629
  if (adapter.provider === "pglite") {
14345
14630
  if (typeof role !== "string" || role.length === 0 || role.includes("\x00"))
14346
- throw new VibeError30({ code: "VIBE_CONFIG", message: "PGlite native row-level security requires a pre-existing restricted runtimeRole; embedded binding is not a boundary against the host process" });
14631
+ throw new VibeError34({ code: "VIBE_CONFIG", message: "PGlite native row-level security requires a pre-existing restricted runtimeRole; embedded binding is not a boundary against the host process" });
14347
14632
  } else if (role !== undefined) {
14348
- throw new VibeError30({ code: "VIBE_CONFIG", message: "Server native row-level security must use the runtime login role, not a runtimeRole switch" });
14633
+ throw new VibeError34({ code: "VIBE_CONFIG", message: "Server native row-level security must use the runtime login role, not a runtimeRole switch" });
14349
14634
  }
14350
14635
  }
14351
14636
  if (extensions?.manifest !== undefined) {
@@ -14355,7 +14640,7 @@ function createClient(params) {
14355
14640
  assertComputedManifest({ manifest: computed.manifest, specs: computed.specs });
14356
14641
  }
14357
14642
  if (computed === undefined && options !== undefined && options["computed"] !== undefined) {
14358
- throw new VibeError30({
14643
+ throw new VibeError34({
14359
14644
  code: "VIBE_CONFIG",
14360
14645
  message: "this client was generated without computed fields \u2014 declare them in vibeorm.config.ts and re-run vibeorm generate",
14361
14646
  meta: {}
@@ -14408,16 +14693,17 @@ function freezeData(params) {
14408
14693
  function defineDatabaseModule(params) {
14409
14694
  for (const key of ["id", "contract", "revision"]) {
14410
14695
  if (typeof params[key] !== "string" || params[key].trim().length === 0 || params[key].includes("\x00"))
14411
- throw new VibeError31({ code: "VIBE_CONFIG", message: `Database module ${key} must be a non-empty identifier`, meta: { reason: "module_manifest", key } });
14696
+ throw new VibeError35({ code: "VIBE_CONFIG", message: `Database module ${key} must be a non-empty identifier`, meta: { reason: "module_manifest", key } });
14412
14697
  }
14413
- assertValidSchemaIR3({ schema: params.schema });
14414
- if (params.schema.rls !== undefined || params.schema.extensions.length > 0 || params.schema.models.some((model) => model.policy !== undefined))
14415
- throw new VibeError31({
14698
+ const preparedSchema = prepareDatabaseModuleSchema({ schema: params.schema, module: params });
14699
+ assertValidSchemaIR3({ schema: preparedSchema });
14700
+ if (preparedSchema.rls !== undefined || preparedSchema.extensions.length > 0 || preparedSchema.models.some((model) => model.policy !== undefined))
14701
+ throw new VibeError35({
14416
14702
  code: "VIBE_UNSUPPORTED_CAPABILITY",
14417
14703
  message: `Module ${params.id} cannot declare extensions, policy or native RLS in this module protocol`,
14418
14704
  meta: { reason: "module_schema_feature", moduleId: params.id }
14419
14705
  });
14420
- const serialized = JSON.stringify(canonicalValue({ value: params.schema }));
14706
+ const serialized = JSON.stringify(canonicalValue({ value: preparedSchema }));
14421
14707
  const schema = JSON.parse(serialized);
14422
14708
  freezeData({ value: schema });
14423
14709
  const manifest = Object.freeze({
@@ -14425,11 +14711,12 @@ function defineDatabaseModule(params) {
14425
14711
  contract: params.contract,
14426
14712
  revision: params.revision,
14427
14713
  protocol: 1,
14714
+ ...params.namespace === undefined ? {} : { namespace: params.namespace },
14428
14715
  dialect: providerToDialect({ provider: schema.datasource.provider }),
14429
- schemaChecksum: createHash("sha256").update(serialized).digest("hex")
14716
+ schemaChecksum: createHash2("sha256").update(serialized).digest("hex")
14430
14717
  });
14431
- if (params.manifest !== undefined && Object.keys(manifest).some((key) => params.manifest[key] !== manifest[key]))
14432
- throw new VibeError31({
14718
+ if (params.manifest !== undefined && (params.manifest.namespace !== manifest.namespace || Object.keys(manifest).some((key) => params.manifest[key] !== manifest[key])))
14719
+ throw new VibeError35({
14433
14720
  code: "VIBE_STALE_CLIENT",
14434
14721
  message: `Module ${params.id} has incompatible or modified generated metadata; regenerate with a compatible runtime`,
14435
14722
  meta: { reason: "module_artifact", moduleId: params.id, revision: params.revision, protocol: params.manifest.protocol }
@@ -14439,32 +14726,9 @@ function defineDatabaseModule(params) {
14439
14726
  return Object.freeze({ ...artifact, bind, create: ({ adapter }) => bind({ db: createClient({ schema, adapter }) }) });
14440
14727
  }
14441
14728
  // packages/runtime/src/keyset-iterator.ts
14442
- import { VibeError as VibeError32 } from "@vibeorm/schema";
14729
+ import { VibeError as VibeError36 } from "@vibeorm/schema";
14443
14730
  function validation(params) {
14444
- return new VibeError32({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
14445
- }
14446
- function projectionFor(params) {
14447
- const { plan, select, omit } = params;
14448
- const names = plan.keys.map((key) => key.field.name);
14449
- if (select !== undefined) {
14450
- const hidden = names.filter((name) => select[name] !== true);
14451
- if (hidden.length === 0)
14452
- return { select, hidden };
14453
- const widened = { ...select };
14454
- for (const name of hidden)
14455
- widened[name] = true;
14456
- return { select: widened, hidden };
14457
- }
14458
- if (omit !== undefined) {
14459
- const hidden = names.filter((name) => omit[name] === true);
14460
- if (hidden.length === 0)
14461
- return { omit, hidden };
14462
- const narrowed = { ...omit };
14463
- for (const name of hidden)
14464
- narrowed[name] = false;
14465
- return { omit: narrowed, hidden };
14466
- }
14467
- return { hidden: [] };
14731
+ return new VibeError36({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
14468
14732
  }
14469
14733
  function iterateKeyset(options) {
14470
14734
  const { source, meta, dialect, orderBy, pageSize, signal } = options;
@@ -14481,7 +14745,7 @@ function iterateKeyset(options) {
14481
14745
  terms: compileKeysetOrderInputs({ dialect, meta, model, orderBy }),
14482
14746
  ...options.timestampPrecision === undefined ? {} : { timestampPrecision: options.timestampPrecision }
14483
14747
  });
14484
- const projection = projectionFor({ plan, select: options.select, omit: options.omit });
14748
+ const projection = keysetProjection({ plan, select: options.select, omit: options.omit });
14485
14749
  const keysetArg = options.timestampPrecision === undefined ? {} : { keyset: { timestampPrecision: options.timestampPrecision } };
14486
14750
  let buffer = [];
14487
14751
  let position = options.after ?? null;
@@ -14518,7 +14782,7 @@ function iterateKeyset(options) {
14518
14782
  });
14519
14783
  if (advanced === false) {
14520
14784
  stop();
14521
- throw new VibeError32({
14785
+ throw new VibeError36({
14522
14786
  code: "VIBE_DATA_INVALID",
14523
14787
  message: `keyset traversal of "${options.model}" is not advancing: the engine returned a row that does not sort after the previous position. ` + "The ordering is not total, or a cursor value lost precision \u2014 a DateTime column finer than milliseconds asserted as millisecond-exact does this.",
14524
14788
  meta: { model: options.model, order: plan.signature, reason: "keyset-position-not-advancing" }
@@ -14591,7 +14855,7 @@ function iterateKeyset(options) {
14591
14855
  return iterator;
14592
14856
  }
14593
14857
  // packages/runtime/src/telemetry/collector.ts
14594
- import { VibeError as VibeError33 } from "@vibeorm/schema";
14858
+ import { VibeError as VibeError37 } from "@vibeorm/schema";
14595
14859
  function createTelemetryCollector(params) {
14596
14860
  const throwOn = new Set(params?.throwOn ?? []);
14597
14861
  const operations = [];
@@ -14601,7 +14865,7 @@ function createTelemetryCollector(params) {
14601
14865
  let shutdowns = 0;
14602
14866
  const hostile = (phase) => {
14603
14867
  if (throwOn.has(phase)) {
14604
- throw new VibeError33({
14868
+ throw new VibeError37({
14605
14869
  code: "VIBE_INTERNAL",
14606
14870
  message: `telemetry collector: deliberate ${phase} failure`,
14607
14871
  meta: { reason: "telemetry-collector-deliberate-failure", phase }
@@ -14657,7 +14921,7 @@ function createTelemetryCollector(params) {
14657
14921
  operationFor: (lookup) => {
14658
14922
  const matches = operations.filter((event) => event.method === lookup.method && (lookup.model === undefined || event.model === lookup.model));
14659
14923
  if (matches.length > 1) {
14660
- throw new VibeError33({
14924
+ throw new VibeError37({
14661
14925
  code: "VIBE_VALIDATION",
14662
14926
  message: `telemetry collector: ${matches.length} operations match ${lookup.model ?? "*"}.${lookup.method}`,
14663
14927
  meta: {
@@ -14691,6 +14955,7 @@ export {
14691
14955
  TELEMETRY_DEFAULTS,
14692
14956
  ViewResult,
14693
14957
  WRITE_DELEGATE_METHODS,
14958
+ advisoryKeyOf,
14694
14959
  affectedRowsAreRowCounts,
14695
14960
  analyzeOperationTelemetry,
14696
14961
  applyComputedFields,
@@ -14717,6 +14982,7 @@ export {
14717
14982
  compileSelect,
14718
14983
  compileWhere,
14719
14984
  createClient,
14985
+ createDelegateMethodClassifier,
14720
14986
  createScopeRewriter,
14721
14987
  createSqlModel,
14722
14988
  createStatementDiagnostics,
@@ -14780,8 +15046,9 @@ export {
14780
15046
  summarizePlan,
14781
15047
  toClientName,
14782
15048
  toSqlExecutor,
15049
+ transactionRowChanges,
14783
15050
  updateWithNested,
14784
15051
  validateWriteData
14785
15052
  };
14786
15053
 
14787
- //# debugId=BC9380E497613E8D64756E2164756E21
15054
+ //# debugId=9B1DF0989FAC48E264756E2164756E21