@prisma/client-engine-runtime 6.9.0-dev.5 → 6.9.0-dev.7

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.
@@ -85,6 +85,7 @@ export type JoinExpression = {
85
85
  child: QueryPlanNode;
86
86
  on: [left: string, right: string][];
87
87
  parentField: string;
88
+ isRelationUnique: boolean;
88
89
  };
89
90
  export type QueryPlanNode = {
90
91
  type: 'seq';
@@ -169,6 +170,24 @@ export type QueryPlanNode = {
169
170
  from: QueryPlanNode;
170
171
  to: QueryPlanNode;
171
172
  };
173
+ } | {
174
+ type: 'distinctBy';
175
+ args: {
176
+ expr: QueryPlanNode;
177
+ fields: string[];
178
+ };
179
+ } | {
180
+ type: 'paginate';
181
+ args: {
182
+ expr: QueryPlanNode;
183
+ pagination: Pagination;
184
+ };
185
+ };
186
+ export type Pagination = {
187
+ cursor: Record<string, PrismaValue> | null;
188
+ take: number | null;
189
+ skip: number | null;
190
+ linkingFields: string[] | null;
172
191
  };
173
192
  export type DataRule = {
174
193
  type: 'rowCountEq';
package/dist/index.d.mts CHANGED
@@ -32,6 +32,11 @@ export declare type Fragment = {
32
32
  type: 'parameterTupleList';
33
33
  };
34
34
 
35
+ /**
36
+ * Checks if two objects are deeply equal, recursively checking all properties for strict equality.
37
+ */
38
+ export declare function isDeepStrictEqual(a: unknown, b: unknown): boolean;
39
+
35
40
  export declare function isPrismaValueBytes(value: unknown): value is PrismaValueBytes;
36
41
 
37
42
  export declare function isPrismaValueGenerator(value: unknown): value is PrismaValueGenerator;
@@ -42,10 +47,18 @@ export declare type JoinExpression = {
42
47
  child: QueryPlanNode;
43
48
  on: [left: string, right: string][];
44
49
  parentField: string;
50
+ isRelationUnique: boolean;
45
51
  };
46
52
 
47
53
  export declare const noopTracingHelper: TracingHelper;
48
54
 
55
+ export declare type Pagination = {
56
+ cursor: Record<string, PrismaValue> | null;
57
+ take: number | null;
58
+ skip: number | null;
59
+ linkingFields: string[] | null;
60
+ };
61
+
49
62
  export declare interface PlaceholderFormat {
50
63
  prefix: string;
51
64
  hasNumbering: boolean;
@@ -233,6 +246,18 @@ export declare type QueryPlanNode = {
233
246
  from: QueryPlanNode;
234
247
  to: QueryPlanNode;
235
248
  };
249
+ } | {
250
+ type: 'distinctBy';
251
+ args: {
252
+ expr: QueryPlanNode;
253
+ fields: string[];
254
+ };
255
+ } | {
256
+ type: 'paginate';
257
+ args: {
258
+ expr: QueryPlanNode;
259
+ pagination: Pagination;
260
+ };
236
261
  };
237
262
 
238
263
  export declare type ResultNode = {
package/dist/index.d.ts CHANGED
@@ -32,6 +32,11 @@ export declare type Fragment = {
32
32
  type: 'parameterTupleList';
33
33
  };
34
34
 
35
+ /**
36
+ * Checks if two objects are deeply equal, recursively checking all properties for strict equality.
37
+ */
38
+ export declare function isDeepStrictEqual(a: unknown, b: unknown): boolean;
39
+
35
40
  export declare function isPrismaValueBytes(value: unknown): value is PrismaValueBytes;
36
41
 
37
42
  export declare function isPrismaValueGenerator(value: unknown): value is PrismaValueGenerator;
@@ -42,10 +47,18 @@ export declare type JoinExpression = {
42
47
  child: QueryPlanNode;
43
48
  on: [left: string, right: string][];
44
49
  parentField: string;
50
+ isRelationUnique: boolean;
45
51
  };
46
52
 
47
53
  export declare const noopTracingHelper: TracingHelper;
48
54
 
55
+ export declare type Pagination = {
56
+ cursor: Record<string, PrismaValue> | null;
57
+ take: number | null;
58
+ skip: number | null;
59
+ linkingFields: string[] | null;
60
+ };
61
+
49
62
  export declare interface PlaceholderFormat {
50
63
  prefix: string;
51
64
  hasNumbering: boolean;
@@ -233,6 +246,18 @@ export declare type QueryPlanNode = {
233
246
  from: QueryPlanNode;
234
247
  to: QueryPlanNode;
235
248
  };
249
+ } | {
250
+ type: 'distinctBy';
251
+ args: {
252
+ expr: QueryPlanNode;
253
+ fields: string[];
254
+ };
255
+ } | {
256
+ type: 'paginate';
257
+ args: {
258
+ expr: QueryPlanNode;
259
+ pagination: Pagination;
260
+ };
236
261
  };
237
262
 
238
263
  export declare type ResultNode = {
package/dist/index.js CHANGED
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  TransactionManager: () => TransactionManager,
35
35
  TransactionManagerError: () => TransactionManagerError,
36
36
  UserFacingError: () => UserFacingError,
37
+ isDeepStrictEqual: () => isDeepStrictEqual,
37
38
  isPrismaValueBytes: () => isPrismaValueBytes,
38
39
  isPrismaValueGenerator: () => isPrismaValueGenerator,
39
40
  isPrismaValuePlaceholder: () => isPrismaValuePlaceholder,
@@ -48,6 +49,9 @@ var import_api = require("@opentelemetry/api");
48
49
  function assertNever(_, message) {
49
50
  throw new Error(message);
50
51
  }
52
+ function isDeepStrictEqual(a, b) {
53
+ 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]));
54
+ }
51
55
 
