@vibeorm/runtime 2.2.0 → 2.3.1

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 (43) hide show
  1. package/dist/adapter-kit/index.d.ts +6 -3
  2. package/dist/adapter-kit/index.d.ts.map +1 -1
  3. package/dist/adapter-kit/index.js +191 -32
  4. package/dist/adapter-kit/index.js.map +8 -5
  5. package/dist/adapter-kit/nested-options.d.ts +22 -0
  6. package/dist/adapter-kit/nested-options.d.ts.map +1 -0
  7. package/dist/adapter-kit/savepoint-gate.d.ts +31 -0
  8. package/dist/adapter-kit/savepoint-gate.d.ts.map +1 -1
  9. package/dist/adapter-kit/session.d.ts +9 -0
  10. package/dist/adapter-kit/session.d.ts.map +1 -0
  11. package/dist/adapter-kit/sqlite-session.d.ts +8 -0
  12. package/dist/adapter-kit/sqlite-session.d.ts.map +1 -0
  13. package/dist/adapter.d.ts +34 -27
  14. package/dist/adapter.d.ts.map +1 -1
  15. package/dist/bulk-upsert.d.ts +5 -3
  16. package/dist/bulk-upsert.d.ts.map +1 -1
  17. package/dist/client-types.d.ts +14 -0
  18. package/dist/client-types.d.ts.map +1 -0
  19. package/dist/client.d.ts.map +1 -1
  20. package/dist/codecs.d.ts +5 -0
  21. package/dist/codecs.d.ts.map +1 -1
  22. package/dist/database-module.d.ts +27 -0
  23. package/dist/database-module.d.ts.map +1 -0
  24. package/dist/diagnostics/plan.d.ts +3 -1
  25. package/dist/diagnostics/plan.d.ts.map +1 -1
  26. package/dist/diagnostics/preview.d.ts +3 -1
  27. package/dist/diagnostics/preview.d.ts.map +1 -1
  28. package/dist/diagnostics/statement-diagnostics.d.ts +10 -6
  29. package/dist/diagnostics/statement-diagnostics.d.ts.map +1 -1
  30. package/dist/index.d.ts +4 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +992 -759
  33. package/dist/index.js.map +20 -18
  34. package/dist/module-context.d.ts +20 -0
  35. package/dist/module-context.d.ts.map +1 -0
  36. package/dist/nested-writes.d.ts.map +1 -1
  37. package/dist/policy.d.ts.map +1 -1
  38. package/dist/query-builder.d.ts.map +1 -1
  39. package/dist/read-only.d.ts.map +1 -1
  40. package/dist/scoped.d.ts.map +1 -1
  41. package/dist/sql-access.d.ts +18 -2
  42. package/dist/sql-access.d.ts.map +1 -1
  43. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -50,22 +50,30 @@ function createSqlModel(params) {
50
50
  return Object.freeze({ table: params.alias === undefined ? table : sql`${table} AS ${sql.ident({ parts: [params.alias] })}`, fields: Object.freeze(fields) });
51
51
  }
52
52
  // packages/runtime/src/adapter.ts
