prisma-sql 1.69.0 → 1.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -55,235 +55,6 @@ var __async = (__this, __arguments, generator) => {
55
55
  });
56
56
  };
57
57
 
58
- // src/utils/normalize-value.ts
59
- var MAX_DEPTH = 20;
60
- function normalizeValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
61
- if (depth > MAX_DEPTH) {
62
- throw new Error(`Max normalization depth exceeded (${MAX_DEPTH} levels)`);
63
- }
64
- if (value instanceof Date) {
65
- return normalizeDateValue(value);
66
- }
67
- if (typeof value === "bigint") {
68
- return value.toString();
69
- }
70
- if (Array.isArray(value)) {
71
- return normalizeArrayValue(value, seen, depth);
72
- }
73
- if (value && typeof value === "object") {
74
- return normalizeObjectValue(value, seen, depth);
75
- }
76
- return value;
77
- }
78
- function normalizeDateValue(date) {
79
- const t = date.getTime();
80
- if (!Number.isFinite(t)) {
81
- throw new Error("Invalid Date value in SQL params");
82
- }
83
- return date.toISOString();
84
- }
85
- function normalizeArrayValue(value, seen, depth) {
86
- const arrRef = value;
87
- if (seen.has(arrRef)) {
88
- throw new Error("Circular reference in SQL params");
89
- }
90
- seen.add(arrRef);
91
- const out = value.map((v) => normalizeValue(v, seen, depth + 1));
92
- seen.delete(arrRef);
93
- return out;
94
- }
95
- function normalizeObjectValue(value, seen, depth) {
96
- if (value instanceof Uint8Array) return value;
97
- if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) return value;
98
- const proto = Object.getPrototypeOf(value);
99
- const isPlain = proto === Object.prototype || proto === null;
100
- if (!isPlain) return value;
101
- const obj = value;
102
- if (seen.has(obj)) {
103
- throw new Error("Circular reference in SQL params");
104
- }
105
- seen.add(obj);
106
- const out = {};
107
- for (const [k, v] of Object.entries(obj)) {
108
- out[k] = normalizeValue(v, seen, depth + 1);
109
- }
110
- seen.delete(obj);
111
- return out;
112
- }
113
-
114
- // src/sql-builder-dialect.ts
115
- var globalDialect = "postgres";
116
- function getGlobalDialect() {
117
- return globalDialect;
118
- }
119
- function assertNonEmpty(value, name) {
120
- if (!value || value.trim().length === 0) {
121
- throw new Error(`${name} is required and cannot be empty`);
122
- }
123
- }
124
- function arrayContains(column, value, arrayType, dialect) {
125
- assertNonEmpty(column, "arrayContains column");
126
- assertNonEmpty(value, "arrayContains value");
127
- if (dialect === "postgres") {
128
- return `${column} @> ARRAY[${value}]::${arrayType}`;
129
- }
130
- return `EXISTS (SELECT 1 FROM json_each(${column}) WHERE value = ${value})`;
131
- }
132
- function arrayOverlaps(column, value, arrayType, dialect) {
133
- assertNonEmpty(column, "arrayOverlaps column");
134
- assertNonEmpty(value, "arrayOverlaps value");
135
- if (dialect === "postgres") {
136
- return `${column} && ${value}::${arrayType}`;
137
- }
138
- return `EXISTS (
139
- SELECT 1 FROM json_each(${column}) AS col
140
- JOIN json_each(${value}) AS val
141
- WHERE col.value = val.value
142
- )`;
143
- }
144
- function arrayContainsAll(column, value, arrayType, dialect) {
145
- assertNonEmpty(column, "arrayContainsAll column");
146
- assertNonEmpty(value, "arrayContainsAll value");
147
- if (dialect === "postgres") {
148
- return `${column} @> ${value}::${arrayType}`;
149
- }
150
- return `NOT EXISTS (
151
- SELECT 1 FROM json_each(${value}) AS val
152
- WHERE NOT EXISTS (
153
- SELECT 1 FROM json_each(${column}) AS col
154
- WHERE col.value = val.value
155
- )
156
- )`;
157
- }
158
- function arrayIsEmpty(column, dialect) {
159
- assertNonEmpty(column, "arrayIsEmpty column");
160
- if (dialect === "postgres") {
161
- return `(${column} IS NULL OR array_length(${column}, 1) IS NULL)`;
162
- }
163
- return `(${column} IS NULL OR json_array_length(${column}) = 0)`;
164
- }
165
- function arrayIsNotEmpty(column, dialect) {
166
- assertNonEmpty(column, "arrayIsNotEmpty column");
167
- if (dialect === "postgres") {
168
- return `(${column} IS NOT NULL AND array_length(${column}, 1) IS NOT NULL)`;
169
- }
170
- return `(${column} IS NOT NULL AND json_array_length(${column}) > 0)`;
171
- }
172
- function arrayEquals(column, value, arrayType, dialect) {
173
- assertNonEmpty(column, "arrayEquals column");
174
- assertNonEmpty(value, "arrayEquals value");
175
- if (dialect === "postgres") {
176
- return `${column} = ${value}::${arrayType}`;
177
- }
178
- return `json(${column}) = json(${value})`;
179
- }
180
- function caseInsensitiveLike(column, pattern, dialect) {
181
- assertNonEmpty(column, "caseInsensitiveLike column");
182
- assertNonEmpty(pattern, "caseInsensitiveLike pattern");
183
- if (dialect === "postgres") {
184
- return `${column} ILIKE ${pattern}`;
185
- }
186
- return `LOWER(${column}) LIKE LOWER(${pattern})`;
187
- }
188
- function caseInsensitiveEquals(column, value, dialect) {
189
- assertNonEmpty(column, "caseInsensitiveEquals column");
190
- assertNonEmpty(value, "caseInsensitiveEquals value");
191
- return `LOWER(${column}) = LOWER(${value})`;
192
- }
193
- function jsonExtractText(column, path, dialect) {
194
- assertNonEmpty(column, "jsonExtractText column");
195
- assertNonEmpty(path, "jsonExtractText path");
196
- if (dialect === "postgres") {
197
- const p = String(path).trim();
198
- const pathExpr = /^\$\d+$/.test(p) ? `${p}::text[]` : p;
199
- return `${column}#>>${pathExpr}`;
200
- }
201
- return `json_extract(${column}, ${path})`;
202
- }
203
- function jsonExtractNumeric(column, path, dialect) {
204
- assertNonEmpty(column, "jsonExtractNumeric column");
205
- assertNonEmpty(path, "jsonExtractNumeric path");
206
- if (dialect === "postgres") {
207
- const p = String(path).trim();
208
- const pathExpr = /^\$\d+$/.test(p) ? `${p}::text[]` : p;
209
- return `(${column}#>>${pathExpr})::numeric`;
210
- }
211
- return `CAST(json_extract(${column}, ${path}) AS REAL)`;
212
- }
213
- function jsonToText(column, dialect) {
214
- assertNonEmpty(column, "jsonToText column");
215
- if (dialect === "postgres") {
216
- return `${column}::text`;
217
- }
218
- return column;
219
- }
220
- function inArray(column, value, dialect) {
221
- assertNonEmpty(column, "inArray column");
222
- assertNonEmpty(value, "inArray value");
223
- if (dialect === "postgres") {
224
- return `${column} = ANY(${value})`;
225
- }
226
- return `${column} IN (SELECT value FROM json_each(${value}))`;
227
- }
228
- function notInArray(column, value, dialect) {
229
- assertNonEmpty(column, "notInArray column");
230
- assertNonEmpty(value, "notInArray value");
231
- if (dialect === "postgres") {
232
- return `${column} != ALL(${value})`;
233
- }
234
- return `${column} NOT IN (SELECT value FROM json_each(${value}))`;
235
- }
236
- function getArrayType(prismaType, dialect) {
237
- if (!prismaType || prismaType.length === 0) {
238
- return dialect === "sqlite" ? "TEXT" : "text[]";
239
- }
240
- if (dialect === "sqlite") {
241
- return "TEXT";
242
- }
243
- const baseType = prismaType.replace(/\[\]|\?/g, "");
244
- switch (baseType) {
245
- case "String":
246
- return "text[]";
247
- case "Int":
248
- return "integer[]";
249
- case "Float":
250
- return "double precision[]";
251
- case "Decimal":
252
- return "numeric[]";
253
- case "Boolean":
254
- return "boolean[]";
255
- case "BigInt":
256
- return "bigint[]";
257
- case "DateTime":
258
- return "timestamptz[]";
259
- default:
260
- return `"${baseType}"[]`;
261
- }
262
- }
263
- function jsonAgg(content, dialect) {
264
- assertNonEmpty(content, "jsonAgg content");
265
- if (dialect === "postgres") {
266
- return `json_agg(${content})`;
267
- }
268
- return `json_group_array(${content})`;
269
- }
270
- function jsonBuildObject(pairs, dialect) {
271
- const safePairs = (pairs != null ? pairs : "").trim();
272
- if (dialect === "postgres") {
273
- return safePairs.length > 0 ? `json_build_object(${safePairs})` : `json_build_object()`;
274
- }
275
- return safePairs.length > 0 ? `json_object(${safePairs})` : `json_object()`;
276
- }
277
- function prepareArrayParam(value, dialect) {
278
- if (!Array.isArray(value)) {
279
- throw new Error("prepareArrayParam requires array value");
280
- }
281
- if (dialect === "postgres") {
282
- return value.map((v) => normalizeValue(v));
283
- }
284
- return JSON.stringify(value.map((v) => normalizeValue(v)));
285
- }
286
-
287
58
  // src/builder/shared/constants.ts