52
56
  // src/tracing.ts
53
57
  var noopTracingHelper = {
@@ -791,6 +795,38 @@ var QueryInterpreter = class _QueryInterpreter {
791
795
  const toSet = new Set(asList(to));
792
796
  return asList(from).filter((item) => !toSet.has(item));
793
797
  }
798
+ case "distinctBy": {
799
+ const value = await this.interpretNode(node.args.expr, queryable, scope, generators);
800
+ const seen = /* @__PURE__ */ new Set();
801
+ const result = [];
802
+ for (const item of asList(value)) {
803
+ const key = getRecordKey(item, node.args.fields);
804
+ if (!seen.has(key)) {
805
+ seen.add(key);
806
+ result.push(item);
807
+ }
808
+ }
809
+ return result;
810
+ }
811
+ case "paginate": {
812
+ const value = await this.interpretNode(node.args.expr, queryable, scope, generators);
813
+ const list = asList(value);
814
+ const linkingFields = node.args.pagination.linkingFields;
815
+ if (linkingFields !== null) {
816
+ const groupedByParent = /* @__PURE__ */ new Map();
817
+ for (const item of list) {
818
+ const parentKey = getRecordKey(item, linkingFields);
819
+ if (!groupedByParent.has(parentKey)) {
820
+ groupedByParent.set(parentKey, []);
821
+ }
822
+ groupedByParent.get(parentKey).push(item);
823
+ }
824
+ const groupList = Array.from(groupedByParent.entries());
825
+ groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
826
+ return groupList.flatMap(([, elems]) => paginate(elems, node.args.pagination));
827
+ }
828
+ return paginate(list, node.args.pagination);
829
+ }
794
830
  default:
795
831
  assertNever(node, `Unexpected node type: ${node.type}`);
796
832
  }
@@ -862,7 +898,12 @@ function attachChildrenToParent(parentRecord, children) {
862
898
  }
863
899
  function filterChildRecords(records, parentRecord, joinExpr) {
864
900
  if (Array.isArray(records)) {
865
- return records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
901
+ const filtered = records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
902
+ if (joinExpr.isRelationUnique) {
903
+ return filtered.length > 0 ? filtered[0] : null;
904
+ } else {
905
+ return filtered;
906
+ }
866
907
  } else if (records === null) {
867
908
  return null;
868
909
  } else {
@@ -878,6 +919,26 @@ function childRecordMatchesParent(childRecord, parentRecord, joinExpr) {
878
919
  }
879
920
  return true;
880
921
  }
922
+ function paginate(list, { cursor, skip, take }) {
923
+ const cursorIndex = cursor !== null ? list.findIndex((item) => doesMatchCursor(item, cursor)) : 0;
924
+ if (cursorIndex === -1) {
925
+ return [];
926
+ }
927
+ const start = cursorIndex + (skip ?? 0);
928
+ const end = take !== null ? start + take : list.length;
929
+ return list.slice(start, end);
930
+ }
931
+ function getRecordKey(record, fields) {
932
+ return JSON.stringify(fields.map((field) => record[field]));
933
+ }
934
+ function doesMatchCursor(item, cursor) {
935
+ return Object.keys(cursor).every((key) => {
936
+ if (typeof item[key] !== typeof cursor[key] && (typeof item[key] === "number" || typeof cursor[key] === "number")) {
937
+ return `${item[key]}` === `${cursor[key]}`;
938
+ }
939
+ return isDeepStrictEqual(cursor[key], item[key]);
940
+ });
941
+ }
881
942
 
882
943
  // src/transactionManager/TransactionManager.ts
883
944
  var import_debug = require("@prisma/debug");
@@ -1100,6 +1161,7 @@ var TransactionManager = class {
1100
1161
  TransactionManager,
1101
1162
  TransactionManagerError,
1102
1163
  UserFacingError,
1164
+ isDeepStrictEqual,
1103
1165
  isPrismaValueBytes,
1104
1166
  isPrismaValueGenerator,
1105
1167
  isPrismaValuePlaceholder,
package/dist/index.mjs CHANGED
@@ -5,6 +5,9 @@ import { SpanKind } from "@opentelemetry/api";
5
5
  function assertNever(_, message) {
6
6
  throw new Error(message);
7
7
  }
8
+ function isDeepStrictEqual(a, b) {
9
+ 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]));
10
+ }
8
11
 
