@prisma/client-engine-runtime 6.9.0-dev.2 → 6.9.0-dev.21

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.
package/dist/index.mjs CHANGED
@@ -1,10 +1,144 @@
1
- // src/interpreter/QueryInterpreter.ts
2
- import { SpanKind } from "@opentelemetry/api";
1
+ // src/interpreter/DataMapper.ts
2
+ import Decimal2 from "decimal.js";
3
3
 
4
4
  // src/utils.ts
5
+ import Decimal from "decimal.js";
5
6
  function assertNever(_, message) {
6
7
  throw new Error(message);
7
8
  }
9
+ function isDeepStrictEqual(a, b) {
10
+ return a === b || a !== null && b !== null && typeof a === "object" && typeof b === "object" && Object.keys(a).length === Object.keys(b).length && Object.keys(a).every((key) => isDeepStrictEqual(a[key], b[key]));
11
+ }
12
+ function doKeysMatch(lhs, rhs) {
13
+ const lhsKeys = Object.keys(lhs);
14
+ const rhsKeys = Object.keys(rhs);
15
+ const smallerKeyList = lhsKeys.length < rhsKeys.length ? lhsKeys : rhsKeys;
16
+ return smallerKeyList.every((key) => {
17
+ if (typeof lhs[key] !== typeof rhs[key]) {
18
+ if (typeof lhs[key] === "number" || typeof rhs[key] === "number") {
19
+ return `${lhs[key]}` === `${rhs[key]}`;
20
+ } else if (typeof lhs[key] === "bigint" || typeof rhs[key] === "bigint") {
21
+ return BigInt(`${lhs[key]}`.replace(/n$/, "")) === BigInt(`${rhs[key]}`.replace(/n$/, ""));
22
+ } else if (lhs[key] instanceof Date || rhs[key] instanceof Date) {
23
+ return (/* @__PURE__ */ new Date(`${lhs[key]}`)).getTime() === (/* @__PURE__ */ new Date(`${rhs[key]}`)).getTime();
24
+ } else if (Decimal.isDecimal(lhs[key]) || Decimal.isDecimal(rhs[key])) {
25
+ return new Decimal(`${lhs[key]}`).equals(new Decimal(`${rhs[key]}`));
26
+ }
27
+ }
28
+ return isDeepStrictEqual(lhs[key], rhs[key]);
29
+ });
30
+ }
31
+
32
+ // src/interpreter/DataMapper.ts
33
+ var DataMapperError = class extends Error {
34
+ name = "DataMapperError";
35
+ };
36
+ function applyDataMap(data, structure) {
37
+ switch (structure.type) {
38
+ case "Object":
39
+ return mapArrayOrObject(data, structure.fields);
40
+ case "Value":
41
+ return mapValue(data, structure.resultType);
42
+ default:
43
+ assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
44
+ }
45
+ }
46
+ function mapArrayOrObject(data, fields) {
47
+ if (data === null) return null;
48
+ if (Array.isArray(data)) {
49
+ const rows = data;
50
+ return rows.map((row) => mapObject(row, fields));
51
+ }
52
+ if (typeof data === "object") {
53
+ const row = data;
54
+ return mapObject(row, fields);
55
+ }
56
+ if (typeof data === "string") {
57
+ let decodedData;
58
+ try {
59
+ decodedData = JSON.parse(data);
60
+ } catch (error) {
61
+ throw new DataMapperError(`Expected an array or object, got a string that is not valid JSON`, {
62
+ cause: error
63
+ });
64
+ }
65
+ return mapArrayOrObject(decodedData, fields);
66
+ }
67
+ throw new DataMapperError(`Expected an array or an object, got: ${typeof data}`);
68
+ }
69
+ function mapObject(data, fields) {
70
+ if (typeof data !== "object") {
71
+ throw new DataMapperError(`Expected an object, but got '${typeof data}'`);
72
+ }
73
+ const result = {};
74
+ for (const [name, node] of Object.entries(fields)) {
75
+ switch (node.type) {
76
+ case "Object": {
77
+ if (!node.flattened && !Object.hasOwn(data, name)) {
78
+ throw new DataMapperError(
79
+ `Missing data field (Object): '${name}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
80
+ );
81
+ }
82
+ const target = node.flattened ? data : data[name];
83
+ result[name] = mapArrayOrObject(target, node.fields);
84
+ break;
85
+ }
86
+ case "Value":
87
+ {
88
+ const dbName = node.dbName;
89
+ if (Object.hasOwn(data, dbName)) {
90
+ result[name] = mapValue(data[dbName], node.resultType);
91
+ } else {
92
+ throw new DataMapperError(
93
+ `Missing data field (Value): '${dbName}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
94
+ );
95
+ }
96
+ }
97
+ break;
98
+ default:
99
+ assertNever(node, `DataMapper: Invalid data mapping node type: '${node.type}'`);
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ function mapValue(value, resultType) {
105
+ if (value === null) return null;
106
+ switch (resultType.type) {
107
+ case "Any":
108
+ return value;
109
+ case "String":
110
+ return typeof value === "string" ? value : `${value}`;
111
+ case "Int":
112
+ return typeof value === "number" ? value : parseInt(`${value}`, 10);
113
+ case "BigInt":
114
+ return typeof value === "bigint" ? value : BigInt(`${value}`);
115
+ case "Float":
116
+ return typeof value === "number" ? value : parseFloat(`${value}`);
117
+ case "Boolean":
118
+ return typeof value === "boolean" ? value : value !== "0";
119
+ case "Decimal":
120
+ return typeof value === "number" ? new Decimal2(value) : new Decimal2(`${value}`);
121
+ case "Date":
122
+ return value instanceof Date ? value : /* @__PURE__ */ new Date(`${value}`);
123
+ case "Array": {
124
+ const values = value;
125
+ return values.map((v) => mapValue(v, resultType.inner));
126
+ }
127
+ case "Object":
128
+ return typeof value === "string" ? value : JSON.stringify(value);
129
+ case "Bytes": {
130
+ if (!Array.isArray(value)) {
131
+ throw new DataMapperError(`Bytes data is invalid, got: ${typeof value}`);
132
+ }
133
+ return new Uint8Array(value);
134
+ }
135
+ default:
136
+ assertNever(resultType, `DataMapper: Unknown result type: ${resultType.type}`);
137
+ }
138
+ }
139
+
140
+ // src/interpreter/QueryInterpreter.ts
141
+ import { SpanKind } from "@opentelemetry/api";
8
142
 
9
143
  // src/tracing.ts
10
144
  var noopTracingHelper = {
@@ -34,7 +168,7 @@ var UserFacingError = class extends Error {
34
168
  constructor(message, code, meta) {
35
169
  super(message);
36
170
  this.code = code;
37
- this.meta = meta;
171
+ this.meta = meta ?? {};
38
172
  }
39
173
  toQueryResponseErrorObject() {
40
174
  return {
@@ -57,7 +191,7 @@ function rethrowAsUserFacing(error) {
57
191
  if (!code || !message) {
58
192
  throw error;
59
193
  }
60
- throw new UserFacingError(message, code, error);
194
+ throw new UserFacingError(message, code, { driverAdapterError: error });
61
195
  }
62
196
  function getErrorCode(err) {
63
197
  switch (err.cause.kind) {
@@ -168,100 +302,6 @@ function renderConstraint(constraint) {
168
302
  return "(not available)";
169
303
  }
170
304
 
171
- // src/interpreter/DataMapper.ts
172
- import Decimal from "decimal.js";
173
- function applyDataMap(data, structure) {
174
- switch (structure.type) {
175
- case "Object":
176
- return mapArrayOrObject(data, structure.fields);
177
- case "Value":
178
- return mapValue(data, structure.resultType);
179
- default:
180
- assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
181
- }
182
- }
183
- function mapArrayOrObject(data, fields) {
184
- if (data === null) return null;
185
- if (Array.isArray(data)) {
186
- const rows = data;
187
- return rows.map((row) => mapObject(row, fields));
188
- }
189
- if (typeof data === "object") {
190
- const row = data;
191
- return mapObject(row, fields);
192
- }
193
- throw new Error(`DataMapper: Expected an array or an object, got: ${typeof data}`);
194
- }
195
- function mapObject(data, fields) {
196
- if (typeof data !== "object") {
197
- throw new Error(`DataMapper: Expected an object, but got '${typeof data}'`);
198
- }
199
- const result = {};
200
- for (const [name, node] of Object.entries(fields)) {
201
- switch (node.type) {
202
- case "Object":
203
- if (Object.hasOwn(data, name)) {
204
- result[name] = mapArrayOrObject(data[name], node.fields);
205
- } else {
206
- throw new Error(
207
- `DataMapper: Missing data field (Object): '${name}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
208
- );
209
- }
210
- break;
211
- case "Value":
212
- {
213
- const dbName = node.dbName;
214
- if (Object.hasOwn(data, dbName)) {
215
- result[name] = mapValue(data[dbName], node.resultType);
216
- } else {
217
- throw new Error(
218
- `DataMapper: Missing data field (Value): '${dbName}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
219
- );
220
- }
221
- }
222
- break;
223
- default:
224
- assertNever(node, `DataMapper: Invalid data mapping node type: '${node.type}'`);
225
- }
226
- }
227
- return result;
228
- }
229
- function mapValue(value, resultType) {
230
- if (value === null) return null;
231
- switch (resultType.type) {
232
- case "Any":
233
- return value;
234
- case "String":
235
- return typeof value === "string" ? value : `${value}`;
236
- case "Int":
237
- return typeof value === "number" ? value : parseInt(`${value}`, 10);
238
- case "BigInt":
239
- return typeof value === "bigint" ? value : BigInt(`${value}`);
240
- case "Float":
241
- return typeof value === "number" ? value : parseFloat(`${value}`);
242
- case "Boolean":
243
- return typeof value === "boolean" ? value : value !== "0";
244
- case "Decimal":
245
- return typeof value === "number" ? new Decimal(value) : new Decimal(`${value}`);
246
- case "Date":
247
- return value instanceof Date ? value : /* @__PURE__ */ new Date(`${value}`);
248
- case "Array": {
249
- const values = value;
250
- return values.map((v) => mapValue(v, resultType.inner));
251
- }
252
- case "Object":
253
- return typeof value === "string" ? value : JSON.stringify(value);
254
- case "Bytes": {
255
- if (!Array.isArray(value)) {
256
- throw new Error(`DataMapper: Bytes data is invalid, got: ${typeof value}`);
257
- }
258
- return new Uint8Array(value);
259
- }
260
- default:
261
- assertNever(resultType, `DataMapper: Unknown result type: ${resultType.type}`);
262
- }
263
- }
264
-
265
305
  // src/interpreter/generators.ts
266
306
  import cuid1 from "@bugsnag/cuid";
267
307
  import { createId as cuid2 } from "@paralleldrive/cuid2";
@@ -366,6 +406,9 @@ function isPrismaValueGenerator(value) {
366
406
  function isPrismaValueBytes(value) {
367
407
  return typeof value === "object" && value !== null && value["prisma__type"] === "bytes";
368
408
  }
409
+ function isPrismaValueBigInt(value) {
410
+ return typeof value === "object" && value !== null && value["prisma__type"] === "bigint";
411
+ }
369
412
 
370
413
  // src/interpreter/renderQuery.ts
371
414
  function renderQuery(dbQuery, scope, generators) {
@@ -408,9 +451,10 @@ function evaluateParam(param, scope, generators) {
408
451
  }
409
452
  if (Array.isArray(value)) {
410
453
  value = value.map((el) => evaluateParam(el, scope, generators));
411
- }
412
- if (isPrismaValueBytes(value)) {
454
+ } else if (isPrismaValueBytes(value)) {
413
455
  value = Buffer.from(value.prisma__value, "base64");
456
+ } else if (isPrismaValueBigInt(value)) {
457
+ value = BigInt(value.prisma__value);
414
458
  }
415
459
  return value;
416
460
  }
@@ -504,6 +548,7 @@ function doesRequireEvaluation(param) {
504
548
  }
505
549
 
506
550
  // src/interpreter/serializeSql.ts
551
+ import { ColumnTypeEnum } from "@prisma/driver-adapter-utils";
507
552
  function serializeSql(resultSet) {
508
553
  return resultSet.rows.map(
509
554
  (row) => row.reduce((acc, value, index) => {
@@ -524,6 +569,85 @@ function serializeSql(resultSet) {
524
569
  }, {})
525
570
  );
526
571
  }
572
+ function serializeRawSql(resultSet) {
573
+ return {
574
+ columns: resultSet.columnNames,
575
+ types: resultSet.columnTypes.map((type) => serializeColumnType(type)),
576
+ rows: resultSet.rows
577
+ };
578
+ }
579
+ function serializeColumnType(columnType) {
580
+ switch (columnType) {
581
+ case ColumnTypeEnum.Int32:
582
+ return "int";
583
+ case ColumnTypeEnum.Int64:
584
+ return "bigint";
585
+ case ColumnTypeEnum.Float:
586
+ return "float";
587
+ case ColumnTypeEnum.Double:
588
+ return "double";
589
+ case ColumnTypeEnum.Text:
590
+ return "string";
591
+ case ColumnTypeEnum.Enum:
592
+ return "enum";
593
+ case ColumnTypeEnum.Bytes:
594
+ return "bytes";
595
+ case ColumnTypeEnum.Boolean:
596
+ return "bool";
597
+ case ColumnTypeEnum.Character:
598
+ return "char";
599
+ case ColumnTypeEnum.Numeric:
600
+ return "decimal";
601
+ case ColumnTypeEnum.Json:
602
+ return "json";
603
+ case ColumnTypeEnum.Uuid:
604
+ return "uuid";
605
+ case ColumnTypeEnum.DateTime:
606
+ return "datetime";
607
+ case ColumnTypeEnum.Date:
608
+ return "date";
609
+ case ColumnTypeEnum.Time:
610
+ return "time";
611
+ case ColumnTypeEnum.Int32Array:
612
+ return "int-array";
613
+ case ColumnTypeEnum.Int64Array:
614
+ return "bigint-array";
615
+ case ColumnTypeEnum.FloatArray:
616
+ return "float-array";
617
+ case ColumnTypeEnum.DoubleArray:
618
+ return "double-array";
619
+ case ColumnTypeEnum.TextArray:
620
+ return "string-array";
621
+ case ColumnTypeEnum.EnumArray:
622
+ return "string-array";
623
+ case ColumnTypeEnum.BytesArray:
624
+ return "bytes-array";
625
+ case ColumnTypeEnum.BooleanArray:
626
+ return "bool-array";
627
+ case ColumnTypeEnum.CharacterArray:
628
+ return "char-array";
629
+ case ColumnTypeEnum.NumericArray:
630
+ return "decimal-array";
631
+ case ColumnTypeEnum.JsonArray:
632
+ return "json-array";
633
+ case ColumnTypeEnum.UuidArray:
634
+ return "uuid-array";
635
+ case ColumnTypeEnum.DateTimeArray:
636
+ return "datetime-array";
637
+ case ColumnTypeEnum.DateArray:
638
+ return "date-array";
639
+ case ColumnTypeEnum.TimeArray:
640
+ return "time-array";
641
+ case ColumnTypeEnum.UnknownNumber:
642
+ return "unknown";
643
+ /// The following PlanetScale type IDs are mapped into Set:
644
+ /// - SET (SET) -> e.g. `"foo,bar"` (String-encoded, comma-separated)
645
+ case ColumnTypeEnum.Set:
646
+ return "string";
647
+ default:
648
+ assertNever(columnType, `Unexpected column type: ${columnType}`);
649
+ }
650
+ }
527
651
 
528
652
  // src/interpreter/validation.ts
529
653
  function performValidation(data, rules, error) {
@@ -551,6 +675,8 @@ function doesSatisfyRule(data, rule) {
551
675
  return rule.args !== 0;
552
676
  }
553
677
  return rule.args !== 1;
678
+ case "affectedRowCountEq":
679
+ return data === rule.args;
554
680
  case "never":
555
681
  return false;
556
682
  default:
@@ -568,7 +694,9 @@ function renderMessage(data, error) {
568
694
  return `An operation failed because it depends on one or more records that were required but not found. No '${error.context.model}' record${hint} was found for ${error.context.operation} on ${error.context.relationType} relation '${error.context.relation}'.`;
569
695
  }
570
696
  case "INCOMPLETE_CONNECT_INPUT":
571
- return `An operation failed because it depends on one or more records that were required but not found. Expected ${error.context.expectedRows} records to be connected, found only ${Array.isArray(data) ? data.length : 0}.`;
697
+ return `An operation failed because it depends on one or more records that were required but not found. Expected ${error.context.expectedRows} records to be connected, found only ${Array.isArray(data) ? data.length : data}.`;
698
+ case "INCOMPLETE_CONNECT_OUTPUT":
699
+ return `The required connected records were not found. Expected ${error.context.expectedRows} records to be connected after connect operation on ${error.context.relationType} relation '${error.context.relation}', found ${Array.isArray(data) ? data.length : data}.`;
572
700
  case "RECORDS_NOT_CONNECTED":
573
701
  return `The records for relation \`${error.context.relation}\` between the \`${error.context.parent}\` and \`${error.context.child}\` models are not connected.`;
574
702
  default:
@@ -581,6 +709,8 @@ function getErrorCode2(error) {
581
709
  return "P2014";
582
710
  case "RECORDS_NOT_CONNECTED":
583
711
  return "P2017";
712
+ case "INCOMPLETE_CONNECT_OUTPUT":
713
+ return "P2018";
584
714
  case "MISSING_RECORD":
585
715
  case "MISSING_RELATED_RECORD":
586
716
  case "INCOMPLETE_CONNECT_INPUT":
@@ -598,12 +728,21 @@ var QueryInterpreter = class _QueryInterpreter {
598
728
  #generators = new GeneratorRegistry();
599
729
  #tracingHelper;
600
730
  #serializer;
601
- constructor({ transactionManager, placeholderValues, onQuery, tracingHelper, serializer }) {
731
+ #rawSerializer;
732
+ constructor({
733
+ transactionManager,
734
+ placeholderValues,
735
+ onQuery,
736
+ tracingHelper,
737
+ serializer,
738
+ rawSerializer
739
+ }) {
602
740
  this.#transactionManager = transactionManager;
603
741
  this.#placeholderValues = placeholderValues;
604
742
  this.#onQuery = onQuery;
605
743
  this.#tracingHelper = tracingHelper;
606
744
  this.#serializer = serializer;
745
+ this.#rawSerializer = rawSerializer ?? serializer;
607
746
  }
608
747
  static forSql(options) {
609
748
  return new _QueryInterpreter({
@@ -611,7 +750,8 @@ var QueryInterpreter = class _QueryInterpreter {
611
750
  placeholderValues: options.placeholderValues,
612
751
  onQuery: options.onQuery,
613
752
  tracingHelper: options.tracingHelper,
614
- serializer: serializeSql
753
+ serializer: serializeSql,
754
+ rawSerializer: serializeRawSql
615
755
  });
616
756
  }
617
757
  async run(queryPlan, queryable) {
@@ -622,8 +762,11 @@ var QueryInterpreter = class _QueryInterpreter {
622
762
  async interpretNode(node, queryable, scope, generators) {
623
763
  switch (node.type) {
624
764
  case "seq": {
625
- const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
626
- return results[results.length - 1];
765
+ let result;
766
+ for (const arg of node.args) {
767
+ result = await this.interpretNode(arg, queryable, scope, generators);
768
+ }
769
+ return result;
627
770
  }
628
771
  case "get": {
629
772
  return scope[node.args.name];
@@ -646,11 +789,11 @@ var QueryInterpreter = class _QueryInterpreter {
646
789
  }
647
790
  case "concat": {
648
791
  const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
649
- return parts.reduce((acc, part) => acc.concat(asList(part)), []);
792
+ return parts.length > 0 ? parts.reduce((acc, part) => acc.concat(asList(part)), []) : [];
650
793
  }
651
794
  case "sum": {
652
795
  const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
653
- return parts.reduce((acc, part) => asNumber(acc) + asNumber(part));
796
+ return parts.length > 0 ? parts.reduce((acc, part) => asNumber(acc) + asNumber(part)) : 0;
654
797
  }
655
798
  case "execute": {
656
799
  const query = renderQuery(node.args, scope, generators);
@@ -661,7 +804,11 @@ var QueryInterpreter = class _QueryInterpreter {
661
804
  case "query": {
662
805
  const query = renderQuery(node.args, scope, generators);
663
806
  return this.#withQueryEvent(query, queryable, async () => {
664
- return this.#serializer(await queryable.queryRaw(query));
807
+ if (node.args.type === "rawSql") {
808
+ return this.#rawSerializer(await queryable.queryRaw(query));
809
+ } else {
810
+ return this.#serializer(await queryable.queryRaw(query));
811
+ }
665
812
  });
666
813
  }
667
814
  case "reverse": {
@@ -691,6 +838,9 @@ var QueryInterpreter = class _QueryInterpreter {
691
838
  }
692
839
  case "join": {
693
840
  const parent = await this.interpretNode(node.args.parent, queryable, scope, generators);
841
+ if (parent === null) {
842
+ return null;
843
+ }
694
844
  const children = await Promise.all(
695
845
  node.args.children.map(async (joinExpr) => ({
696
846
  joinExpr,
@@ -747,6 +897,38 @@ var QueryInterpreter = class _QueryInterpreter {
747
897
  const toSet = new Set(asList(to));
748
898
  return asList(from).filter((item) => !toSet.has(item));
749
899
  }
900
+ case "distinctBy": {
901
+ const value = await this.interpretNode(node.args.expr, queryable, scope, generators);
902
+ const seen = /* @__PURE__ */ new Set();
903
+ const result = [];
904
+ for (const item of asList(value)) {
905
+ const key = getRecordKey(item, node.args.fields);
906
+ if (!seen.has(key)) {
907
+ seen.add(key);
908
+ result.push(item);
909
+ }
910
+ }
911
+ return result;
912
+ }
913
+ case "paginate": {
914
+ const value = await this.interpretNode(node.args.expr, queryable, scope, generators);
915
+ const list = asList(value);
916
+ const linkingFields = node.args.pagination.linkingFields;
917
+ if (linkingFields !== null) {
918
+ const groupedByParent = /* @__PURE__ */ new Map();
919
+ for (const item of list) {
920
+ const parentKey = getRecordKey(item, linkingFields);
921
+ if (!groupedByParent.has(parentKey)) {
922
+ groupedByParent.set(parentKey, []);
923
+ }
924
+ groupedByParent.get(parentKey).push(item);
925
+ }
926
+ const groupList = Array.from(groupedByParent.entries());
927
+ groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
928
+ return groupList.flatMap(([, elems]) => paginate(elems, node.args.pagination));
929
+ }
930
+ return paginate(list, node.args.pagination);
931
+ }
750
932
  default:
751
933
  assertNever(node, `Unexpected node type: ${node.type}`);
752
934
  }
@@ -818,7 +1000,12 @@ function attachChildrenToParent(parentRecord, children) {
818
1000
  }
819
1001
  function filterChildRecords(records, parentRecord, joinExpr) {
820
1002
  if (Array.isArray(records)) {
821
- return records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
1003
+ const filtered = records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
1004
+ if (joinExpr.isRelationUnique) {
1005
+ return filtered.length > 0 ? filtered[0] : null;
1006
+ } else {
1007
+ return filtered;
1008
+ }
822
1009
  } else if (records === null) {
823
1010
  return null;
824
1011
  } else {
@@ -834,6 +1021,18 @@ function childRecordMatchesParent(childRecord, parentRecord, joinExpr) {
834
1021
  }
835
1022
  return true;
836
1023
  }
1024
+ function paginate(list, { cursor, skip, take }) {
1025
+ const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
1026
+ if (cursorIndex === -1) {
1027
+ return [];
1028
+ }
1029
+ const start = cursorIndex + (skip ?? 0);
1030
+ const end = take !== null ? start + take : list.length;
1031
+ return list.slice(start, end);
1032
+ }
1033
+ function getRecordKey(record, fields) {
1034
+ return JSON.stringify(fields.map((field) => record[field]));
1035
+ }
837
1036
 
838
1037
  // src/transactionManager/TransactionManager.ts
839
1038
  import { Debug } from "@prisma/debug";
@@ -848,12 +1047,11 @@ async function randomUUID() {
848
1047
  }
849
1048
 
850
1049
  // src/transactionManager/TransactionManagerErrors.ts
851
- var TransactionManagerError = class extends Error {
1050
+ var TransactionManagerError = class extends UserFacingError {
1051
+ name = "TransactionManagerError";
852
1052
  constructor(message, meta) {
853
- super("Transaction API error: " + message);
854
- this.meta = meta;
1053
+ super("Transaction API error: " + message, "P2028", meta);
855
1054
  }
856
- code = "P2028";
857
1055
  };
858
1056
  var TransactionNotFoundError = class extends TransactionManagerError {
859
1057
  constructor() {
@@ -864,12 +1062,12 @@ var TransactionNotFoundError = class extends TransactionManagerError {
864
1062
  };
865
1063
  var TransactionClosedError = class extends TransactionManagerError {
866
1064
  constructor(operation) {
867
- super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`);
1065
+ super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction.`);
868
1066
  }
869
1067
  };
870
1068
  var TransactionRolledBackError = class extends TransactionManagerError {
871
1069
  constructor(operation) {
872
- super(`Transaction already closed: A ${operation} cannot be executed on a transaction that was rolled back`);
1070
+ super(`Transaction already closed: A ${operation} cannot be executed on a transaction that was rolled back.`);
873
1071
  }
874
1072
  };
875
1073
  var TransactionStartTimeoutError = class extends TransactionManagerError {
@@ -1051,10 +1249,14 @@ var TransactionManager = class {
1051
1249
  }
1052
1250
  };
1053
1251
  export {
1252
+ DataMapperError,
1054
1253
  QueryInterpreter,
1055
1254
  TransactionManager,
1056
1255
  TransactionManagerError,
1057
1256
  UserFacingError,
1257
+ doKeysMatch,
1258
+ isDeepStrictEqual,
1259
+ isPrismaValueBigInt,
1058
1260
  isPrismaValueBytes,
1059
1261
  isPrismaValueGenerator,
1060
1262
  isPrismaValuePlaceholder,
@@ -1,3 +1,6 @@
1
1
  import { ResultNode } from '../QueryPlan';
2
2
  import { Value } from './scope';
3
+ export declare class DataMapperError extends Error {
4
+ name: string;
5
+ }
3
6
  export declare function applyDataMap(data: Value, structure: ResultNode): Value;
@@ -16,10 +16,11 @@ export type QueryInterpreterOptions = {
16
16
  onQuery?: (event: QueryEvent) => void;
17
17
  tracingHelper: TracingHelper;
18
18
  serializer: (results: SqlResultSet) => Value;
19
+ rawSerializer?: (results: SqlResultSet) => Value;
19
20
  };
20
21
  export declare class QueryInterpreter {
21
22
  #private;
22
- constructor({ transactionManager, placeholderValues, onQuery, tracingHelper, serializer }: QueryInterpreterOptions);
23
+ constructor({ transactionManager, placeholderValues, onQuery, tracingHelper, serializer, rawSerializer, }: QueryInterpreterOptions);
23
24
  static forSql(options: {
24
25
  transactionManager: QueryInterpreterTransactionManager;
25
26
  placeholderValues: Record<string, unknown>;
@@ -1,2 +1,3 @@
1
- import type { SqlResultSet } from '@prisma/driver-adapter-utils';
1
+ import { type SqlResultSet } from '@prisma/driver-adapter-utils';
2
2
  export declare function serializeSql(resultSet: SqlResultSet): Record<string, unknown>[];
3
+ export declare function serializeRawSql(resultSet: SqlResultSet): Record<string, unknown>;
@@ -1,7 +1,7 @@
1
- export declare class TransactionManagerError extends Error {
2
- meta?: Record<string, unknown> | undefined;
3
- code: string;
4
- constructor(message: string, meta?: Record<string, unknown> | undefined);
1
+ import { UserFacingError } from '../UserFacingError';
2
+ export declare class TransactionManagerError extends UserFacingError {
3
+ name: string;
4
+ constructor(message: string, meta?: Record<string, unknown>);
5
5
  }
6
6
  export declare class TransactionNotFoundError extends TransactionManagerError {
7
7
  constructor();
package/dist/utils.d.ts CHANGED
@@ -1 +1,11 @@
1
1
  export declare function assertNever(_: never, message: string): never;
2
+ /**
3
+ * Checks if two objects are deeply equal, recursively checking all properties for strict equality.
4
+ */
5
+ export declare function isDeepStrictEqual(a: unknown, b: unknown): boolean;
6
+ /**
7
+ * Checks if two objects representing the names and values of key columns match. A match is
8
+ * defined by one of the sets of keys being a subset of the other. This function also
9
+ * converts arguments to the types used by driver adapters if necessary.
10
+ */
11
+ export declare function doKeysMatch(lhs: {}, rhs: {}): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/client-engine-runtime",
3
- "version": "6.9.0-dev.2",
3
+ "version": "6.9.0-dev.21",
4
4
  "description": "This package is intended for Prisma's internal use",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -31,8 +31,8 @@
31
31
  "nanoid": "5.1.5",
32
32
  "ulid": "3.0.0",
33
33
  "uuid": "11.1.0",
34
- "@prisma/debug": "6.9.0-dev.2",
35
- "@prisma/driver-adapter-utils": "6.9.0-dev.2"
34
+ "@prisma/debug": "6.9.0-dev.21",
35
+ "@prisma/driver-adapter-utils": "6.9.0-dev.21"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/jest": "29.5.14",