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