9
12
  // src/tracing.ts
10
13
  var noopTracingHelper = {
@@ -748,6 +751,38 @@ var QueryInterpreter = class _QueryInterpreter {
748
751
  const toSet = new Set(asList(to));
749
752
  return asList(from).filter((item) => !toSet.has(item));
750
753
  }
754
+ case "distinctBy": {
755
+ const value = await this.interpretNode(node.args.expr, queryable, scope, generators);
756
+ const seen = /* @__PURE__ */ new Set();
757
+ const result = [];
758
+ for (const item of asList(value)) {
759
+ const key = getRecordKey(item, node.args.fields);
760
+ if (!seen.has(key)) {
761
+ seen.add(key);
762
+ result.push(item);
763
+ }
764
+ }
765
+ return result;
766
+ }
767
+ case "paginate": {
768
+ const value = await this.interpretNode(node.args.expr, queryable, scope, generators);
769
+ const list = asList(value);
770
+ const linkingFields = node.args.pagination.linkingFields;
771
+ if (linkingFields !== null) {
772
+ const groupedByParent = /* @__PURE__ */ new Map();
773
+ for (const item of list) {
774
+ const parentKey = getRecordKey(item, linkingFields);
775
+ if (!groupedByParent.has(parentKey)) {
776
+ groupedByParent.set(parentKey, []);
777
+ }
778
+ groupedByParent.get(parentKey).push(item);
779
+ }
780
+ const groupList = Array.from(groupedByParent.entries());
781
+ groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
782
+ return groupList.flatMap(([, elems]) => paginate(elems, node.args.pagination));
783
+ }
784
+ return paginate(list, node.args.pagination);
785
+ }
751
786
  default:
752
787
  assertNever(node, `Unexpected node type: ${node.type}`);
753
788
  }
@@ -819,7 +854,12 @@ function attachChildrenToParent(parentRecord, children) {
819
854
  }
820
855
  function filterChildRecords(records, parentRecord, joinExpr) {
821
856
  if (Array.isArray(records)) {
822
- return records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
857
+ const filtered = records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
858
+ if (joinExpr.isRelationUnique) {
859
+ return filtered.length > 0 ? filtered[0] : null;
860
+ } else {
861
+ return filtered;
862
+ }
823
863
  } else if (records === null) {
824
864
  return null;
825
865
  } else {
@@ -835,6 +875,26 @@ function childRecordMatchesParent(childRecord, parentRecord, joinExpr) {
835
875
  }
836
876
  return true;
837
877
  }
878
+ function paginate(list, { cursor, skip, take }) {
879
+ const cursorIndex = cursor !== null ? list.findIndex((item) => doesMatchCursor(item, cursor)) : 0;
880
+ if (cursorIndex === -1) {
881
+ return [];
882
+ }
883
+ const start = cursorIndex + (skip ?? 0);
884
+ const end = take !== null ? start + take : list.length;
885
+ return list.slice(start, end);
886
+ }
887
+ function getRecordKey(record, fields) {
888
+ return JSON.stringify(fields.map((field) => record[field]));
889
+ }
890
+ function doesMatchCursor(item, cursor) {
891
+ return Object.keys(cursor).every((key) => {
892
+ if (typeof item[key] !== typeof cursor[key] && (typeof item[key] === "number" || typeof cursor[key] === "number")) {
893
+ return `${item[key]}` === `${cursor[key]}`;
894
+ }
895
+ return isDeepStrictEqual(cursor[key], item[key]);
896
+ });
897
+ }
838
898
 
839
899
  // src/transactionManager/TransactionManager.ts
840
900
  import { Debug } from "@prisma/debug";
@@ -1056,6 +1116,7 @@ export {
1056
1116
  TransactionManager,
1057
1117
  TransactionManagerError,
1058
1118
  UserFacingError,
1119
+ isDeepStrictEqual,
1059
1120
  isPrismaValueBytes,
1060
1121
  isPrismaValueGenerator,
1061
1122
  isPrismaValuePlaceholder,
package/dist/utils.d.ts CHANGED
@@ -1 +1,5 @@
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/client-engine-runtime",
3
- "version": "6.9.0-dev.5",
3
+ "version": "6.9.0-dev.7",
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/driver-adapter-utils": "6.9.0-dev.5",
35
- "@prisma/debug": "6.9.0-dev.5"
34
+ "@prisma/debug": "6.9.0-dev.7",
35
+ "@prisma/driver-adapter-utils": "6.9.0-dev.7"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/jest": "29.5.14",