53
+ import { VibeError as VibeError2 } from "@vibeorm/schema";
53
54
  function toSqlExecutor(params) {
54
55
  const { adapter } = params;
55
- return async (queryParams) => {
56
- const result = await adapter.executeUnsafe({
57
- text: queryParams.text,
58
- values: queryParams.values
59
- });
56
+ const execute = async (queryParams) => {
57
+ const result = await adapter.executeUnsafe(queryParams);
60
58
  return result.rows;
61
59
  };
60
+ const withSession = async ({ run }) => {
61
+ if (adapter.withSession === undefined)
62
+ throw new VibeError2({
63
+ code: "VIBE_UNSUPPORTED_CAPABILITY",
64
+ message: "This adapter cannot reserve a migration session. Supply an adapter with session support or an explicitly owned SqlExecutor.",
65
+ meta: { capability: "session", provider: adapter.provider }
66
+ });
67
+ return adapter.withSession({ run });
68
+ };
69
+ return Object.assign(execute, { withSession });
62
70
  }
63
71
  // packages/runtime/src/db-now.ts
64
- import { VibeError as VibeError2 } from "@vibeorm/schema";
72
+ import { VibeError as VibeError3 } from "@vibeorm/schema";
65
73
  function dbNow(options) {
66
74
  const offset = options?.plusSeconds ?? 0;
67
75
  if (typeof offset !== "number" || !Number.isFinite(offset)) {
68
- throw new VibeError2({
76
+ throw new VibeError3({
69
77
  code: "VIBE_VALIDATION",
70
78
  message: `dbNow plusSeconds must be a finite number of seconds (fractional is fine), got ${String(offset)}`,
71
79
  meta: { plusSeconds: offset }
@@ -84,10 +92,10 @@ function isDbNow(value) {
84
92
  return candidate.__vibeDbNow === true && typeof candidate.offsetSeconds === "number" && Number.isFinite(candidate.offsetSeconds);
85
93
  }
86
94
  // packages/runtime/src/advisory-lock.ts
87
- import { VibeError as VibeError3, unsupportedCapability } from "@vibeorm/schema";
95
+ import { VibeError as VibeError4, unsupportedCapability } from "@vibeorm/schema";
88
96
  import { ADVISORY_KEY_BOUNDS } from "@vibeorm/sql";
89
97
  function validationError(params) {
90
- return new VibeError3({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
98
+ return new VibeError4({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
91
99
  }
92
100
  function readInt32(params) {
93
101
  const { value, member, method } = params;
@@ -157,8 +165,8 @@ function compileAdvisoryLock(params) {
157
165
  }
158
166
  const mode = readMode({ value: request.mode, method });
159
167
  if (hasSingle) {
160
- const key2 = { key: readInt64({ value: request.key, method }) };
161
- return statementFor({ method, mode, key: key2 });
168
+ const key = { key: readInt64({ value: request.key, method }) };
169
+ return statementFor({ method, mode, key });
162
170
  }
163
171
  if (!("classId" in request) || !("objectId" in request)) {
164
172
  throw validationError({
@@ -192,7 +200,7 @@ function statementFor(params) {
192
200
  };
193
201
  }
194
202
  // packages/runtime/src/model-meta.ts
195
- import { VibeError as VibeError4, enumStorageOf, isEnumType as isEnumType2, validateComputedConfig } from "@vibeorm/schema";
203
+ import { VibeError as VibeError5, enumStorageOf, isEnumType as isEnumType2, validateComputedConfig } from "@vibeorm/schema";
196
204
  import { enumMembershipCodec } from "@vibeorm/sql";
197
205
  function toClientName(params) {
198
206
  const { name } = params;
@@ -321,7 +329,7 @@ function buildModelMeta(params) {
321
329
  for (const name of model.primaryKey.fields) {
322
330
  const field = fieldByName.get(name);
323
331
  if (field === undefined) {
324
- throw new VibeError4({
332
+ throw new VibeError5({
325
333
  code: "VIBE_SCHEMA_INVALID",
326
334
  message: `model "${model.name}" declares composite primary-key field "${name}", which does not exist`,
327
335
  meta: { model: model.name, field: name }
@@ -427,7 +435,7 @@ function getModelMeta(params) {
427
435
  const { meta, model } = params;
428
436
  const found = meta.modelByName.get(model);
429
437
  if (found === undefined) {
430
- throw new VibeError4({
438
+ throw new VibeError5({
431
439
  code: "VIBE_VALIDATION",
432
440
  message: `unknown model "${model}"`,
433
441
  meta: { model, known: [...new Set(meta.models.map((entry) => entry.name))] }
@@ -440,20 +448,20 @@ function getFieldMeta(params) {
440
448
  const found = model.fieldByName.get(field);
441
449
  if (found === undefined) {
442
450
  if (model.computed !== null && model.computed.has(field)) {
443
- throw new VibeError4({
451
+ throw new VibeError5({
444
452
  code: "VIBE_VALIDATION",
445
453
  message: `"${field}" on model "${model.name}" is a computed field \u2014 computed fields appear in results (select/omit) only, not in ${context}`,
446
454
  meta: { model: model.name, field, context, computed: true }
447
455
  });
448
456
  }
449
457
  if (model.relationByName.has(field)) {
450
- throw new VibeError4({
458
+ throw new VibeError5({
451
459
  code: "VIBE_VALIDATION",
452
460
  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)`,
453
461
  meta: { model: model.name, field, context }
454
462
  });
455
463
  }
456
- throw new VibeError4({
464
+ throw new VibeError5({
457
465
  code: "VIBE_VALIDATION",
458
466
  message: `unknown field "${field}" on model "${model.name}" in ${context}`,
459
467
  meta: { model: model.name, field, context }
@@ -463,7 +471,7 @@ function getFieldMeta(params) {
463
471
  }
464
472
  // packages/runtime/src/codecs.ts
465
473
  import { JSON_TRANSPORT, projectionOutputName, parsePgArrayLiteral, toPgArrayLiteral } from "@vibeorm/sql";
466
- import { VibeError as VibeError5, isEnumType as isEnumType3 } from "@vibeorm/schema";
474
+ import { VibeError as VibeError6, isEnumType as isEnumType3 } from "@vibeorm/schema";
467
475
  import { DIALECT_CODECS, decodeIsNoop } from "@vibeorm/sql";
468
476
  import {
469
477
  DIALECT_CODECS as DIALECT_CODECS2,
@@ -512,10 +520,29 @@ function decodeValue(params) {
512
520
  return codec.decode(value);
513
521
  }
514
522
  var DECIMAL_LITERAL = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/;
523
+ function validateAtomicOperand(params) {
524
+ const { field, value } = params;
525
+ if (field.scalarType === "BigInt") {
526
+ if (typeof value === "bigint" || typeof value === "number" && Number.isSafeInteger(value))
527
+ return value;
528
+ } else if (field.scalarType === "Decimal") {
529
+ if (typeof value === "string" && DECIMAL_LITERAL.test(value.trim()))
530
+ return value.trim();
531
+ if (typeof value === "number" && Number.isFinite(value))
532
+ return value;
533
+ } else if (typeof value === "number" && Number.isFinite(value)) {
534
+ return value;
535
+ }
536
+ throw new VibeError6({
537
+ code: "VIBE_VALIDATION",
538
+ message: `Invalid arithmetic operand for ${field.scalarType} field "${field.name}"`,
539
+ meta: { field: field.name, value }
540
+ });
541
+ }
515
542
  function toRealNumber(params) {
516
543
  const { field, value } = params;
517
544
  const refuse = () => {
518
- throw new VibeError5({
545
+ throw new VibeError6({
519
546
  code: "VIBE_VALIDATION",
520
547
  message: `"${String(value)}" is not a numeric value for the Decimal field "${field.name}"`,
521
548
  meta: { field: field.name, value }
@@ -584,20 +611,20 @@ function wirePlanKey(wire) {
584
611
  }
585
612
  function fieldDecoder(params) {
586
613
  const { dialect, field, wire } = params;
587
- const decode2 = fieldCodec({ dialect, field }).decode;
614
+ const decode = fieldCodec({ dialect, field }).decode;
588
615
  if (isPostgresEnumList({ dialect, field })) {
589
616
  return (value) => decodeValue({ dialect, field, value });
590
617
  }
591
- if (decode2 === IDENTITY_DECODE)
618
+ if (decode === IDENTITY_DECODE)
592
619
  return null;
593
620
  if (field.isList) {
594
621
  if (field.scalarType === "Json" && decodeIsNoop({ scalarType: "Json", wire }))
595
622
  return null;
596
- return (value) => Array.isArray(value) ? value.map((element) => element === null || element === undefined ? element : decode2(element)) : decode2(value);
623
+ return (value) => Array.isArray(value) ? value.map((element) => element === null || element === undefined ? element : decode(element)) : decode(value);
597
624
  }
598
625
  if (field.scalarType !== null && decodeIsNoop({ scalarType: field.scalarType, wire }))
599
626
  return null;
600
- return decode2;
627
+ return decode;
601
628
  }
602
629
  function buildDecodePlan(params) {
603
630
  const { dialect, model, wire } = params;
@@ -605,12 +632,12 @@ function buildDecodePlan(params) {
605
632
  const inPlace = [];
606
633
  const renamedColumns = [];
607
634
  for (const field of model.fields) {
608
- const decode2 = fieldDecoder({ dialect, field, ...wire === undefined ? {} : { wire } });
609
- byColumn.set(field.columnName, { name: field.name, decode: decode2 });
635
+ const decode = fieldDecoder({ dialect, field, ...wire === undefined ? {} : { wire } });
636
+ byColumn.set(field.columnName, { name: field.name, decode });
610
637
  if (field.columnName !== field.name)
611
638
  renamedColumns.push(field.columnName);
612
- if (decode2 !== null)
613
- inPlace.push({ column: field.columnName, decode: decode2 });
639
+ if (decode !== null)
640
+ inPlace.push({ column: field.columnName, decode });
614
641
  }
615
642
  return { byColumn, renamedColumns, decoders: inPlace, inPlace: renamedColumns.length > 0 ? null : inPlace };
616
643
  }
@@ -737,12 +764,12 @@ function getJsonDecodePlan(model) {
737
764
  const inPlace = [];
738
765
  const renamedColumns = [];
739
766
  for (const field of model.fields) {
740
- const decode2 = field.scalarType === "Json" ? null : field.scalarType === "Bytes" && !field.isList ? decodeBase64Bytes : fieldDecoder({ dialect: "postgres", field });
741
- byColumn.set(field.columnName, { name: field.name, decode: decode2 });
767
+ const decode = field.scalarType === "Json" ? null : field.scalarType === "Bytes" && !field.isList ? decodeBase64Bytes : fieldDecoder({ dialect: "postgres", field });
768
+ byColumn.set(field.columnName, { name: field.name, decode });
742
769
  if (field.columnName !== field.name)
743
770
  renamedColumns.push(field.columnName);
744
- if (decode2 !== null)
745
- inPlace.push({ column: field.columnName, decode: decode2 });
771
+ if (decode !== null)
772
+ inPlace.push({ column: field.columnName, decode });
746
773
  }
747
774
  plan = { byColumn, renamedColumns, decoders: inPlace, inPlace: renamedColumns.length > 0 ? null : inPlace };
748
775
  jsonDecodePlanCache.set(model, plan);
@@ -755,7 +782,7 @@ function positionalMaterializer(params) {
755
782
  const output = projectionOutputName({ column });
756
783
  const entry = plan.byColumn.get(output);
757
784
  if (entry === undefined)
758
- throw new VibeError5({ code: "VIBE_INTERNAL", message: "positional projection has no schema field", meta: { model: model.name, column: output } });
785
+ throw new VibeError6({ code: "VIBE_INTERNAL", message: "positional projection has no schema field", meta: { model: model.name, column: output } });
759
786
  return entry;
760
787
  });
761
788
  const width = slots.length;
@@ -763,7 +790,7 @@ function positionalMaterializer(params) {
763
790
  const chunked = width > chunkSize;
764
791
  const count = Math.ceil(width / chunkSize);
765
792
  const invalid = () => {
766
- throw new VibeError5({ code: "VIBE_INTERNAL", message: "positional relation payload does not match its SQL projection", meta: { model: model.name, expectedColumns: width } });
793
+ throw new VibeError6({ code: "VIBE_INTERNAL", message: "positional relation payload does not match its SQL projection", meta: { model: model.name, expectedColumns: width } });
767
794
  };
768
795
  if (width === 0 || new Set(slots.map((slot) => slot.name)).size !== width)
769
796
  return invalid();
@@ -805,7 +832,7 @@ function decodeAggregateValue(params) {
805
832
  return field === null ? value : decodeValue({ dialect, field, value });
806
833
  }
807
834
  // packages/runtime/src/lateral-projection.ts
808
- import { VibeError as VibeError6, unsupportedCapability as unsupportedCapability2 } from "@vibeorm/schema";
835
+ import { VibeError as VibeError7, unsupportedCapability as unsupportedCapability2 } from "@vibeorm/schema";
809
836
  function isPlainObject(value) {
810
837
  return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
811
838
  }
@@ -822,7 +849,7 @@ function lateralProjection(params) {
822
849
  const columns = names.map((name) => {
823
850
  const field = model.fieldByName.get(name);
824
851
  if (field === undefined)
825
- throw new VibeError6({ code: "VIBE_INTERNAL", message: "lateral projection references an unknown field", meta: { model: model.name, field: name } });
852
+ throw new VibeError7({ code: "VIBE_INTERNAL", message: "lateral projection references an unknown field", meta: { model: model.name, field: name } });
826
853
  return Object.freeze(applyLateralTransform({ model, column: { table: LATERAL_CHILD_ALIAS, name: field.columnName } }));
827
854
  });
828
855
  const descriptor = Object.freeze({ columns: Object.freeze(columns), hiddenOrder: Object.freeze(hiddenOrder) });
@@ -871,7 +898,7 @@ function applyLateralTransform(params) {
871
898
 
872
899
  // packages/runtime/src/query-builder.ts
873
900
  import { isSqlFragment, mapConflictColumns } from "@vibeorm/sql";
874
- import { VibeError as VibeError10, unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
901
+ import { VibeError as VibeError11, unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
875
902
  import {
876
903
  SQL_DEFAULT_CELL,
877
904
  containsPattern,
@@ -885,9 +912,9 @@ import {
885
912
  import { describeRowLock } from "@vibeorm/sql";
886
913
 
887
914
  // packages/runtime/src/bulk-upsert.ts
888
- import { VibeError as VibeError7, unsupportedCapability as unsupportedCapability3 } from "@vibeorm/schema";
915
+ import { VibeError as VibeError8, unsupportedCapability as unsupportedCapability3 } from "@vibeorm/schema";
889
916
  function validationError2(params) {
890
- return new VibeError7({
917
+ return new VibeError8({
891
918
  code: "VIBE_VALIDATION",
892
919
  message: params.message,
893
920
  ...params.meta === undefined ? {} : { meta: params.meta }
@@ -1069,8 +1096,13 @@ function conflictKeyOf(params) {
1069
1096
  function assertNoDuplicateConflictKeys(params) {
1070
1097
  const { model, compiled, targetColumns } = params;
1071
1098
  const firstIndexByKey = new Map;
1099
+ const signature = [...targetColumns].sort((left, right) => left < right ? -1 : 1).join("\x00");
1100
+ const nullsNotDistinct = [...model.compoundUniques.values(), ...model.singleIndexUniques].some((group) => group.nullsNotDistinct && signatureOf({ fields: group.fields }) === signature);
1072
1101
  for (let index = 0;index < compiled.length; index += 1) {
1073
- const key = conflictKeyOf({ row: compiled[index], columns: targetColumns });
1102
+ const row = compiled[index];
1103
+ if (!nullsNotDistinct && targetColumns.some((column) => row[column] === null))
1104
+ continue;
1105
+ const key = conflictKeyOf({ row, columns: targetColumns });
1074
1106
  const first = firstIndexByKey.get(key);
1075
1107
  if (first !== undefined) {
1076
1108
  throw validationError2({
@@ -1206,7 +1238,7 @@ function assertConflictKeysAreComparable(params) {
1206
1238
  }
1207
1239
 
1208
1240
  // packages/runtime/src/keyset.ts
1209
- import { VibeError as VibeError8 } from "@vibeorm/schema";
1241
+ import { VibeError as VibeError9 } from "@vibeorm/schema";
1210
1242
  var KEYSET_TOKEN_VERSION = 1;
1211
1243
  var KEYSET_TOKEN_PREFIX = "vk1.";
1212
1244
  var KEYSET_MAX_PAGE_SIZE = 1e4;
@@ -1216,10 +1248,10 @@ var DATETIME_NEEDS_PRECISION_ASSERTION = Object.freeze({
1216
1248
  sqlite: false
1217
1249
  });
1218
1250
  function keysetValidation(params) {
1219
- return new VibeError8({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
1251
+ return new VibeError9({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
1220
1252
  }
1221
1253
  function keysetUnsupported(params) {
1222
- return new VibeError8({
1254
+ return new VibeError9({
1223
1255
  code: "VIBE_UNSUPPORTED_CAPABILITY",
1224
1256
  message: params.message,
1225
1257
  meta: params.meta
@@ -1602,9 +1634,9 @@ function decodeKeysetToken(params) {
1602
1634
  }
1603
1635
 
1604
1636
  // packages/runtime/src/relation-plan.ts
1605
- import { VibeError as VibeError9, implicitJoinTable } from "@vibeorm/schema";
1637
+ import { VibeError as VibeError10, implicitJoinTable } from "@vibeorm/schema";
1606
1638
  function validationError3(params) {
1607
- return new VibeError9({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
1639
+ return new VibeError10({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
1608
1640
  }
1609
1641
  function isPlainObject2(value) {
1610
1642
  return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date);
@@ -1629,7 +1661,7 @@ function keyFields(params) {
1629
1661
  return names.map((name) => {
1630
1662
  const field = model.fieldByName.get(name);
1631
1663
  if (field === undefined) {
1632
- throw new VibeError9({
1664
+ throw new VibeError10({
1633
1665
  code: "VIBE_SCHEMA_INVALID",
1634
1666
  message: `relation "${relation.name}" on ${relation.model} names unknown ${what} field "${name}"`,
1635
1667
  meta: { model: relation.model, relation: relation.name }
@@ -1641,7 +1673,7 @@ function keyFields(params) {
1641
1673
  function singleKeyPair(params) {
1642
1674
  const { link, what } = params;
1643
1675
  if (link.parentKeys.length !== 1 || link.childKeys.length !== 1) {
1644
- throw new VibeError9({
1676
+ throw new VibeError10({
1645
1677
  code: "VIBE_UNSUPPORTED_CAPABILITY",
1646
1678
  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`,
1647
1679
  meta: { model: link.relation.model, relation: link.relation.name, arity: link.parentKeys.length }
@@ -1685,7 +1717,7 @@ function resolveRelationLinkUncached(params) {
1685
1717
  const target = getModelMeta({ meta, model: relation.targetModel });
1686
1718
  if (relation.type === "manyToMany") {
1687
1719
  if (relation.model === relation.targetModel) {
1688
- throw new VibeError9({
1720
+ throw new VibeError10({
1689
1721
  code: "VIBE_SCHEMA_INVALID",
1690
1722
  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.`,
1691
1723
  meta: { model: relation.model, relation: relation.name, targetModel: relation.targetModel }
@@ -1727,7 +1759,7 @@ function resolveRelationLinkUncached(params) {
1727
1759
  }
1728
1760
  const reverse = findReverseRelation({ relation, target });
1729
1761
  if (reverse === null || reverse.fields === undefined || reverse.fields.length === 0) {
1730
- throw new VibeError9({
1762
+ throw new VibeError10({
1731
1763
  code: "VIBE_SCHEMA_INVALID",
1732
1764
  message: `relation "${relation.name}" on ${relation.model} has no foreign-key counterpart on ${relation.targetModel}`,
1733
1765
  meta: { model: relation.model, relation: relation.name, target: relation.targetModel }
@@ -1752,7 +1784,7 @@ function pairedKeys(params) {
1752
1784
  const parentKeys = keyFields({ model, names: parentNames, relation, what: "fields" });
1753
1785
  const childKeys = keyFields({ model: target, names: childNames, relation, what: "references" });
1754
1786
  if (parentKeys.length !== childKeys.length) {
1755
- throw new VibeError9({
1787
+ throw new VibeError10({
1756
1788
  code: "VIBE_SCHEMA_INVALID",
1757
1789
  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`,
1758
1790
  meta: { model: relation.model, relation: relation.name }
@@ -2102,7 +2134,7 @@ var AGG_FN_BY_KEY = {
2102
2134
  _max: "max"
2103
2135
  };
2104
2136
  function validationError4(params) {
2105
- return new VibeError10({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
2137
+ return new VibeError11({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
2106
2138
  }
2107
2139
  function isPlainObject3(value) {
2108
2140
  return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date) && !(value instanceof Uint8Array);
@@ -2584,7 +2616,7 @@ function compileOperatorFilter(params) {
2584
2616
  }
2585
2617
  const insensitive = mode === "insensitive";
2586
2618
  const strict = mode === "strict";
2587
- const ciCollated = (params2) => params2.dialect.name === "mysql" && params2.field.collation?.toLowerCase().endsWith("_ci") === true;
2619
+ const ciCollated = (params) => params.dialect.name === "mysql" && params.field.collation?.toLowerCase().endsWith("_ci") === true;
2588
2620
  const requireStringOperand = (operator, operand) => {
2589
2621
  if (typeof operand !== "string") {
2590
2622
  throw validationError4({
@@ -2667,6 +2699,12 @@ function compileOperatorFilter(params) {
2667
2699
  });
2668
2700
  }
2669
2701
  for (const item of operand) {
2702
+ if (item === null) {
2703
+ throw validationError4({
2704
+ message: `"${operator}" on ${model.name}.${field.name} cannot contain null; use an explicit null comparison`,
2705
+ meta: { model: model.name, field: field.name, operator }
2706
+ });
2707
+ }
2670
2708
  if (isDbNow(item)) {
2671
2709
  throw validationError4({
2672
2710
  message: `dbNow() cannot ride an "${operator}" list on ${model.name}.${field.name} \u2014 compare with lt/lte/gt/gte/equals instead`,
@@ -2865,13 +2903,13 @@ function compileRelationFilter(params) {
2865
2903
  meta: { model: model.name, relation: relation.name }
2866
2904
  });
2867
2905
  }
2868
- const conditions2 = [];
2906
+ const conditions = [];
2869
2907
  for (const [operator, operand] of Object.entries(value)) {
2870
2908
  if (operand === undefined)
2871
2909
  continue;
2872
2910
  switch (operator) {
2873
2911
  case "some":
2874
- conditions2.push(buildRelationExists({
2912
+ conditions.push(buildRelationExists({
2875
2913
  ctx,
2876
2914
  link,
2877
2915
  outer,
@@ -2879,7 +2917,7 @@ function compileRelationFilter(params) {
2879
2917
  }));
2880
2918
  break;
2881
2919
  case "none":
2882
- conditions2.push(buildRelationExists({
2920
+ conditions.push(buildRelationExists({
2883
2921
  ctx,
2884
2922
  link,
2885
2923
  outer,
@@ -2888,7 +2926,7 @@ function compileRelationFilter(params) {
2888
2926
  }));
2889
2927
  break;
2890
2928
  case "every":
2891
- conditions2.push(buildRelationExists({
2929
+ conditions.push(buildRelationExists({
2892
2930
  ctx,
2893
2931
  link,
2894
2932
  outer,
@@ -2904,15 +2942,15 @@ function compileRelationFilter(params) {
2904
2942
  });
2905
2943
  }
2906
2944
  }
2907
- if (conditions2.length === 0) {
2945
+ if (conditions.length === 0) {
2908
2946
  throw validationError4({
2909
2947
  message: `filter on relation ${model.name}.${relation.name} must contain some, every or none`,
2910
2948
  meta: { model: model.name, relation: relation.name }
2911
2949
  });
2912
2950
  }
2913
- if (conditions2.length === 1)
2914
- return conditions2[0];
2915
- return { kind: "and", operands: conditions2 };
2951
+ if (conditions.length === 1)
2952
+ return conditions[0];
2953
+ return { kind: "and", operands: conditions };
2916
2954
  }
2917
2955
  let isArm;
2918
2956
  let hasIs = false;
@@ -3107,17 +3145,17 @@ function compileRelationOrderTerms(params) {
3107
3145
  meta: { model: model.name, relation: relation.name }
3108
3146
  });
3109
3147
  }
3110
- const direction2 = requireDirection(value, `orderBy.${relation.name}._count`);
3111
- const alias2 = `__ord${++aliasSeq.n}`;
3148
+ const direction = requireDirection(value, `orderBy.${relation.name}._count`);
3149
+ const alias = `__ord${++aliasSeq.n}`;
3112
3150
  const select = link.kind === "manyToMany" ? {
3113
3151
  kind: "select",
3114
- table: { name: link.join.tableName, alias: alias2 },
3152
+ table: { name: link.join.tableName, alias },
3115
3153
  columns: [],
3116
3154
  selectExpr: { kind: "countAll" },
3117
3155
  where: {
3118
3156
  kind: "cmpCol",
3119
3157
  op: "eq",
3120
- left: { table: alias2, name: link.join.parentColumn },
3158
+ left: { table: alias, name: link.join.parentColumn },
3121
3159
  right: {
3122
3160
  table: outer,
3123
3161
  name: singleKeyPair({ link, what: "implicit many-to-many ordering" }).parent.columnName
@@ -3125,12 +3163,12 @@ function compileRelationOrderTerms(params) {
3125
3163
  }
3126
3164
  } : {
3127
3165
  kind: "select",
3128
- table: { name: link.target.tableName, alias: alias2 },
3166
+ table: { name: link.target.tableName, alias },
3129
3167
  columns: [],
3130
3168
  selectExpr: { kind: "countAll" },
3131
- where: correlateLink({ link, childTable: alias2, outerTable: outer })
3169
+ where: correlateLink({ link, childTable: alias, outerTable: outer })
3132
3170
  };
3133
- terms.push({ select, direction: direction2 });
3171
+ terms.push({ select, direction });
3134
3172
  continue;
3135
3173
  }
3136
3174
  if (isList) {
@@ -3496,21 +3534,17 @@ function orderedColumns(params) {
3496
3534
  return model.fields.map((field) => field.columnName).filter((column) => (column in values));
3497
3535
  }
3498
3536
  function compileAtomicOperation(params) {
3499
- const { model, field, operator, operand } = params;
3537
+ const { model, entry, operator, operand } = params;
3538
+ const field = entry.field;
3500
3539
  if (field.scalarType === null || !NUMERIC_TYPES.includes(field.scalarType)) {
3501
3540
  throw validationError4({
3502
3541
  message: `"${operator}" needs a numeric field, but ${model.name}.${field.name} is ${String(field.enumName ?? field.scalarType)}`,
3503
3542
  meta: { model: model.name, field: field.name, operator }
3504
3543
  });
3505
3544
  }
3506
- const numeric = typeof operand === "bigint" ? Number(operand) : operand;
3507
- if (typeof numeric !== "number" || !Number.isFinite(numeric)) {
3508
- throw validationError4({
3509
- message: `"${operator}" on ${model.name}.${field.name} expects a number`,
3510
- meta: { model: model.name, field: field.name, operator, operand }
3511
- });
3512
- }
3513
- return { __op: operator, value: numeric };
3545
+ const numeric = validateAtomicOperand({ field, value: operand });
3546
+ const encoded = encodeWith(entry, numeric);
3547
+ return { __op: operator, value: encoded, ...field.scalarType === "Decimal" ? { numericType: "Decimal" } : {} };
3514
3548
  }
3515
3549
  function compileUpdateSet(params) {
3516
3550
  const { dialect, model, data } = params;
@@ -3542,7 +3576,7 @@ function compileUpdateSet(params) {
3542
3576
  });
3543
3577
  }
3544
3578
  if (isPlainObject3(value) && field.scalarType !== "Json") {
3545
- const entries = Object.entries(value).filter(([, operand2]) => operand2 !== undefined);
3579
+ const entries = Object.entries(value).filter(([, operand]) => operand !== undefined);
3546
3580
  if (entries.length !== 1) {
3547
3581
  throw validationError4({
3548
3582
  message: `update of ${model.name}.${field.name} must use exactly one operation`,
@@ -3565,7 +3599,7 @@ function compileUpdateSet(params) {
3565
3599
  meta: { model: model.name, field: field.name, operator }
3566
3600
  });
3567
3601
  }
3568
- set[field.columnName] = compileAtomicOperation({ model, field, operator: atomic, operand });
3602
+ set[field.columnName] = compileAtomicOperation({ model, entry, operator: atomic, operand });
3569
3603
  continue;
3570
3604
  }
3571
3605
  set[field.columnName] = encodeWith(entry, value);
@@ -4100,7 +4134,7 @@ function buildFindShape(params) {
4100
4134
  },
4101
4135
  ...where === undefined ? {} : { where }
4102
4136
  };
4103
- const statement2 = {
4137
+ const statement = {
4104
4138
  kind: "select",
4105
4139
  table: { name: DISTINCT_TABLE_ALIAS },
4106
4140
  columns: projectionColumns({ model, selectedFields }),
@@ -4110,7 +4144,7 @@ function buildFindShape(params) {
4110
4144
  ...limit === undefined ? {} : { limit },
4111
4145
  ...offset === undefined ? {} : { offset }
4112
4146
  };
4113
- return { statement: statement2, reverseRows: backward, resortBy };
4147
+ return { statement, reverseRows: backward, resortBy };
4114
4148
  }
4115
4149
  if (distinctOuterOrder !== null) {
4116
4150
  const inner = {
@@ -4126,7 +4160,7 @@ function buildFindShape(params) {
4126
4160
  ...projectionColumns({ model, selectedFields }),
4127
4161
  ...lateralJoins.map((join) => ({ name: join.columnAlias }))
4128
4162
  ];
4129
- const statement2 = {
4163
+ const statement = {
4130
4164
  kind: "select",
4131
4165
  table: { name: DISTINCT_TABLE_ALIAS },
4132
4166
  columns: outerColumns,
@@ -4135,7 +4169,7 @@ function buildFindShape(params) {
4135
4169
  ...limit === undefined ? {} : { limit },
4136
4170
  ...offset === undefined ? {} : { offset }
4137
4171
  };
4138
- return { statement: statement2, reverseRows: backward, resortBy };
4172
+ return { statement, reverseRows: backward, resortBy };
4139
4173
  }
4140
4174
  const pageFirst = lateralJoins.length > 0 && (limit !== undefined || offset !== undefined) && orderTerms.every((term) => ("column" in term));
4141
4175
  if (pageFirst && selection !== undefined) {
@@ -4151,7 +4185,7 @@ function buildFindShape(params) {
4151
4185
  ...limit === undefined ? {} : { limit },
4152
4186
  ...offset === undefined ? {} : { offset }
4153
4187
  };
4154
- const statement2 = {
4188
+ const statement = {
4155
4189
  kind: "select",
4156
4190
  table: { name: model.tableName },
4157
4191
  columns,
@@ -4159,7 +4193,7 @@ function buildFindShape(params) {
4159
4193
  lateralJoins,
4160
4194
  ...orderTerms.length === 0 ? {} : { orderBy: orderTerms }
4161
4195
  };
4162
- return { statement: statement2, reverseRows: backward, resortBy };
4196
+ return { statement, reverseRows: backward, resortBy };
4163
4197
  }
4164
4198
  const statement = {
4165
4199
  kind: "select",
@@ -4584,9 +4618,9 @@ function compileGroupByOrder(params) {
4584
4618
  }
4585
4619
  agg = { fn: "countAll" };
4586
4620
  } else {
4587
- const field2 = getFieldMeta({ model, field: selector, context: `orderBy ${name}` });
4588
- validateAggregatedField({ model, field: field2, key });
4589
- const aggColumn = key === "_count" ? { name: field2.columnName } : compareColumnRef({ dialect, field: field2 });
4621
+ const field = getFieldMeta({ model, field: selector, context: `orderBy ${name}` });
4622
+ validateAggregatedField({ model, field, key });
4623
+ const aggColumn = key === "_count" ? { name: field.columnName } : compareColumnRef({ dialect, field });
4590
4624
  agg = { fn: AGG_FN_BY_KEY[key], column: aggColumn };
4591
4625
  }
4592
4626
  terms.push({ agg, direction });
@@ -5036,7 +5070,7 @@ function buildQuery(params) {
5036
5070
  throw validationError4({ message: "A conflict update requires an explicit target" });
5037
5071
  const updates = requireObject({ value: spec.update, what: "onConflict.update", model });
5038
5072
  const fields = resolveUpsertUpdateFields({ model, update: Object.keys(updates), targetColumns: new Set(compiled.columns ?? []), skipUpdatedAt: true });
5039
- const columns2 = Object.fromEntries(model.fields.map((field) => [field.name, field.columnName]));
5073
+ const columns = Object.fromEntries(model.fields.map((field) => [field.name, field.columnName]));
5040
5074
  conflictClause = {
5041
5075
  columns: compiled.columns ?? [],
5042
5076
  ...compiled.constraint === undefined ? {} : { constraint: compiled.constraint },
@@ -5045,7 +5079,7 @@ function buildQuery(params) {
5045
5079
  const fragment = updates[field.name];
5046
5080
  if (!isSqlFragment(fragment))
5047
5081
  throw validationError4({ message: "Conflict update expressions must be constructed SQL fragments" });
5048
- return [field.columnName, mapConflictColumns({ fragment, columns: columns2 })];
5082
+ return [field.columnName, mapConflictColumns({ fragment, columns })];
5049
5083
  }))
5050
5084
  };
5051
5085
  } else
@@ -5283,7 +5317,7 @@ function buildQuery(params) {
5283
5317
  const targetFields = conflictTargetGroup({ model, where }).fields;
5284
5318
  for (const field of targetFields) {
5285
5319
  if (!(field.columnName in row.values)) {
5286
- throw new VibeError10({
5320
+ throw new VibeError11({
5287
5321
  code: "VIBE_INTERNAL",
5288
5322
  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`,
5289
5323
  meta: { model: model.name, column: field.columnName }
@@ -5294,7 +5328,7 @@ function buildQuery(params) {
5294
5328
  for (const [key, value] of Object.entries(where)) {
5295
5329
  if (value === undefined || nativeTargetNames.has(key))
5296
5330
  continue;
5297
- throw new VibeError10({
5331
+ throw new VibeError11({
5298
5332
  code: "VIBE_INTERNAL",
5299
5333
  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`,
5300
5334
  meta: { model: model.name, field: key }
@@ -5346,8 +5380,95 @@ function buildQuery(params) {
5346
5380
  // packages/runtime/src/diagnostics/preview.ts
5347
5381
  import { getSqlDialect, renderStatement } from "@vibeorm/sql";
5348
5382
 
5383
+ // packages/runtime/src/extensions.ts
5384
+ import { VibeError as VibeError12, extensionManifestEntry } from "@vibeorm/schema";
5385
+ function assertExtensionManifest(params) {
5386
+ const { manifest } = params;
5387
+ const instances = params.instances ?? [];
5388
+ const live = new Map(instances.map((extension) => [extension.name, extensionManifestEntry({ extension })]));
5389
+ const problems = [];
5390
+ for (const baked of manifest) {
5391
+ const current = live.get(baked.name);
5392
+ if (current === undefined) {
5393
+ problems.push(`"${baked.name}" was baked into the client but not passed to VibeClient`);
5394
+ continue;
5395
+ }
5396
+ if (current.version !== baked.version) {
5397
+ problems.push(`"${baked.name}" version changed (generated ${baked.version}, live ${current.version})`);
5398
+ } else if (current.optionsHash !== baked.optionsHash) {
5399
+ problems.push(`"${baked.name}" options changed since generate`);
5400
+ }
5401
+ live.delete(baked.name);
5402
+ }
5403
+ for (const name of live.keys()) {
5404
+ problems.push(`"${name}" is configured but missing from the generated client`);
5405
+ }
5406
+ if (problems.length > 0) {
5407
+ throw new VibeError12({
5408
+ code: "VIBE_STALE_CLIENT",
5409
+ message: `extension list changed since generate; run vibeorm generate \u2014 ${problems.join("; ")}`,
5410
+ meta: { manifest, problems }
5411
+ });
5412
+ }
5413
+ }
5414
+ function buildExtensionOperatorMap(params) {
5415
+ const { instances, dialect, provider } = params;
5416
+ const map = new Map;
5417
+ const owner = new Map;
5418
+ for (const extension of instances) {
5419
+ for (const operator of extension.sql?.whereOperators ?? []) {
5420
+ const existing = owner.get(operator.name);
5421
+ if (existing !== undefined) {
5422
+ throw new VibeError12({
5423
+ code: "VIBE_CONFIG",
5424
+ message: `where operator "${operator.name}" is claimed by both "${existing}" and "${extension.name}"`,
5425
+ meta: { operator: operator.name }
5426
+ });
5427
+ }
5428
+ owner.set(operator.name, extension.name);
5429
+ map.set(operator.name, ({ column, operand, model, field }) => {
5430
+ const compiled = operator.compile({
5431
+ column,
5432
+ operand,
5433
+ dialect,
5434
+ provider,
5435
+ options: extension.options
5436
+ });
5437
+ if ("error" in compiled) {
5438
+ throw new VibeError12({
5439
+ code: "VIBE_VALIDATION",
5440
+ message: `"${operator.name}" on ${model}.${field}: ${compiled.error}`,
5441
+ meta: { model, field, operator: operator.name, extension: extension.name }
5442
+ });
5443
+ }
5444
+ return { kind: "fragment", fragment: compiled.fragment };
5445
+ });
5446
+ }
5447
+ }
5448
+ return map.size === 0 ? null : map;
5449
+ }
5450
+ function buildConnectHooks(params) {
5451
+ const { instances, dialect, provider } = params;
5452
+ const hooks = [];
5453
+ for (const extension of instances) {
5454
+ const onConnect = extension.runtime?.onConnect;
5455
+ if (onConnect === undefined)
5456
+ continue;
5457
+ hooks.push(({ execute }) => onConnect({
5458
+ execute: (execParams) => execute({
5459
+ text: execParams.text,
5460
+ ...execParams.values === undefined ? {} : { values: execParams.values }
5461
+ }),
5462
+ dialect,
5463
+ provider,
5464
+ options: extension.options
5465
+ }));
5466
+ }
5467
+ return hooks;
5468
+ }
5469
+
5349
5470
  // packages/runtime/src/relation-key.ts
5350
- import { VibeError as VibeError11 } from "@vibeorm/schema";
5471
+ import { VibeError as VibeError13 } from "@vibeorm/schema";
5351
5472
  function relationValueKey(params) {
5352
5473
  const { value } = params;
5353
5474
  if (value === null || value === undefined)
@@ -5380,7 +5501,7 @@ function relationTupleKey(params) {
5380
5501
  if (value === null || value === undefined)
5381
5502
  return null;
5382
5503
  if (typeof value === "object" && !(value instanceof Date) && !(value instanceof Uint8Array)) {
5383
- throw new VibeError11({
5504
+ throw new VibeError13({
5384
5505
  code: "VIBE_UNSUPPORTED_CAPABILITY",
5385
5506
  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",
5386
5507
  meta: { received: Object.prototype.toString.call(value) }
@@ -5406,7 +5527,7 @@ function assertWriteScope(params) {
5406
5527
  }
5407
5528
 
5408
5529
  // packages/runtime/src/nested-writes.ts
5409
- import { VibeError as VibeError12 } from "@vibeorm/schema";
5530
+ import { VibeError as VibeError14 } from "@vibeorm/schema";
5410
5531
  function parentTupleOf(params) {
5411
5532
  const { link, row } = params;
5412
5533
  return link.parentKeys.map((field) => row[field.name]);
@@ -5453,10 +5574,10 @@ function detachAssignment(params) {
5453
5574
  return out;
5454
5575
  }
5455
5576
  function validationError5(params) {
5456
- return new VibeError12({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
5577
+ return new VibeError14({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
5457
5578
  }
5458
5579
  function notFound(params) {
5459
- return new VibeError12({ code: "VIBE_NOT_FOUND", message: params.message, meta: params.meta });
5580
+ return new VibeError14({ code: "VIBE_NOT_FOUND", message: params.message, meta: params.meta });
5460
5581
  }
5461
5582
  function isPlainObject4(value) {
5462
5583
  return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date) && !(value instanceof Uint8Array);
@@ -5601,7 +5722,7 @@ function chunkKeyList(params) {
5601
5722
  const { dialect, keys, perKey, reserved } = params;
5602
5723
  if (keys.length === 0)
5603
5724
  return [];
5604
- if (dialect.inArrayStrategy !== "expand")
5725
+ if (params.expanded !== true && dialect.inArrayStrategy !== "expand")
5605
5726
  return [keys];
5606
5727
  const size = Math.max(1, Math.floor((dialect.paramBudget - reserved) / perKey));
5607
5728
  const chunks = [];
@@ -5638,27 +5759,30 @@ async function deleteJoinRows(params) {
5638
5759
  const join = link.join;
5639
5760
  const pair = singleKeyPair({ link, what: "implicit many-to-many writes" });
5640
5761
  const parentValue = encodeValue({ dialect: dialect.name, field: pair.parent, value: parentKey });
5641
- await run.statement({
5642
- statement: {
5643
- kind: "delete",
5644
- table: { name: join.tableName },
5645
- where: {
5646
- kind: "and",
5647
- operands: [
5648
- { kind: "cmp", op: "eq", column: { name: join.parentColumn }, value: parentValue },
5649
- ...childKeys === undefined ? [] : [
5650
- {
5651
- kind: "inArray",
5652
- column: { name: join.childColumn },
5653
- values: childKeys.map((key) => encodeValue({ dialect: dialect.name, field: pair.child, value: key }))
5654
- }
5762
+ const chunks = childKeys === undefined ? [undefined] : chunkKeyList({ dialect, keys: childKeys, perKey: 1, reserved: 1 });
5763
+ for (const chunk of chunks) {
5764
+ await run.statement({
5765
+ statement: {
5766
+ kind: "delete",
5767
+ table: { name: join.tableName },
5768
+ where: {
5769
+ kind: "and",
5770
+ operands: [
5771
+ { kind: "cmp", op: "eq", column: { name: join.parentColumn }, value: parentValue },
5772
+ ...chunk === undefined ? [] : [
5773
+ {
5774
+ kind: "inArray",
5775
+ column: { name: join.childColumn },
5776
+ values: chunk.map((key) => encodeValue({ dialect: dialect.name, field: pair.child, value: key }))
5777
+ }
5778
+ ]
5655
5779
  ]
5656
- ]
5657
- }
5658
- },
5659
- model: link.relation.model,
5660
- method: "nested.disconnect"
5661
- });
5780
+ }
5781
+ },
5782
+ model: link.relation.model,
5783
+ method: "nested.disconnect"
5784
+ });
5785
+ }
5662
5786
  }
5663
5787
  async function assertM2MMembers(params) {
5664
5788
  const { run, ctx, link, parentKey, childKeys, target, verb, relation } = params;
@@ -5666,10 +5790,10 @@ async function assertM2MMembers(params) {
5666
5790
  return;
5667
5791
  const members = await loadMemberKeys({ run, ctx, link, parentKey, childKeys });
5668
5792
  const pair = singleKeyPair({ link, what: "implicit many-to-many writes" });
5669
- const connected = new Set(members.map((member) => String(member)));
5793
+ const connected = new Set(members.map((member) => relationValueKey({ value: decodeValue({ dialect: ctx.dialect.name, field: pair.child, value: member }) })));
5670
5794
  for (const childKey of childKeys) {
5671
- const childValue = encodeValue({ dialect: ctx.dialect.name, field: pair.child, value: childKey });
5672
- if (connected.has(String(childValue)))
5795
+ const childValue = decodeValue({ dialect: ctx.dialect.name, field: pair.child, value: childKey });
5796
+ if (connected.has(relationValueKey({ value: childValue })))
5673
5797
  continue;
5674
5798
  throw notFound({
5675
5799
  message: `nested "${verb}" on ${link.relation.model}.${relation}: ${target} is not connected`,
@@ -5760,7 +5884,7 @@ function isFilterableUniqueWhere(params) {
5760
5884
  return isUniqueWhere({ model: target, where });
5761
5885
  }
5762
5886
  async function connectChildrenByFk(params) {
5763
- const { run, op, items, fk, verb } = params;
5887
+ const { dialect, run, op, items, fk, verb } = params;
5764
5888
  const target = op.link.target;
5765
5889
  if (items.length === 0)
5766
5890
  return;
@@ -5771,11 +5895,18 @@ async function connectChildrenByFk(params) {
5771
5895
  }
5772
5896
  return;
5773
5897
  }
5774
- const affected = await run.affected({
5775
- model: target.name,
5776
- method: "updateMany",
5777
- args: { where: { OR: items.map((item) => ({ ...item })) }, data: fk }
5778
- });
5898
+ let perKey = 1;
5899
+ for (const item of items)
5900
+ perKey = Math.max(perKey, Object.values(item).filter((value) => value !== undefined && value !== null).length);
5901
+ const reserved = Object.values(fk).filter((value) => value !== undefined).length + target.fields.filter((field) => field.isUpdatedAt && fk[field.name] === undefined).length;
5902
+ let affected = 0;
5903
+ for (const chunk of chunkKeyList({ dialect, keys: items, perKey, reserved, expanded: true })) {
5904
+ affected += await run.affected({
5905
+ model: target.name,
5906
+ method: "updateMany",
5907
+ args: { where: { OR: chunk.map((item) => ({ ...item })) }, data: fk }
5908
+ });
5909
+ }
5779
5910
  if (affected >= items.length)
5780
5911
  return;
5781
5912
  for (const item of items) {
@@ -5845,7 +5976,7 @@ async function applyChildCreateOps(params) {
5845
5976
  continue;
5846
5977
  }
5847
5978
  if (verb === "connect") {
5848
- await connectChildrenByFk({ run, op, items, fk, verb });
5979
+ await connectChildrenByFk({ dialect: ctx.dialect, run, op, items, fk, verb });
5849
5980
  continue;
5850
5981
  }
5851
5982
  for (const item of items) {
@@ -6082,7 +6213,8 @@ async function loadMemberKeys(params) {
6082
6213
  const values = childKeys.map((childKey) => encodeValue({ dialect: ctx.dialect.name, field: pair.child, value: childKey }));
6083
6214
  const found = [];
6084
6215
  for (const chunk of chunkKeyList({ dialect: ctx.dialect, keys: values, perKey: 1, reserved: 1 })) {
6085
- found.push(...await scan(chunk));
6216
+ for (const member of await scan(chunk))
6217
+ found.push(member);
6086
6218
  }
6087
6219
  return found;
6088
6220
  }
@@ -6128,7 +6260,7 @@ async function applyChildUpdateOps(params) {
6128
6260
  method: "updateMany",
6129
6261
  args: { where: fk, data: detach }
6130
6262
  });
6131
- await connectChildrenByFk({ run, op, items, fk, verb });
6263
+ await connectChildrenByFk({ dialect: ctx.dialect, run, op, items, fk, verb });
6132
6264
  }
6133
6265
  break;
6134
6266
  }
@@ -6578,7 +6710,9 @@ function previewOperation(params) {
6578
6710
  const { schema, model, method, args, relationStrategy, clientOptions } = params;
6579
6711
  const includeValues = params.includeParameterValues === true;
6580
6712
  const dialect = getSqlDialect({ dialect: params.dialect });
6581
- const meta = buildRuntimeMeta({ schema });
6713
+ const baseMeta = buildRuntimeMeta({ schema });
6714
+ const operatorMap = buildExtensionOperatorMap({ instances: params.extensions ?? [], dialect: params.dialect, provider: schema.datasource.provider });
6715
+ const meta = operatorMap === null ? baseMeta : { ...baseMeta, extensionOperators: operatorMap };
6582
6716
  const modelMeta = getModelMeta({ meta, model });
6583
6717
  const writesNested = (method === "create" || method === "update" || method === "upsert") && (hasNestedWrites({ model: modelMeta, data: args?.data }) || hasNestedWrites({ model: modelMeta, data: args?.create }) || hasNestedWrites({ model: modelMeta, data: args?.update }));
6584
6718
  const effectiveArgs = args === undefined || !writesNested ? args : {
@@ -6660,7 +6794,7 @@ function previewOperation(params) {
6660
6794
  };
6661
6795
  }
6662
6796
  // packages/runtime/src/diagnostics/plan.ts
6663
- import { VibeError as VibeError13, unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
6797
+ import { VibeError as VibeError15, unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
6664
6798
  import { NATIVE_RLS, getSqlDialect as getSqlDialect2, renderPostgresExplain, renderPostgresWorkload, renderStatement as renderStatement2 } from "@vibeorm/sql";
6665
6799
  var PLAN_DEFAULTS = Object.freeze({ maxNodes: 200, maxConditionLength: 2000 });
6666
6800
  var CONDITION_KEYS = [
@@ -6679,7 +6813,7 @@ var CONDITION_KEYS = [
6679
6813
  "Output"
6680
6814
  ];
6681
6815
  function planError(params) {
6682
- return new VibeError13({ code: "VIBE_ADAPTER", message: params.message, meta: {} });
6816
+ return new VibeError15({ code: "VIBE_ADAPTER", message: params.message, meta: {} });
6683
6817
  }
6684
6818
  function asRecord(value) {
6685
6819
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
@@ -6712,14 +6846,14 @@ function parsePostgresPlan(params) {
6712
6846
  const maxNodes = params.maxNodes ?? PLAN_DEFAULTS.maxNodes;
6713
6847
  const includeLiterals = params.includeLiterals === true;
6714
6848
  if (!Number.isInteger(maxNodes) || maxNodes < 1) {
6715
- throw new VibeError13({ code: "VIBE_CONFIG", message: `maxNodes must be a positive integer, got ${String(maxNodes)}`, meta: { maxNodes } });
6849
+ throw new VibeError15({ code: "VIBE_CONFIG", message: `maxNodes must be a positive integer, got ${String(maxNodes)}`, meta: { maxNodes } });
6716
6850
  }
6717
6851
  let parsed = payload;
6718
6852
  if (typeof payload === "string") {
6719
6853
  try {
6720
6854
  parsed = JSON.parse(payload);
6721
6855
  } catch {
6722
- throw new VibeError13({
6856
+ throw new VibeError15({
6723
6857
  code: "VIBE_ADAPTER",
6724
6858
  message: "EXPLAIN returned malformed JSON",
6725
6859
  meta: { reason: "malformed-plan-json", mode }
@@ -6787,7 +6921,7 @@ function parsePostgresPlan(params) {
6787
6921
  var WRITE_LEADERS = ["INSERT", "UPDATE", "DELETE", "MERGE", "TRUNCATE", "CREATE", "DROP", "ALTER", "GRANT", "REVOKE", "COPY", "CALL", "DO"];
6788
6922
  var SIDE_EFFECT_CALLS = /\bpg_(?:try_)?advisory_(?:xact_)?lock(?:_shared)?\s*\(/i;
6789
6923
  function refuse(params) {
6790
- return new VibeError13({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta ?? {} });
6924
+ return new VibeError15({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta ?? {} });
6791
6925
  }
6792
6926
  function executableReadRefusal(params) {
6793
6927
  const normalized = normalizeSql({ text: params.text });
@@ -6847,7 +6981,7 @@ function requirePostgres(params) {
6847
6981
  return getSqlDialect2({ dialect: params.dialect });
6848
6982
  }
6849
6983
  async function explainSql(params) {
6850
- const { executor, sql: sql2, rlsContext } = params;
6984
+ const { executor, sql, rlsContext } = params;
6851
6985
  const mode = params.mode ?? "estimate";
6852
6986
  const dialect = requirePostgres({ dialect: params.dialect });
6853
6987
  const warnings = [];
@@ -6864,7 +6998,7 @@ async function explainSql(params) {
6864
6998
  meta: { mode }
6865
6999
  });
6866
7000
  }
6867
- assertExecutableRead({ text: sql2.text });
7001
+ assertExecutableRead({ text: sql.text });
6868
7002
  warnings.push("this statement was EXECUTED to produce observed rows and milliseconds; a read-only transaction and a keyword check are not a proof of safety, because a SELECT can call a function with side effects");
6869
7003
  }
6870
7004
  const contextKeys = rlsContext === undefined ? [] : Object.keys(rlsContext);
@@ -6880,7 +7014,7 @@ async function explainSql(params) {
6880
7014
  const report = await explainOnSession({
6881
7015
  executor,
6882
7016
  dialect: params.dialect,
6883
- sql: sql2,
7017
+ sql,
6884
7018
  mode,
6885
7019
  warnings,
6886
7020
  ...rlsContext === undefined ? {} : { rlsContext },
@@ -6899,7 +7033,7 @@ async function explainSql(params) {
6899
7033
  }
6900
7034
  }
6901
7035
  async function explainOnSession(params) {
6902
- const { executor, sql: sql2, mode, rlsContext } = params;
7036
+ const { executor, sql, mode, rlsContext } = params;
6903
7037
  const dialect = requirePostgres({ dialect: params.dialect });
6904
7038
  const warnings = params.warnings ?? [];
6905
7039
  const contextKeys = rlsContext === undefined ? [] : Object.keys(rlsContext);
@@ -6917,7 +7051,7 @@ async function explainOnSession(params) {
6917
7051
  const context = await readPlanContext({ executor, dialect, rlsContextKeys: contextKeys });
6918
7052
  if (!context.representative) {
6919
7053
  if (params.requireRepresentativeContext === true) {
6920
- throw new VibeError13({
7054
+ throw new VibeError15({
6921
7055
  code: "VIBE_RLS_CONTEXT",
6922
7056
  message: `refusing to report a plan taken under a non-representative identity: ${context.reason ?? "role bypasses row policies"}`,
6923
7057
  meta: { currentUser: context.currentUser, bypassRls: context.bypassRls, superuser: context.superuser }
@@ -6927,7 +7061,7 @@ async function explainOnSession(params) {
6927
7061
  }
6928
7062
  const explain = renderPostgresExplain({
6929
7063
  dialect,
6930
- query: { text: sql2.text, values: [...sql2.values], returning: "none" },
7064
+ query: { text: sql.text, values: [...sql.values], returning: "none" },
6931
7065
  options: mode === "analyze" ? { analyze: true, buffers: true } : {}
6932
7066
  });
6933
7067
  const rows = await run(explain);
@@ -6960,7 +7094,9 @@ async function explainOperation(params) {
6960
7094
  const { schema, model, method, args } = params;
6961
7095
  const dialect = requirePostgres({ dialect: params.dialect });
6962
7096
  const mode = params.mode ?? "estimate";
6963
- const meta = buildRuntimeMeta({ schema });
7097
+ const baseMeta = buildRuntimeMeta({ schema });
7098
+ const operatorMap = buildExtensionOperatorMap({ instances: params.extensions ?? [], dialect: params.dialect, provider: schema.datasource.provider });
7099
+ const meta = operatorMap === null ? baseMeta : { ...baseMeta, extensionOperators: operatorMap };
6964
7100
  const plan = buildQuery({
6965
7101
  meta,
6966
7102
  dialect,
@@ -6991,18 +7127,19 @@ async function explainOperation(params) {
6991
7127
  });
6992
7128
  }
6993
7129
  // packages/runtime/src/diagnostics/statement-diagnostics.ts
6994
- import { VibeError as VibeError14 } from "@vibeorm/schema";
7130
+ import { VibeError as VibeError16 } from "@vibeorm/schema";
6995
7131
  import { renderPostgresWorkload as renderPostgresWorkload2 } from "@vibeorm/sql";
6996
7132
  var STATEMENT_DIAGNOSTICS_DEFAULTS = Object.freeze({
6997
7133
  slowerThanMs: 0,
6998
7134
  explain: "off",
6999
7135
  explainTimeoutMs: 5000,
7136
+ maxOutstandingExplains: 4,
7000
7137
  analyzeWarnBelowMs: 1,
7001
7138
  envVariable: "VIBEORM_DIAGNOSTICS"
7002
7139
  });
7003
7140
  var EXPLAIN_MODES = ["off", "estimate", "analyze"];
7004
7141
  function configError(params) {
7005
- return new VibeError14({ code: "VIBE_CONFIG", message: params.message, meta: params.meta ?? {} });
7142
+ return new VibeError16({ code: "VIBE_CONFIG", message: params.message, meta: params.meta ?? {} });
7006
7143
  }
7007
7144
  function isExplainMode(value) {
7008
7145
  return typeof value === "string" && EXPLAIN_MODES.includes(value);
@@ -7128,7 +7265,7 @@ function summarizePlan(params) {
7128
7265
  };
7129
7266
  }
7130
7267
  function errorCode(error) {
7131
- return error instanceof VibeError14 ? error.code : "VIBE_INTERNAL";
7268
+ return error instanceof VibeError16 ? error.code : "VIBE_INTERNAL";
7132
7269
  }
7133
7270
  function createStatementDiagnostics(params) {
7134
7271
  const { config, adapter, dialect } = params;
@@ -7151,7 +7288,7 @@ function createStatementDiagnostics(params) {
7151
7288
  text: query.text,
7152
7289
  values: (query.values ?? []).map((value) => Array.isArray(value) ? tx.formatArrayParam(value) : value)
7153
7290
  });
7154
- const report2 = await explainOnSession({
7291
+ const report = await explainOnSession({
7155
7292
  executor,
7156
7293
  dialect: dialect.name,
7157
7294
  sql: { text: statement.text, values: statement.values },
@@ -7160,11 +7297,11 @@ function createStatementDiagnostics(params) {
7160
7297
  });
7161
7298
  return summarizePlan({
7162
7299
  plan: {
7163
- root: report2.root,
7164
- nodeCount: report2.nodeCount,
7165
- truncated: report2.truncated,
7166
- ...report2.planningTimeMs === undefined ? {} : { planningTimeMs: report2.planningTimeMs },
7167
- ...report2.executionTimeMs === undefined ? {} : { executionTimeMs: report2.executionTimeMs }
7300
+ root: report.root,
7301
+ nodeCount: report.nodeCount,
7302
+ truncated: report.truncated,
7303
+ ...report.planningTimeMs === undefined ? {} : { planningTimeMs: report.planningTimeMs },
7304
+ ...report.executionTimeMs === undefined ? {} : { executionTimeMs: report.executionTimeMs }
7168
7305
  },
7169
7306
  mode
7170
7307
  });
@@ -7215,6 +7352,10 @@ function createStatementDiagnostics(params) {
7215
7352
  report({ ...base, explainSkipped: "not-a-read" });
7216
7353
  return;
7217
7354
  }
7355
+ if (outstanding.size >= STATEMENT_DIAGNOSTICS_DEFAULTS.maxOutstandingExplains) {
7356
+ report({ ...base, explainSkipped: "overload" });
7357
+ return;
7358
+ }
7218
7359
  schedule(statement, config.explain, base);
7219
7360
  },
7220
7361
  flush: async () => {
@@ -7346,7 +7487,7 @@ async function readWorkloadStatistics(params) {
7346
7487
  };
7347
7488
  }
7348
7489
  // packages/runtime/src/diagnostics/insight.ts
7349
- import { VibeError as VibeError15 } from "@vibeorm/schema";
7490
+ import { VibeError as VibeError17 } from "@vibeorm/schema";
7350
7491
  var DIAGNOSTIC_THRESHOLDS = Object.freeze({
7351
7492
  repeatThreshold: 5,
7352
7493
  minRepeatThreshold: 2,
@@ -7364,7 +7505,7 @@ function bounded(params) {
7364
7505
  if (value === undefined)
7365
7506
  return fallback;
7366
7507
  if (!Number.isInteger(value) || value < min || value > max) {
7367
- throw new VibeError15({
7508
+ throw new VibeError17({
7368
7509
  code: "VIBE_CONFIG",
7369
7510
  message: `${name} must be an integer between ${min} and ${max}, got ${String(value)}`,
7370
7511
  meta: { [name]: value }
@@ -7509,13 +7650,13 @@ function recommendFromPlan(params) {
7509
7650
  candidate: false
7510
7651
  });
7511
7652
  } else {
7512
- const removed2 = node.rowsRemovedByFilter;
7653
+ const removed = node.rowsRemovedByFilter;
7513
7654
  findings.push({
7514
7655
  code: "sequential-scan-on-large-table",
7515
7656
  severity: "warn",
7516
7657
  node: node.nodeType,
7517
7658
  relation,
7518
- evidence: `sequential scan over "${relation}" (about ${facts.estimatedRows} rows, planner cost ${node.estimatedTotalCost} cost units)` + (removed2 === undefined ? "" : `, discarding ${removed2} rows by filter`) + (node.actualRows === undefined ? "" : `, returning ${node.actualRows}`),
7659
+ evidence: `sequential scan over "${relation}" (about ${facts.estimatedRows} rows, planner cost ${node.estimatedTotalCost} cost units)` + (removed === undefined ? "" : `, discarding ${removed} rows by filter`) + (node.actualRows === undefined ? "" : `, returning ${node.actualRows}`),
7519
7660
  candidate: true,
7520
7661
  indexCandidate: {
7521
7662
  table: relation,
@@ -7587,11 +7728,11 @@ function recommendFromPlan(params) {
7587
7728
  return findings.slice(0, maxFindings);
7588
7729
  }
7589
7730
  // packages/runtime/src/relation-loader.ts
7590
- import { VibeError as VibeError17 } from "@vibeorm/schema";
7731
+ import { VibeError as VibeError19 } from "@vibeorm/schema";
7591
7732
  import { renderStatement as renderStatement3 } from "@vibeorm/sql";
7592
7733
 
7593
7734
  // packages/runtime/src/computed.ts
7594
- import { VibeError as VibeError16 } from "@vibeorm/schema";
7735
+ import { VibeError as VibeError18 } from "@vibeorm/schema";
7595
7736
  function sameNeeds(a, b) {
7596
7737
  if (a.length !== b.length)
7597
7738
  return false;
@@ -7627,7 +7768,7 @@ function assertComputedManifest(params) {
7627
7768
  problems.push(`"${key}" is configured but missing from the generated client`);
7628
7769
  }
7629
7770
  if (problems.length > 0) {
7630
- throw new VibeError16({
7771
+ throw new VibeError18({
7631
7772
  code: "VIBE_STALE_CLIENT",
7632
7773
  message: `computed-field config changed since generate; run vibeorm generate \u2014 ${problems.join("; ")}`,
7633
7774
  meta: { problems }
@@ -7655,7 +7796,7 @@ function resolveRelationConcurrency(params) {
7655
7796
  if (concurrency === undefined)
7656
7797
  return 1;
7657
7798
  if (!Number.isInteger(concurrency) || concurrency < 1) {
7658
- throw new VibeError17({
7799
+ throw new VibeError19({
7659
7800
  code: "VIBE_CONFIG",
7660
7801
  message: `relationLoading.concurrency must be a positive integer \u2014 got ${String(concurrency)}`,
7661
7802
  meta: { concurrency }
@@ -7840,7 +7981,7 @@ function chunkKeys(params) {
7840
7981
  const rendered = renderStatement3({ dialect: ctx.dialect, statement: build(keys.slice(0, 1)) });
7841
7982
  fixed = rendered.values.length - (expands ? arity : 1);
7842
7983
  if (fixed + arity > budget) {
7843
- throw new VibeError17({
7984
+ throw new VibeError19({
7844
7985
  code: "VIBE_UNSUPPORTED_CAPABILITY",
7845
7986
  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`,
7846
7987
  meta: { relation, dialect: ctx.dialect.name, required: fixed + arity, budget }
@@ -7970,7 +8111,7 @@ async function loadManyToMany(params) {
7970
8111
  const link = node.link;
7971
8112
  const join = link.join;
7972
8113
  if (join === null) {
7973
- throw new VibeError17({
8114
+ throw new VibeError19({
7974
8115
  code: "VIBE_INTERNAL",
7975
8116
  message: `manyToMany relation "${node.name}" resolved without join-table wiring`
7976
8117
  });
@@ -8066,8 +8207,8 @@ async function loadManyToMany(params) {
8066
8207
  for (const pair of pairs) {
8067
8208
  const rawParent = pair[M2M_PARENT_ALIAS];
8068
8209
  delete pair[M2M_PARENT_ALIAS];
8069
- const parentKey2 = decodeParent === null || rawParent === null || rawParent === undefined ? rawParent : decodeParent(rawParent);
8070
- const key = relationValueKey({ value: parentKey2 });
8210
+ const parentKey = decodeParent === null || rawParent === null || rawParent === undefined ? rawParent : decodeParent(rawParent);
8211
+ const key = relationValueKey({ value: parentKey });
8071
8212
  const group = groups.get(key);
8072
8213
  if (group === undefined)
8073
8214
  groups.set(key, [pair]);
@@ -8262,12 +8403,12 @@ async function attachLateralRelations(params) {
8262
8403
  for (const row of rows) {
8263
8404
  const raw = row[column];
8264
8405
  delete row[column];
8265
- let parsed2 = raw;
8406
+ let parsed = raw;
8266
8407
  if (typeof raw === "string") {
8267
8408
  try {
8268
- parsed2 = JSON.parse(raw);
8409
+ parsed = JSON.parse(raw);
8269
8410
  } catch (cause) {
8270
- throw new VibeError17({
8411
+ throw new VibeError19({
8271
8412
  code: "VIBE_INTERNAL",
8272
8413
  message: `relation column "${column}" returned text that is not valid JSON`,
8273
8414
  meta: { relation: node.name },
@@ -8276,10 +8417,10 @@ async function attachLateralRelations(params) {
8276
8417
  }
8277
8418
  }
8278
8419
  if (isList) {
8279
- if (!Array.isArray(parsed2)) {
8280
- throw new VibeError17({ code: "VIBE_INTERNAL", message: "to-many relation payload must be an array", meta: { relation: node.name } });
8420
+ if (!Array.isArray(parsed)) {
8421
+ throw new VibeError19({ code: "VIBE_INTERNAL", message: "to-many relation payload must be an array", meta: { relation: node.name } });
8281
8422
  }
8282
- const children = parsed2.map(decodePosition);
8423
+ const children = parsed.map(decodePosition);
8283
8424
  for (const child of children) {
8284
8425
  for (const name of hiddenOrder)
8285
8426
  delete child[name];
@@ -8287,11 +8428,11 @@ async function attachLateralRelations(params) {
8287
8428
  row[node.name] = children;
8288
8429
  pushAll(kept, children);
8289
8430
  } else {
8290
- if (parsed2 === null) {
8431
+ if (parsed === null) {
8291
8432
  row[node.name] = null;
8292
8433
  continue;
8293
8434
  }
8294
- const child = decodePosition(parsed2);
8435
+ const child = decodePosition(parsed);
8295
8436
  for (const name of hiddenOrder)
8296
8437
  delete child[name];
8297
8438
  row[node.name] = child;
@@ -8318,7 +8459,7 @@ async function attachLateralRelations(params) {
8318
8459
  const raw = row[column];
8319
8460
  const count = typeof raw === "number" || typeof raw === "bigint" || typeof raw === "string" && /^\d+$/.test(raw) ? Number(raw) : NaN;
8320
8461
  if (!Number.isSafeInteger(count) || count < 0) {
8321
- throw new VibeError17({ code: "VIBE_INTERNAL", message: "relation count payload must be a non-negative safe integer", meta: { relation: selection.counts[index]?.name } });
8462
+ throw new VibeError19({ code: "VIBE_INTERNAL", message: "relation count payload must be a non-negative safe integer", meta: { relation: selection.counts[index]?.name } });
8322
8463
  }
8323
8464
  counts[selection.counts[index].name] = count;
8324
8465
  delete row[column];
@@ -8326,97 +8467,12 @@ async function attachLateralRelations(params) {
8326
8467
  row._count = counts;
8327
8468
  }
8328
8469
  }
8329
- // packages/runtime/src/extensions.ts
8330
- import { VibeError as VibeError18, extensionManifestEntry } from "@vibeorm/schema";
8331
- function assertExtensionManifest(params) {
8332
- const { manifest } = params;
8333
- const instances = params.instances ?? [];
8334
- const live = new Map(instances.map((extension) => [extension.name, extensionManifestEntry({ extension })]));
8335
- const problems = [];
8336
- for (const baked of manifest) {
8337
- const current = live.get(baked.name);
8338
- if (current === undefined) {
8339
- problems.push(`"${baked.name}" was baked into the client but not passed to VibeClient`);
8340
- continue;
8341
- }
8342
- if (current.version !== baked.version) {
8343
- problems.push(`"${baked.name}" version changed (generated ${baked.version}, live ${current.version})`);
8344
- } else if (current.optionsHash !== baked.optionsHash) {
8345
- problems.push(`"${baked.name}" options changed since generate`);
8346
- }
8347
- live.delete(baked.name);
8348
- }
8349
- for (const name of live.keys()) {
8350
- problems.push(`"${name}" is configured but missing from the generated client`);
8351
- }
8352
- if (problems.length > 0) {
8353
- throw new VibeError18({
8354
- code: "VIBE_STALE_CLIENT",
8355
- message: `extension list changed since generate; run vibeorm generate \u2014 ${problems.join("; ")}`,
8356
- meta: { manifest, problems }
8357
- });
8358
- }
8359
- }
8360
- function buildExtensionOperatorMap(params) {
8361
- const { instances, dialect, provider } = params;
8362
- const map = new Map;
8363
- const owner = new Map;
8364
- for (const extension of instances) {
8365
- for (const operator of extension.sql?.whereOperators ?? []) {
8366
- const existing = owner.get(operator.name);
8367
- if (existing !== undefined) {
8368
- throw new VibeError18({
8369
- code: "VIBE_CONFIG",
8370
- message: `where operator "${operator.name}" is claimed by both "${existing}" and "${extension.name}"`,
8371
- meta: { operator: operator.name }
8372
- });
8373
- }
8374
- owner.set(operator.name, extension.name);
8375
- map.set(operator.name, ({ column, operand, model, field }) => {
8376
- const compiled = operator.compile({
8377
- column,
8378
- operand,
8379
- dialect,
8380
- provider,
8381
- options: extension.options
8382
- });
8383
- if ("error" in compiled) {
8384
- throw new VibeError18({
8385
- code: "VIBE_VALIDATION",
8386
- message: `"${operator.name}" on ${model}.${field}: ${compiled.error}`,
8387
- meta: { model, field, operator: operator.name, extension: extension.name }
8388
- });
8389
- }
8390
- return { kind: "fragment", fragment: compiled.fragment };
8391
- });
8392
- }
8393
- }
8394
- return map.size === 0 ? null : map;
8395
- }
8396
- function buildConnectHooks(params) {
8397
- const { instances, dialect, provider } = params;
8398
- const hooks = [];
8399
- for (const extension of instances) {
8400
- const onConnect = extension.runtime?.onConnect;
8401
- if (onConnect === undefined)
8402
- continue;
8403
- hooks.push(({ execute }) => onConnect({
8404
- execute: (execParams) => execute({
8405
- text: execParams.text,
8406
- ...execParams.values === undefined ? {} : { values: execParams.values }
8407
- }),
8408
- dialect,
8409
- provider,
8410
- options: extension.options
8411
- }));
8412
- }
8413
- return hooks;
8414
- }
8415
8470
  // packages/runtime/src/views.ts
8416
- import { VibeError as VibeError20 } from "@vibeorm/schema";
8471
+ import { VibeError as VibeError21 } from "@vibeorm/schema";
8417
8472
 
8418
8473
  // packages/runtime/src/sql-access.ts
8419
- import { VibeError as VibeError19 } from "@vibeorm/schema";
8474
+ import { Buffer as Buffer2 } from "buffer";
8475
+ import { VibeError as VibeError20 } from "@vibeorm/schema";
8420
8476
  import { isSqlFragment as isSqlFragment2 } from "@vibeorm/sql";
8421
8477
  function containsSqlFragment(value, seen = new Set) {
8422
8478
  if (isSqlFragment2(value))
@@ -8424,42 +8480,92 @@ function containsSqlFragment(value, seen = new Set) {
8424
8480
  if (typeof value !== "object" || value === null || seen.has(value))
8425
8481
  return false;
8426
8482
  seen.add(value);
8427
- if (Array.isArray(value))
8428
- return value.some((entry) => containsSqlFragment(entry, seen));
8429
- return Object.values(value).some((entry) => containsSqlFragment(entry, seen));
8483
+ const keys = new Set;
8484
+ for (let object = value;object !== null && object !== Object.prototype; object = Object.getPrototypeOf(object)) {
8485
+ for (const key of Object.getOwnPropertyNames(object)) {
8486
+ if (keys.has(key) || key === "constructor")
8487
+ continue;
8488
+ keys.add(key);
8489
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
8490
+ if (descriptor === undefined)
8491
+ continue;
8492
+ const child = "value" in descriptor ? descriptor.value : object === value && descriptor.enumerable ? value[key] : undefined;
8493
+ if (containsSqlFragment(child, seen))
8494
+ return true;
8495
+ }
8496
+ }
8497
+ return false;
8430
8498
  }
8431
8499
  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 } });
8501
+ if (containsSqlFragment(params.value))
8502
+ throw refuse();
8432
8503
  const seen = new Map;
8433
8504
  const copy = (value) => {
8434
8505
  if (isSqlFragment2(value))
8435
- throw new VibeError19({ code: "VIBE_VALIDATION", message: `SQL fragments are unavailable through ${params.path}; use the unrestricted client`, meta: { path: params.path } });
8506
+ throw refuse();
8436
8507
  if (typeof value !== "object" || value === null)
8437
8508
  return value;
8438
8509
  if (seen.has(value))
8439
8510
  return seen.get(value);
8511
+ let out;
8440
8512
  if (Array.isArray(value)) {
8441
- const out2 = [];
8442
- seen.set(value, out2);
8513
+ const array = [];
8514
+ out = array;
8515
+ seen.set(value, out);
8443
8516
  for (const item of value)
8444
- out2.push(copy(item));
8445
- return out2;
8446
- }
8447
- if (value instanceof Date)
8448
- return new Date(value.getTime());
8449
- if (value instanceof Uint8Array)
8450
- return new Uint8Array(value);
8451
- const out = Object.create(null);
8517
+ array.push(copy(item));
8518
+ } else if (value instanceof Date) {
8519
+ out = new Date(value.getTime());
8520
+ } else if (value instanceof Uint8Array) {
8521
+ out = Buffer2.isBuffer(value) ? Buffer2.from(value) : new Uint8Array(value);
8522
+ } else {
8523
+ const record = Object.create(null);
8524
+ out = record;
8525
+ seen.set(value, out);
8526
+ for (const [key, child] of Object.entries(value)) {
8527
+ if (key !== "toJSON" || typeof child !== "function")
8528
+ record[key] = copy(child);
8529
+ }
8530
+ }
8452
8531
  seen.set(value, out);
8453
- for (const [key, child] of Object.entries(value))
8454
- out[key] = copy(child);
8532
+ const toJSON = value.toJSON;
8533
+ const nativeJson = value instanceof Date && toJSON === Date.prototype.toJSON || Buffer2.isBuffer(value) && toJSON === Buffer2.prototype.toJSON;
8534
+ if (typeof toJSON === "function" && !nativeJson) {
8535
+ Object.defineProperty(out, "toJSON", { enumerable: false, value: (key) => {
8536
+ const result = toJSON.call(value, key);
8537
+ return result === value ? out : restrictedSqlArgs({ ...params, value: result });
8538
+ } });
8539
+ }
8455
8540
  return out;
8456
8541
  };
8457
8542
  return copy(params.value);
8458
8543
  }
8544
+ var conflictSchemas = new WeakMap;
8545
+ function registerRestrictedSqlSchema(params) {
8546
+ conflictSchemas.set(params.meta, new Map(params.schema.models.map((model) => [
8547
+ model.name,
8548
+ model.indexes.flatMap((index) => index.kind === "unique" && index.where !== undefined ? [{ fields: index.fields.map((field) => field.name), where: index.where }] : [])
8549
+ ])));
8550
+ }
8551
+ function restrictConflictPredicates(params) {
8552
+ for (const key of ["onConflict", "skipDuplicates"]) {
8553
+ const option = params.args[key];
8554
+ if (typeof option !== "object" || option === null)
8555
+ continue;
8556
+ const spec = option;
8557
+ if (spec.where === undefined)
8558
+ continue;
8559
+ const target = spec.target;
8560
+ 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
+ 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 } });
8563
+ }
8564
+ }
8459
8565
 
8460
8566
  // packages/runtime/src/views.ts
8461
8567
  function validationError6(params) {
8462
- return new VibeError20({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
8568
+ return new VibeError21({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
8463
8569
  }
8464
8570
 
8465
8571
  class ViewResult {
@@ -8690,9 +8796,9 @@ function mergeLevel(params) {
8690
8796
  continue;
8691
8797
  }
8692
8798
  if (spec === true) {
8693
- const child2 = mergeLevel({ meta, name, definition, mask: targetMask, args: {} });
8694
- select[relationName] = child2.merged;
8695
- relationPlans.set(relationName, child2.plan);
8799
+ const child = mergeLevel({ meta, name, definition, mask: targetMask, args: {} });
8800
+ select[relationName] = child.merged;
8801
+ relationPlans.set(relationName, child.plan);
8696
8802
  continue;
8697
8803
  }
8698
8804
  if (!isPlainObject5(spec)) {
@@ -8813,7 +8919,7 @@ function createView(params) {
8813
8919
  for (const [clientName, mask] of resolved) {
8814
8920
  const delegate = models[clientName];
8815
8921
  if (delegate === undefined) {
8816
- throw new VibeError20({
8922
+ throw new VibeError21({
8817
8923
  code: "VIBE_INTERNAL",
8818
8924
  message: `view "${name}": no delegate for model "${mask.model.name}"`,
8819
8925
  meta: { view: name, model: mask.model.name }
@@ -8829,9 +8935,9 @@ function attachDefineView(params) {
8829
8935
  Object.defineProperty(client, "$defineView", { value, enumerable: true });
8830
8936
  }
8831
8937
  // packages/runtime/src/validators.ts
8832
- import { VibeError as VibeError21 } from "@vibeorm/schema";
8938
+ import { VibeError as VibeError22 } from "@vibeorm/schema";
8833
8939
  function validationFailed(params) {
8834
- return new VibeError21({
8940
+ return new VibeError22({
8835
8941
  code: "VIBE_VALIDATION",
8836
8942
  message: `validation failed for ${params.model}.${params.field}: ${params.issues[0]?.message ?? "invalid value"}`,
8837
8943
  meta: { model: params.model, field: params.field, issues: params.issues }
@@ -8840,7 +8946,7 @@ function validationFailed(params) {
8840
8946
  function validateValue(params) {
8841
8947
  const result = params.schema["~standard"].validate(params.value);
8842
8948
  if (result instanceof Promise) {
8843
- throw new VibeError21({
8949
+ throw new VibeError22({
8844
8950
  code: "VIBE_VALIDATION",
8845
8951
  message: `async validator on ${params.model}.${params.field} \u2014 write validators must be synchronous (validate before calling the client for async rules)`,
8846
8952
  meta: { model: params.model, field: params.field }
@@ -8908,12 +9014,12 @@ function validateNestedVerbs(params) {
8908
9014
  return value;
8909
9015
  if (!arms.some((arm) => value[arm] !== undefined))
8910
9016
  return one(value);
8911
- const next2 = { ...value };
9017
+ const next = { ...value };
8912
9018
  for (const arm of arms) {
8913
9019
  if (value[arm] !== undefined)
8914
- next2[arm] = many(value[arm]);
9020
+ next[arm] = many(value[arm]);
8915
9021
  }
8916
- return next2;
9022
+ return next;
8917
9023
  };
8918
9024
  const eachBody = (value, arms) => Array.isArray(value) ? value.map((item) => body(item, arms)) : body(value, arms);
8919
9025
  const next = { ...verbs };
@@ -8963,7 +9069,29 @@ function deferPolicyOperation(params) {
8963
9069
  }
8964
9070
 
8965
9071
  // packages/runtime/src/policy.ts
8966
- import { VibeError as VibeError22 } from "@vibeorm/schema";
9072
+ import { VibeError as VibeError24 } from "@vibeorm/schema";
9073
+
9074
+ // packages/runtime/src/module-context.ts
9075
+ import { VibeError as VibeError23 } from "@vibeorm/schema";
9076
+ var binders = new WeakMap;
9077
+ function registerModuleBinder(params) {
9078
+ binders.set(params.client, params.bind);
9079
+ }
9080
+ function inheritReadOnlyModuleBinder(params) {
9081
+ const bind = binders.get(params.from);
9082
+ if (bind !== undefined)
9083
+ binders.set(params.to, (artifact) => bind(artifact).$readOnly());
9084
+ }
9085
+ function bindModuleContext(params) {
9086
+ const bind = binders.get(params.db);
9087
+ if (bind === undefined)
9088
+ throw new VibeError23({
9089
+ code: "VIBE_CONFIG",
9090
+ 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
+ meta: { reason: "module_handle", moduleId: params.artifact.manifest.id, protocol: params.artifact.manifest.protocol }
9092
+ });
9093
+ return bind(params.artifact);
9094
+ }
8967
9095
 
8968
9096
  // packages/runtime/src/read-only.ts
8969
9097
  import { ReadOnlyClientError } from "@vibeorm/schema";
@@ -9050,7 +9178,7 @@ function classifiedMount(params) {
9050
9178
  return typeof value === "function" ? (...args) => {
9051
9179
  if (containsSqlFragment(args))
9052
9180
  return Promise.reject(readOnlyRefusal({ path: "extension", reason: "raw" }));
9053
- return value(...restrictedSqlArgs({ value: args, path: "$readOnly extension" }));
9181
+ return value(...restrictedSqlArgs({ value: args, path: "$readOnly extension", refusal: () => readOnlyRefusal({ path: "extension", reason: "raw" }) }));
9054
9182
  } : undefined;
9055
9183
  if (typeof value !== "object" || value === null)
9056
9184
  return;
@@ -9062,7 +9190,7 @@ function classifiedMount(params) {
9062
9190
  namespace[member] = (...args) => {
9063
9191
  if (containsSqlFragment(args))
9064
9192
  return Promise.reject(readOnlyRefusal({ path: member, reason: "raw" }));
9065
- return fn(...restrictedSqlArgs({ value: args, path: "$readOnly extension" }));
9193
+ return fn(...restrictedSqlArgs({ value: args, path: "$readOnly extension", refusal: () => readOnlyRefusal({ path: member, reason: "raw" }) }));
9066
9194
  };
9067
9195
  }
9068
9196
  return Object.freeze(namespace);
@@ -9077,7 +9205,7 @@ function readOnlyDelegate(params) {
9077
9205
  delegate[method] = (...args) => {
9078
9206
  if (containsSqlFragment(args))
9079
9207
  return Promise.reject(readOnlyRefusal({ path: `${model.clientName}.${method}`, reason: "raw" }));
9080
- const operation = fn(...args);
9208
+ const operation = fn(...restrictedSqlArgs({ value: args, path: "$readOnly", refusal: () => readOnlyRefusal({ path: `${model.clientName}.${method}`, reason: "raw" }) }));
9081
9209
  params.operations.restrictSql?.({ value: operation });
9082
9210
  return operation;
9083
9211
  };
@@ -9196,6 +9324,7 @@ function readOnlyOver(params) {
9196
9324
  if (existing !== undefined)
9197
9325
  return existing;
9198
9326
  const built = buildReadOnly(params);
9327
+ inheritReadOnlyModuleBinder({ from: params.client, to: built });
9199
9328
  facades.set(params.client, built);
9200
9329
  return built;
9201
9330
  }
@@ -9226,7 +9355,7 @@ function inheritReadOnly(params) {
9226
9355
 
9227
9356
  // packages/runtime/src/policy.ts
9228
9357
  function policyError(message, meta) {
9229
- return new VibeError22({ code: "VIBE_VALIDATION", message, meta: meta ?? {} });
9358
+ return new VibeError24({ code: "VIBE_VALIDATION", message, meta: meta ?? {} });
9230
9359
  }
9231
9360
  function policiedModels(meta) {
9232
9361
  return meta.models.filter((model) => model.policy !== undefined);
@@ -9392,20 +9521,20 @@ function scopeSelection(params) {
9392
9521
  if (spec === undefined || spec === false)
9393
9522
  continue;
9394
9523
  if (name === "_count") {
9395
- const names = spec === true ? model.relations.filter((relation2) => relation2.isList).map((relation2) => relation2.name) : isPlainObject7(spec) && isPlainObject7(spec.select) ? Object.keys(spec.select).filter((key2) => {
9396
- const entry = spec.select[key2];
9524
+ const names = spec === true ? model.relations.filter((relation) => relation.isList).map((relation) => relation.name) : isPlainObject7(spec) && isPlainObject7(spec.select) ? Object.keys(spec.select).filter((key) => {
9525
+ const entry = spec.select[key];
9397
9526
  return entry === true || isPlainObject7(entry);
9398
9527
  }) : [];
9399
9528
  const countSelect = isPlainObject7(spec) && isPlainObject7(spec.select) ? { ...spec.select } : undefined;
9400
9529
  for (const counted of names) {
9401
- const relation2 = model.relationByName.get(counted);
9402
- const target2 = relation2 === undefined ? undefined : meta.modelByName.get(relation2.targetModel);
9403
- if (target2?.policy !== undefined) {
9530
+ const relation = model.relationByName.get(counted);
9531
+ const target = relation === undefined ? undefined : meta.modelByName.get(relation.targetModel);
9532
+ if (target?.policy !== undefined) {
9404
9533
  throw policyError(`_count of ${model.name}.${counted} cannot enforce @@policy because relation counts take no filter \u2014 use a scoped child count query instead`, { model: model.name, relation: counted });
9405
9534
  }
9406
9535
  const entry = countSelect?.[counted];
9407
- if (target2 !== undefined && countSelect !== undefined && isPlainObject7(entry) && entry.where !== undefined) {
9408
- countSelect[counted] = { ...entry, where: scopeWhere({ meta, model: target2, where: entry.where, context }) };
9536
+ if (target !== undefined && countSelect !== undefined && isPlainObject7(entry) && entry.where !== undefined) {
9537
+ countSelect[counted] = { ...entry, where: scopeWhere({ meta, model: target, where: entry.where, context }) };
9409
9538
  }
9410
9539
  }
9411
9540
  if (countSelect !== undefined)
@@ -9498,8 +9627,8 @@ function forceWriteData(params) {
9498
9627
  }
9499
9628
  function forceNestedVerbs(params) {
9500
9629
  const { meta, target, verbs, context } = params;
9501
- const walk2 = (row, phase) => isPlainObject7(row) ? forceWriteData({ meta, model: target, data: row, context, phase }) : row;
9502
- const each = (value, phase) => Array.isArray(value) ? value.map((row) => walk2(row, phase)) : walk2(value, phase);
9630
+ const walk = (row, phase) => isPlainObject7(row) ? forceWriteData({ meta, model: target, data: row, context, phase }) : row;
9631
+ const each = (value, phase) => Array.isArray(value) ? value.map((row) => walk(row, phase)) : walk(value, phase);
9503
9632
  const body = (value, keys) => {
9504
9633
  if (!isPlainObject7(value))
9505
9634
  return value;
@@ -9551,7 +9680,11 @@ function scopedDelegate(params) {
9551
9680
  const flat = uniqueToFilter({ model, where: scoped.where ?? {} });
9552
9681
  return { ...scoped, where: mergeWhere({ where: flat, field: policy.field, value }) };
9553
9682
  };
9554
- const scopeWrite = (args) => scopeSelection({ meta, model, args, context });
9683
+ const scopeWrite = (input) => {
9684
+ const args = restrictedSqlArgs({ value: input, path: "$withPolicy" });
9685
+ restrictConflictPredicates({ meta, model, args, path: "$withPolicy" });
9686
+ return scopeSelection({ meta, model, args, context });
9687
+ };
9555
9688
  const writeData = (data, phase) => forceWriteData({ meta, model, data: data ?? {}, context, phase });
9556
9689
  const pkClientKey = () => {
9557
9690
  for (const [key, group] of model.compoundUniques) {
@@ -9572,7 +9705,7 @@ function scopedDelegate(params) {
9572
9705
  const pkWhere = pk.length === 1 ? { [pk[0]]: target[pk[0]] } : { [pkClientKey()]: Object.fromEntries(pk.map((name) => [name, target[name]])) };
9573
9706
  return write(raw, pkWhere);
9574
9707
  };
9575
- const notFound2 = (method) => new VibeError22({ 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 } });
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 } });
9576
9709
  return {
9577
9710
  findMany: (args) => base.findMany(scopeFind(args)),
9578
9711
  findFirst: (args) => base.findFirst(scopeFind(args)),
@@ -9581,7 +9714,7 @@ function scopedDelegate(params) {
9581
9714
  findUniqueOrThrow: (args) => base.findFirstOrThrow(scopeUnique(args)),
9582
9715
  create: (args) => deferred(() => base.create({ ...scopeWrite(args), data: writeData(args.data, "create") })),
9583
9716
  createMany: (args) => deferred(() => base.createMany({
9584
- ...args,
9717
+ ...scopeWrite(args),
9585
9718
  data: (args.data ?? []).map((row) => writeData(row, "create"))
9586
9719
  })),
9587
9720
  createManyAndReturn: (args) => deferred(() => base.createManyAndReturn({
@@ -9591,9 +9724,9 @@ function scopedDelegate(params) {
9591
9724
  update: (args) => defer(async (tx) => {
9592
9725
  const raw = tx.$bypassPolicy === undefined ? tx : tx.$bypassPolicy();
9593
9726
  const data = writeData(args.data, "update");
9594
- const row = await lockThen(raw, args, (raw2, pkWhere) => raw2.$models[model.name].update({ ...scopeWrite(args), data, where: pkWhere }));
9727
+ const row = await lockThen(raw, args, (raw, pkWhere) => raw.$models[model.name].update({ ...scopeWrite(args), data, where: pkWhere }));
9595
9728
  if (row === null)
9596
- throw notFound2("update");
9729
+ throw notFound("update");
9597
9730
  return row;
9598
9731
  }),
9599
9732
  updateMany: (args) => deferred(() => base.updateMany({
@@ -9606,7 +9739,7 @@ function scopedDelegate(params) {
9606
9739
  })
9607
9740
  })),
9608
9741
  upsertMany: () => {
9609
- throw new VibeError22({
9742
+ throw new VibeError24({
9610
9743
  code: "VIBE_UNSUPPORTED_CAPABILITY",
9611
9744
  message: "upsertMany is not available on a policy-bound client: its conflict target is not policy-checked yet",
9612
9745
  meta: { model: model.name }
@@ -9615,7 +9748,7 @@ function scopedDelegate(params) {
9615
9748
  updateManyAndReturn: (args) => deferred(() => {
9616
9749
  const run = base.updateManyAndReturn;
9617
9750
  if (run === undefined) {
9618
- throw new VibeError22({
9751
+ throw new VibeError24({
9619
9752
  code: "VIBE_UNSUPPORTED_CAPABILITY",
9620
9753
  message: "updateManyAndReturn is not available on this delegate",
9621
9754
  meta: { model: model.name }
@@ -9636,16 +9769,16 @@ function scopedDelegate(params) {
9636
9769
  const update = writeData(args.update, "update");
9637
9770
  const create = writeData(args.create, "create");
9638
9771
  const projection = scopeWrite(Object.fromEntries(["select", "include"].flatMap((key) => args[key] === undefined ? [] : [[key, args[key]]])));
9639
- const row = await lockThen(raw, args, (raw2, pkWhere) => raw2.$models[model.name].update({ ...projection, where: pkWhere, data: update }));
9772
+ const row = await lockThen(raw, args, (raw, pkWhere) => raw.$models[model.name].update({ ...projection, where: pkWhere, data: update }));
9640
9773
  if (row !== null)
9641
9774
  return row;
9642
9775
  return await raw.$models[model.name].create({ ...projection, data: create });
9643
9776
  }),
9644
9777
  delete: (args) => defer(async (tx) => {
9645
9778
  const raw = tx.$bypassPolicy === undefined ? tx : tx.$bypassPolicy();
9646
- const row = await lockThen(raw, args, (raw2, pkWhere) => raw2.$models[model.name].delete({ ...scopeWrite(args), where: pkWhere }));
9779
+ const row = await lockThen(raw, args, (raw, pkWhere) => raw.$models[model.name].delete({ ...scopeWrite(args), where: pkWhere }));
9647
9780
  if (row === null)
9648
- throw notFound2("delete");
9781
+ throw notFound("delete");
9649
9782
  return row;
9650
9783
  }),
9651
9784
  deleteMany: (args) => deferred(() => base.deleteMany({
@@ -9664,7 +9797,10 @@ function scopedDelegate(params) {
9664
9797
  function globalDelegate(params) {
9665
9798
  const { meta, model, base, context } = params;
9666
9799
  const readArgs = (args) => scopeArgs({ meta, model, args: args ?? {}, context });
9667
- const sel = (args) => {
9800
+ const sel = (input) => {
9801
+ const args = params.policyBound === false ? input : restrictedSqlArgs({ value: input, path: "$withPolicy" });
9802
+ if (params.policyBound !== false)
9803
+ restrictConflictPredicates({ meta, model, args, path: "$withPolicy" });
9668
9804
  const scoped = scopeSelection({ meta, model, args, context });
9669
9805
  return scoped.where === undefined ? scoped : { ...scoped, where: scopeWhere({ meta, model, where: scoped.where, context }) };
9670
9806
  };
@@ -9679,14 +9815,14 @@ function globalDelegate(params) {
9679
9815
  aggregate: (args) => base.aggregate(readArgs(args)),
9680
9816
  groupBy: (args) => base.groupBy(readArgs(args)),
9681
9817
  create: (args) => deferred(() => base.create({ ...sel(args), data: payload(args.data, "create") })),
9682
- createMany: (args) => deferred(() => base.createMany({ ...args, data: (args.data ?? []).map((r) => payload(r, "create")) })),
9818
+ createMany: (args) => deferred(() => base.createMany({ ...sel(args), data: (args.data ?? []).map((r) => payload(r, "create")) })),
9683
9819
  createManyAndReturn: (args) => deferred(() => base.createManyAndReturn({ ...sel(args), data: (args.data ?? []).map((r) => payload(r, "create")) })),
9684
9820
  update: (args) => deferred(() => base.update({ ...sel(args), data: payload(args.data, "update") })),
9685
9821
  updateMany: (args) => deferred(() => base.updateMany({ ...sel(args), data: payload(args.data, "update") })),
9686
9822
  updateManyAndReturn: (args) => deferred(() => {
9687
9823
  const run = base.updateManyAndReturn;
9688
9824
  if (run === undefined) {
9689
- throw new VibeError22({
9825
+ throw new VibeError24({
9690
9826
  code: "VIBE_UNSUPPORTED_CAPABILITY",
9691
9827
  message: "updateManyAndReturn is not available on this delegate"
9692
9828
  });
@@ -9697,7 +9833,7 @@ function globalDelegate(params) {
9697
9833
  upsertMany: (args) => deferred(() => {
9698
9834
  if (params.policyBound === false)
9699
9835
  return base.upsertMany(args);
9700
- throw new VibeError22({
9836
+ throw new VibeError24({
9701
9837
  code: "VIBE_UNSUPPORTED_CAPABILITY",
9702
9838
  message: "upsertMany is not available on a policy-bound client: its conflict target is not policy-checked yet"
9703
9839
  });
@@ -9764,13 +9900,26 @@ function attachPolicy(params) {
9764
9900
  });
9765
9901
  }
9766
9902
  }
9767
- const buildScoped = (context) => {
9768
- for (const model of policied) {
9769
- const key = model.policy?.context;
9770
- if (context[key] === undefined || context[key] === null) {
9771
- throw policyError(`$withPolicy: missing context value "${key}" (required by ${model.name})`, { context: key });
9772
- }
9903
+ const buildScoped = (input) => {
9904
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
9905
+ throw policyError("$withPolicy: context must contain own scalar identity values");
9773
9906
  }
9907
+ const snapshot = Object.create(null);
9908
+ for (const model of policied) {
9909
+ const policy = model.policy;
9910
+ const key = policy.context;
9911
+ const descriptor = Object.getOwnPropertyDescriptor(Object.hasOwn(snapshot, key) ? snapshot : input, key);
9912
+ if (descriptor === undefined || !("value" in descriptor) || descriptor.value === undefined || descriptor.value === null) {
9913
+ throw policyError(`$withPolicy: missing context value "${key}" (required as an own data property by ${model.name})`, { context: key });
9914
+ }
9915
+ const value = descriptor.value;
9916
+ const field = model.fieldByName.get(policy.field);
9917
+ const valid = field !== undefined && !field.isList && (field.scalarType === "String" ? typeof value === "string" : field.scalarType === "Int" ? typeof value === "number" && Number.isSafeInteger(value) : field.scalarType === "BigInt" ? typeof value === "bigint" : field.scalarType === "Float" || field.scalarType === "Decimal" ? typeof value === "number" && Number.isFinite(value) : field.enumName !== null && typeof value === "string" && meta.enums.get(field.enumName)?.includes(value) === true);
9918
+ if (!valid)
9919
+ throw policyError(`$withPolicy: context "${key}" must match the scalar type of ${model.name}.${policy.field}`, { context: key, model: model.name, field: policy.field });
9920
+ snapshot[key] = value;
9921
+ }
9922
+ const context = Object.freeze(snapshot);
9774
9923
  const scoped = Object.create(client);
9775
9924
  const scopedModels = { ...client.$models };
9776
9925
  for (const model of meta.models) {
@@ -9855,7 +10004,7 @@ function attachPolicy(params) {
9855
10004
  });
9856
10005
  }
9857
10006
  // packages/runtime/src/scoped.ts
9858
- import { ScopedQueryError, VibeError as VibeError23 } from "@vibeorm/schema";
10007
+ import { ScopedQueryError, VibeError as VibeError25 } from "@vibeorm/schema";
9859
10008
  function refusal(params) {
9860
10009
  return new ScopedQueryError(params);
9861
10010
  }
@@ -10440,7 +10589,7 @@ function walkNestedVerbs(params) {
10440
10589
  const mode = nestedModeFor(targetEntry);
10441
10590
  const out = { ...verbs };
10442
10591
  const pred = (verbPath) => requirePred({ ctx, model: target, path: verbPath });
10443
- const refuse2 = (verb, why) => {
10592
+ const refuse = (verb, why) => {
10444
10593
  throw refusal({
10445
10594
  model: target.name,
10446
10595
  path: `${path}.${verb}`,
@@ -10469,7 +10618,7 @@ function walkNestedVerbs(params) {
10469
10618
  continue;
10470
10619
  }
10471
10620
  if (scoped && mode === "refuse" && REFERENCE_VERBS2.includes(verb)) {
10472
- refuse2(verb, `is disabled \u2014 ${target.name} is configured nested: "refuse"; go through the base client or its own delegate`);
10621
+ refuse(verb, `is disabled \u2014 ${target.name} is configured nested: "refuse"; go through the base client or its own delegate`);
10473
10622
  }
10474
10623
  switch (verb) {
10475
10624
  case "connect":
@@ -10484,9 +10633,9 @@ function walkNestedVerbs(params) {
10484
10633
  if (scoped) {
10485
10634
  const kind = link().kind;
10486
10635
  if (kind === "manyToMany")
10487
- refuse2(verb, "clears the whole join set \u2014 unlinking other tenants' rows cannot be verified; disconnect explicit rows instead");
10636
+ refuse(verb, "clears the whole join set \u2014 unlinking other tenants' rows cannot be verified; disconnect explicit rows instead");
10488
10637
  if (!implicitSafe)
10489
- refuse2(verb, "first detaches EVERY current child, which cannot be tenant-filtered on this edge; disconnect explicit rows instead");
10638
+ refuse(verb, "first detaches EVERY current child, which cannot be tenant-filtered on this edge; disconnect explicit rows instead");
10490
10639
  }
10491
10640
  out[verb] = mapItems(operand ?? [], (item) => isPlainObject8(item) ? uniqueWhere(item, verbPath) : item);
10492
10641
  break;
@@ -10497,10 +10646,10 @@ function walkNestedVerbs(params) {
10497
10646
  const kind = link().kind;
10498
10647
  if (kind === "toOneOwner") {
10499
10648
  if (tenancyEdge) {
10500
- refuse2(verb, "would orphan the row out of its tenant (through-parent set to null) \u2014 delete it or connect a replacement");
10649
+ refuse(verb, "would orphan the row out of its tenant (through-parent set to null) \u2014 delete it or connect a replacement");
10501
10650
  }
10502
10651
  } else if (!implicitSafe) {
10503
- refuse2(verb, "targets whatever row currently points here \u2014 not tenant-verifiable on this edge");
10652
+ refuse(verb, "targets whatever row currently points here \u2014 not tenant-verifiable on this edge");
10504
10653
  }
10505
10654
  }
10506
10655
  break;
@@ -10511,7 +10660,7 @@ function walkNestedVerbs(params) {
10511
10660
  case "delete": {
10512
10661
  if (!relation.isList) {
10513
10662
  if (scoped && !implicitSafe) {
10514
- refuse2(verb, "targets whatever row is currently connected \u2014 not tenant-verifiable on this edge");
10663
+ refuse(verb, "targets whatever row is currently connected \u2014 not tenant-verifiable on this edge");
10515
10664
  }
10516
10665
  break;
10517
10666
  }
@@ -10521,7 +10670,7 @@ function walkNestedVerbs(params) {
10521
10670
  case "update": {
10522
10671
  if (!relation.isList) {
10523
10672
  if (scoped && !implicitSafe) {
10524
- refuse2(verb, "targets whatever row is currently connected \u2014 not tenant-verifiable on this edge; update it through its own delegate");
10673
+ refuse(verb, "targets whatever row is currently connected \u2014 not tenant-verifiable on this edge; update it through its own delegate");
10525
10674
  }
10526
10675
  out[verb] = isPlainObject8(operand) ? "data" in operand && isPlainObject8(operand.data) ? { ...operand, data: walkChildUpdate(operand.data, verbPath) } : walkChildUpdate(operand, verbPath) : operand;
10527
10676
  break;
@@ -10538,7 +10687,7 @@ function walkNestedVerbs(params) {
10538
10687
  case "upsert": {
10539
10688
  if (!relation.isList) {
10540
10689
  if (scoped && !implicitSafe) {
10541
- refuse2(verb, "updates whatever row is currently connected \u2014 not tenant-verifiable on this edge");
10690
+ refuse(verb, "updates whatever row is currently connected \u2014 not tenant-verifiable on this edge");
10542
10691
  }
10543
10692
  out[verb] = isPlainObject8(operand) ? {
10544
10693
  ...operand,
@@ -10588,6 +10737,7 @@ function rewriteScopedCall(params) {
10588
10737
  const scoped = entry.kind !== "none";
10589
10738
  const root = `${model.clientName}.${method}`;
10590
10739
  const args = restrictedSqlArgs({ value: params.args ?? {}, path: "$scoped" });
10740
+ restrictConflictPredicates({ meta, model, args, path: "$scoped" });
10591
10741
  const ownPred = () => requirePred({ ctx, model, path: root });
10592
10742
  const walkOwnWhere = (where, path) => isPlainObject8(where) ? walkWhere({ ctx, model, where, path }) : where;
10593
10743
  if (FIND_LIKE.includes(method)) {
@@ -10606,9 +10756,9 @@ function rewriteScopedCall(params) {
10606
10756
  case "findUniqueOrThrow": {
10607
10757
  walkSelection({ ctx, model, args, path: root });
10608
10758
  if (!scoped) {
10609
- const walked2 = walkOwnWhere(args.where, `${root}.where`);
10610
- if (walked2 !== undefined)
10611
- args.where = walked2;
10759
+ const walked = walkOwnWhere(args.where, `${root}.where`);
10760
+ if (walked !== undefined)
10761
+ args.where = walked;
10612
10762
  return { model: model.name, method, args };
10613
10763
  }
10614
10764
  const flat = isPlainObject8(args.where) ? flattenUniqueWhere({ model, where: args.where }) : args.where;
@@ -10810,7 +10960,7 @@ function attachScoped(params) {
10810
10960
  Object.defineProperty(client, "$scoped", {
10811
10961
  value: (config) => {
10812
10962
  if (!isPlainObject8(config) || !isPlainObject8(config.models)) {
10813
- throw new VibeError23({
10963
+ throw new VibeError25({
10814
10964
  code: "VIBE_VALIDATION",
10815
10965
  message: "$scoped takes { scope: string | number | bigint | null, models: { <Model>: \u2026 } }"
10816
10966
  });
@@ -10826,7 +10976,7 @@ function attachScoped(params) {
10826
10976
  }
10827
10977
  const scope = config.scope;
10828
10978
  if (scope !== null && typeof scope !== "string" && typeof scope !== "number" && typeof scope !== "bigint") {
10829
- throw new VibeError23({
10979
+ throw new VibeError25({
10830
10980
  code: "VIBE_VALIDATION",
10831
10981
  message: `$scoped: scope must be a string, number, bigint or null \u2014 got ${typeof scope}`
10832
10982
  });
@@ -10842,7 +10992,7 @@ function attachScoped(params) {
10842
10992
  });
10843
10993
  }
10844
10994
  // packages/runtime/src/rls-readiness.ts
10845
- import { VibeError as VibeError24, assertValidSchemaIR, unsupportedCapability as unsupportedCapability7 } from "@vibeorm/schema";
10995
+ import { VibeError as VibeError26, assertValidSchemaIR, unsupportedCapability as unsupportedCapability7 } from "@vibeorm/schema";
10846
10996
  import { NATIVE_RLS as NATIVE_RLS2, getSqlDialect as getSqlDialect4, renderRlsPolicy, renderRlsRole, NATIVE_RLS_PROBE_POLICY, renderRlsReadinessQuery, renderRlsProbeTable } from "@vibeorm/sql";
10847
10997
  import { RLS_READINESS_SQL, NATIVE_RLS_PROBE_POLICY as NATIVE_RLS_PROBE_POLICY2 } from "@vibeorm/sql";
10848
10998
  function textOf(params) {
@@ -10866,7 +11016,7 @@ function intOf(params) {
10866
11016
  return Number.parseInt(value, 10);
10867
11017
  }
10868
11018
  function unreadableCatalog(params) {
10869
- return new VibeError24({
11019
+ return new VibeError26({
10870
11020
  code: "VIBE_ADAPTER",
10871
11021
  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.",
10872
11022
  meta: { result: params.key }
@@ -10925,7 +11075,7 @@ function requireNativeRls(params) {
10925
11075
  throw unsupportedCapability7({ dialect: dialect.name, feature: "nativeRowLevelSecurity" });
10926
11076
  }
10927
11077
  if (params.schema.rls === undefined) {
10928
- throw new VibeError24({
11078
+ throw new VibeError26({
10929
11079
  code: "VIBE_CONFIG",
10930
11080
  message: "Native row-level security readiness requires a schema that declares native RLS"
10931
11081
  });
@@ -11338,7 +11488,7 @@ async function inspectNativeRls(params) {
11338
11488
  function requireEmbeddedRole(params) {
11339
11489
  const { role } = params;
11340
11490
  if (typeof role !== "string" || role.length === 0 || role.includes("\x00")) {
11341
- throw new VibeError24({
11491
+ throw new VibeError26({
11342
11492
  code: "VIBE_CONFIG",
11343
11493
  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",
11344
11494
  meta: { provider: "pglite" }
@@ -11350,7 +11500,7 @@ function assertNativeRlsReady(params) {
11350
11500
  const { report } = params;
11351
11501
  if (report.ready)
11352
11502
  return;
11353
- throw new VibeError24({
11503
+ throw new VibeError26({
11354
11504
  code: "VIBE_CONFIG",
11355
11505
  message: `Native row-level security is not ready on this database: ${report.problems.map((problem) => `${problem.name} (${problem.status})`).join(", ")}`,
11356
11506
  meta: {
@@ -11374,9 +11524,13 @@ function formatNativeRlsReport(params) {
11374
11524
  }
11375
11525
  return lines;
11376
11526
  }
11527
+ // packages/runtime/src/database-module.ts
11528
+ import { createHash } from "crypto";
11529
+ import { VibeError as VibeError31, assertValidSchemaIR as assertValidSchemaIR3, providerToDialect } from "@vibeorm/schema";
11530
+
11377
11531
  // packages/runtime/src/client.ts
11378
11532
  import { compileSql } from "@vibeorm/sql";
11379
- import { RlsContextError as RlsContextError2, VibeError as VibeError28, assertValidSchemaIR as assertValidSchemaIR2, unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
11533
+ import { RlsContextError as RlsContextError2, VibeError as VibeError30, assertValidSchemaIR as assertValidSchemaIR2, unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
11380
11534
  import { ADVISORY_LOCK_RESULT_COLUMN, ParamCollector, getSqlDialect as getSqlDialect5, renderRlsContext, renderRlsPolicy as renderRlsPolicy2, renderRlsRole as renderRlsRole2, renderStatement as renderStatement5 } from "@vibeorm/sql";
11381
11535
 
11382
11536
  // packages/runtime/src/render-cache.ts
@@ -11416,186 +11570,186 @@ class StatementRenderCache {
11416
11570
  this.entries.set(key, slot);
11417
11571
  }
11418
11572
  }
11419
- function addIdent(walk2, name) {
11420
- walk2.key += `\xA7${name.length}~${name}`;
11573
+ function addIdent(walk, name) {
11574
+ walk.key += `\xA7${name.length}~${name}`;
11421
11575
  }
11422
- function addCol(walk2, column) {
11576
+ function addCol(walk, column) {
11423
11577
  if (column.table !== undefined)
11424
- addIdent(walk2, column.table);
11425
- walk2.key += ".";
11426
- addIdent(walk2, column.name);
11578
+ addIdent(walk, column.table);
11579
+ walk.key += ".";
11580
+ addIdent(walk, column.name);
11427
11581
  if (column.transform !== undefined)
11428
- walk2.key += column.transform === "castText" ? "^t" : "^b";
11582
+ walk.key += column.transform === "castText" ? "^t" : "^b";
11429
11583
  if (column.castReal === true)
11430
- walk2.key += "^r";
11584
+ walk.key += "^r";
11431
11585
  if (column.alias !== undefined) {
11432
- walk2.key += "^a";
11433
- addIdent(walk2, column.alias);
11586
+ walk.key += "^a";
11587
+ addIdent(walk, column.alias);
11434
11588
  }
11435
11589
  }
11436
- function addTable(walk2, table) {
11437
- addIdent(walk2, table.name);
11590
+ function addTable(walk, table) {
11591
+ addIdent(walk, table.name);
11438
11592
  if (table.alias !== undefined) {
11439
- walk2.key += "@";
11440
- addIdent(walk2, table.alias);
11593
+ walk.key += "@";
11594
+ addIdent(walk, table.alias);
11441
11595
  }
11442
11596
  }
11443
- function addAgg(walk2, agg) {
11444
- walk2.key += agg.fn;
11597
+ function addAgg(walk, agg) {
11598
+ walk.key += agg.fn;
11445
11599
  if (agg.fn !== "countAll")
11446
- addCol(walk2, agg.column);
11600
+ addCol(walk, agg.column);
11447
11601
  }
11448
- function addSetEntry(walk2, name, value) {
11602
+ function addSetEntry(walk, name, value) {
11449
11603
  if (isJsonParamCell(value)) {
11450
- walk2.key += "=j";
11451
- addIdent(walk2, name);
11452
- walk2.values.push(value.text);
11604
+ walk.key += "=j";
11605
+ addIdent(walk, name);
11606
+ walk.values.push(value.text);
11453
11607
  return;
11454
11608
  }
11455
11609
  if (isSetOperation(value)) {
11456
- walk2.key += `=o${value.__op}`;
11457
- addIdent(walk2, name);
11458
- walk2.values.push(value.value);
11610
+ walk.key += `=o${value.__op}`;
11611
+ addIdent(walk, name);
11612
+ walk.values.push(value.value);
11459
11613
  return;
11460
11614
  }
11461
11615
  if (isDbNowMarker(value)) {
11462
- walk2.key += value.offsetSeconds === 0 ? "=N0" : "=N1";
11463
- addIdent(walk2, name);
11616
+ walk.key += value.offsetSeconds === 0 ? "=N0" : "=N1";
11617
+ addIdent(walk, name);
11464
11618
  if (value.offsetSeconds !== 0)
11465
- walk2.values.push(value.offsetSeconds);
11619
+ walk.values.push(value.offsetSeconds);
11466
11620
  return;
11467
11621
  }
11468
11622
  if (isListSetOperation(value)) {
11469
- walk2.key += `=l${value.__listOp}`;
11470
- addIdent(walk2, name);
11471
- walk2.values.push(value.value);
11623
+ walk.key += `=l${value.__listOp}`;
11624
+ addIdent(walk, name);
11625
+ walk.values.push(value.value);
11472
11626
  return;
11473
11627
  }
11474
- walk2.key += "=v";
11475
- addIdent(walk2, name);
11476
- walk2.values.push(value);
11628
+ walk.key += "=v";
11629
+ addIdent(walk, name);
11630
+ walk.values.push(value);
11477
11631
  }
11478
- function addReturning(walk2, returning) {
11632
+ function addReturning(walk, returning) {
11479
11633
  if (returning === undefined || returning.length === 0) {
11480
- walk2.key += "r0";
11634
+ walk.key += "r0";
11481
11635
  return;
11482
11636
  }
11483
- walk2.key += "r(";
11637
+ walk.key += "r(";
11484
11638
  for (const name of returning)
11485
- addIdent(walk2, name);
11486
- walk2.key += ")";
11639
+ addIdent(walk, name);
11640
+ walk.key += ")";
11487
11641
  }
11488
- function walkExpr(walk2, dialect, expr) {
11642
+ function walkExpr(walk, dialect, expr) {
11489
11643
  switch (expr.kind) {
11490
11644
  case "cmp":
11491
11645
  if (isDbNowMarker(expr.value)) {
11492
- walk2.key += `cN${expr.op}${expr.value.offsetSeconds === 0 ? "0" : "1"}`;
11493
- addCol(walk2, expr.column);
11646
+ walk.key += `cN${expr.op}${expr.value.offsetSeconds === 0 ? "0" : "1"}`;
11647
+ addCol(walk, expr.column);
11494
11648
  if (expr.value.offsetSeconds !== 0)
11495
- walk2.values.push(expr.value.offsetSeconds);
11649
+ walk.values.push(expr.value.offsetSeconds);
11496
11650
  return true;
11497
11651
  }
11498
- walk2.key += `c${expr.op}`;
11499
- addCol(walk2, expr.column);
11500
- walk2.values.push(expr.value);
11652
+ walk.key += `c${expr.op}`;
11653
+ addCol(walk, expr.column);
11654
+ walk.values.push(expr.value);
11501
11655
  return true;
11502
11656
  case "cmpCol":
11503
- walk2.key += `k${expr.op}`;
11504
- addCol(walk2, expr.left);
11505
- addCol(walk2, expr.right);
11657
+ walk.key += `k${expr.op}`;
11658
+ addCol(walk, expr.left);
11659
+ addCol(walk, expr.right);
11506
11660
  return true;
11507
11661
  case "isNull":
11508
- walk2.key += expr.negate === true ? "n1" : "n0";
11509
- addCol(walk2, expr.column);
11662
+ walk.key += expr.negate === true ? "n1" : "n0";
11663
+ addCol(walk, expr.column);
11510
11664
  return true;
11511
11665
  case "inArray": {
11512
11666
  if (expr.values.length === 0) {
11513
- walk2.key += expr.negate === true ? "z1" : "z0";
11667
+ walk.key += expr.negate === true ? "z1" : "z0";
11514
11668
  return true;
11515
11669
  }
11516
- walk2.key += expr.negate === true ? "i1" : "i0";
11517
- addCol(walk2, expr.column);
11670
+ walk.key += expr.negate === true ? "i1" : "i0";
11671
+ addCol(walk, expr.column);
11518
11672
  if (dialect.inArrayStrategy === "any") {
11519
- walk2.values.push([...expr.values]);
11673
+ walk.values.push([...expr.values]);
11520
11674
  } else {
11521
- walk2.key += `#${expr.values.length}`;
11675
+ walk.key += `#${expr.values.length}`;
11522
11676
  for (const value of expr.values)
11523
- walk2.values.push(value);
11677
+ walk.values.push(value);
11524
11678
  }
11525
11679
  return true;
11526
11680
  }
11527
11681
  case "tupleIn": {
11528
11682
  if (expr.columns.length === 0)
11529
11683
  return false;
11530
- walk2.key += `Tu${expr.negate === true ? "1" : "0"}${expr.columns.length}#${expr.rows.length}(`;
11684
+ walk.key += `Tu${expr.negate === true ? "1" : "0"}${expr.columns.length}#${expr.rows.length}(`;
11531
11685
  for (const column of expr.columns)
11532
- addCol(walk2, column);
11533
- walk2.key += ")";
11686
+ addCol(walk, column);
11687
+ walk.key += ")";
11534
11688
  if (expr.rows.length === 0)
11535
11689
  return true;
11536
11690
  for (const row of expr.rows) {
11537
11691
  if (row.length !== expr.columns.length)
11538
11692
  return false;
11539
11693
  for (const value of row)
11540
- walk2.values.push(value);
11694
+ walk.values.push(value);
11541
11695
  }
11542
11696
  return true;
11543
11697
  }
11544
11698
  case "like":
11545
- walk2.key += `L${expr.insensitive === true ? "i" : "s"}${expr.negate === true ? "n" : "p"}`;
11546
- addCol(walk2, expr.column);
11547
- walk2.values.push(expr.pattern);
11699
+ walk.key += `L${expr.insensitive === true ? "i" : "s"}${expr.negate === true ? "n" : "p"}`;
11700
+ addCol(walk, expr.column);
11701
+ walk.values.push(expr.pattern);
11548
11702
  return true;
11549
11703
  case "strictMatch":
11550
- walk2.key += `S${expr.op}${expr.negate === true ? "n" : "p"}`;
11551
- addCol(walk2, expr.column);
11552
- walk2.values.push(expr.op === "equals" ? expr.value : strictMatchPattern({ strategy: dialect.strictMatchStrategy, op: expr.op, value: expr.value }));
11704
+ walk.key += `S${expr.op}${expr.negate === true ? "n" : "p"}`;
11705
+ addCol(walk, expr.column);
11706
+ walk.values.push(expr.op === "equals" ? expr.value : strictMatchPattern({ strategy: dialect.strictMatchStrategy, op: expr.op, value: expr.value }));
11553
11707
  return true;
11554
11708
  case "and":
11555
11709
  case "or": {
11556
- walk2.key += `${expr.kind === "and" ? "A" : "O"}${expr.operands.length}(`;
11710
+ walk.key += `${expr.kind === "and" ? "A" : "O"}${expr.operands.length}(`;
11557
11711
  for (const operand of expr.operands) {
11558
- if (!walkExpr(walk2, dialect, operand))
11712
+ if (!walkExpr(walk, dialect, operand))
11559
11713
  return false;
11560
11714
  }
11561
- walk2.key += ")";
11715
+ walk.key += ")";
11562
11716
  return true;
11563
11717
  }
11564
11718
  case "not":
11565
- walk2.key += "!(";
11566
- if (!walkExpr(walk2, dialect, expr.operand))
11719
+ walk.key += "!(";
11720
+ if (!walkExpr(walk, dialect, expr.operand))
11567
11721
  return false;
11568
- walk2.key += ")";
11722
+ walk.key += ")";
11569
11723
  return true;
11570
11724
  case "exists":
11571
- walk2.key += expr.negate === true ? "E1(" : "E0(";
11572
- if (!walkSelect(walk2, dialect, expr.select))
11725
+ walk.key += expr.negate === true ? "E1(" : "E0(";
11726
+ if (!walkSelect(walk, dialect, expr.select))
11573
11727
  return false;
11574
- walk2.key += ")";
11728
+ walk.key += ")";
11575
11729
  return true;
11576
11730
  case "aggCmp":
11577
- walk2.key += `g${expr.op}`;
11578
- addAgg(walk2, expr.agg);
11579
- walk2.values.push(expr.value);
11731
+ walk.key += `g${expr.op}`;
11732
+ addAgg(walk, expr.agg);
11733
+ walk.values.push(expr.value);
11580
11734
  return true;
11581
11735
  case "arrayHas":
11582
- walk2.key += expr.negate === true ? "h1" : "h0";
11583
- addCol(walk2, expr.column);
11584
- walk2.values.push(expr.value);
11736
+ walk.key += expr.negate === true ? "h1" : "h0";
11737
+ addCol(walk, expr.column);
11738
+ walk.values.push(expr.value);
11585
11739
  return true;
11586
11740
  case "arrayContainsAll":
11587
- walk2.key += "H";
11588
- addCol(walk2, expr.column);
11589
- walk2.values.push([...expr.values]);
11741
+ walk.key += "H";
11742
+ addCol(walk, expr.column);
11743
+ walk.values.push([...expr.values]);
11590
11744
  return true;
11591
11745
  case "arrayOverlaps":
11592
- walk2.key += "V";
11593
- addCol(walk2, expr.column);
11594
- walk2.values.push([...expr.values]);
11746
+ walk.key += "V";
11747
+ addCol(walk, expr.column);
11748
+ walk.values.push([...expr.values]);
11595
11749
  return true;
11596
11750
  case "arrayIsEmpty":
11597
- walk2.key += expr.empty ? "e1" : "e0";
11598
- addCol(walk2, expr.column);
11751
+ walk.key += expr.empty ? "e1" : "e0";
11752
+ addCol(walk, expr.column);
11599
11753
  return true;
11600
11754
  case "jsonFilter":
11601
11755
  return false;
@@ -11603,140 +11757,140 @@ function walkExpr(walk2, dialect, expr) {
11603
11757
  case "fragment":
11604
11758
  return false;
11605
11759
  case "raw":
11606
- walk2.key += "R(";
11607
- addIdent(walk2, expr.text);
11608
- walk2.key += ")";
11760
+ walk.key += "R(";
11761
+ addIdent(walk, expr.text);
11762
+ walk.key += ")";
11609
11763
  return true;
11610
11764
  }
11611
11765
  }
11612
- function walkOrderTerm2(walk2, dialect, term) {
11766
+ function walkOrderTerm2(walk, dialect, term) {
11613
11767
  if ("agg" in term) {
11614
- walk2.key += "a";
11615
- addAgg(walk2, term.agg);
11768
+ walk.key += "a";
11769
+ addAgg(walk, term.agg);
11616
11770
  } else if ("select" in term) {
11617
- walk2.key += "q(";
11618
- if (!walkSelect(walk2, dialect, term.select))
11771
+ walk.key += "q(";
11772
+ if (!walkSelect(walk, dialect, term.select))
11619
11773
  return false;
11620
- walk2.key += ")";
11774
+ walk.key += ")";
11621
11775
  } else {
11622
- addCol(walk2, term.column);
11623
- walk2.key += term.nulls === undefined ? "-" : term.nulls === "first" ? "^" : "$";
11776
+ addCol(walk, term.column);
11777
+ walk.key += term.nulls === undefined ? "-" : term.nulls === "first" ? "^" : "$";
11624
11778
  }
11625
- walk2.key += term.direction === "asc" ? "+" : "~";
11779
+ walk.key += term.direction === "asc" ? "+" : "~";
11626
11780
  return true;
11627
11781
  }
11628
- function walkSelect(walk2, dialect, statement) {
11629
- walk2.key += "S{";
11782
+ function walkSelect(walk, dialect, statement) {
11783
+ walk.key += "S{";
11630
11784
  if (statement.distinctOn !== undefined && statement.distinctOn.length > 0) {
11631
- walk2.key += "d(";
11785
+ walk.key += "d(";
11632
11786
  for (const column of statement.distinctOn)
11633
- addCol(walk2, column);
11634
- walk2.key += ")";
11787
+ addCol(walk, column);
11788
+ walk.key += ")";
11635
11789
  }
11636
- walk2.key += "p(";
11790
+ walk.key += "p(";
11637
11791
  for (const column of statement.columns)
11638
- addCol(walk2, column);
11639
- walk2.key += ")";
11792
+ addCol(walk, column);
11793
+ walk.key += ")";
11640
11794
  if (statement.selectExpr !== undefined) {
11641
11795
  if (statement.selectExpr.kind === "one") {
11642
- walk2.key += "x1";
11796
+ walk.key += "x1";
11643
11797
  } else {
11644
- walk2.key += "xc";
11798
+ walk.key += "xc";
11645
11799
  if (statement.selectExpr.alias !== undefined)
11646
- addIdent(walk2, statement.selectExpr.alias);
11800
+ addIdent(walk, statement.selectExpr.alias);
11647
11801
  }
11648
11802
  }
11649
11803
  if (statement.aggregates !== undefined) {
11650
11804
  for (const selection of statement.aggregates) {
11651
- walk2.key += "a";
11652
- addAgg(walk2, selection.agg);
11653
- addIdent(walk2, selection.alias);
11805
+ walk.key += "a";
11806
+ addAgg(walk, selection.agg);
11807
+ addIdent(walk, selection.alias);
11654
11808
  }
11655
11809
  }
11656
11810
  if (statement.rowNumber !== undefined) {
11657
- walk2.key += "W(";
11811
+ walk.key += "W(";
11658
11812
  for (const column of statement.rowNumber.partitionBy)
11659
- addCol(walk2, column);
11660
- walk2.key += ":";
11813
+ addCol(walk, column);
11814
+ walk.key += ":";
11661
11815
  for (const term of statement.rowNumber.orderBy) {
11662
- if (!walkOrderTerm2(walk2, dialect, term))
11816
+ if (!walkOrderTerm2(walk, dialect, term))
11663
11817
  return false;
11664
11818
  }
11665
- addIdent(walk2, statement.rowNumber.alias);
11666
- walk2.key += ")";
11819
+ addIdent(walk, statement.rowNumber.alias);
11820
+ walk.key += ")";
11667
11821
  }
11668
- walk2.key += "f";
11669
- addTable(walk2, statement.table);
11822
+ walk.key += "f";
11823
+ addTable(walk, statement.table);
11670
11824
  if (statement.fromSelect !== undefined) {
11671
- walk2.key += "F(";
11672
- if (!walkSelect(walk2, dialect, statement.fromSelect))
11825
+ walk.key += "F(";
11826
+ if (!walkSelect(walk, dialect, statement.fromSelect))
11673
11827
  return false;
11674
- walk2.key += ")";
11828
+ walk.key += ")";
11675
11829
  }
11676
11830
  if (statement.innerJoins !== undefined && statement.innerJoins.length > 0) {
11677
11831
  for (const join of statement.innerJoins) {
11678
- walk2.key += "J(";
11679
- addTable(walk2, join.table);
11832
+ walk.key += "J(";
11833
+ addTable(walk, join.table);
11680
11834
  for (const pair of join.on) {
11681
- addCol(walk2, pair.left);
11682
- walk2.key += "=";
11683
- addCol(walk2, pair.right);
11835
+ addCol(walk, pair.left);
11836
+ walk.key += "=";
11837
+ addCol(walk, pair.right);
11684
11838
  }
11685
- walk2.key += ")";
11839
+ walk.key += ")";
11686
11840
  }
11687
11841
  }
11688
11842
  if (statement.lateralJoins !== undefined && statement.lateralJoins.length > 0) {
11689
11843
  for (const join of statement.lateralJoins) {
11690
- walk2.key += join.agg === "count" ? "Jc(" : join.agg === "jsonArray" ? "Ja(" : "Jo(";
11691
- walk2.key += join.rowFormat === "positional" ? "pos;" : "obj;";
11692
- if (!walkSelect(walk2, dialect, join.select))
11844
+ walk.key += join.agg === "count" ? "Jc(" : join.agg === "jsonArray" ? "Ja(" : "Jo(";
11845
+ walk.key += join.rowFormat === "positional" ? "pos;" : "obj;";
11846
+ if (!walkSelect(walk, dialect, join.select))
11693
11847
  return false;
11694
- addIdent(walk2, join.columnAlias);
11695
- addIdent(walk2, join.alias);
11696
- walk2.key += ")";
11848
+ addIdent(walk, join.columnAlias);
11849
+ addIdent(walk, join.alias);
11850
+ walk.key += ")";
11697
11851
  }
11698
11852
  }
11699
11853
  if (statement.where !== undefined) {
11700
- walk2.key += "w";
11701
- if (!walkExpr(walk2, dialect, statement.where))
11854
+ walk.key += "w";
11855
+ if (!walkExpr(walk, dialect, statement.where))
11702
11856
  return false;
11703
11857
  }
11704
11858
  if (statement.groupBy !== undefined && statement.groupBy.length > 0) {
11705
- walk2.key += "b(";
11859
+ walk.key += "b(";
11706
11860
  for (const column of statement.groupBy)
11707
- addCol(walk2, column);
11708
- walk2.key += ")";
11861
+ addCol(walk, column);
11862
+ walk.key += ")";
11709
11863
  }
11710
11864
  if (statement.having !== undefined) {
11711
- walk2.key += "v";
11712
- if (!walkExpr(walk2, dialect, statement.having))
11865
+ walk.key += "v";
11866
+ if (!walkExpr(walk, dialect, statement.having))
11713
11867
  return false;
11714
11868
  }
11715
11869
  if (statement.orderBy !== undefined && statement.orderBy.length > 0) {
11716
- walk2.key += "o(";
11870
+ walk.key += "o(";
11717
11871
  for (const term of statement.orderBy) {
11718
- if (!walkOrderTerm2(walk2, dialect, term))
11872
+ if (!walkOrderTerm2(walk, dialect, term))
11719
11873
  return false;
11720
11874
  }
11721
- walk2.key += ")";
11875
+ walk.key += ")";
11722
11876
  }
11723
11877
  if (statement.limit !== undefined)
11724
- walk2.key += `t${statement.limit}`;
11878
+ walk.key += `t${statement.limit}`;
11725
11879
  if (statement.offset !== undefined)
11726
- walk2.key += `s${statement.offset}`;
11880
+ walk.key += `s${statement.offset}`;
11727
11881
  if (statement.rowLock !== undefined) {
11728
- walk2.key += `u:${statement.rowLock.strength}/${statement.rowLock.wait}`;
11882
+ walk.key += `u:${statement.rowLock.strength}/${statement.rowLock.wait}`;
11729
11883
  }
11730
- walk2.key += "}";
11884
+ walk.key += "}";
11731
11885
  return true;
11732
11886
  }
11733
- function walkInsert(walk2, dialect, statement) {
11734
- walk2.key += "I{";
11735
- addTable(walk2, statement.table);
11736
- walk2.key += "c(";
11887
+ function walkInsert(walk, dialect, statement) {
11888
+ walk.key += "I{";
11889
+ addTable(walk, statement.table);
11890
+ walk.key += "c(";
11737
11891
  for (const name of statement.columns)
11738
- addIdent(walk2, name);
11739
- walk2.key += `)r${statement.rows.length}`;
11892
+ addIdent(walk, name);
11893
+ walk.key += `)r${statement.rows.length}`;
11740
11894
  const arity = statement.columns.length;
11741
11895
  for (let rowIndex = 0;rowIndex < statement.rows.length; rowIndex++) {
11742
11896
  const row = statement.rows[rowIndex];
@@ -11745,95 +11899,95 @@ function walkInsert(walk2, dialect, statement) {
11745
11899
  for (let cell = 0;cell < row.length; cell++) {
11746
11900
  const value = row[cell];
11747
11901
  if (isSqlDefaultCell(value))
11748
- walk2.key += `D${rowIndex}:${cell};`;
11902
+ walk.key += `D${rowIndex}:${cell};`;
11749
11903
  else if (isJsonParamCell(value)) {
11750
- walk2.key += `J${rowIndex}:${cell};`;
11751
- walk2.values.push(value.text);
11904
+ walk.key += `J${rowIndex}:${cell};`;
11905
+ walk.values.push(value.text);
11752
11906
  } else if (isDbNowMarker(value)) {
11753
- walk2.key += `T${rowIndex}:${cell}:${value.offsetSeconds === 0 ? "0" : "1"};`;
11907
+ walk.key += `T${rowIndex}:${cell}:${value.offsetSeconds === 0 ? "0" : "1"};`;
11754
11908
  if (value.offsetSeconds !== 0)
11755
- walk2.values.push(value.offsetSeconds);
11909
+ walk.values.push(value.offsetSeconds);
11756
11910
  } else
11757
- walk2.values.push(value);
11911
+ walk.values.push(value);
11758
11912
  }
11759
11913
  }
11760
11914
  const onConflict = statement.onConflict;
11761
11915
  if (onConflict !== undefined) {
11762
11916
  if ("doNothing" in onConflict) {
11763
- walk2.key += "N(";
11917
+ walk.key += "N(";
11764
11918
  if (onConflict.constraint !== undefined) {
11765
- walk2.key += "K";
11766
- addIdent(walk2, onConflict.constraint);
11919
+ walk.key += "K";
11920
+ addIdent(walk, onConflict.constraint);
11767
11921
  }
11768
11922
  if (onConflict.columns !== undefined) {
11769
11923
  for (const name of onConflict.columns)
11770
- addIdent(walk2, name);
11924
+ addIdent(walk, name);
11771
11925
  }
11772
11926
  if (onConflict.conflictWhere !== undefined) {
11773
- walk2.key += "w";
11774
- addIdent(walk2, onConflict.conflictWhere);
11927
+ walk.key += "w";
11928
+ addIdent(walk, onConflict.conflictWhere);
11775
11929
  }
11776
- walk2.key += ")";
11930
+ walk.key += ")";
11777
11931
  } else {
11778
11932
  if (Object.values(onConflict.update).some(isSqlFragment3))
11779
11933
  return false;
11780
- walk2.key += "U(";
11934
+ walk.key += "U(";
11781
11935
  if (onConflict.constraint !== undefined) {
11782
- walk2.key += "K";
11783
- addIdent(walk2, onConflict.constraint);
11936
+ walk.key += "K";
11937
+ addIdent(walk, onConflict.constraint);
11784
11938
  }
11785
11939
  for (const name of onConflict.columns)
11786
- addIdent(walk2, name);
11787
- walk2.key += ":";
11940
+ addIdent(walk, name);
11941
+ walk.key += ":";
11788
11942
  for (const [name, value] of Object.entries(onConflict.update))
11789
- addSetEntry(walk2, name, value);
11943
+ addSetEntry(walk, name, value);
11790
11944
  if (onConflict.lastInsertIdColumn !== undefined) {
11791
- walk2.key += "@";
11792
- addIdent(walk2, onConflict.lastInsertIdColumn);
11945
+ walk.key += "@";
11946
+ addIdent(walk, onConflict.lastInsertIdColumn);
11793
11947
  }
11794
- walk2.key += ")";
11948
+ walk.key += ")";
11795
11949
  }
11796
11950
  }
11797
- addReturning(walk2, statement.returning);
11798
- walk2.key += "}";
11951
+ addReturning(walk, statement.returning);
11952
+ walk.key += "}";
11799
11953
  return true;
11800
11954
  }
11801
- function walkUpdate(walk2, dialect, statement) {
11802
- walk2.key += "U{";
11803
- addTable(walk2, statement.table);
11955
+ function walkUpdate(walk, dialect, statement) {
11956
+ walk.key += "U{";
11957
+ addTable(walk, statement.table);
11804
11958
  for (const [name, value] of Object.entries(statement.set))
11805
- addSetEntry(walk2, name, value);
11959
+ addSetEntry(walk, name, value);
11806
11960
  if (statement.where !== undefined) {
11807
- walk2.key += "w";
11808
- if (!walkExpr(walk2, dialect, statement.where))
11961
+ walk.key += "w";
11962
+ if (!walkExpr(walk, dialect, statement.where))
11809
11963
  return false;
11810
11964
  }
11811
- addReturning(walk2, statement.returning);
11812
- walk2.key += "}";
11965
+ addReturning(walk, statement.returning);
11966
+ walk.key += "}";
11813
11967
  return true;
11814
11968
  }
11815
- function walkDelete(walk2, dialect, statement) {
11816
- walk2.key += "D{";
11817
- addTable(walk2, statement.table);
11969
+ function walkDelete(walk, dialect, statement) {
11970
+ walk.key += "D{";
11971
+ addTable(walk, statement.table);
11818
11972
  if (statement.where !== undefined) {
11819
- walk2.key += "w";
11820
- if (!walkExpr(walk2, dialect, statement.where))
11973
+ walk.key += "w";
11974
+ if (!walkExpr(walk, dialect, statement.where))
11821
11975
  return false;
11822
11976
  }
11823
- addReturning(walk2, statement.returning);
11824
- walk2.key += "}";
11977
+ addReturning(walk, statement.returning);
11978
+ walk.key += "}";
11825
11979
  return true;
11826
11980
  }
11827
- function walkStatement(walk2, dialect, statement) {
11981
+ function walkStatement(walk, dialect, statement) {
11828
11982
  switch (statement.kind) {
11829
11983
  case "select":
11830
- return walkSelect(walk2, dialect, statement);
11984
+ return walkSelect(walk, dialect, statement);
11831
11985
  case "insert":
11832
- return walkInsert(walk2, dialect, statement);
11986
+ return walkInsert(walk, dialect, statement);
11833
11987
  case "update":
11834
- return walkUpdate(walk2, dialect, statement);
11988
+ return walkUpdate(walk, dialect, statement);
11835
11989
  case "delete":
11836
- return walkDelete(walk2, dialect, statement);
11990
+ return walkDelete(walk, dialect, statement);
11837
11991
  case "rlsEnable":
11838
11992
  case "rlsForce":
11839
11993
  case "rlsDisable":
@@ -11871,27 +12025,27 @@ function sameValues(walked, rendered) {
11871
12025
  }
11872
12026
  function renderStatementCached(params) {
11873
12027
  const { dialect, statement, cache } = params;
11874
- const walk2 = { key: "", values: [] };
11875
- if (!walkStatement(walk2, dialect, statement)) {
12028
+ const walk = { key: "", values: [] };
12029
+ if (!walkStatement(walk, dialect, statement)) {
11876
12030
  return renderStatement4({ dialect, statement });
11877
12031
  }
11878
- const slot = cache.get(walk2.key);
12032
+ const slot = cache.get(walk.key);
11879
12033
  if (slot !== undefined) {
11880
12034
  if (slot === null)
11881
12035
  return renderStatement4({ dialect, statement });
11882
- return { text: slot.text, values: walk2.values, returning: slot.returning };
12036
+ return { text: slot.text, values: walk.values, returning: slot.returning };
11883
12037
  }
11884
12038
  const rendered = renderStatement4({ dialect, statement });
11885
- cache.set(walk2.key, sameValues(walk2.values, rendered.values) ? { text: rendered.text, returning: rendered.returning } : null);
12039
+ cache.set(walk.key, sameValues(walk.values, rendered.values) ? { text: rendered.text, returning: rendered.returning } : null);
11886
12040
  return rendered;
11887
12041
  }
11888
12042
 
11889
12043
  // packages/runtime/src/strict-args.ts
11890
- import { VibeError as VibeError25 } from "@vibeorm/schema";
12044
+ import { VibeError as VibeError27 } from "@vibeorm/schema";
11891
12045
  var SKIP = Symbol.for("vibeorm.skip");
11892
12046
  function explicitUndefined(params) {
11893
12047
  const { model, method, path } = params;
11894
- return new VibeError25({
12048
+ return new VibeError27({
11895
12049
  code: "VIBE_VALIDATION",
11896
12050
  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.`,
11897
12051
  meta: { model, method, path }
@@ -12068,10 +12222,10 @@ function bindRlsContext(params) {
12068
12222
  }
12069
12223
 
12070
12224
  // packages/runtime/src/telemetry/recorder.ts
12071
- import { VibeError as VibeError27 } from "@vibeorm/schema";
12225
+ import { VibeError as VibeError29 } from "@vibeorm/schema";
12072
12226
 
12073
12227
  // packages/runtime/src/telemetry/config.ts
12074
- import { VibeError as VibeError26 } from "@vibeorm/schema";
12228
+ import { VibeError as VibeError28 } from "@vibeorm/schema";
12075
12229
  var TELEMETRY_DEFAULTS = Object.freeze({
12076
12230
  captureSql: false,
12077
12231
  captureParameterValues: false,
@@ -12086,7 +12240,7 @@ var TELEMETRY_DEFAULTS = Object.freeze({
12086
12240
  latencyBucketsMs: Object.freeze([1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000])
12087
12241
  });
12088
12242
  function configError2(params) {
12089
- return new VibeError26({
12243
+ return new VibeError28({
12090
12244
  code: "VIBE_CONFIG",
12091
12245
  message: `telemetry: ${params.message}`,
12092
12246
  ...params.meta === undefined ? {} : { meta: params.meta }
@@ -12174,7 +12328,7 @@ function deriveStage(params) {
12174
12328
  return "decode";
12175
12329
  }
12176
12330
  function errorCodeOf(error) {
12177
- return error instanceof VibeError27 ? error.code : undefined;
12331
+ return error instanceof VibeError29 ? error.code : undefined;
12178
12332
  }
12179
12333
  function newHistogram(bounds) {
12180
12334
  return { counts: new Array(bounds.length + 1).fill(0), sum: 0, count: 0 };
@@ -12557,7 +12711,7 @@ async function instrumentStatement(params) {
12557
12711
  // packages/runtime/src/client.ts
12558
12712
  function notFound2(params) {
12559
12713
  const { model, method } = params;
12560
- return new VibeError28({
12714
+ return new VibeError30({
12561
12715
  code: "VIBE_NOT_FOUND",
12562
12716
  message: `no ${model} record matched the where clause of ${method}()`,
12563
12717
  meta: { model, method }
@@ -12565,7 +12719,7 @@ function notFound2(params) {
12565
12719
  }
12566
12720
  function transactionLifecycleRefusal(params) {
12567
12721
  const { method } = params;
12568
- return new VibeError28({
12722
+ return new VibeError30({
12569
12723
  code: "VIBE_VALIDATION",
12570
12724
  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`,
12571
12725
  meta: { method, inTransaction: true }
@@ -12573,7 +12727,7 @@ function transactionLifecycleRefusal(params) {
12573
12727
  }
12574
12728
  function viewIsReadOnly(params) {
12575
12729
  const { model, method } = params;
12576
- return new VibeError28({
12730
+ return new VibeError30({
12577
12731
  code: "VIBE_VALIDATION",
12578
12732
  message: `${model} is a view \u2014 ${method}() is not available on views (they are read-only); write to the underlying table instead`,
12579
12733
  meta: { model, method }
@@ -12656,6 +12810,7 @@ function assembleAggregates(params) {
12656
12810
  }
12657
12811
  return into;
12658
12812
  }
12813
+ var moduleMetadata = new WeakMap;
12659
12814
  function engineStateError(params) {
12660
12815
  const { engine } = params;
12661
12816
  for (let frame = engine.lifetime;frame !== undefined; frame = frame.parent) {
@@ -12679,7 +12834,7 @@ async function engineTransaction(params) {
12679
12834
  const support = engine.adapter.budgets?.transactionDeadline;
12680
12835
  const requested = options.deadline.enforcement ?? "between-statements";
12681
12836
  if (support === undefined || support === "unsupported" || requested === "cancel-running-statements" && support !== "cancel-running-statements") {
12682
- throw new VibeError28({
12837
+ throw new VibeError30({
12683
12838
  code: "VIBE_UNSUPPORTED_CAPABILITY",
12684
12839
  message: "the adapter does not declare support for the requested transaction deadline",
12685
12840
  meta: { provider: engine.adapter.provider, feature: "transactionDeadline", requested, supported: support ?? "undeclared" }
@@ -12854,8 +13009,6 @@ class QueryPromise extends Promise {
12854
13009
  const state = engineStateError({ engine: this.#target });
12855
13010
  if (state !== undefined)
12856
13011
  return state;
12857
- if (engine.rlsSchema === undefined && this.#target.rlsSchema === undefined)
12858
- return;
12859
13012
  if (this.#target.rootIdentity !== engine.rootIdentity || this.#target.lifetime !== engine.lifetime || !sameRecord(this.#target.context?.settings ?? {}, engine.context?.settings ?? {}))
12860
13013
  return new RlsContextError2({ reason: "conflicting" });
12861
13014
  return;
@@ -12870,7 +13023,7 @@ class QueryPromise extends Promise {
12870
13023
  }
12871
13024
  #claim() {
12872
13025
  if (this.#started) {
12873
- throw new VibeError28({
13026
+ throw new VibeError30({
12874
13027
  code: "VIBE_VALIDATION",
12875
13028
  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)"
12876
13029
  });
@@ -12879,6 +13032,7 @@ class QueryPromise extends Promise {
12879
13032
  const scope = this.#scope;
12880
13033
  return {
12881
13034
  start: (target) => {
13035
+ target = { ...target, meta: this.#target.meta, renderCache: this.#target.renderCache, options: this.#target.options };
12882
13036
  if (this.#target.readOnlySql === true)
12883
13037
  target = { ...target, readOnlySql: true };
12884
13038
  if (scope !== undefined && target.operation !== undefined) {
@@ -12939,11 +13093,11 @@ async function runRows(params) {
12939
13093
  return materializeRows({ dialect: engine.dialect.name, model: plan.model, rows, wire: engine.adapter.wire });
12940
13094
  }
12941
13095
  async function runBoundAffected(params) {
12942
- const { adapter, text: text2, values } = params;
12943
- const bound2 = adapter.executeAffected;
12944
- if (bound2 !== undefined)
12945
- return await bound2.call(adapter, { text: text2, values });
12946
- return await adapter.executeUnsafe({ text: text2, values });
13096
+ const { adapter, text, values } = params;
13097
+ const bound = adapter.executeAffected;
13098
+ if (bound !== undefined)
13099
+ return await bound.call(adapter, { text, values });
13100
+ return await adapter.executeUnsafe({ text, values });
12947
13101
  }
12948
13102
  async function runAffected(params) {
12949
13103
  const { engine, plan } = params;
@@ -12983,19 +13137,18 @@ async function runAffected(params) {
12983
13137
  }
12984
13138
  var LOCKABLE_METHODS = Object.freeze(["findMany", "findFirst", "findUnique"]);
12985
13139
  function plan(params) {
12986
- const { engine, model, method, args } = params;
12987
- if (engine.readOnlySql === true && containsSqlFragment(args))
12988
- throw readOnlyRefusal({ path: `${model}.${method}`, reason: "raw" });
13140
+ const { engine, model, method } = params;
13141
+ const args = engine.readOnlySql === true ? restrictedSqlArgs({ value: params.args, path: "$readOnly", refusal: () => readOnlyRefusal({ path: `${model}.${method}`, reason: "raw" }) }) : params.args;
12989
13142
  if (args !== undefined && args["lock"] !== undefined) {
12990
13143
  if (engine.inTransaction !== true) {
12991
- throw new VibeError28({
13144
+ throw new VibeError30({
12992
13145
  code: "VIBE_VALIDATION",
12993
13146
  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)`,
12994
13147
  meta: { model, method }
12995
13148
  });
12996
13149
  }
12997
13150
  if (!LOCKABLE_METHODS.includes(method)) {
12998
- throw new VibeError28({
13151
+ throw new VibeError30({
12999
13152
  code: "VIBE_VALIDATION",
13000
13153
  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`,
13001
13154
  meta: { model, method }
@@ -13022,7 +13175,7 @@ function readAcquiredVerdict(params) {
13022
13175
  return true;
13023
13176
  if (value === false || value === 0 || value === "f" || value === "false" || value === "0")
13024
13177
  return false;
13025
- throw new VibeError28({
13178
+ throw new VibeError30({
13026
13179
  code: "VIBE_INTERNAL",
13027
13180
  message: `internal: ${params.method}() expected a boolean "${ADVISORY_LOCK_RESULT_COLUMN}" column, got ${String(value)}`,
13028
13181
  meta: { method: params.method, value: String(value) }
@@ -13070,6 +13223,10 @@ async function insertedKeyWhere(params) {
13070
13223
  hint: "this model's key is assigned by the database and cannot be read back on this dialect"
13071
13224
  });
13072
13225
  }
13226
+ const insertId = params.insertId;
13227
+ if (typeof insertId === "number" && Number.isSafeInteger(insertId) || typeof insertId === "string" && /^-?\d+$/.test(insertId)) {
13228
+ return { [keyField.name]: decodeValue({ dialect: engine.dialect.name, field: keyField, value: insertId }) };
13229
+ }
13073
13230
  const result = await runStatement({
13074
13231
  engine,
13075
13232
  kind: "rows",
@@ -13082,7 +13239,7 @@ async function insertedKeyWhere(params) {
13082
13239
  });
13083
13240
  const id = result.rows[0]?.id;
13084
13241
  if (id === undefined || id === null) {
13085
- throw new VibeError28({
13242
+ throw new VibeError30({
13086
13243
  code: "VIBE_INTERNAL",
13087
13244
  message: `could not read back the generated key for ${source.model.name}`,
13088
13245
  meta: { model: source.model.name }
@@ -13120,7 +13277,7 @@ async function runSingleMutation(params) {
13120
13277
  values: bindValues({ adapter: target.adapter, values: rendered.values })
13121
13278
  })
13122
13279
  });
13123
- return result.affectedRows;
13280
+ return result;
13124
13281
  };
13125
13282
  if (readBeforeWrite) {
13126
13283
  const where = source.refetchWhere;
@@ -13131,7 +13288,7 @@ async function runSingleMutation(params) {
13131
13288
  const before = await refetch({ engine: txEngine, source, where, lock: true });
13132
13289
  if (before === null)
13133
13290
  throw notFound2({ model: source.model.name, method: source.method });
13134
- const affected = await executeWrite(txEngine);
13291
+ const { affectedRows: affected } = await executeWrite(txEngine);
13135
13292
  if (affected === 0)
13136
13293
  throw notFound2({ model: source.model.name, method: source.method });
13137
13294
  return before;
@@ -13157,25 +13314,25 @@ async function runSingleMutation(params) {
13157
13314
  if (!hasIdTrick)
13158
13315
  throw notFound2({ model: source.model.name, method: source.method });
13159
13316
  const where = await insertedKeyWhere({ engine: txEngine, source: { ...source, refetchWhere: null } });
13160
- const after2 = await refetch({ engine: txEngine, source, where });
13161
- if (after2 === null)
13317
+ const after = await refetch({ engine: txEngine, source, where });
13318
+ if (after === null)
13162
13319
  throw notFound2({ model: source.model.name, method: source.method });
13163
- return after2;
13320
+ return after;
13164
13321
  });
13165
13322
  }
13166
13323
  if (source.method === "update") {
13167
13324
  return await engine.adapter.transaction(async (txAdapter) => {
13168
13325
  const txEngine = { ...engine, adapter: txAdapter, inTransaction: true };
13169
- const affected2 = await executeWrite(txEngine);
13170
- if (affected2 === 0)
13326
+ const { affectedRows: affected } = await executeWrite(txEngine);
13327
+ if (affected === 0)
13171
13328
  throw notFound2({ model: source.model.name, method: source.method });
13172
- const after2 = await refetch({ engine: txEngine, source, where: knownWhere });
13173
- if (after2 === null)
13329
+ const after = await refetch({ engine: txEngine, source, where: knownWhere });
13330
+ if (after === null)
13174
13331
  throw notFound2({ model: source.model.name, method: source.method });
13175
- return after2;
13332
+ return after;
13176
13333
  });
13177
13334
  }
13178
- const affected = await executeWrite(engine);
13335
+ const { affectedRows: affected } = await executeWrite(engine);
13179
13336
  if (affected === 0 && params.allowZeroRows === true)
13180
13337
  return null;
13181
13338
  const after = await refetch({ engine, source, where: knownWhere });
@@ -13185,10 +13342,10 @@ async function runSingleMutation(params) {
13185
13342
  }
13186
13343
  return await engine.adapter.transaction(async (txAdapter) => {
13187
13344
  const txEngine = { ...engine, adapter: txAdapter, inTransaction: true };
13188
- const affected = await executeWrite(txEngine);
13345
+ const { affectedRows: affected, insertId } = await executeWrite(txEngine);
13189
13346
  if (affected === 0 && params.allowZeroRows === true)
13190
13347
  return null;
13191
- const where = await insertedKeyWhere({ engine: txEngine, source });
13348
+ const where = await insertedKeyWhere({ engine: txEngine, source, insertId });
13192
13349
  const after = await refetch({ engine: txEngine, source, where });
13193
13350
  if (after === null)
13194
13351
  throw notFound2({ model: source.model.name, method: source.method });
@@ -13352,21 +13509,21 @@ function makeWriteContext(params) {
13352
13509
  }
13353
13510
  function readOnlyDelegate2(params) {
13354
13511
  const { delegate, model } = params;
13355
- const refuse2 = (method) => async () => {
13512
+ const refuse = (method) => async () => {
13356
13513
  throw viewIsReadOnly({ model, method });
13357
13514
  };
13358
13515
  return {
13359
13516
  ...delegate,
13360
- create: refuse2("create"),
13361
- createMany: refuse2("createMany"),
13362
- createManyAndReturn: refuse2("createManyAndReturn"),
13363
- update: refuse2("update"),
13364
- updateMany: refuse2("updateMany"),
13365
- updateManyAndReturn: refuse2("updateManyAndReturn"),
13366
- upsert: refuse2("upsert"),
13367
- upsertMany: refuse2("upsertMany"),
13368
- delete: refuse2("delete"),
13369
- deleteMany: refuse2("deleteMany")
13517
+ create: refuse("create"),
13518
+ createMany: refuse("createMany"),
13519
+ createManyAndReturn: refuse("createManyAndReturn"),
13520
+ update: refuse("update"),
13521
+ updateMany: refuse("updateMany"),
13522
+ updateManyAndReturn: refuse("updateManyAndReturn"),
13523
+ upsert: refuse("upsert"),
13524
+ upsertMany: refuse("upsertMany"),
13525
+ delete: refuse("delete"),
13526
+ deleteMany: refuse("deleteMany")
13370
13527
  };
13371
13528
  }
13372
13529
  function isEffectivelyEmptyData(value) {
@@ -13410,14 +13567,14 @@ function createDelegate(params) {
13410
13567
  const skipping = args.onConflict !== undefined;
13411
13568
  if (hasNestedWrites({ model: modelMeta, data: args.data })) {
13412
13569
  if (skipping) {
13413
- throw new VibeError28({
13570
+ throw new VibeError30({
13414
13571
  code: "VIBE_VALIDATION",
13415
13572
  message: `onConflict cannot combine with nested writes on ${modelMeta.name}.create() \u2014 insert the parent row alone, then connect relations`,
13416
13573
  meta: { model: modelMeta.name }
13417
13574
  });
13418
13575
  }
13419
13576
  const shape = resolveResultShape({ meta: target.meta, model: modelMeta, method: "create", args });
13420
- const row2 = await createWithNested({
13577
+ const row = await createWithNested({
13421
13578
  ctx: makeWriteContext({ engine: target }),
13422
13579
  model: modelMeta,
13423
13580
  data: args.data
@@ -13426,7 +13583,7 @@ function createDelegate(params) {
13426
13583
  engine: target,
13427
13584
  model: modelMeta,
13428
13585
  shape: { ...shape, relationStrategy: "query" },
13429
- row: row2
13586
+ row
13430
13587
  });
13431
13588
  }
13432
13589
  const built = plan({ engine: target, model, method: "create", args });
@@ -13444,7 +13601,7 @@ function createDelegate(params) {
13444
13601
  const modelMeta = getModelMeta({ meta: target.meta, model });
13445
13602
  if (hasNestedWrites({ model: modelMeta, data: args.data })) {
13446
13603
  const shape = resolveResultShape({ meta: target.meta, model: modelMeta, method: "update", args });
13447
- const row2 = await updateWithNested({
13604
+ const row = await updateWithNested({
13448
13605
  ctx: makeWriteContext({ engine: target }),
13449
13606
  model: modelMeta,
13450
13607
  where: args.where,
@@ -13454,7 +13611,7 @@ function createDelegate(params) {
13454
13611
  engine: target,
13455
13612
  model: modelMeta,
13456
13613
  shape: { ...shape, relationStrategy: "query" },
13457
- row: row2
13614
+ row
13458
13615
  });
13459
13616
  }
13460
13617
  const built = plan({ engine: target, model, method: "update", args });
@@ -13511,7 +13668,7 @@ function createDelegate(params) {
13511
13668
  const upsert = async (target, args) => {
13512
13669
  const modelMeta = getModelMeta({ meta: target.meta, model });
13513
13670
  if (hasNestedWrites({ model: modelMeta, data: args.create }) || hasNestedWrites({ model: modelMeta, data: args.update })) {
13514
- throw new VibeError28({
13671
+ throw new VibeError30({
13515
13672
  code: "VIBE_VALIDATION",
13516
13673
  message: `nested writes are not supported inside upsert arms on ${modelMeta.name} \u2014 use create()/update() with nested data`,
13517
13674
  meta: { model: modelMeta.name }
@@ -13519,7 +13676,7 @@ function createDelegate(params) {
13519
13676
  }
13520
13677
  if (!upsertUsesNativeStatement({ model: modelMeta, args })) {
13521
13678
  if (args.onConflict !== undefined) {
13522
- throw new VibeError28({
13679
+ throw new VibeError30({
13523
13680
  code: "VIBE_VALIDATION",
13524
13681
  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`,
13525
13682
  meta: { model: modelMeta.name }
@@ -13531,12 +13688,12 @@ function createDelegate(params) {
13531
13688
  method: "upsert",
13532
13689
  args
13533
13690
  });
13534
- const row2 = await runUpsertFallback({ engine: target, model: modelMeta, args });
13691
+ const row = await runUpsertFallback({ engine: target, model: modelMeta, args });
13535
13692
  return await finalizeRow({
13536
13693
  engine: target,
13537
13694
  model: modelMeta,
13538
13695
  shape: { ...shape, relationStrategy: "query" },
13539
- row: row2
13696
+ row
13540
13697
  });
13541
13698
  }
13542
13699
  const built = plan({ engine: target, model, method: "upsert", args });
@@ -13691,11 +13848,11 @@ function withStrictArguments(params) {
13691
13848
  function buildRawStatement(params) {
13692
13849
  const { dialect, strings, values } = params;
13693
13850
  const collector = new ParamCollector(dialect);
13694
- let text2 = strings[0] ?? "";
13851
+ let text = strings[0] ?? "";
13695
13852
  for (let index = 0;index < values.length; index++) {
13696
- text2 += collector.add(values[index]) + (strings[index + 1] ?? "");
13853
+ text += collector.add(values[index]) + (strings[index + 1] ?? "");
13697
13854
  }
13698
- return { text: text2, values: collector.values };
13855
+ return { text, values: collector.values };
13699
13856
  }
13700
13857
  function buildClient(params) {
13701
13858
  const { engine } = params;
@@ -13712,7 +13869,7 @@ function buildClient(params) {
13712
13869
  models[model.name] = delegate;
13713
13870
  models[model.clientName] = delegate;
13714
13871
  }
13715
- const runRaw = async (method, statement, decodeRows2) => {
13872
+ const runRaw = async (method, statement, decodeRows) => {
13716
13873
  const scope = beginOperation({ engine, kind: "raw", model: null, method });
13717
13874
  scope?.dispatch();
13718
13875
  const running = executeOperation({
@@ -13726,9 +13883,9 @@ function buildClient(params) {
13726
13883
  text: statement.text,
13727
13884
  values: statement.values,
13728
13885
  rowCount: (value) => method.startsWith("$query") ? value.rows.length : value.affectedRows,
13729
- run: () => statement.values.length > 0 ? runBoundAffected({ adapter: target.adapter, text: statement.text, values: statement.values }) : target.adapter.executeUnsafe(statement)
13886
+ run: () => statement.values.length > 0 ? target.adapter.executeRawBound !== undefined ? target.adapter.executeRawBound(statement) : runBoundAffected({ adapter: target.adapter, text: statement.text, values: statement.values }) : target.adapter.executeUnsafe(statement)
13730
13887
  });
13731
- decodeRows2?.(result.rows);
13888
+ decodeRows?.(result.rows);
13732
13889
  return result;
13733
13890
  }
13734
13891
  });
@@ -13744,8 +13901,8 @@ function buildClient(params) {
13744
13901
  });
13745
13902
  return await running;
13746
13903
  };
13747
- const runAdvisoryLock = async (params2) => {
13748
- const { method, options } = params2;
13904
+ const runAdvisoryLock = async (params) => {
13905
+ const { method, options } = params;
13749
13906
  assertEngineActive({ engine });
13750
13907
  const statement = compileAdvisoryLock({
13751
13908
  dialect: engine.dialect,
@@ -13797,7 +13954,7 @@ function buildClient(params) {
13797
13954
  }
13798
13955
  for (const operation of operations) {
13799
13956
  if (!isQueryPromise(operation)) {
13800
- claimError = new VibeError28({
13957
+ claimError = new VibeError30({
13801
13958
  code: "VIBE_VALIDATION",
13802
13959
  message: "$transaction([...]) takes query promises from model delegate calls \u2014 a foreign promise is already running and cannot join the transaction"
13803
13960
  });
@@ -13862,7 +14019,7 @@ function buildClient(params) {
13862
14019
  $models: models,
13863
14020
  $on: (event, listener) => {
13864
14021
  if (event !== "query") {
13865
- throw new VibeError28({
14022
+ throw new VibeError30({
13866
14023
  code: "VIBE_VALIDATION",
13867
14024
  message: `unknown client event "${String(event)}" \u2014 supported: "query"`,
13868
14025
  meta: { event }
@@ -13877,7 +14034,7 @@ function buildClient(params) {
13877
14034
  $querySql: async ({ query, decoder }) => {
13878
14035
  assertEngineActive({ engine });
13879
14036
  if (decoder === null || typeof decoder !== "object" || typeof decoder.decode !== "function")
13880
- throw new VibeError28({ code: "VIBE_VALIDATION", message: "$querySql requires an explicit result decoder" });
14037
+ throw new VibeError30({ code: "VIBE_VALIDATION", message: "$querySql requires an explicit result decoder" });
13881
14038
  const statement = compileSql({ dialect: engine.dialect, query });
13882
14039
  let output = [];
13883
14040
  await runRaw("$querySql", statement, (rows) => {
@@ -13891,14 +14048,16 @@ function buildClient(params) {
13891
14048
  },
13892
14049
  $queryRaw: async (strings, ...values) => (await runRaw("$queryRaw", buildRawStatement({ dialect: engine.dialect, strings, values }))).rows,
13893
14050
  $executeRaw: async (strings, ...values) => (await runRaw("$executeRaw", buildRawStatement({ dialect: engine.dialect, strings, values }))).affectedRows,
13894
- $queryRawUnsafe: async (text2, ...values) => (await runRaw("$queryRawUnsafe", { text: text2, values })).rows,
13895
- $executeRawUnsafe: async (text2, ...values) => (await runRaw("$executeRawUnsafe", { text: text2, values })).affectedRows,
14051
+ $queryRawUnsafe: async (text, ...values) => (await runRaw("$queryRawUnsafe", { text, values })).rows,
14052
+ $executeRawUnsafe: async (text, ...values) => (await runRaw("$executeRawUnsafe", { text, values })).affectedRows,
13896
14053
  $advisoryLock: async (options) => {
13897
14054
  await runAdvisoryLock({ method: "$advisoryLock", options });
13898
14055
  },
13899
14056
  $tryAdvisoryLock: (options) => runAdvisoryLock({ method: "$tryAdvisoryLock", options }),
13900
14057
  $connect: async () => {
13901
14058
  assertEngineActive({ engine, requireContext: false });
14059
+ if (engine.borrowedModule === true)
14060
+ 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" } });
13902
14061
  if (engine.inTransaction === true)
13903
14062
  throw transactionLifecycleRefusal({ method: "$connect" });
13904
14063
  if (engine.rlsSchema !== undefined) {
@@ -13919,6 +14078,8 @@ function buildClient(params) {
13919
14078
  },
13920
14079
  $disconnect: async () => {
13921
14080
  assertEngineActive({ engine, requireContext: false });
14081
+ if (engine.borrowedModule === true)
14082
+ 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" } });
13922
14083
  if (engine.inTransaction === true)
13923
14084
  throw transactionLifecycleRefusal({ method: "$disconnect" });
13924
14085
  await engine.diagnostics?.flush();
@@ -13934,7 +14095,7 @@ function buildClient(params) {
13934
14095
  }
13935
14096
  attachExtensionMounts({ engine, client, models });
13936
14097
  attachDefineView({ client, meta: engine.meta, models });
13937
- const wrapDelegate = engine.options?.strictArguments !== false ? (params2) => withStrictArguments({ engine, ...params2 }) : undefined;
14098
+ const wrapDelegate = engine.options?.strictArguments !== false ? (params) => withStrictArguments({ engine, ...params }) : undefined;
13938
14099
  if (engine.rlsSchema === undefined)
13939
14100
  attachScoped({ client, meta: engine.meta, ...wrapDelegate === undefined ? {} : { wrapDelegate } });
13940
14101
  if (engine.rlsSchema === undefined) {
@@ -13954,7 +14115,7 @@ function buildClient(params) {
13954
14115
  });
13955
14116
  } else {
13956
14117
  const refuseLegacy = () => {
13957
- throw new VibeError28({ code: "VIBE_CONFIG", message: "Native row-level security cannot be combined with application policy or tenant scoping" });
14118
+ throw new VibeError30({ code: "VIBE_CONFIG", message: "Native row-level security cannot be combined with application policy or tenant scoping" });
13958
14119
  };
13959
14120
  Object.defineProperties(client, {
13960
14121
  $withContext: { enumerable: true, value: (context) => {
@@ -13980,6 +14141,25 @@ function buildClient(params) {
13980
14141
  Object.freeze(models);
13981
14142
  Object.freeze(client);
13982
14143
  }
14144
+ registerModuleBinder({ client, bind: ({ schema, manifest }) => {
14145
+ assertEngineActive({ engine, requireContext: false });
14146
+ if (engine.rlsSchema !== undefined || engine.meta.models.some((model) => model.policy !== undefined))
14147
+ 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 } });
14148
+ if (manifest.dialect !== engine.dialect.name)
14149
+ 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 } });
14150
+ const previous = engine.moduleManifests.get(manifest.id);
14151
+ if (previous !== undefined && (previous.schemaChecksum !== manifest.schemaChecksum || previous.revision !== manifest.revision || previous.contract !== manifest.contract))
14152
+ 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 } });
14153
+ let meta = moduleMetadata.get(schema);
14154
+ if (meta === undefined) {
14155
+ meta = buildRuntimeMeta({ schema });
14156
+ registerRestrictedSqlSchema({ meta, schema });
14157
+ moduleMetadata.set(schema, meta);
14158
+ }
14159
+ engine.moduleManifests.set(manifest.id, manifest);
14160
+ const { validate: _validate, ...options } = engine.options;
14161
+ return buildClient({ engine: { ...engine, meta, options, borrowedModule: true, extensionMounts: [], connectHooks: [], renderCache: new StatementRenderCache } });
14162
+ } });
13983
14163
  return client;
13984
14164
  }
13985
14165
  function makeMountContext(params) {
@@ -13990,7 +14170,7 @@ function makeMountContext(params) {
13990
14170
  provider: engine.adapter.provider,
13991
14171
  meta: engine.meta,
13992
14172
  model,
13993
- executeRows: async ({ text: text2, values, method }) => {
14173
+ executeRows: async ({ text, values, method }) => {
13994
14174
  const scope = beginOperation({
13995
14175
  engine,
13996
14176
  kind: "extension",
@@ -14006,11 +14186,11 @@ function makeMountContext(params) {
14006
14186
  kind: "extension",
14007
14187
  model: model?.name ?? null,
14008
14188
  method: method ?? extension,
14009
- text: text2,
14189
+ text,
14010
14190
  values,
14011
14191
  rowCount: (value) => value.length,
14012
14192
  run: () => target.adapter.execute({
14013
- text: text2,
14193
+ text,
14014
14194
  values: bindValues({ adapter: target.adapter, values: [...values] })
14015
14195
  })
14016
14196
  });
@@ -14024,7 +14204,7 @@ function makeMountContext(params) {
14024
14204
  compileWhere: ({ where, model: modelName, qualify }) => {
14025
14205
  const target = modelName === undefined ? model : getModelMeta({ meta: engine.meta, model: modelName });
14026
14206
  if (target === null) {
14027
- throw new VibeError28({
14207
+ throw new VibeError30({
14028
14208
  code: "VIBE_INTERNAL",
14029
14209
  message: `extension "${extension}" compiled a where with no model in scope`,
14030
14210
  meta: { extension }
@@ -14053,24 +14233,24 @@ function createMountSurface(params) {
14053
14233
  for (const key of path) {
14054
14234
  receiver = current;
14055
14235
  if (current === null || typeof current !== "object" && typeof current !== "function")
14056
- throw new VibeError28({ code: "VIBE_CONFIG", message: "Extension mount changed its method shape" });
14236
+ throw new VibeError30({ code: "VIBE_CONFIG", message: "Extension mount changed its method shape" });
14057
14237
  current = Reflect.get(current, key);
14058
14238
  }
14059
14239
  if (typeof current !== "function")
14060
- throw new VibeError28({ code: "VIBE_CONFIG", message: "Extension mount changed its method shape" });
14240
+ throw new VibeError30({ code: "VIBE_CONFIG", message: "Extension mount changed its method shape" });
14061
14241
  return Reflect.apply(current, receiver, args);
14062
14242
  } });
14063
14243
  }
14064
14244
  if (value === null || typeof value !== "object")
14065
14245
  return value;
14066
14246
  if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
14067
- throw new VibeError28({ code: "VIBE_CONFIG", message: "Native RLS extension mounts must expose plain objects and methods" });
14247
+ throw new VibeError30({ code: "VIBE_CONFIG", message: "Native RLS extension mounts must expose plain objects and methods" });
14068
14248
  }
14069
14249
  const result = {};
14070
14250
  for (const key of Reflect.ownKeys(value)) {
14071
14251
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
14072
14252
  if (!("value" in descriptor))
14073
- throw new VibeError28({ code: "VIBE_CONFIG", message: "Native RLS extension mount accessors are unsupported" });
14253
+ throw new VibeError30({ code: "VIBE_CONFIG", message: "Native RLS extension mount accessors are unsupported" });
14074
14254
  Object.defineProperty(result, key, { value: wrap(descriptor.value, [...path, key]), enumerable: descriptor.enumerable });
14075
14255
  }
14076
14256
  return Object.freeze(result);
@@ -14087,18 +14267,18 @@ function attachExtensionMounts(params) {
14087
14267
  const model = getModelMeta({ meta: engine.meta, model: mount.model ?? "" });
14088
14268
  const delegate = models[model.name];
14089
14269
  if (delegate === undefined || mount.property in delegate) {
14090
- throw new VibeError28({
14270
+ throw new VibeError30({
14091
14271
  code: "VIBE_CONFIG",
14092
14272
  message: `extension "${mount.extension}" cannot mount "${mount.property}" on ${model.name} \u2014 the name is taken`,
14093
14273
  meta: { extension: mount.extension, model: model.name, property: mount.property }
14094
14274
  });
14095
14275
  }
14096
- const value2 = createMountSurface({ engine, mount, model });
14097
- Object.defineProperty(delegate, mount.property, { value: value2, enumerable: true, configurable: true });
14276
+ const value = createMountSurface({ engine, mount, model });
14277
+ Object.defineProperty(delegate, mount.property, { value, enumerable: true, configurable: true });
14098
14278
  continue;
14099
14279
  }
14100
14280
  if (!mount.property.startsWith("$") || mount.property in client) {
14101
- throw new VibeError28({
14281
+ throw new VibeError30({
14102
14282
  code: "VIBE_CONFIG",
14103
14283
  message: `extension "${mount.extension}" cannot mount client property "${mount.property}" \u2014 root mounts are $-prefixed and must not collide`,
14104
14284
  meta: { extension: mount.extension, property: mount.property }
@@ -14133,9 +14313,9 @@ function createClient(params) {
14133
14313
  const role = options?.nativeRls?.runtimeRole;
14134
14314
  if (adapter.provider === "pglite") {
14135
14315
  if (typeof role !== "string" || role.length === 0 || role.includes("\x00"))
14136
- throw new VibeError28({ 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" });
14316
+ 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" });
14137
14317
  } else if (role !== undefined) {
14138
- throw new VibeError28({ code: "VIBE_CONFIG", message: "Server native row-level security must use the runtime login role, not a runtimeRole switch" });
14318
+ throw new VibeError30({ code: "VIBE_CONFIG", message: "Server native row-level security must use the runtime login role, not a runtimeRole switch" });
14139
14319
  }
14140
14320
  }
14141
14321
  if (extensions?.manifest !== undefined) {
@@ -14145,7 +14325,7 @@ function createClient(params) {
14145
14325
  assertComputedManifest({ manifest: computed.manifest, specs: computed.specs });
14146
14326
  }
14147
14327
  if (computed === undefined && options !== undefined && options["computed"] !== undefined) {
14148
- throw new VibeError28({
14328
+ throw new VibeError30({
14149
14329
  code: "VIBE_CONFIG",
14150
14330
  message: "this client was generated without computed fields \u2014 declare them in vibeorm.config.ts and re-run vibeorm generate",
14151
14331
  meta: {}
@@ -14159,9 +14339,11 @@ function createClient(params) {
14159
14339
  ...computed?.specs === undefined ? {} : { computed: computed.specs }
14160
14340
  });
14161
14341
  const meta = operatorMap === null ? baseMeta : { ...baseMeta, extensionOperators: operatorMap };
14342
+ registerRestrictedSqlSchema({ meta, schema });
14162
14343
  return buildClient({
14163
14344
  engine: {
14164
14345
  rootIdentity: Object.freeze({}),
14346
+ moduleManifests: new Map,
14165
14347
  ...schema.rls === undefined ? {} : { rlsSchema: schema },
14166
14348
  meta,
14167
14349
  adapter,
@@ -14176,14 +14358,64 @@ function createClient(params) {
14176
14358
  }
14177
14359
  });
14178
14360
  }
14361
+
14362
+ // packages/runtime/src/database-module.ts
14363
+ function canonicalValue(params) {
14364
+ const { value } = params;
14365
+ if (Array.isArray(value))
14366
+ return value.map((entry) => canonicalValue({ value: entry }));
14367
+ if (value === null || typeof value !== "object")
14368
+ return value;
14369
+ return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, entry]) => [key, canonicalValue({ value: entry })]));
14370
+ }
14371
+ function freezeData(params) {
14372
+ if (params.value === null || typeof params.value !== "object" || Object.isFrozen(params.value))
14373
+ return;
14374
+ for (const value of Object.values(params.value))
14375
+ freezeData({ value });
14376
+ Object.freeze(params.value);
14377
+ }
14378
+ function defineDatabaseModule(params) {
14379
+ for (const key of ["id", "contract", "revision"]) {
14380
+ if (typeof params[key] !== "string" || params[key].trim().length === 0 || params[key].includes("\x00"))
14381
+ throw new VibeError31({ code: "VIBE_CONFIG", message: `Database module ${key} must be a non-empty identifier`, meta: { reason: "module_manifest", key } });
14382
+ }
14383
+ assertValidSchemaIR3({ schema: params.schema });
14384
+ if (params.schema.rls !== undefined || params.schema.extensions.length > 0 || params.schema.models.some((model) => model.policy !== undefined))
14385
+ throw new VibeError31({
14386
+ code: "VIBE_UNSUPPORTED_CAPABILITY",
14387
+ message: `Module ${params.id} cannot declare extensions, policy or native RLS in this module protocol`,
14388
+ meta: { reason: "module_schema_feature", moduleId: params.id }
14389
+ });
14390
+ const serialized = JSON.stringify(canonicalValue({ value: params.schema }));
14391
+ const schema = JSON.parse(serialized);
14392
+ freezeData({ value: schema });
14393
+ const manifest = Object.freeze({
14394
+ id: params.id,
14395
+ contract: params.contract,
14396
+ revision: params.revision,
14397
+ protocol: 1,
14398
+ dialect: providerToDialect({ provider: schema.datasource.provider }),
14399
+ schemaChecksum: createHash("sha256").update(serialized).digest("hex")
14400
+ });
14401
+ if (params.manifest !== undefined && Object.keys(manifest).some((key) => params.manifest[key] !== manifest[key]))
14402
+ throw new VibeError31({
14403
+ code: "VIBE_STALE_CLIENT",
14404
+ message: `Module ${params.id} has incompatible or modified generated metadata; regenerate with a compatible runtime`,
14405
+ meta: { reason: "module_artifact", moduleId: params.id, revision: params.revision, protocol: params.manifest.protocol }
14406
+ });
14407
+ const artifact = Object.freeze({ schema, manifest });
14408
+ const bind = ({ db }) => bindModuleContext({ db, artifact });
14409
+ return Object.freeze({ ...artifact, bind, create: ({ adapter }) => bind({ db: createClient({ schema, adapter }) }) });
14410
+ }
14179
14411
  // packages/runtime/src/keyset-iterator.ts
14180
- import { VibeError as VibeError29 } from "@vibeorm/schema";
14412
+ import { VibeError as VibeError32 } from "@vibeorm/schema";
14181
14413
  function validation(params) {
14182
- return new VibeError29({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
14414
+ return new VibeError32({ code: "VIBE_VALIDATION", message: params.message, meta: params.meta });
14183
14415
  }
14184
14416
  function projectionFor(params) {
14185
- const { plan: plan2, select, omit } = params;
14186
- const names = plan2.keys.map((key) => key.field.name);
14417
+ const { plan, select, omit } = params;
14418
+ const names = plan.keys.map((key) => key.field.name);
14187
14419
  if (select !== undefined) {
14188
14420
  const hidden = names.filter((name) => select[name] !== true);
14189
14421
  if (hidden.length === 0)
@@ -14213,13 +14445,13 @@ function iterateKeyset(options) {
14213
14445
  });
14214
14446
  }
14215
14447
  const model = getModelMeta({ meta, model: options.model });
14216
- const plan2 = compileKeysetOrderPlan({
14448
+ const plan = compileKeysetOrderPlan({
14217
14449
  model,
14218
14450
  dialect,
14219
14451
  terms: compileKeysetOrderInputs({ dialect, meta, model, orderBy }),
14220
14452
  ...options.timestampPrecision === undefined ? {} : { timestampPrecision: options.timestampPrecision }
14221
14453
  });
14222
- const projection = projectionFor({ plan: plan2, select: options.select, omit: options.omit });
14454
+ const projection = projectionFor({ plan, select: options.select, omit: options.omit });
14223
14455
  const keysetArg = options.timestampPrecision === undefined ? {} : { keyset: { timestampPrecision: options.timestampPrecision } };
14224
14456
  let buffer = [];
14225
14457
  let position = options.after ?? null;
@@ -14250,16 +14482,16 @@ function iterateKeyset(options) {
14250
14482
  const first = rows[0];
14251
14483
  if (position !== null && first !== undefined) {
14252
14484
  const advanced = keysetRowIsAfter({
14253
- keys: plan2.keys,
14254
- row: keysetRowValues({ plan: plan2, row: first }),
14255
- position: decodeKeysetToken({ plan: plan2, token: position })
14485
+ keys: plan.keys,
14486
+ row: keysetRowValues({ plan, row: first }),
14487
+ position: decodeKeysetToken({ plan, token: position })
14256
14488
  });
14257
14489
  if (advanced === false) {
14258
14490
  stop();
14259
- throw new VibeError29({
14491
+ throw new VibeError32({
14260
14492
  code: "VIBE_DATA_INVALID",
14261
14493
  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.",
14262
- meta: { model: options.model, order: plan2.signature, reason: "keyset-position-not-advancing" }
14494
+ meta: { model: options.model, order: plan.signature, reason: "keyset-position-not-advancing" }
14263
14495
  });
14264
14496
  }
14265
14497
  }
@@ -14291,7 +14523,7 @@ function iterateKeyset(options) {
14291
14523
  }
14292
14524
  }
14293
14525
  const raw = buffer.shift();
14294
- pending = encodeKeysetToken({ plan: plan2, row: raw });
14526
+ pending = encodeKeysetToken({ plan, row: raw });
14295
14527
  position = pending;
14296
14528
  if (projection.hidden.length === 0)
14297
14529
  return { done: false, value: raw };
@@ -14329,7 +14561,7 @@ function iterateKeyset(options) {
14329
14561
  return iterator;
14330
14562
  }
14331
14563
  // packages/runtime/src/telemetry/collector.ts
14332
- import { VibeError as VibeError30 } from "@vibeorm/schema";
14564
+ import { VibeError as VibeError33 } from "@vibeorm/schema";
14333
14565
  function createTelemetryCollector(params) {
14334
14566
  const throwOn = new Set(params?.throwOn ?? []);
14335
14567
  const operations = [];
@@ -14339,7 +14571,7 @@ function createTelemetryCollector(params) {
14339
14571
  let shutdowns = 0;
14340
14572
  const hostile = (phase) => {
14341
14573
  if (throwOn.has(phase)) {
14342
- throw new VibeError30({
14574
+ throw new VibeError33({
14343
14575
  code: "VIBE_INTERNAL",
14344
14576
  message: `telemetry collector: deliberate ${phase} failure`,
14345
14577
  meta: { reason: "telemetry-collector-deliberate-failure", phase }
@@ -14395,7 +14627,7 @@ function createTelemetryCollector(params) {
14395
14627
  operationFor: (lookup) => {
14396
14628
  const matches = operations.filter((event) => event.method === lookup.method && (lookup.model === undefined || event.model === lookup.model));
14397
14629
  if (matches.length > 1) {
14398
- throw new VibeError30({
14630
+ throw new VibeError33({
14399
14631
  code: "VIBE_VALIDATION",
14400
14632
  message: `telemetry collector: ${matches.length} operations match ${lookup.model ?? "*"}.${lookup.method}`,
14401
14633
  meta: {
@@ -14411,114 +14643,115 @@ function createTelemetryCollector(params) {
14411
14643
  };
14412
14644
  }
14413
14645
  export {
14414
- validateWriteData,
14415
- updateWithNested,
14416
- toSqlExecutor,
14417
- toClientName,
14418
- summarizePlan,
14419
- sqlProjection,
14420
- sql2 as sql,
14421
- rewriteScopedCall,
14422
- resolveTelemetryConfig,
14423
- resolveStatementDiagnostics,
14424
- resolveScopedModels,
14425
- resolveResultShape,
14426
- resolveRelationSelection,
14427
- resolveRelationLink,
14428
- recommendFromPlan,
14429
- readWorkloadStatistics,
14430
- readOnlyRefusal,
14431
- queryFingerprint,
14432
- previewOperation,
14433
- parsePostgresPlan,
14434
- parseDiagnosticsEnv,
14435
- parameterTypeTag,
14436
- normalizeSql,
14437
- lateralColumnAlias,
14438
- keysetRowValues,
14439
- keysetRowIsAfter,
14440
- iterateKeyset,
14441
- isExecutableRead,
14442
- isDbNow,
14443
- inspectNativeRlsTransaction,
14444
- inspectNativeRls,
14445
- inheritReadOnly,
14446
- hasNestedWrites,
14447
- getModelMeta,
14448
- getFieldMeta,
14449
- getCodec,
14450
- generateUuid,
14451
- generateUlid,
14452
- generateNanoid,
14453
- generateDefaultValue,
14454
- generateCuid,
14455
- formatStatementDiagnostic,
14456
- formatNativeRlsReport,
14457
- explainSql,
14458
- explainOperation,
14459
- explainOnSession,
14460
- encodeValue,
14461
- encodeKeysetToken,
14462
- delegateMethodAccess,
14463
- decodeValue,
14464
- decodeRows,
14465
- decodeRow,
14466
- decodeKeysetToken,
14467
- decodeIsNoop2 as decodeIsNoop,
14468
- decodeAggregateValue,
14469
- decode2 as decode,
14470
- dbNow,
14471
- createWithNested,
14472
- createView,
14473
- createTelemetryRecorder,
14474
- createTelemetryCollector,
14475
- createStatementDiagnostics,
14476
- createSqlModel,
14477
- createScopeRewriter,
14478
- createClient,
14479
- compileWhere,
14480
- compileSelect,
14481
- compileOrderBy,
14482
- compileKeysetOrderPlan,
14483
- compileKeysetOrderInputs,
14484
- compileAdvisoryLock,
14485
- clientMemberAccess,
14486
- checkStrictArguments,
14487
- buildRuntimeMeta,
14488
- buildQuery,
14489
- buildExtensionOperatorMap,
14490
- buildConnectHooks,
14491
- attachScoped,
14492
- attachRelations,
14493
- attachReadOnly,
14494
- attachPolicy,
14495
- attachLateralRelations,
14496
- attachDefineView,
14497
- assertNativeRlsReady,
14498
- assertExtensionManifest,
14499
- assertComputedManifest,
14500
- applyWriteValidators,
14501
- applyComputedFields,
14502
- analyzeOperationTelemetry,
14503
- affectedRowsAreRowCounts,
14504
- WRITE_DELEGATE_METHODS,
14505
- ViewResult,
14506
- TELEMETRY_DEFAULTS,
14507
- STATEMENT_DIAGNOSTICS_DEFAULTS,
14508
- SQLITE_CODECS,
14509
- SKIP,
14510
- READ_DELEGATE_METHODS,
14511
- POSTGRES_CODECS,
14512
- PLAN_DEFAULTS,
14513
- MYSQL_CODECS,
14514
- KEYSET_TOKEN_VERSION,
14515
- KEYSET_TOKEN_PREFIX,
14516
- KEYSET_MAX_PAGE_SIZE,
14517
- DIALECT_CODECS2 as DIALECT_CODECS,
14518
- DIAGNOSTIC_THRESHOLDS,
14519
- DELEGATE_METHOD_ACCESS,
14646
+ CLIENT_MEMBER_ACCESS,
14520
14647
  COUNT_ALIAS,
14521
- CLIENT_MEMBER_ACCESS
14648
+ DELEGATE_METHOD_ACCESS,
14649
+ DIAGNOSTIC_THRESHOLDS,
14650
+ DIALECT_CODECS2 as DIALECT_CODECS,
14651
+ KEYSET_MAX_PAGE_SIZE,
14652
+ KEYSET_TOKEN_PREFIX,
14653
+ KEYSET_TOKEN_VERSION,
14654
+ MYSQL_CODECS,
14655
+ PLAN_DEFAULTS,
14656
+ POSTGRES_CODECS,
14657
+ READ_DELEGATE_METHODS,
14658
+ SKIP,
14659
+ SQLITE_CODECS,
14660
+ STATEMENT_DIAGNOSTICS_DEFAULTS,
14661
+ TELEMETRY_DEFAULTS,
14662
+ ViewResult,
14663
+ WRITE_DELEGATE_METHODS,
14664
+ affectedRowsAreRowCounts,
14665
+ analyzeOperationTelemetry,
14666
+ applyComputedFields,
14667
+ applyWriteValidators,
14668
+ assertComputedManifest,
14669
+ assertExtensionManifest,
14670
+ assertNativeRlsReady,
14671
+ attachDefineView,
14672
+ attachLateralRelations,
14673
+ attachPolicy,
14674
+ attachReadOnly,
14675
+ attachRelations,
14676
+ attachScoped,
14677
+ buildConnectHooks,
14678
+ buildExtensionOperatorMap,
14679
+ buildQuery,
14680
+ buildRuntimeMeta,
14681
+ checkStrictArguments,
14682
+ clientMemberAccess,
14683
+ compileAdvisoryLock,
14684
+ compileKeysetOrderInputs,
14685
+ compileKeysetOrderPlan,
14686
+ compileOrderBy,
14687
+ compileSelect,
14688
+ compileWhere,
14689
+ createClient,
14690
+ createScopeRewriter,
14691
+ createSqlModel,
14692
+ createStatementDiagnostics,
14693
+ createTelemetryCollector,
14694
+ createTelemetryRecorder,
14695
+ createView,
14696
+ createWithNested,
14697
+ dbNow,
14698
+ decode2 as decode,
14699
+ decodeAggregateValue,
14700
+ decodeIsNoop2 as decodeIsNoop,
14701
+ decodeKeysetToken,
14702
+ decodeRow,
14703
+ decodeRows,
14704
+ decodeValue,
14705
+ defineDatabaseModule,
14706
+ delegateMethodAccess,
14707
+ encodeKeysetToken,
14708
+ encodeValue,
14709
+ explainOnSession,
14710
+ explainOperation,
14711
+ explainSql,
14712
+ formatNativeRlsReport,
14713
+ formatStatementDiagnostic,
14714
+ generateCuid,
14715
+ generateDefaultValue,
14716
+ generateNanoid,
14717
+ generateUlid,
14718
+ generateUuid,
14719
+ getCodec,
14720
+ getFieldMeta,
14721
+ getModelMeta,
14722
+ hasNestedWrites,
14723
+ inheritReadOnly,
14724
+ inspectNativeRls,
14725
+ inspectNativeRlsTransaction,
14726
+ isDbNow,
14727
+ isExecutableRead,
14728
+ iterateKeyset,
14729
+ keysetRowIsAfter,
14730
+ keysetRowValues,
14731
+ lateralColumnAlias,
14732
+ normalizeSql,
14733
+ parameterTypeTag,
14734
+ parseDiagnosticsEnv,
14735
+ parsePostgresPlan,
14736
+ previewOperation,
14737
+ queryFingerprint,
14738
+ readOnlyRefusal,
14739
+ readWorkloadStatistics,
14740
+ recommendFromPlan,
14741
+ resolveRelationLink,
14742
+ resolveRelationSelection,
14743
+ resolveResultShape,
14744
+ resolveScopedModels,
14745
+ resolveStatementDiagnostics,
14746
+ resolveTelemetryConfig,
14747
+ rewriteScopedCall,
14748
+ sql2 as sql,
14749
+ sqlProjection,
14750
+ summarizePlan,
14751
+ toClientName,
14752
+ toSqlExecutor,
14753
+ updateWithNested,
14754
+ validateWriteData
14522
14755
  };
14523
14756
 
14524
- //# debugId=66C6E11BD1A77F7364756E2164756E21
14757
+ //# debugId=28EC8E14B301CBEB64756E2164756E21