288
59
  var IS_PRODUCTION = process.env.NODE_ENV === "production";
289
60
  var SQL_SEPARATORS = Object.freeze({
@@ -1118,25 +889,276 @@ function joinCondition(field, parentModel, childModel, parentAlias, childAlias)
1118
889
  { field: field.name }
1119
890
  );
1120
891
  }
1121
- const refFields = getReferenceFieldNames(field, fkFields.length);
1122
- if (refFields.length !== fkFields.length) {
1123
- throw createError(
1124
- `Relation '${field.name}' is missing references (or references count does not match foreignKey count). This is required to support non-id and composite keys.`,
1125
- { field: field.name }
1126
- );
892
+ const refFields = getReferenceFieldNames(field, fkFields.length);
893
+ if (refFields.length !== fkFields.length) {
894
+ throw createError(
895
+ `Relation '${field.name}' is missing references (or references count does not match foreignKey count). This is required to support non-id and composite keys.`,
896
+ { field: field.name }
897
+ );
898
+ }
899
+ const parts = [];
900
+ for (let i = 0; i < fkFields.length; i++) {
901
+ const fk = fkFields[i];
902
+ const ref = refFields[i];
903
+ const left = field.isForeignKeyLocal ? `${childAlias}.${quoteColumn(childModel, ref)}` : `${childAlias}.${quoteColumn(childModel, fk)}`;
904
+ const right = field.isForeignKeyLocal ? `${parentAlias}.${quoteColumn(parentModel, fk)}` : `${parentAlias}.${quoteColumn(parentModel, ref)}`;
905
+ parts.push(`${left} = ${right}`);
906
+ }
907
+ return parts.length === 1 ? parts[0] : `(${parts.join(" AND ")})`;
908
+ }
909
+ function getModelByName(schemas, name) {
910
+ return schemas.find((m) => m.name === name);
911
+ }
912
+
913
+ // src/utils/normalize-value.ts
914
+ var globalDateMode = "iso";
915
+ function setNormalizeDateMode(mode) {
916
+ globalDateMode = mode;
917
+ }
918
+ function detectSqliteDateMode(client) {
919
+ try {
920
+ const tables = client.prepare(
921
+ "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_%' LIMIT 50"
922
+ ).all();
923
+ for (const { name } of tables) {
924
+ const row = client.prepare(`SELECT typeof("createdAt") as t FROM "${name}" LIMIT 1`).get();
925
+ if (row) {
926
+ return row.t === "integer" ? "ms" : "iso";
927
+ }
928
+ }
929
+ } catch (e) {
930
+ }
931
+ return "iso";
932
+ }
933
+ var MAX_DEPTH = 20;
934
+ function normalizeValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
935
+ if (depth > MAX_DEPTH) {
936
+ throw new Error(`Max normalization depth exceeded (${MAX_DEPTH} levels)`);
937
+ }
938
+ if (value instanceof Date) {
939
+ return normalizeDateValue(value);
940
+ }
941
+ if (typeof value === "bigint") {
942
+ return value.toString();
943
+ }
944
+ if (Array.isArray(value)) {
945
+ return normalizeArrayValue(value, seen, depth);
946
+ }
947
+ if (value && typeof value === "object") {
948
+ return normalizeObjectValue(value, seen, depth);
949
+ }
950
+ return value;
951
+ }
952
+ function normalizeDateValue(date) {
953
+ const t = date.getTime();
954
+ if (!Number.isFinite(t)) {
955
+ throw new Error("Invalid Date value in SQL params");
956
+ }
957
+ if (globalDateMode === "ms") {
958
+ return t;
959
+ }
960
+ return date.toISOString();
961
+ }
962
+ function normalizeArrayValue(value, seen, depth) {
963
+ const arrRef = value;
964
+ if (seen.has(arrRef)) {
965
+ throw new Error("Circular reference in SQL params");
966
+ }
967
+ seen.add(arrRef);
968
+ const out = value.map((v) => normalizeValue(v, seen, depth + 1));
969
+ seen.delete(arrRef);
970
+ return out;
971
+ }
972
+ function normalizeObjectValue(value, seen, depth) {
973
+ if (value instanceof Uint8Array) return value;
974
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) return value;
975
+ const proto = Object.getPrototypeOf(value);
976
+ const isPlain = proto === Object.prototype || proto === null;
977
+ if (!isPlain) return value;
978
+ const obj = value;
979
+ if (seen.has(obj)) {
980
+ throw new Error("Circular reference in SQL params");
981
+ }
982
+ seen.add(obj);
983
+ const out = {};
984
+ for (const [k, v] of Object.entries(obj)) {
985
+ out[k] = normalizeValue(v, seen, depth + 1);
986
+ }
987
+ seen.delete(obj);
988
+ return out;
989
+ }
990
+
991
+ // src/sql-builder-dialect.ts
992
+ var globalDialect = "postgres";
993
+ function getGlobalDialect() {
994
+ return globalDialect;
995
+ }
996
+ function assertNonEmpty(value, name) {
997
+ if (!value || value.trim().length === 0) {
998
+ throw new Error(`${name} is required and cannot be empty`);
999
+ }
1000
+ }
1001
+ function arrayContains(column, value, arrayType, dialect) {
1002
+ assertNonEmpty(column, "arrayContains column");
1003
+ assertNonEmpty(value, "arrayContains value");
1004
+ if (dialect === "postgres") {
1005
+ return `${column} @> ARRAY[${value}]::${arrayType}`;
1006
+ }
1007
+ return `EXISTS (SELECT 1 FROM json_each(${column}) WHERE value = ${value})`;
1008
+ }
1009
+ function arrayOverlaps(column, value, arrayType, dialect) {
1010
+ assertNonEmpty(column, "arrayOverlaps column");
1011
+ assertNonEmpty(value, "arrayOverlaps value");
1012
+ if (dialect === "postgres") {
1013
+ return `${column} && ${value}::${arrayType}`;
1014
+ }
1015
+ return `EXISTS (
1016
+ SELECT 1 FROM json_each(${column}) AS col
1017
+ JOIN json_each(${value}) AS val
1018
+ WHERE col.value = val.value
1019
+ )`;
1020
+ }
1021
+ function arrayContainsAll(column, value, arrayType, dialect) {
1022
+ assertNonEmpty(column, "arrayContainsAll column");
1023
+ assertNonEmpty(value, "arrayContainsAll value");
1024
+ if (dialect === "postgres") {
1025
+ return `${column} @> ${value}::${arrayType}`;
1026
+ }
1027
+ return `NOT EXISTS (
1028
+ SELECT 1 FROM json_each(${value}) AS val
1029
+ WHERE NOT EXISTS (
1030
+ SELECT 1 FROM json_each(${column}) AS col
1031
+ WHERE col.value = val.value
1032
+ )
1033
+ )`;
1034
+ }
1035
+ function arrayIsEmpty(column, dialect) {
1036
+ assertNonEmpty(column, "arrayIsEmpty column");
1037
+ if (dialect === "postgres") {
1038
+ return `(${column} IS NULL OR array_length(${column}, 1) IS NULL)`;
1039
+ }
1040
+ return `(${column} IS NULL OR json_array_length(${column}) = 0)`;
1041
+ }
1042
+ function arrayIsNotEmpty(column, dialect) {
1043
+ assertNonEmpty(column, "arrayIsNotEmpty column");
1044
+ if (dialect === "postgres") {
1045
+ return `(${column} IS NOT NULL AND array_length(${column}, 1) IS NOT NULL)`;
1046
+ }
1047
+ return `(${column} IS NOT NULL AND json_array_length(${column}) > 0)`;
1048
+ }
1049
+ function arrayEquals(column, value, arrayType, dialect) {
1050
+ assertNonEmpty(column, "arrayEquals column");
1051
+ assertNonEmpty(value, "arrayEquals value");
1052
+ if (dialect === "postgres") {
1053
+ return `${column} = ${value}::${arrayType}`;
1054
+ }
1055
+ return `json(${column}) = json(${value})`;
1056
+ }
1057
+ function caseInsensitiveLike(column, pattern, dialect) {
1058
+ assertNonEmpty(column, "caseInsensitiveLike column");
1059
+ assertNonEmpty(pattern, "caseInsensitiveLike pattern");
1060
+ if (dialect === "postgres") {
1061
+ return `${column} ILIKE ${pattern}`;
1062
+ }
1063
+ return `LOWER(${column}) LIKE LOWER(${pattern})`;
1064
+ }
1065
+ function caseInsensitiveEquals(column, value, dialect) {
1066
+ assertNonEmpty(column, "caseInsensitiveEquals column");
1067
+ assertNonEmpty(value, "caseInsensitiveEquals value");
1068
+ return `LOWER(${column}) = LOWER(${value})`;
1069
+ }
1070
+ function jsonExtractText(column, path, dialect) {
1071
+ assertNonEmpty(column, "jsonExtractText column");
1072
+ assertNonEmpty(path, "jsonExtractText path");
1073
+ if (dialect === "postgres") {
1074
+ const p = String(path).trim();
1075
+ const pathExpr = /^\$\d+$/.test(p) ? `${p}::text[]` : p;
1076
+ return `${column}#>>${pathExpr}`;
1077
+ }
1078
+ return `json_extract(${column}, ${path})`;
1079
+ }
1080
+ function jsonExtractNumeric(column, path, dialect) {
1081
+ assertNonEmpty(column, "jsonExtractNumeric column");
1082
+ assertNonEmpty(path, "jsonExtractNumeric path");
1083
+ if (dialect === "postgres") {
1084
+ const p = String(path).trim();
1085
+ const pathExpr = /^\$\d+$/.test(p) ? `${p}::text[]` : p;
1086
+ return `(${column}#>>${pathExpr})::numeric`;
1087
+ }
1088
+ return `CAST(json_extract(${column}, ${path}) AS REAL)`;
1089
+ }
1090
+ function jsonToText(column, dialect) {
1091
+ assertNonEmpty(column, "jsonToText column");
1092
+ if (dialect === "postgres") {
1093
+ return `${column}::text`;
1094
+ }
1095
+ return column;
1096
+ }
1097
+ function inArray(column, value, dialect) {
1098
+ assertNonEmpty(column, "inArray column");
1099
+ assertNonEmpty(value, "inArray value");
1100
+ if (dialect === "postgres") {
1101
+ return `${column} = ANY(${value})`;
1102
+ }
1103
+ return `${column} IN (SELECT value FROM json_each(${value}))`;
1104
+ }
1105
+ function notInArray(column, value, dialect) {
1106
+ assertNonEmpty(column, "notInArray column");
1107
+ assertNonEmpty(value, "notInArray value");
1108
+ if (dialect === "postgres") {
1109
+ return `${column} != ALL(${value})`;
1110
+ }
1111
+ return `${column} NOT IN (SELECT value FROM json_each(${value}))`;
1112
+ }
1113
+ function getArrayType(prismaType, dialect) {
1114
+ if (!prismaType || prismaType.length === 0) {
1115
+ return dialect === "sqlite" ? "TEXT" : "text[]";
1116
+ }
1117
+ if (dialect === "sqlite") {
1118
+ return "TEXT";
1119
+ }
1120
+ const baseType = prismaType.replace(/\[\]|\?/g, "");
1121
+ switch (baseType) {
1122
+ case "String":
1123
+ return "text[]";
1124
+ case "Int":
1125
+ return "integer[]";
1126
+ case "Float":
1127
+ return "double precision[]";
1128
+ case "Decimal":
1129
+ return "numeric[]";
1130
+ case "Boolean":
1131
+ return "boolean[]";
1132
+ case "BigInt":
1133
+ return "bigint[]";
1134
+ case "DateTime":
1135
+ return "timestamptz[]";
1136
+ default:
1137
+ return `"${baseType}"[]`;
1138
+ }
1139
+ }
1140
+ function jsonAgg(content, dialect) {
1141
+ assertNonEmpty(content, "jsonAgg content");
1142
+ if (dialect === "postgres") {
1143
+ return `json_agg(${content})`;
1127
1144
  }
1128
- const parts = [];
1129
- for (let i = 0; i < fkFields.length; i++) {
1130
- const fk = fkFields[i];
1131
- const ref = refFields[i];
1132
- const left = field.isForeignKeyLocal ? `${childAlias}.${quoteColumn(childModel, ref)}` : `${childAlias}.${quoteColumn(childModel, fk)}`;
1133
- const right = field.isForeignKeyLocal ? `${parentAlias}.${quoteColumn(parentModel, fk)}` : `${parentAlias}.${quoteColumn(parentModel, ref)}`;
1134
- parts.push(`${left} = ${right}`);
1145
+ return `json_group_array(${content})`;
1146
+ }
1147
+ function jsonBuildObject(pairs, dialect) {
1148
+ const safePairs = (pairs != null ? pairs : "").trim();
1149
+ if (dialect === "postgres") {
1150
+ return safePairs.length > 0 ? `json_build_object(${safePairs})` : `json_build_object()`;
1135
1151
  }
1136
- return parts.length === 1 ? parts[0] : `(${parts.join(" AND ")})`;
1152
+ return safePairs.length > 0 ? `json_object(${safePairs})` : `json_object()`;
1137
1153
  }
1138
- function getModelByName(schemas, name) {
1139
- return schemas.find((m) => m.name === name);
1154
+ function prepareArrayParam(value, dialect) {
1155
+ if (!Array.isArray(value)) {
1156
+ throw new Error("prepareArrayParam requires array value");
1157
+ }
1158
+ if (dialect === "postgres") {
1159
+ return value.map((v) => normalizeValue(v));
1160
+ }
1161
+ return JSON.stringify(value.map((v) => normalizeValue(v)));
1140
1162
  }
1141
1163
  function normalizeIntLike(name, v, opts = {}) {
1142
1164
  var _a3, _b;
@@ -2276,14 +2298,15 @@ function hasPaginationArgs(value) {
2276
2298
  const obj = value;
2277
2299
  return "take" in obj && obj.take != null || "skip" in obj && typeof obj.skip === "number" && obj.skip > 0;
2278
2300
  }
2279
- function buildCostTree(includeSpec, model, schemas) {
2301
+ function buildCostTree(includeSpec, model, schemas, depth = 0) {
2302
+ if (depth > LIMITS.MAX_INCLUDE_DEPTH) return [];
2280
2303
  const relations = resolveIncludeRelations(includeSpec, model, schemas);
2281
2304
  const nodes = [];
2282
2305
  for (const rel of relations) {
2283
2306
  const fan = rel.isList ? getFanOut(model.name, rel.relName) : 1;
2284
2307
  const take = rel.isList ? readTake(rel.value) : 1;
2285
2308
  const eff = Math.min(fan, take);
2286
- const children = Object.keys(rel.nestedSpec).length > 0 ? buildCostTree(rel.nestedSpec, rel.relModel, schemas) : [];
2309
+ const children = Object.keys(rel.nestedSpec).length > 0 ? buildCostTree(rel.nestedSpec, rel.relModel, schemas, depth + 1) : [];
2287
2310
  nodes.push({
2288
2311
  name: rel.relName,
2289
2312
  fan,
@@ -2349,19 +2372,26 @@ function hasOnlyToOneRelations(includeSpec, model) {
2349
2372
  }
2350
2373
  return true;
2351
2374
  }
2352
- function countIncludeDepth(includeSpec, model, schemas) {
2375
+ function countIncludeDepth(includeSpec, model, schemas, depth = 0) {
2376
+ if (depth > LIMITS.MAX_INCLUDE_DEPTH) return 0;
2353
2377
  const relations = resolveIncludeRelations(includeSpec, model, schemas);
2354
2378
  let maxDepth = 0;
2355
2379
  for (const rel of relations) {
2356
2380
  let childDepth = 1;
2357
2381
  if (Object.keys(rel.nestedSpec).length > 0) {
2358
- childDepth += countIncludeDepth(rel.nestedSpec, rel.relModel, schemas);
2382
+ childDepth += countIncludeDepth(
2383
+ rel.nestedSpec,
2384
+ rel.relModel,
2385
+ schemas,
2386
+ depth + 1
2387
+ );
2359
2388
  }
2360
2389
  if (childDepth > maxDepth) maxDepth = childDepth;
2361
2390
  }
2362
2391
  return maxDepth;
2363
2392
  }
2364
- function hasChildPaginationAnywhere(includeSpec, model, schemas) {
2393
+ function hasChildPaginationAnywhere(includeSpec, model, schemas, depth = 0) {
2394
+ if (depth > LIMITS.MAX_INCLUDE_DEPTH) return false;
2365
2395
  for (const [, value] of Object.entries(includeSpec)) {
2366
2396
  if (value === false) continue;
2367
2397
  if (hasPaginationArgs(value)) return true;
@@ -2369,7 +2399,12 @@ function hasChildPaginationAnywhere(includeSpec, model, schemas) {
2369
2399
  const relations = resolveIncludeRelations(includeSpec, model, schemas);
2370
2400
  for (const rel of relations) {
2371
2401
  if (Object.keys(rel.nestedSpec).length > 0) {
2372
- if (hasChildPaginationAnywhere(rel.nestedSpec, rel.relModel, schemas)) {
2402
+ if (hasChildPaginationAnywhere(
2403
+ rel.nestedSpec,
2404
+ rel.relModel,
2405
+ schemas,
2406
+ depth + 1
2407
+ )) {
2373
2408
  return true;
2374
2409
  }
2375
2410
  }
@@ -6134,9 +6169,10 @@ function buildAggregateFields(args, alias, model) {
6134
6169
  addAggregateFields(fields, args, alias, model);
6135
6170
  return fields;
6136
6171
  }
6137
- function buildAggregateSql(args, whereResult, tableName, alias, model) {
6172
+ function buildAggregateSql(args, whereResult, tableName, alias, model, dialect) {
6138
6173
  assertSafeAlias(alias);
6139
6174
  assertSafeTableRef(tableName);
6175
+ const d = dialect != null ? dialect : getGlobalDialect();
6140
6176
  const aggFields = buildAggregateFields(args, alias, model);
6141
6177
  if (!isNonEmptyArray(aggFields)) {
6142
6178
  throw new Error("buildAggregateSql requires at least one aggregate field");
@@ -6155,7 +6191,7 @@ function buildAggregateSql(args, whereResult, tableName, alias, model) {
6155
6191
  if (whereClause) parts.push(whereClause);
6156
6192
  const sql = parts.join(" ").trim();
6157
6193
  validateSelectQuery(sql);
6158
- validateParamConsistency(sql, whereResult.params);
6194
+ validateParamConsistencyByDialect(sql, whereResult.params, d);
6159
6195
  return {
6160
6196
  sql,
6161
6197
  params: [...whereResult.params],
@@ -6234,7 +6270,7 @@ function buildGroupBySql(args, whereResult, tableName, alias, model, dialect) {
6234
6270
  const allParams = [...whereResult.params, ...snapshot.params];
6235
6271
  const allMappings = [...whereResult.paramMappings, ...snapshot.mappings];
6236
6272
  validateSelectQuery(sql);
6237
- validateParamConsistency(sql, allParams);
6273
+ validateParamConsistencyByDialect(sql, allParams, d);
6238
6274
  return {
6239
6275
  sql,
6240
6276
  params: allParams,
@@ -6251,7 +6287,7 @@ function assertNoNegativeTake(args) {
6251
6287
  throw new Error("Negative take is not supported for count()");
6252
6288
  }
6253
6289
  }
6254
- function buildSimpleCountSql(whereResult, tableName, alias) {
6290
+ function buildSimpleCountSql(whereResult, tableName, alias, dialect) {
6255
6291
  const joinsPart = whereResult.joins && whereResult.joins.length > 0 ? whereResult.joins.join(" ") : "";
6256
6292
  const whereClause = isValidWhereClause(whereResult.clause) ? SQL_TEMPLATES.WHERE + " " + whereResult.clause : "";
6257
6293
  const parts = [
@@ -6267,7 +6303,7 @@ function buildSimpleCountSql(whereResult, tableName, alias) {
6267
6303
  if (whereClause) parts.push(whereClause);
6268
6304
  const sql = parts.join(" ").trim();
6269
6305
  validateSelectQuery(sql);
6270
- validateParamConsistency(sql, whereResult.params);
6306
+ validateParamConsistencyByDialect(sql, whereResult.params, dialect);
6271
6307
  return {
6272
6308
  sql,
6273
6309
  params: [...whereResult.params],
@@ -6279,14 +6315,15 @@ function buildCountSql(whereResult, tableName, alias, argsOrSkip, dialect, model
6279
6315
  assertSafeTableRef(tableName);
6280
6316
  const args = normalizeCountArgs(argsOrSkip);
6281
6317
  assertNoNegativeTake(args);
6318
+ const d = dialect != null ? dialect : getGlobalDialect();
6282
6319
  if (!model) {
6283
- return buildSimpleCountSql(whereResult, tableName, alias);
6320
+ return buildSimpleCountSql(whereResult, tableName, alias, d);
6284
6321
  }
6285
6322
  const pkFields = getPrimaryKeyFields(model);
6286
6323
  const distinctFields = isNonEmptyArray(args.distinct) ? args.distinct.map((x) => String(x)).filter((x) => x) : [];
6287
6324
  const selectFields = distinctFields.length > 0 ? distinctFields : pkFields;
6288
6325
  if (selectFields.length === 0) {
6289
- return buildSimpleCountSql(whereResult, tableName, alias);
6326
+ return buildSimpleCountSql(whereResult, tableName, alias, d);
6290
6327
  }
6291
6328
  const select = {};
6292
6329
  for (const f of selectFields) select[f] = true;
@@ -6294,7 +6331,6 @@ function buildCountSql(whereResult, tableName, alias, argsOrSkip, dialect, model
6294
6331
  include: void 0,
6295
6332
  select
6296
6333
  });
6297
- const d = dialect != null ? dialect : getGlobalDialect();
6298
6334
  const subSchemas = Array.isArray(schemas) && schemas.length > 0 ? schemas : [model];
6299
6335
  const sub = buildSelectSql({
6300
6336
  method: "findMany",
@@ -6310,7 +6346,7 @@ function buildCountSql(whereResult, tableName, alias, argsOrSkip, dialect, model
6310
6346
  "_count._all"
6311
6347
  )} ${SQL_TEMPLATES.FROM} (${sub.sql}) ${SQL_TEMPLATES.AS} ${countAlias}`;
6312
6348
  validateSelectQuery(sql);
6313
- validateParamConsistency(sql, sub.params);
6349
+ validateParamConsistencyByDialect(sql, sub.params, d);
6314
6350
  return {
6315
6351
  sql,
6316
6352
  params: sub.params,
@@ -6601,7 +6637,14 @@ function buildSqlResult(args) {
6601
6637
  dialect
6602
6638
  } = args;
6603
6639
  if (method === "aggregate") {
6604
- return buildAggregateSql(processed, whereResult, tableName, alias, modelDef);
6640
+ return buildAggregateSql(
6641
+ processed,
6642
+ whereResult,
6643
+ tableName,
6644
+ alias,
6645
+ modelDef,
6646
+ dialect
6647
+ );
6605
6648
  }
6606
6649
  if (method === "groupBy") {
6607
6650
  return buildGroupBySql(
@@ -7308,7 +7351,8 @@ function buildSQLFull(model, models, method, args, dialect) {
7308
7351
  whereResult,
7309
7352
  tableName,
7310
7353
  alias,
7311
- model
7354
+ model,
7355
+ dialect
7312
7356
  );
7313
7357
  break;
7314
7358
  case "groupBy":
@@ -7326,8 +7370,10 @@ function buildSQLFull(model, models, method, args, dialect) {
7326
7370
  whereResult,
7327
7371
  tableName,
7328
7372
  alias,
7329
- args.skip,
7330
- dialect
7373
+ args,
7374
+ dialect,
7375
+ model,
7376
+ models
7331
7377
  );
7332
7378
  break;
7333
7379
  default:
@@ -7341,7 +7387,8 @@ function buildSQLFull(model, models, method, args, dialect) {
7341
7387
  dialect
7342
7388
  });
7343
7389
  }
7344
- const sqlResult = dialect === "sqlite" ? pgToSqlitePlaceholders(result.sql, result.params) : { sql: result.sql, params: [...result.params] };
7390
+ const needsPlaceholderConversion = dialect === "sqlite" && result.sql.includes("$");
7391
+ const sqlResult = needsPlaceholderConversion ? pgToSqlitePlaceholders(result.sql, result.params) : { sql: result.sql, params: [...result.params] };
7345
7392
  return __spreadProps(__spreadValues({}, sqlResult), {
7346
7393
  paramMappings: result.paramMappings,
7347
7394
  requiresReduction: result.requiresReduction,
@@ -7502,68 +7549,234 @@ function validateTimeout(timeout) {
7502
7549
  `Transaction timeout must be a number, got ${typeof timeout}`
7503
7550
  );
7504
7551
  }
7505
- if (!Number.isFinite(timeout)) {
7506
- throw new Error(`Transaction timeout must be finite, got ${timeout}`);
7552
+ if (!Number.isFinite(timeout)) {
7553
+ throw new Error(`Transaction timeout must be finite, got ${timeout}`);
7554
+ }
7555
+ if (timeout < 0) {
7556
+ throw new Error(`Transaction timeout must be non-negative, got ${timeout}`);
7557
+ }
7558
+ return Math.floor(timeout);
7559
+ }
7560
+ function createTransactionExecutor(deps) {
7561
+ const { modelMap, allModels, dialect, postgresClient } = deps;
7562
+ return {
7563
+ execute(queries, options) {
7564
+ return __async(this, null, function* () {
7565
+ if (queries.length === 0) return [];
7566
+ if (dialect !== "postgres") {
7567
+ throw new Error("$transaction is only supported for postgres dialect");
7568
+ }
7569
+ if (!postgresClient) {
7570
+ throw new Error("postgresClient is required for transactions");
7571
+ }
7572
+ const transactionCallback = (sql) => __async(null, null, function* () {
7573
+ const results = [];
7574
+ const isolationLevel = isolationLevelToPostgresKeyword(
7575
+ options == null ? void 0 : options.isolationLevel
7576
+ );
7577
+ if (isolationLevel) {
7578
+ yield sql.unsafe(
7579
+ `SET TRANSACTION ISOLATION LEVEL ${isolationLevel.toUpperCase()}`
7580
+ );
7581
+ }
7582
+ if ((options == null ? void 0 : options.timeout) !== void 0 && options.timeout !== null) {
7583
+ const validatedTimeout = validateTimeout(options.timeout);
7584
+ yield sql.unsafe(`SET LOCAL statement_timeout = $1`, [
7585
+ validatedTimeout
7586
+ ]);
7587
+ }
7588
+ for (const q of queries) {
7589
+ const model = modelMap.get(q.model);
7590
+ if (!model) {
7591
+ throw new Error(
7592
+ `Model '${q.model}' not found. Available: ${[...modelMap.keys()].join(", ")}`
7593
+ );
7594
+ }
7595
+ const { sql: sqlStr, params } = buildSQLWithCache(
7596
+ model,
7597
+ allModels,
7598
+ q.method,
7599
+ q.args || {},
7600
+ dialect
7601
+ );
7602
+ let rawResults = yield sql.unsafe(sqlStr, params);
7603
+ const rowTransformer = getRowTransformer(q.method);
7604
+ if (rowTransformer && Array.isArray(rawResults)) {
7605
+ rawResults = rawResults.map(rowTransformer);
7606
+ }
7607
+ results.push(transformQueryResults(q.method, rawResults));
7608
+ }
7609
+ return results;
7610
+ });
7611
+ return yield postgresClient.begin(transactionCallback);
7612
+ });
7613
+ }
7614
+ };
7615
+ }
7616
+
7617
+ // src/builder/select/segment-planner.ts
7618
+ function isListField2(field) {
7619
+ return typeof field.type === "string" && field.type.endsWith("[]");
7620
+ }
7621
+ function resolveRelation(model, relName, allModels) {
7622
+ const field = model.fields.find((f) => f.name === relName);
7623
+ if (!field || !field.isRelation || !field.relatedModel) return null;
7624
+ const relModel = allModels.find((m) => m.name === field.relatedModel);
7625
+ if (!relModel) return null;
7626
+ return { field, relModel };
7627
+ }
7628
+ function extractPagination(relArgs) {
7629
+ if (!isPlainObject(relArgs)) return {};
7630
+ const obj = relArgs;
7631
+ const result = {};
7632
+ if ("take" in obj && typeof obj.take === "number") {
7633
+ result.take = obj.take;
7634
+ }
7635
+ if ("skip" in obj && typeof obj.skip === "number" && obj.skip > 0) {
7636
+ result.skip = obj.skip;
7637
+ }
7638
+ return result;
7639
+ }
7640
+ function buildWhereInSegment(name, relArgs, field, relModel) {
7641
+ const keys = resolveRelationKeys(field, "whereIn");
7642
+ if (keys.childKeys.length !== 1) return null;
7643
+ const isList = isListField2(field);
7644
+ const pagination = isList ? extractPagination(relArgs) : {};
7645
+ return {
7646
+ relationName: name,
7647
+ relArgs,
7648
+ childModelName: relModel.name,
7649
+ fkFieldName: keys.childKeys[0],
7650
+ parentKeyFieldName: keys.parentKeys[0],
7651
+ isList,
7652
+ perParentTake: pagination.take,
7653
+ perParentSkip: pagination.skip
7654
+ };
7655
+ }
7656
+ function deepClone(obj) {
7657
+ if (obj === null || typeof obj !== "object") return obj;
7658
+ if (obj instanceof Date) return new Date(obj.getTime());
7659
+ if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);
7660
+ if (Array.isArray(obj)) return obj.map((item) => deepClone(item));
7661
+ const cloned = {};
7662
+ for (const key in obj) {
7663
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
7664
+ cloned[key] = deepClone(obj[key]);
7665
+ }
7666
+ }
7667
+ return cloned;
7668
+ }
7669
+ function removeRelationsFromArgs(args, names) {
7670
+ if (!args) return args;
7671
+ const filtered = deepClone(args);
7672
+ if (filtered.include && isPlainObject(filtered.include)) {
7673
+ for (const name of names) {
7674
+ delete filtered.include[name];
7675
+ }
7676
+ if (Object.keys(filtered.include).length === 0) {
7677
+ delete filtered.include;
7678
+ }
7679
+ }
7680
+ if (filtered.select && isPlainObject(filtered.select)) {
7681
+ for (const name of names) {
7682
+ delete filtered.select[name];
7683
+ }
7684
+ }
7685
+ return filtered;
7686
+ }
7687
+ function ensureParentKeysInSelect(args, segments) {
7688
+ if (!(args == null ? void 0 : args.select)) return { args, injectedKeys: [] };
7689
+ const injected = [];
7690
+ const newSelect = __spreadValues({}, args.select);
7691
+ for (const seg of segments) {
7692
+ if (!newSelect[seg.parentKeyFieldName]) {
7693
+ newSelect[seg.parentKeyFieldName] = true;
7694
+ injected.push(seg.parentKeyFieldName);
7695
+ }
7696
+ }
7697
+ if (injected.length === 0) return { args, injectedKeys: [] };
7698
+ return { args: __spreadProps(__spreadValues({}, args), { select: newSelect }), injectedKeys: injected };
7699
+ }
7700
+ function extractIncludeSpec3(args, model) {
7701
+ const spec = {};
7702
+ const entries = extractRelationEntries(args, model);
7703
+ for (const e of entries) {
7704
+ if (e.value !== false) {
7705
+ spec[e.name] = e.value;
7706
+ }
7707
+ }
7708
+ return spec;
7709
+ }
7710
+ function planQueryStrategy(params) {
7711
+ const { model, args, allModels, dialect, debug } = params;
7712
+ const emptyPlan = {
7713
+ filteredArgs: args,
7714
+ originalArgs: args,
7715
+ whereInSegments: [],
7716
+ injectedParentKeys: []
7717
+ };
7718
+ const entries = extractRelationEntries(args, model);
7719
+ if (entries.length === 0) {
7720
+ return emptyPlan;
7721
+ }
7722
+ if (dialect === "postgres") {
7723
+ const includeSpec = extractIncludeSpec3(args, model);
7724
+ if (Object.keys(includeSpec).length > 0) {
7725
+ isPlainObject(args) && "take" in args && args.take != null;
7726
+ const takeValue = isPlainObject(args) && typeof args.take === "number" ? args.take : null;
7727
+ const canFlatJoin = canUseFlatJoinForAll(includeSpec, model, allModels);
7728
+ canUseLateralJoin(includeSpec, model, allModels);
7729
+ hasChildPaginationAnywhere(
7730
+ includeSpec,
7731
+ model,
7732
+ allModels
7733
+ );
7734
+ const strategy = pickIncludeStrategy({
7735
+ includeSpec,
7736
+ model,
7737
+ schemas: allModels,
7738
+ method: params.method,
7739
+ takeValue,
7740
+ canFlatJoin,
7741
+ debug
7742
+ });
7743
+ if (debug) {
7744
+ console.log(` [planner] ${model.name}: strategy=${strategy}`);
7745
+ }
7746
+ if (strategy !== "where-in") {
7747
+ return emptyPlan;
7748
+ }
7749
+ }
7750
+ }
7751
+ const whereInSegments = [];
7752
+ const toRemove = /* @__PURE__ */ new Set();
7753
+ for (const entry of entries) {
7754
+ const resolved = resolveRelation(model, entry.name, allModels);
7755
+ if (!resolved) continue;
7756
+ const segment = buildWhereInSegment(
7757
+ entry.name,
7758
+ entry.value,
7759
+ resolved.field,
7760
+ resolved.relModel
7761
+ );
7762
+ if (segment) {
7763
+ whereInSegments.push(segment);
7764
+ toRemove.add(entry.name);
7765
+ }
7507
7766
  }
7508
- if (timeout < 0) {
7509
- throw new Error(`Transaction timeout must be non-negative, got ${timeout}`);
7767
+ if (toRemove.size === 0) {
7768
+ return emptyPlan;
7510
7769
  }
7511
- return Math.floor(timeout);
7512
- }
7513
- function createTransactionExecutor(deps) {
7514
- const { modelMap, allModels, dialect, postgresClient } = deps;
7770
+ const filteredArgs = removeRelationsFromArgs(args, toRemove);
7771
+ const { args: finalArgs, injectedKeys } = ensureParentKeysInSelect(
7772
+ filteredArgs,
7773
+ whereInSegments
7774
+ );
7515
7775
  return {
7516
- execute(queries, options) {
7517
- return __async(this, null, function* () {
7518
- if (queries.length === 0) return [];
7519
- if (dialect !== "postgres") {
7520
- throw new Error("$transaction is only supported for postgres dialect");
7521
- }
7522
- if (!postgresClient) {
7523
- throw new Error("postgresClient is required for transactions");
7524
- }
7525
- const transactionCallback = (sql) => __async(null, null, function* () {
7526
- const results = [];
7527
- const isolationLevel = isolationLevelToPostgresKeyword(
7528
- options == null ? void 0 : options.isolationLevel
7529
- );
7530
- if (isolationLevel) {
7531
- yield sql.unsafe(
7532
- `SET TRANSACTION ISOLATION LEVEL ${isolationLevel.toUpperCase()}`
7533
- );
7534
- }
7535
- if ((options == null ? void 0 : options.timeout) !== void 0 && options.timeout !== null) {
7536
- const validatedTimeout = validateTimeout(options.timeout);
7537
- yield sql.unsafe(`SET LOCAL statement_timeout = $1`, [
7538
- validatedTimeout
7539
- ]);
7540
- }
7541
- for (const q of queries) {
7542
- const model = modelMap.get(q.model);
7543
- if (!model) {
7544
- throw new Error(
7545
- `Model '${q.model}' not found. Available: ${[...modelMap.keys()].join(", ")}`
7546
- );
7547
- }
7548
- const { sql: sqlStr, params } = buildSQLWithCache(
7549
- model,
7550
- allModels,
7551
- q.method,
7552
- q.args || {},
7553
- dialect
7554
- );
7555
- let rawResults = yield sql.unsafe(sqlStr, params);
7556
- const rowTransformer = getRowTransformer(q.method);
7557
- if (rowTransformer && Array.isArray(rawResults)) {
7558
- rawResults = rawResults.map(rowTransformer);
7559
- }
7560
- results.push(transformQueryResults(q.method, rawResults));
7561
- }
7562
- return results;
7563
- });
7564
- return yield postgresClient.begin(transactionCallback);
7565
- });
7566
- }
7776
+ filteredArgs: finalArgs,
7777
+ originalArgs: args,
7778
+ whereInSegments,
7779
+ injectedParentKeys: injectedKeys
7567
7780
  };
7568
7781
  }
7569
7782
 
@@ -7607,9 +7820,9 @@ function extractChildLimit(relArgs) {
7607
7820
  return void 0;
7608
7821
  }
7609
7822
  function buildReducerConfig(parentModel, includeSpec, allModels, prefix = "", depth = 0) {
7610
- if (depth > 10) {
7823
+ if (depth > LIMITS.MAX_NESTED_JOIN_DEPTH) {
7611
7824
  throw new Error(
7612
- `Reducer config exceeded maximum depth of 10 at path '${prefix}'`
7825
+ `Reducer config exceeded maximum depth of ${LIMITS.MAX_NESTED_JOIN_DEPTH} at path '${prefix}'`
7613
7826
  );
7614
7827
  }
7615
7828
  const includedRelations = [];
@@ -7781,172 +7994,6 @@ function reduceFlatRows(rows, config) {
7781
7994
  return Array.from(resultMap.values());
7782
7995
  }
7783
7996
 
7784
- // src/builder/select/segment-planner.ts
7785
- function isListField2(field) {
7786
- return typeof field.type === "string" && field.type.endsWith("[]");
7787
- }
7788
- function resolveRelation(model, relName, allModels) {
7789
- const field = model.fields.find((f) => f.name === relName);
7790
- if (!field || !field.isRelation || !field.relatedModel) return null;
7791
- const relModel = allModels.find((m) => m.name === field.relatedModel);
7792
- if (!relModel) return null;
7793
- return { field, relModel };
7794
- }
7795
- function extractPagination(relArgs) {
7796
- if (!isPlainObject(relArgs)) return {};
7797
- const obj = relArgs;
7798
- const result = {};
7799
- if ("take" in obj && typeof obj.take === "number") {
7800
- result.take = obj.take;
7801
- }
7802
- if ("skip" in obj && typeof obj.skip === "number" && obj.skip > 0) {
7803
- result.skip = obj.skip;
7804
- }
7805
- return result;
7806
- }
7807
- function buildWhereInSegment(name, relArgs, field, relModel) {
7808
- const keys = resolveRelationKeys(field, "whereIn");
7809
- if (keys.childKeys.length !== 1) return null;
7810
- const isList = isListField2(field);
7811
- const pagination = isList ? extractPagination(relArgs) : {};
7812
- return {
7813
- relationName: name,
7814
- relArgs,
7815
- childModelName: relModel.name,
7816
- fkFieldName: keys.childKeys[0],
7817
- parentKeyFieldName: keys.parentKeys[0],
7818
- isList,
7819
- perParentTake: pagination.take,
7820
- perParentSkip: pagination.skip
7821
- };
7822
- }
7823
- function deepClone(obj) {
7824
- if (obj === null || typeof obj !== "object") return obj;
7825
- if (obj instanceof Date) return new Date(obj.getTime());
7826
- if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);
7827
- if (Array.isArray(obj)) return obj.map((item) => deepClone(item));
7828
- const cloned = {};
7829
- for (const key in obj) {
7830
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
7831
- cloned[key] = deepClone(obj[key]);
7832
- }
7833
- }
7834
- return cloned;
7835
- }
7836
- function removeRelationsFromArgs(args, names) {
7837
- if (!args) return args;
7838
- const filtered = deepClone(args);
7839
- if (filtered.include && isPlainObject(filtered.include)) {
7840
- for (const name of names) {
7841
- delete filtered.include[name];
7842
- }
7843
- if (Object.keys(filtered.include).length === 0) {
7844
- delete filtered.include;
7845
- }
7846
- }
7847
- if (filtered.select && isPlainObject(filtered.select)) {
7848
- for (const name of names) {
7849
- delete filtered.select[name];
7850
- }
7851
- }
7852
- return filtered;
7853
- }
7854
- function ensureParentKeysInSelect(args, segments) {
7855
- if (!(args == null ? void 0 : args.select)) return { args, injectedKeys: [] };
7856
- const injected = [];
7857
- const newSelect = __spreadValues({}, args.select);
7858
- for (const seg of segments) {
7859
- if (!newSelect[seg.parentKeyFieldName]) {
7860
- newSelect[seg.parentKeyFieldName] = true;
7861
- injected.push(seg.parentKeyFieldName);
7862
- }
7863
- }
7864
- if (injected.length === 0) return { args, injectedKeys: [] };
7865
- return { args: __spreadProps(__spreadValues({}, args), { select: newSelect }), injectedKeys: injected };
7866
- }
7867
- function extractIncludeSpec3(args, model) {
7868
- const spec = {};
7869
- const entries = extractRelationEntries(args, model);
7870
- for (const e of entries) {
7871
- if (e.value !== false) {
7872
- spec[e.name] = e.value;
7873
- }
7874
- }
7875
- return spec;
7876
- }
7877
- function planQueryStrategy(params) {
7878
- const { model, args, allModels, dialect, debug } = params;
7879
- const emptyPlan = {
7880
- filteredArgs: args,
7881
- originalArgs: args,
7882
- whereInSegments: [],
7883
- injectedParentKeys: []
7884
- };
7885
- const entries = extractRelationEntries(args, model);
7886
- if (entries.length === 0) {
7887
- return emptyPlan;
7888
- }
7889
- if (dialect === "postgres") {
7890
- const includeSpec = extractIncludeSpec3(args, model);
7891
- if (Object.keys(includeSpec).length > 0) {
7892
- isPlainObject(args) && "take" in args && args.take != null;
7893
- const takeValue = isPlainObject(args) && typeof args.take === "number" ? args.take : null;
7894
- const canFlatJoin = canUseFlatJoinForAll(includeSpec, model, allModels);
7895
- canUseLateralJoin(includeSpec, model, allModels);
7896
- hasChildPaginationAnywhere(
7897
- includeSpec,
7898
- model,
7899
- allModels
7900
- );
7901
- const strategy = pickIncludeStrategy({
7902
- includeSpec,
7903
- model,
7904
- schemas: allModels,
7905
- method: params.method,
7906
- takeValue,
7907
- canFlatJoin,
7908
- debug
7909
- });
7910
- if (debug) {
7911
- console.log(` [planner] ${model.name}: strategy=${strategy}`);
7912
- }
7913
- if (strategy !== "where-in") {
7914
- return emptyPlan;
7915
- }
7916
- }
7917
- }
7918
- const whereInSegments = [];
7919
- const toRemove = /* @__PURE__ */ new Set();
7920
- for (const entry of entries) {
7921
- const resolved = resolveRelation(model, entry.name, allModels);
7922
- if (!resolved) continue;
7923
- const segment = buildWhereInSegment(
7924
- entry.name,
7925
- entry.value,
7926
- resolved.field,
7927
- resolved.relModel
7928
- );
7929
- if (segment) {
7930
- whereInSegments.push(segment);
7931
- toRemove.add(entry.name);
7932
- }
7933
- }
7934
- if (toRemove.size === 0) {
7935
- return emptyPlan;
7936
- }
7937
- const filteredArgs = removeRelationsFromArgs(args, toRemove);
7938
- const { args: finalArgs, injectedKeys } = ensureParentKeysInSelect(
7939
- filteredArgs,
7940
- whereInSegments
7941
- );
7942
- return {
7943
- filteredArgs: finalArgs,
7944
- originalArgs: args,
7945
- whereInSegments,
7946
- injectedParentKeys: injectedKeys
7947
- };
7948
- }
7949
-
7950
7997
  // src/builder/shared/where-in-utils.ts
7951
7998
  var MAX_RECURSIVE_DEPTH = 10;
7952
7999
  function buildParentKeyIndex(parentRows, parentKeyFieldName) {
@@ -9296,18 +9343,9 @@ function executePostgresQuery(opts) {
9296
9343
  return results;
9297
9344
  });
9298
9345
  }
9299
- function executeSqliteQuery(client, sql, params, method, requiresReduction, includeSpec, model, allModels) {
9346
+ function executeSqliteQuery(client, sql, params, method) {
9300
9347
  const normalizedParams = normalizeParams(params);
9301
9348
  const shouldTransform = method === "groupBy" || method === "aggregate" || method === "count";
9302
- if (requiresReduction && includeSpec) {
9303
- const config = buildReducerConfig(model, includeSpec, allModels);
9304
- const stmt2 = getOrPrepareStatement(client, sql);
9305
- const useGet2 = shouldSqliteUseGet(method);
9306
- const rawResults2 = useGet2 ? stmt2.get(...normalizedParams) : stmt2.all(...normalizedParams);
9307
- const results2 = Array.isArray(rawResults2) ? rawResults2 : [rawResults2];
9308
- const transformed = shouldTransform ? results2.map(transformAggregateRow) : results2;
9309
- return reduceFlatRows(transformed, config);
9310
- }
9311
9349
  const stmt = getOrPrepareStatement(client, sql);
9312
9350
  const useGet = shouldSqliteUseGet(method);
9313
9351
  const rawResults = useGet ? stmt.get(...normalizedParams) : stmt.all(...normalizedParams);
@@ -9331,6 +9369,6 @@ function generateSQL2(directive) {
9331
9369
  return generateSQL(directive);
9332
9370
  }
9333
9371
 
9334
- export { buildBatchCountSql, buildBatchSql, buildLateralReducerConfig, buildReducerConfig, buildSQL, countIncludeDepth, createProgressiveReducer, createStreamingReducer, createTransactionExecutor, executePostgresQuery, executeRaw, executeSqliteQuery, executeWhereInSegments, executeWhereInSegmentsStreaming, executeWithPreFetchedParents, extractCountValue, generateSQL2 as generateSQL, getOrPrepareStatement, getPrimaryKeyField, getRelationStats, getRowTransformer, normalizeParams, normalizeValue, parseBatchCountResults, parseBatchResults, planQueryStrategy, reduceFlatRows, reduceLateralRows, setJsonRowFactor, setRelationStats, setRoundtripRowEquivalent, shouldSqliteUseGet, transformAggregateRow, transformQueryResults };
9372
+ export { buildBatchCountSql, buildBatchSql, buildLateralReducerConfig, buildReducerConfig, buildSQL, countIncludeDepth, createProgressiveReducer, createStreamingReducer, createTransactionExecutor, detectSqliteDateMode, executePostgresQuery, executeRaw, executeSqliteQuery, executeWhereInSegments, executeWhereInSegmentsStreaming, executeWithPreFetchedParents, extractCountValue, generateSQL2 as generateSQL, getOrPrepareStatement, getPrimaryKeyField, getRelationStats, getRowTransformer, normalizeParams, normalizeValue, parseBatchCountResults, parseBatchResults, planQueryStrategy, reduceFlatRows, reduceLateralRows, setJsonRowFactor, setNormalizeDateMode, setRelationStats, setRoundtripRowEquivalent, shouldSqliteUseGet, transformAggregateRow, transformQueryResults };
9335
9373
  //# sourceMappingURL=index.js.map
9336
9374
  //# sourceMappingURL=index.js.map