bun-query-builder 0.2.28 → 0.2.29

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/src/index.js CHANGED
@@ -12554,6 +12554,30 @@ var init_pivot = __esm(() => {
12554
12554
  init_config();
12555
12555
  });
12556
12556
 
12557
+ // src/sql-fragments.ts
12558
+ function renderWhereTerms(terms) {
12559
+ if (terms.length === 0)
12560
+ return "";
12561
+ const runs = [];
12562
+ for (const term of terms) {
12563
+ if (term.conn === "OR" && runs.length > 0)
12564
+ runs[runs.length - 1].push(term);
12565
+ else
12566
+ runs.push([term]);
12567
+ }
12568
+ return runs.map((run, i) => {
12569
+ const body = run.map((t) => t.sql).join(" OR ");
12570
+ const piece = run.length > 1 && runs.length > 1 ? `(${body})` : body;
12571
+ return i === 0 ? piece : `${run[0].conn} ${piece}`;
12572
+ }).join(" ");
12573
+ }
12574
+ function renderInPredicate(column, values, negated, placeholders) {
12575
+ if (values.length === 0)
12576
+ return negated ? TRUE_PREDICATE : FALSE_PREDICATE;
12577
+ return `${column} ${negated ? "NOT IN" : "IN"} (${placeholders})`;
12578
+ }
12579
+ var FALSE_PREDICATE = "1 = 0", TRUE_PREDICATE = "1 = 1";
12580
+
12557
12581
  // src/client.ts
12558
12582
  function isRawExpression(expr) {
12559
12583
  return typeof expr === "object" && expr !== null && "raw" in expr && typeof expr.raw === "string";
@@ -12625,11 +12649,6 @@ function renderSelectColumn(col) {
12625
12649
  }
12626
12650
  throw new TypeError(`[query-builder] select(): unsupported column ${String(col)} \u2014 pass a column name, a string[], or a SQL fragment (e.g. sql\`count(*) as c\`)`);
12627
12651
  }
12628
- function renderInPredicate(column, values, negated, placeholders) {
12629
- if (values.length === 0)
12630
- return negated ? TRUE_PREDICATE : FALSE_PREDICATE;
12631
- return `${column} ${negated ? "NOT IN" : "IN"} (${placeholders})`;
12632
- }
12633
12652
  function validateIdentifier(name, context) {
12634
12653
  if (!SQL_PATTERNS.IDENTIFIER.test(name)) {
12635
12654
  const contextMsg = context ? ` in ${context}` : "";
@@ -13106,20 +13125,125 @@ function createQueryBuilder(state) {
13106
13125
  function makeSelect(table, columns) {
13107
13126
  const sql = _sql;
13108
13127
  let text = columns && columns.length > 0 ? `SELECT ${columns.join(", ")} FROM ${String(table)}` : `SELECT * FROM ${String(table)}`;
13128
+ const whereTerms = [];
13129
+ const whereParams = [];
13130
+ let whereTail = false;
13109
13131
  let built = null;
13110
13132
  const ensureBuilt = () => {
13111
13133
  if (built === null) {
13112
- const finalText = reorderSelectClauses(text);
13134
+ const finalText = reorderSelectClauses(currentSql());
13113
13135
  built = whereParams.length > 0 ? _sql.unsafe(finalText, whereParams) : _sql.unsafe(finalText);
13114
13136
  }
13115
13137
  return built;
13116
13138
  };
13139
+ const pushWhere = (conn, clause) => {
13140
+ whereTerms.push({ conn, sql: clause });
13141
+ built = null;
13142
+ };
13117
13143
  const addWhereText = (prefix, clause) => {
13118
- const hasWhere = SQL_PATTERNS.WHERE.test(text);
13119
- const p = !hasWhere ? "WHERE" : prefix === "WHERE" ? "AND" : prefix;
13120
- text = `${text} ${p} ${clause}`;
13144
+ pushWhere(prefix === "OR" ? "OR" : "AND", clause);
13145
+ };
13146
+ const TAIL_CLAUSE = /\(|\)|\b(?:GROUP\s+BY|HAVING|ORDER\s+BY|LIMIT|OFFSET|WINDOW|UNION|INTERSECT|EXCEPT|FOR\s+UPDATE|FOR\s+SHARE|LOCK\s+IN\s+SHARE\s+MODE)\b/gi;
13147
+ const firstTailIndex = (s) => {
13148
+ TAIL_CLAUSE.lastIndex = 0;
13149
+ let depth = 0;
13150
+ let m;
13151
+ while (m = TAIL_CLAUSE.exec(s)) {
13152
+ if (m[0] === "(") {
13153
+ depth++;
13154
+ } else if (m[0] === ")") {
13155
+ depth = Math.max(0, depth - 1);
13156
+ } else if (depth === 0) {
13157
+ return m.index;
13158
+ }
13159
+ }
13160
+ return -1;
13161
+ };
13162
+ const currentSql = () => {
13163
+ const body = renderWhereTerms(whereTerms);
13164
+ if (!body)
13165
+ return text;
13166
+ if (whereTail) {
13167
+ const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
13168
+ return `${text} ${kw} ${body}`;
13169
+ }
13170
+ const cut = firstTailIndex(text);
13171
+ return cut >= 0 ? `${text.slice(0, cut)}WHERE ${body} ${text.slice(cut)}` : `${text} WHERE ${body}`;
13172
+ };
13173
+ const addWhereGroup = (conn, cb) => {
13174
+ const sub = makeSelect(table);
13175
+ cb(sub);
13176
+ const st = sub.__whereState?.();
13177
+ if (!st || !st.body) {
13178
+ throw new TypeError("[query-builder] whereGroup(callback): the callback added no conditions. " + "Add at least one where()/orWhere() to the builder it receives.");
13179
+ }
13180
+ const offset = whereParams.length;
13181
+ const body = offset > 0 && config5.dialect === "postgres" ? st.body.replace(/\$(\d+)/g, (_m, n) => `$${Number(n) + offset}`) : st.body;
13182
+ whereParams.push(...st.params);
13183
+ pushWhere(conn, `(${body})`);
13184
+ };
13185
+ const addBooleanWhere = (self, conn, label, expr, op, value) => {
13186
+ if (typeof expr === "string" && op !== undefined) {
13187
+ validateIdentifier(String(expr), `${label}(column)`);
13188
+ assertSafeWhereOperator(op, `${label}(operator)`);
13189
+ const paramIndex = whereParams.length + 1;
13190
+ whereParams.push(value);
13191
+ pushWhere(conn, `${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
13192
+ return self;
13193
+ }
13194
+ if (Array.isArray(expr)) {
13195
+ const [col, rawOp, val] = expr;
13196
+ const colName = String(col);
13197
+ validateIdentifier(colName, `${label}(column)`);
13198
+ const operator = assertSafeWhereOperator(rawOp, `${label}(operator)`);
13199
+ if (operator === "in" || operator === "not in") {
13200
+ const values = Array.isArray(val) ? val : [val];
13201
+ const placeholders = getPlaceholders(values.length, whereParams.length + 1);
13202
+ const clause = renderInPredicate(colName, values, operator === "not in", placeholders);
13203
+ whereParams.push(...values);
13204
+ pushWhere(conn, clause);
13205
+ } else {
13206
+ const paramIndex = whereParams.length + 1;
13207
+ whereParams.push(val);
13208
+ pushWhere(conn, `${colName} ${operator} ${getPlaceholder(paramIndex)}`);
13209
+ }
13210
+ return self;
13211
+ }
13212
+ if (typeof expr === "function") {
13213
+ addWhereGroup(conn, expr);
13214
+ return self;
13215
+ }
13216
+ if (expr && typeof expr === "object" && !("raw" in expr)) {
13217
+ const conditions = [];
13218
+ for (const key of Object.keys(expr)) {
13219
+ validateIdentifier(key, `${label}(column)`);
13220
+ const v = expr[key];
13221
+ if (Array.isArray(v)) {
13222
+ const placeholders = getPlaceholders(v.length, whereParams.length + 1);
13223
+ conditions.push(renderInPredicate(key, v, false, placeholders));
13224
+ whereParams.push(...v);
13225
+ } else {
13226
+ const paramIndex = whereParams.length + 1;
13227
+ conditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
13228
+ whereParams.push(v);
13229
+ }
13230
+ }
13231
+ if (conditions.length > 0)
13232
+ pushWhere(conn, conditions.length > 1 ? `(${conditions.join(" AND ")})` : conditions[0]);
13233
+ return self;
13234
+ }
13235
+ if (expr && typeof expr.raw !== "undefined") {
13236
+ pushWhere(conn, expr.raw);
13237
+ return self;
13238
+ }
13239
+ return self;
13121
13240
  };
13122
13241
  const appendSetOp = (op, other) => {
13242
+ if (whereTerms.length > 0) {
13243
+ text = currentSql();
13244
+ whereTerms.length = 0;
13245
+ }
13246
+ whereTail = true;
13123
13247
  const st = other.__rawState?.();
13124
13248
  if (st) {
13125
13249
  const offset = whereParams.length;
@@ -13209,8 +13333,6 @@ function createQueryBuilder(state) {
13209
13333
  text = `${text} LEFT JOIN ${resolved.pivotTable} ON ${resolved.pivotTable}.${resolved.fkParent} = ${parentTable}.${parentPk}`;
13210
13334
  joinedTables.add(resolved.pivotTable);
13211
13335
  };
13212
- const whereConditions = [];
13213
- const whereParams = [];
13214
13336
  const addToSelectClause = (columnsToAdd) => {
13215
13337
  if (SQL_PATTERNS.SELECT_STAR.test(text)) {
13216
13338
  text = text.replace(SQL_PATTERNS.SELECT_STAR, `SELECT *, ${columnsToAdd}`);
@@ -13834,10 +13956,7 @@ function createQueryBuilder(state) {
13834
13956
  } else {
13835
13957
  throw new Error(`[query-builder] Unsupported relationship type '${type}' for whereHas`);
13836
13958
  }
13837
- built = sql`${ensureBuilt()} WHERE EXISTS (${sql([subquerySQL])})`;
13838
- try {
13839
- addWhereText("WHERE", `EXISTS (${subquerySQL})`);
13840
- } catch {}
13959
+ addWhereText("WHERE", `EXISTS (${subquerySQL})`);
13841
13960
  return this;
13842
13961
  },
13843
13962
  whereDoesntHave(relation, callback) {
@@ -13870,10 +13989,7 @@ function createQueryBuilder(state) {
13870
13989
  } else {
13871
13990
  throw new Error(`[query-builder] Unsupported relationship type '${type}' for whereDoesntHave`);
13872
13991
  }
13873
- built = sql`${ensureBuilt()} WHERE NOT EXISTS (${sql([subquerySQL])})`;
13874
- try {
13875
- addWhereText("WHERE", `NOT EXISTS (${subquerySQL})`);
13876
- } catch {}
13992
+ addWhereText("WHERE", `NOT EXISTS (${subquerySQL})`);
13877
13993
  return this;
13878
13994
  },
13879
13995
  has(relation) {
@@ -13904,10 +14020,7 @@ function createQueryBuilder(state) {
13904
14020
  } else {
13905
14021
  throw new Error(`[query-builder] Unsupported relationship type '${type}' for has`);
13906
14022
  }
13907
- built = sql`${ensureBuilt()} WHERE EXISTS (${sql([subquerySQL])})`;
13908
- try {
13909
- addWhereText("WHERE", `EXISTS (${subquerySQL})`);
13910
- } catch {}
14023
+ addWhereText("WHERE", `EXISTS (${subquerySQL})`);
13911
14024
  return this;
13912
14025
  },
13913
14026
  doesntHave(relation) {
@@ -13938,10 +14051,7 @@ function createQueryBuilder(state) {
13938
14051
  } else {
13939
14052
  throw new Error(`[query-builder] Unsupported relationship type '${type}' for doesntHave`);
13940
14053
  }
13941
- built = sql`${ensureBuilt()} WHERE NOT EXISTS (${sql([subquerySQL])})`;
13942
- try {
13943
- addWhereText("WHERE", `NOT EXISTS (${subquerySQL})`);
13944
- } catch {}
14054
+ addWhereText("WHERE", `NOT EXISTS (${subquerySQL})`);
13945
14055
  return this;
13946
14056
  },
13947
14057
  withCount(...relations) {
@@ -14024,17 +14134,14 @@ function createQueryBuilder(state) {
14024
14134
  const val = value === undefined ? opOrValue : value;
14025
14135
  const paramIndex = whereParams.length + 1;
14026
14136
  const clause = `${resolved.pivotTable}.${column} ${op} ${getPlaceholder(paramIndex)}`;
14027
- whereConditions.push(clause);
14028
14137
  whereParams.push(val);
14029
- const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14030
- text = `${text} ${kw} ${clause}`;
14031
- built = null;
14138
+ pushWhere("AND", clause);
14032
14139
  if (resolved.hasConfig)
14033
14140
  pivotConfigRelations.add(relation);
14034
14141
  return this;
14035
14142
  },
14036
14143
  wherePivotIn(relation, column, values) {
14037
- if (!meta || !Array.isArray(values) || values.length === 0)
14144
+ if (!meta || !Array.isArray(values))
14038
14145
  return this;
14039
14146
  const resolved = resolvePivotLocal(relation);
14040
14147
  if (!resolved) {
@@ -14044,12 +14151,9 @@ function createQueryBuilder(state) {
14044
14151
  validateIdentifier(column, "wherePivotIn (column)");
14045
14152
  ensurePivotJoined(resolved);
14046
14153
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14047
- const clause = `${resolved.pivotTable}.${column} IN (${placeholders})`;
14048
- whereConditions.push(clause);
14154
+ const clause = renderInPredicate(`${resolved.pivotTable}.${column}`, values, false, placeholders);
14049
14155
  whereParams.push(...values);
14050
- const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14051
- text = `${text} ${kw} ${clause}`;
14052
- built = null;
14156
+ pushWhere("AND", clause);
14053
14157
  if (resolved.hasConfig)
14054
14158
  pivotConfigRelations.add(relation);
14055
14159
  return this;
@@ -14066,11 +14170,8 @@ function createQueryBuilder(state) {
14066
14170
  ensurePivotJoined(resolved);
14067
14171
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14068
14172
  const clause = `${resolved.pivotTable}.${column} NOT IN (${placeholders})`;
14069
- whereConditions.push(clause);
14070
14173
  whereParams.push(...values);
14071
- const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14072
- text = `${text} ${kw} ${clause}`;
14073
- built = null;
14174
+ pushWhere("AND", clause);
14074
14175
  if (resolved.hasConfig)
14075
14176
  pivotConfigRelations.add(relation);
14076
14177
  return this;
@@ -14085,11 +14186,7 @@ function createQueryBuilder(state) {
14085
14186
  validateIdentifier(resolved.pivotTable, "wherePivotNull (pivot table)");
14086
14187
  validateIdentifier(column, "wherePivotNull (column)");
14087
14188
  ensurePivotJoined(resolved);
14088
- const clause = `${resolved.pivotTable}.${column} IS NULL`;
14089
- whereConditions.push(clause);
14090
- const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14091
- text = `${text} ${kw} ${clause}`;
14092
- built = null;
14189
+ pushWhere("AND", `${resolved.pivotTable}.${column} IS NULL`);
14093
14190
  if (resolved.hasConfig)
14094
14191
  pivotConfigRelations.add(relation);
14095
14192
  return this;
@@ -14104,17 +14201,12 @@ function createQueryBuilder(state) {
14104
14201
  validateIdentifier(resolved.pivotTable, "wherePivotNotNull (pivot table)");
14105
14202
  validateIdentifier(column, "wherePivotNotNull (column)");
14106
14203
  ensurePivotJoined(resolved);
14107
- const clause = `${resolved.pivotTable}.${column} IS NOT NULL`;
14108
- whereConditions.push(clause);
14109
- const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14110
- text = `${text} ${kw} ${clause}`;
14111
- built = null;
14204
+ pushWhere("AND", `${resolved.pivotTable}.${column} IS NOT NULL`);
14112
14205
  if (resolved.hasConfig)
14113
14206
  pivotConfigRelations.add(relation);
14114
14207
  return this;
14115
14208
  },
14116
14209
  where(expr, op, value) {
14117
- const getWhereKeyword = () => SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14118
14210
  if (typeof expr === "string" && op !== undefined) {
14119
14211
  validateIdentifier(String(expr), "where(column)");
14120
14212
  assertSafeWhereOperator(op, "where(operator)");
@@ -14122,18 +14214,14 @@ function createQueryBuilder(state) {
14122
14214
  if (operator === "in" || operator === "not in") {
14123
14215
  const values = Array.isArray(value) ? value : [value];
14124
14216
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14125
- const clause = `${String(expr)} ${operator.toUpperCase()} (${placeholders})`;
14126
- whereConditions.push(clause);
14217
+ const clause = renderInPredicate(String(expr), values, operator === "not in", placeholders);
14127
14218
  whereParams.push(...values);
14128
- text = `${text} ${getWhereKeyword()} ${clause}`;
14129
- built = null;
14219
+ pushWhere("AND", clause);
14130
14220
  return this;
14131
14221
  }
14132
14222
  const paramIndex = whereParams.length + 1;
14133
- whereConditions.push(`${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
14134
14223
  whereParams.push(value);
14135
- text = `${text} ${getWhereKeyword()} ${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`;
14136
- built = null;
14224
+ pushWhere("AND", `${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
14137
14225
  return this;
14138
14226
  }
14139
14227
  if (Array.isArray(expr)) {
@@ -14144,16 +14232,13 @@ function createQueryBuilder(state) {
14144
14232
  if (operator === "in" || operator === "not in") {
14145
14233
  const values = Array.isArray(val) ? val : [val];
14146
14234
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14147
- whereConditions.push(`${colName} ${operator.toUpperCase()} (${placeholders})`);
14235
+ const clause = renderInPredicate(colName, values, operator === "not in", placeholders);
14148
14236
  whereParams.push(...values);
14149
- text = `${text} ${getWhereKeyword()} ${colName} ${operator.toUpperCase()} (${placeholders})`;
14150
- built = null;
14237
+ pushWhere("AND", clause);
14151
14238
  } else {
14152
14239
  const paramIndex = whereParams.length + 1;
14153
- whereConditions.push(`${colName} ${operator} ${getPlaceholder(paramIndex)}`);
14154
14240
  whereParams.push(val);
14155
- text = `${text} ${getWhereKeyword()} ${colName} ${operator} ${getPlaceholder(paramIndex)}`;
14156
- built = null;
14241
+ pushWhere("AND", `${colName} ${operator} ${getPlaceholder(paramIndex)}`);
14157
14242
  }
14158
14243
  return this;
14159
14244
  }
@@ -14166,30 +14251,25 @@ function createQueryBuilder(state) {
14166
14251
  const value2 = whereObject[key];
14167
14252
  if (Array.isArray(value2)) {
14168
14253
  const placeholders = getPlaceholders(value2.length, whereParams.length + 1);
14169
- conditions.push(`${key} IN (${placeholders})`);
14170
- whereConditions.push(`${key} IN (${placeholders})`);
14254
+ conditions.push(renderInPredicate(key, value2, false, placeholders));
14171
14255
  whereParams.push(...value2);
14172
14256
  } else {
14173
14257
  const paramIndex = whereParams.length + 1;
14174
14258
  conditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
14175
- whereConditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
14176
14259
  whereParams.push(value2);
14177
14260
  }
14178
14261
  }
14179
- if (conditions.length > 0) {
14180
- text = `${text} ${getWhereKeyword()} ${conditions.join(" AND ")}`;
14181
- built = null;
14182
- }
14262
+ if (conditions.length > 0)
14263
+ pushWhere("AND", conditions.length > 1 ? `(${conditions.join(" AND ")})` : conditions[0]);
14183
14264
  return this;
14184
14265
  }
14185
14266
  if (isRawExpression(expr)) {
14186
- whereConditions.push(expr.raw);
14187
- text = `${text} ${getWhereKeyword()} ${expr.raw}`;
14188
- built = null;
14267
+ pushWhere("AND", expr.raw);
14189
14268
  return this;
14190
14269
  }
14191
14270
  if (typeof expr === "function") {
14192
- throw new TypeError("where(callback) is not supported. This builder has no expression callback, and " + "ignoring one silently would leave the query matching every row the filter was " + "meant to exclude. Use whereNested(subquery), whereAny(...), or the orWhere* " + "helpers to build a grouped condition.");
14271
+ addWhereGroup("AND", expr);
14272
+ return this;
14193
14273
  }
14194
14274
  if (expr === undefined || expr === null) {
14195
14275
  throw new TypeError("where() was called with no condition.");
@@ -14201,61 +14281,83 @@ function createQueryBuilder(state) {
14201
14281
  },
14202
14282
  whereNull(column) {
14203
14283
  validateIdentifier(String(column), "whereNull(column)");
14204
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14205
- text = `${text} ${keyword} ${String(column)} IS NULL`;
14206
- built = null;
14284
+ pushWhere("AND", `${String(column)} IS NULL`);
14207
14285
  return this;
14208
14286
  },
14209
14287
  whereNotNull(column) {
14210
14288
  validateIdentifier(String(column), "whereNotNull(column)");
14211
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14212
- text = `${text} ${keyword} ${String(column)} IS NOT NULL`;
14213
- built = null;
14289
+ pushWhere("AND", `${String(column)} IS NOT NULL`);
14290
+ return this;
14291
+ },
14292
+ orWhereNull(column) {
14293
+ validateIdentifier(String(column), "orWhereNull(column)");
14294
+ pushWhere("OR", `${String(column)} IS NULL`);
14295
+ return this;
14296
+ },
14297
+ orWhereNotNull(column) {
14298
+ validateIdentifier(String(column), "orWhereNotNull(column)");
14299
+ pushWhere("OR", `${String(column)} IS NOT NULL`);
14214
14300
  return this;
14215
14301
  },
14216
14302
  whereBetween(column, start, end) {
14217
14303
  validateIdentifier(String(column), "whereBetween(column)");
14218
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14219
14304
  const i = whereParams.length + 1;
14220
- text = `${text} ${keyword} ${String(column)} BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`;
14221
14305
  whereParams.push(start, end);
14222
- built = null;
14306
+ pushWhere("AND", `${String(column)} BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`);
14307
+ return this;
14308
+ },
14309
+ orWhereBetween(column, start, end) {
14310
+ validateIdentifier(String(column), "orWhereBetween(column)");
14311
+ const i = whereParams.length + 1;
14312
+ whereParams.push(start, end);
14313
+ pushWhere("OR", `${String(column)} BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`);
14223
14314
  return this;
14224
14315
  },
14225
14316
  whereExists(subquery) {
14226
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14227
- text = `${text} ${keyword} EXISTS (${subquery.toSQL()})`;
14228
- built = null;
14317
+ pushWhere("AND", `EXISTS (${subquery.toSQL()})`);
14318
+ return this;
14319
+ },
14320
+ orWhereExists(subquery) {
14321
+ pushWhere("OR", `EXISTS (${subquery.toSQL()})`);
14322
+ return this;
14323
+ },
14324
+ whereGroup(cb) {
14325
+ addWhereGroup("AND", cb);
14326
+ return this;
14327
+ },
14328
+ orWhereGroup(cb) {
14329
+ addWhereGroup("OR", cb);
14229
14330
  return this;
14230
14331
  },
14332
+ __whereState() {
14333
+ return { body: renderWhereTerms(whereTerms), params: [...whereParams] };
14334
+ },
14231
14335
  whereJsonContains(column, json) {
14232
14336
  validateIdentifier(String(column), "whereJsonContains(column)");
14233
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14234
14337
  const dialect = config5.dialect;
14235
14338
  const idx = whereParams.length + 1;
14236
14339
  if (dialect === "postgres") {
14237
14340
  if (config5.sql?.jsonContainsMode === "function")
14238
- text += ` ${keyword} jsonb_contains(${column}, ${getPlaceholder(idx)})`;
14341
+ pushWhere("AND", `jsonb_contains(${column}, ${getPlaceholder(idx)})`);
14239
14342
  else
14240
- text += ` ${keyword} ${column} @> ${getPlaceholder(idx)}`;
14343
+ pushWhere("AND", `${column} @> ${getPlaceholder(idx)}`);
14241
14344
  whereParams.push(JSON.stringify(json));
14242
14345
  } else if (isMysqlLike(dialect)) {
14243
- text += ` ${keyword} JSON_CONTAINS(${column}, ${getPlaceholder(idx)})`;
14346
+ pushWhere("AND", `JSON_CONTAINS(${column}, ${getPlaceholder(idx)})`);
14244
14347
  whereParams.push(JSON.stringify(json));
14245
14348
  } else {
14246
14349
  if (Array.isArray(json)) {
14247
14350
  const conds = json.map((_, i) => `EXISTS (SELECT 1 FROM json_each(${column}) WHERE json_each.value = ${getPlaceholder(idx + i)})`);
14248
- text += ` ${keyword} (${conds.join(" AND ")})`;
14351
+ pushWhere("AND", `(${conds.join(" AND ")})`);
14249
14352
  for (const v of json)
14250
14353
  whereParams.push(v);
14251
14354
  } else if (json !== null && typeof json === "object") {
14252
14355
  throw new Error("[query-builder] whereJsonContains: object containment is not supported on SQLite \u2014 pass a scalar or array, or use whereJsonPath.");
14253
14356
  } else {
14254
- text += ` ${keyword} EXISTS (SELECT 1 FROM json_each(${column}) WHERE json_each.value = ${getPlaceholder(idx)})`;
14357
+ pushWhere("AND", `EXISTS (SELECT 1 FROM json_each(${column}) WHERE json_each.value = ${getPlaceholder(idx)})`);
14255
14358
  whereParams.push(json);
14256
14359
  }
14257
14360
  }
14258
- built = null;
14259
14361
  return this;
14260
14362
  },
14261
14363
  whereJsonPath(path, op, value) {
@@ -14265,17 +14367,14 @@ function createQueryBuilder(state) {
14265
14367
  if (!/^[A-Za-z0-9_.[\]$'\->* ,]+$/.test(path))
14266
14368
  throw new TypeError(`[query-builder] whereJsonPath(path): refusing to use '${path}' \u2014 contains characters outside the allowed JSON-path set`);
14267
14369
  const dialect = config5.dialect;
14268
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14269
14370
  const idx = whereParams.length + 1;
14270
- if (dialect === "postgres") {
14271
- text += ` ${keyword} ${path} ${op} ${getPlaceholder(idx)}`;
14272
- } else if (isMysqlLike(dialect)) {
14273
- text += ` ${keyword} JSON_EXTRACT(${path}) ${op} ${getPlaceholder(idx)}`;
14274
- } else {
14275
- text += ` ${keyword} json_extract(${path}) ${op} ${getPlaceholder(idx)}`;
14276
- }
14371
+ if (dialect === "postgres")
14372
+ pushWhere("AND", `${path} ${op} ${getPlaceholder(idx)}`);
14373
+ else if (isMysqlLike(dialect))
14374
+ pushWhere("AND", `JSON_EXTRACT(${path}) ${op} ${getPlaceholder(idx)}`);
14375
+ else
14376
+ pushWhere("AND", `json_extract(${path}) ${op} ${getPlaceholder(idx)}`);
14277
14377
  whereParams.push(value);
14278
- built = null;
14279
14378
  return this;
14280
14379
  },
14281
14380
  whereLike(column, pattern, caseSensitive = false) {
@@ -14348,51 +14447,41 @@ function createQueryBuilder(state) {
14348
14447
  },
14349
14448
  whereAny(cols, op, value) {
14350
14449
  if (cols.length === 0) {
14351
- const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14352
- text += ` ${kw} (${FALSE_PREDICATE})`;
14353
- built = null;
14450
+ pushWhere("AND", `(${FALSE_PREDICATE})`);
14354
14451
  return this;
14355
14452
  }
14356
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14357
14453
  const idx = whereParams.length + 1;
14358
14454
  const conds = cols.map((c, i) => `${c} ${op} ${getPlaceholder(idx + i)}`);
14359
- text += ` ${keyword} (${conds.join(" OR ")})`;
14360
14455
  for (let i = 0;i < cols.length; i++)
14361
14456
  whereParams.push(value);
14362
- built = null;
14457
+ pushWhere("AND", `(${conds.join(" OR ")})`);
14363
14458
  return this;
14364
14459
  },
14365
14460
  whereAll(cols, op, value) {
14366
14461
  if (cols.length === 0)
14367
14462
  return this;
14368
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14369
14463
  const idx = whereParams.length + 1;
14370
14464
  const conds = cols.map((c, i) => `${c} ${op} ${getPlaceholder(idx + i)}`);
14371
- text += ` ${keyword} (${conds.join(" AND ")})`;
14372
14465
  for (let i = 0;i < cols.length; i++)
14373
14466
  whereParams.push(value);
14374
- built = null;
14467
+ pushWhere("AND", `(${conds.join(" AND ")})`);
14375
14468
  return this;
14376
14469
  },
14377
14470
  whereNone(cols, op, value) {
14378
14471
  if (cols.length === 0)
14379
14472
  return this;
14380
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14381
14473
  const idx = whereParams.length + 1;
14382
14474
  const conds = cols.map((c, i) => `${c} ${op} ${getPlaceholder(idx + i)}`);
14383
- text += ` ${keyword} NOT (${conds.join(" OR ")})`;
14384
14475
  for (let i = 0;i < cols.length; i++)
14385
14476
  whereParams.push(value);
14386
- built = null;
14477
+ pushWhere("AND", `NOT (${conds.join(" OR ")})`);
14387
14478
  return this;
14388
14479
  },
14389
14480
  whereNotBetween(column, start, end) {
14390
14481
  validateIdentifier(String(column), "whereNotBetween(column)");
14391
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14392
14482
  const i = whereParams.length + 1;
14393
- text += ` ${keyword} ${column} NOT BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`;
14394
14483
  whereParams.push(start, end);
14395
- built = null;
14484
+ pushWhere("AND", `${column} NOT BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`);
14396
14485
  return this;
14397
14486
  },
14398
14487
  whereDate(column, op, date) {
@@ -14400,223 +14489,94 @@ function createQueryBuilder(state) {
14400
14489
  const dateString = date instanceof Date ? date.toISOString() : typeof date === "string" ? date : (() => {
14401
14490
  throw new TypeError(`[query-builder] whereDate(date): expected string or Date, got ${typeof date}`);
14402
14491
  })();
14403
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14404
14492
  const idx = whereParams.length + 1;
14405
- text += ` ${keyword} ${column} ${op} ${getPlaceholder(idx)}`;
14406
14493
  whereParams.push(dateString);
14407
- built = null;
14494
+ pushWhere("AND", `${column} ${op} ${getPlaceholder(idx)}`);
14408
14495
  return this;
14409
14496
  },
14410
14497
  whereRaw(fragment) {
14411
- const frag = renderRawFragment(fragment, "whereRaw(fragment)");
14412
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14413
- text += ` ${keyword} ${frag}`;
14414
- built = null;
14498
+ pushWhere("AND", renderRawFragment(fragment, "whereRaw(fragment)"));
14499
+ return this;
14500
+ },
14501
+ orWhereRaw(fragment) {
14502
+ pushWhere("OR", renderRawFragment(fragment, "orWhereRaw(fragment)"));
14415
14503
  return this;
14416
14504
  },
14417
14505
  whereColumn(left, op, right) {
14418
14506
  validateIdentifier(left, "whereColumn(left)");
14419
14507
  validateIdentifier(right, "whereColumn(right)");
14420
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14421
- text += ` ${keyword} ${left} ${op} ${right}`;
14422
- built = null;
14508
+ pushWhere("AND", `${left} ${op} ${right}`);
14423
14509
  return this;
14424
14510
  },
14425
14511
  orWhereColumn(left, op, right) {
14426
14512
  validateIdentifier(left, "orWhereColumn(left)");
14427
14513
  validateIdentifier(right, "orWhereColumn(right)");
14428
- text += ` OR ${left} ${op} ${right}`;
14429
- built = null;
14514
+ pushWhere("OR", `${left} ${op} ${right}`);
14430
14515
  return this;
14431
14516
  },
14432
14517
  whereIn(column, values) {
14433
14518
  validateIdentifier(String(column), "whereIn(column)");
14434
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14435
14519
  if (Array.isArray(values)) {
14436
14520
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14437
- text += ` ${keyword} ${renderInPredicate(column, values, false, placeholders)}`;
14521
+ const clause = renderInPredicate(column, values, false, placeholders);
14438
14522
  whereParams.push(...values);
14523
+ pushWhere("AND", clause);
14439
14524
  } else {
14440
- text += ` ${keyword} ${column} IN (${String(values.toSQL())})`;
14525
+ pushWhere("AND", `${column} IN (${String(values.toSQL())})`);
14441
14526
  }
14442
- built = null;
14443
14527
  return this;
14444
14528
  },
14445
14529
  orWhereIn(column, values) {
14446
14530
  validateIdentifier(String(column), "orWhereIn(column)");
14447
14531
  if (Array.isArray(values)) {
14448
14532
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14449
- text += ` OR ${renderInPredicate(column, values, false, placeholders)}`;
14533
+ const clause = renderInPredicate(column, values, false, placeholders);
14450
14534
  whereParams.push(...values);
14535
+ pushWhere("OR", clause);
14451
14536
  } else {
14452
- text += ` OR ${column} IN (${String(values.toSQL())})`;
14537
+ pushWhere("OR", `${column} IN (${String(values.toSQL())})`);
14453
14538
  }
14454
- built = null;
14455
14539
  return this;
14456
14540
  },
14457
14541
  whereNotIn(column, values) {
14458
14542
  validateIdentifier(String(column), "whereNotIn(column)");
14459
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14460
14543
  if (Array.isArray(values)) {
14461
14544
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14462
- text += ` ${keyword} ${renderInPredicate(column, values, true, placeholders)}`;
14545
+ const clause = renderInPredicate(column, values, true, placeholders);
14463
14546
  whereParams.push(...values);
14547
+ pushWhere("AND", clause);
14464
14548
  } else {
14465
- text += ` ${keyword} ${column} NOT IN (${String(values.toSQL())})`;
14549
+ pushWhere("AND", `${column} NOT IN (${String(values.toSQL())})`);
14466
14550
  }
14467
- built = null;
14468
14551
  return this;
14469
14552
  },
14470
14553
  orWhereNotIn(column, values) {
14471
14554
  validateIdentifier(String(column), "orWhereNotIn(column)");
14472
14555
  if (Array.isArray(values)) {
14473
14556
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14474
- text += ` OR ${renderInPredicate(column, values, true, placeholders)}`;
14557
+ const clause = renderInPredicate(column, values, true, placeholders);
14475
14558
  whereParams.push(...values);
14559
+ pushWhere("OR", clause);
14476
14560
  } else {
14477
- text += ` OR ${column} NOT IN (${String(values.toSQL())})`;
14561
+ pushWhere("OR", `${column} NOT IN (${String(values.toSQL())})`);
14478
14562
  }
14479
- built = null;
14480
14563
  return this;
14481
14564
  },
14482
14565
  whereNested(fragment) {
14483
- const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14484
14566
  const inner = fragment.toSQL ? String(fragment.toSQL()) : String(fragment);
14485
- text += ` ${keyword} (${inner})`;
14486
- built = null;
14567
+ pushWhere("AND", `(${inner})`);
14487
14568
  return this;
14488
14569
  },
14489
14570
  orWhereNested(fragment) {
14490
14571
  const inner = fragment.toSQL ? String(fragment.toSQL()) : String(fragment);
14491
- text += ` OR (${inner})`;
14492
- built = null;
14572
+ pushWhere("OR", `(${inner})`);
14493
14573
  return this;
14494
14574
  },
14495
14575
  andWhere(expr, op, value) {
14496
- if (typeof expr === "string" && op !== undefined) {
14497
- validateIdentifier(String(expr), "andWhere(column)");
14498
- assertSafeWhereOperator(op, "andWhere(operator)");
14499
- const paramIndex = whereParams.length + 1;
14500
- whereConditions.push(`${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
14501
- whereParams.push(value);
14502
- text = `${text} AND ${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`;
14503
- built = null;
14504
- return this;
14505
- }
14506
- if (Array.isArray(expr)) {
14507
- const [col, op2, val] = expr;
14508
- const colName = String(col);
14509
- validateIdentifier(colName, "andWhere(column)");
14510
- const operator = assertSafeWhereOperator(op2, "andWhere(operator)");
14511
- if (operator === "in" || operator === "not in") {
14512
- const values = Array.isArray(val) ? val : [val];
14513
- const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14514
- whereConditions.push(`${colName} ${operator.toUpperCase()} (${placeholders})`);
14515
- whereParams.push(...values);
14516
- text = `${text} AND ${colName} ${operator.toUpperCase()} (${placeholders})`;
14517
- built = null;
14518
- } else {
14519
- const paramIndex = whereParams.length + 1;
14520
- whereConditions.push(`${colName} ${operator} ${getPlaceholder(paramIndex)}`);
14521
- whereParams.push(val);
14522
- text = `${text} AND ${colName} ${operator} ${getPlaceholder(paramIndex)}`;
14523
- built = null;
14524
- }
14525
- return this;
14526
- }
14527
- if (expr && typeof expr === "object" && !("raw" in expr)) {
14528
- const keys = Object.keys(expr);
14529
- const conditions = [];
14530
- for (const key of keys) {
14531
- const value2 = expr[key];
14532
- if (Array.isArray(value2)) {
14533
- const placeholders = getPlaceholders(value2.length, whereParams.length + 1);
14534
- conditions.push(`${key} IN (${placeholders})`);
14535
- whereConditions.push(`${key} IN (${placeholders})`);
14536
- whereParams.push(...value2);
14537
- } else {
14538
- const paramIndex = whereParams.length + 1;
14539
- conditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
14540
- whereConditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
14541
- whereParams.push(value2);
14542
- }
14543
- }
14544
- if (conditions.length > 0) {
14545
- text = `${text} AND ${conditions.join(" AND ")}`;
14546
- built = null;
14547
- }
14548
- return this;
14549
- }
14550
- if (expr && typeof expr.raw !== "undefined") {
14551
- whereConditions.push(expr.raw);
14552
- text = `${text} AND ${expr.raw}`;
14553
- built = null;
14554
- return this;
14555
- }
14556
- return this;
14576
+ return addBooleanWhere(this, "AND", "andWhere", expr, op, value);
14557
14577
  },
14558
14578
  orWhere(expr, op, value) {
14559
- if (typeof expr === "string" && op !== undefined) {
14560
- validateIdentifier(String(expr), "orWhere(column)");
14561
- assertSafeWhereOperator(op, "orWhere(operator)");
14562
- const paramIndex = whereParams.length + 1;
14563
- whereConditions.push(`OR ${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
14564
- whereParams.push(value);
14565
- text = `${text} OR ${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`;
14566
- built = null;
14567
- return this;
14568
- }
14569
- if (Array.isArray(expr)) {
14570
- const [col, op2, val] = expr;
14571
- const colName = String(col);
14572
- validateIdentifier(colName, "orWhere(column)");
14573
- const operator = assertSafeWhereOperator(op2, "orWhere(operator)");
14574
- if (operator === "in" || operator === "not in") {
14575
- const values = Array.isArray(val) ? val : [val];
14576
- const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14577
- whereConditions.push(`OR ${colName} ${operator.toUpperCase()} (${placeholders})`);
14578
- whereParams.push(...values);
14579
- text = `${text} OR ${colName} ${operator.toUpperCase()} (${placeholders})`;
14580
- built = null;
14581
- } else {
14582
- const paramIndex = whereParams.length + 1;
14583
- whereConditions.push(`OR ${colName} ${operator} ${getPlaceholder(paramIndex)}`);
14584
- whereParams.push(val);
14585
- text = `${text} OR ${colName} ${operator} ${getPlaceholder(paramIndex)}`;
14586
- built = null;
14587
- }
14588
- return this;
14589
- }
14590
- if (expr && typeof expr === "object" && !("raw" in expr)) {
14591
- const keys = Object.keys(expr);
14592
- const conditions = [];
14593
- for (const key of keys) {
14594
- const value2 = expr[key];
14595
- if (Array.isArray(value2)) {
14596
- const placeholders = getPlaceholders(value2.length, whereParams.length + 1);
14597
- conditions.push(`${key} IN (${placeholders})`);
14598
- whereConditions.push(`OR ${key} IN (${placeholders})`);
14599
- whereParams.push(...value2);
14600
- } else {
14601
- const paramIndex = whereParams.length + 1;
14602
- conditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
14603
- whereConditions.push(`OR ${key} = ${getPlaceholder(paramIndex)}`);
14604
- whereParams.push(value2);
14605
- }
14606
- }
14607
- if (conditions.length > 0) {
14608
- text = `${text} OR ${conditions.join(" AND ")}`;
14609
- built = null;
14610
- }
14611
- return this;
14612
- }
14613
- if (expr && typeof expr.raw !== "undefined") {
14614
- whereConditions.push(`OR ${expr.raw}`);
14615
- text = `${text} OR ${expr.raw}`;
14616
- built = null;
14617
- return this;
14618
- }
14619
- return this;
14579
+ return addBooleanWhere(this, "OR", "orWhere", expr, op, value);
14620
14580
  },
14621
14581
  orderBy(column, direction = "asc") {
14622
14582
  const dir = direction === "asc" ? "ASC" : "DESC";
@@ -14853,7 +14813,7 @@ function createQueryBuilder(state) {
14853
14813
  return this;
14854
14814
  },
14855
14815
  toSQL() {
14856
- const sqlText = reorderSelectClauses(text);
14816
+ const sqlText = reorderSelectClauses(currentSql());
14857
14817
  return {
14858
14818
  sql: sqlText,
14859
14819
  toString: () => sqlText,
@@ -14899,7 +14859,7 @@ function createQueryBuilder(state) {
14899
14859
  if (!Number.isFinite(page) || page < 1 || !Number.isInteger(page))
14900
14860
  throw new TypeError(`[query-builder] paginate(page): expected integer >= 1, got ${page}`);
14901
14861
  if (opts.tx) {
14902
- const baseSql = reorderSelectClauses(text);
14862
+ const baseSql = reorderSelectClauses(currentSql());
14903
14863
  const baseParams = [...whereParams];
14904
14864
  const cRows2 = await opts.tx.unsafe(`SELECT COUNT(*) as c FROM (${baseSql}) as sub`, baseParams);
14905
14865
  const total2 = Number(cRows2?.[0]?.c ?? 0);
@@ -15019,8 +14979,8 @@ function createQueryBuilder(state) {
15019
14979
  };
15020
14980
  const predicate = `${table}.${softDeleteColumn} IS NOT NULL`;
15021
14981
  text = splice(text, predicate);
15022
- const currentSql = String(ensureBuilt());
15023
- built = sql([splice(currentSql, predicate)]);
14982
+ const currentSql2 = String(ensureBuilt());
14983
+ built = sql([splice(currentSql2, predicate)]);
15024
14984
  return this;
15025
14985
  },
15026
14986
  scope(name, value) {
@@ -15063,7 +15023,7 @@ function createQueryBuilder(state) {
15063
15023
  return ensureBuilt().simple();
15064
15024
  },
15065
15025
  toText() {
15066
- return text;
15026
+ return currentSql();
15067
15027
  },
15068
15028
  async get() {
15069
15029
  const hooks = activeHooks();
@@ -15071,11 +15031,12 @@ function createQueryBuilder(state) {
15071
15031
  if (!config5.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !hasQueryHooks) {
15072
15032
  const prepareFn = _sql._prepareStatement;
15073
15033
  if (prepareFn) {
15074
- const stmt = prepareFn(text);
15034
+ const stmt = prepareFn(currentSql());
15075
15035
  return hydratePivotRows(whereParams.length > 0 ? stmt.all(...whereParams) : stmt.all());
15076
15036
  }
15077
15037
  }
15078
- built = whereParams.length > 0 ? _sql.unsafe(text, whereParams) : _sql.unsafe(text);
15038
+ const getText = currentSql();
15039
+ built = whereParams.length > 0 ? _sql.unsafe(getText, whereParams) : _sql.unsafe(getText);
15079
15040
  if (!config5.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !hasQueryHooks) {
15080
15041
  const stmt = ensureBuilt()._stmt;
15081
15042
  const params = ensureBuilt()._params;
@@ -15092,9 +15053,9 @@ function createQueryBuilder(state) {
15092
15053
  const col = config5.softDeletes.column;
15093
15054
  const tbl = String(table);
15094
15055
  const hasCol = schema ? Boolean(schema[tbl]?.columns?.[col]) : true;
15095
- if (hasCol && !SQL_PATTERNS.DELETED_AT.test(text)) {
15096
- finalQuery = sql`${ensureBuilt()} WHERE ${sql(String(col))} IS ${onlyTrashed ? sql`NOT NULL` : sql`NULL`}`;
15056
+ if (hasCol && !SQL_PATTERNS.DELETED_AT.test(currentSql())) {
15097
15057
  addWhereText("WHERE", `${String(col)} IS ${onlyTrashed ? "NOT " : ""}NULL`);
15058
+ finalQuery = ensureBuilt();
15098
15059
  }
15099
15060
  }
15100
15061
  const cacheKey = useCache ? `${String(finalQuery)}\x00${JSON.stringify(whereParams)}` : "";
@@ -15124,7 +15085,8 @@ function createQueryBuilder(state) {
15124
15085
  if (!config5.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !fHasQueryHooks) {
15125
15086
  const prepareFn = _sql._prepareStatement;
15126
15087
  if (prepareFn) {
15127
- const firstText = text.includes(" LIMIT ") ? text : `${text} LIMIT 1`;
15088
+ const base2 = currentSql();
15089
+ const firstText = base2.includes(" LIMIT ") ? base2 : `${base2} LIMIT 1`;
15128
15090
  const stmt = prepareFn(firstText);
15129
15091
  const rows2 = whereParams.length > 0 ? stmt.all(...whereParams) : stmt.all();
15130
15092
  return hydratePivotRow(rows2[0]);
@@ -15191,13 +15153,14 @@ function createQueryBuilder(state) {
15191
15153
  return fn(this);
15192
15154
  },
15193
15155
  async count() {
15194
- const fromIdx = text.indexOf(" FROM ");
15195
- const hasGroupBy = / GROUP BY /i.test(text);
15156
+ const src = currentSql();
15157
+ const fromIdx = src.indexOf(" FROM ");
15158
+ const hasGroupBy = / GROUP BY /i.test(src);
15196
15159
  let countText;
15197
15160
  if (hasGroupBy) {
15198
- countText = `SELECT COUNT(*) as c FROM (${text}) AS _bqb_count_sub`;
15161
+ countText = `SELECT COUNT(*) as c FROM (${src}) AS _bqb_count_sub`;
15199
15162
  } else if (fromIdx !== -1) {
15200
- countText = `SELECT COUNT(*) as c${text.substring(fromIdx)}`;
15163
+ countText = `SELECT COUNT(*) as c${src.substring(fromIdx)}`;
15201
15164
  } else {
15202
15165
  countText = `SELECT COUNT(*) as c FROM ${table}`;
15203
15166
  }
@@ -15217,8 +15180,9 @@ function createQueryBuilder(state) {
15217
15180
  return Number(row?.c ?? 0);
15218
15181
  },
15219
15182
  async avg(column) {
15220
- const fromIdx = text.indexOf(" FROM ");
15221
- const avgText = fromIdx !== -1 ? `SELECT AVG(${column}) as a${text.substring(fromIdx)}` : `SELECT AVG(${column}) as a FROM ${table}`;
15183
+ const src = currentSql();
15184
+ const fromIdx = src.indexOf(" FROM ");
15185
+ const avgText = fromIdx !== -1 ? `SELECT AVG(${column}) as a${src.substring(fromIdx)}` : `SELECT AVG(${column}) as a FROM ${table}`;
15222
15186
  const aHooks = activeHooks();
15223
15187
  const aHasHooks = aHooks && (aHooks.onQueryStart || aHooks.onQueryEnd || aHooks.onQueryError || aHooks.startSpan || hasSlowQueryHook(aHooks));
15224
15188
  if (!config5.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !aHasHooks) {
@@ -15235,24 +15199,27 @@ function createQueryBuilder(state) {
15235
15199
  return Number(row?.a ?? 0);
15236
15200
  },
15237
15201
  async sum(column) {
15238
- const fromIdx = text.indexOf(" FROM ");
15239
- const sumText = fromIdx !== -1 ? `SELECT SUM(${column}) as s${text.substring(fromIdx)}` : `SELECT SUM(${column}) as s FROM ${table}`;
15202
+ const src = currentSql();
15203
+ const fromIdx = src.indexOf(" FROM ");
15204
+ const sumText = fromIdx !== -1 ? `SELECT SUM(${column}) as s${src.substring(fromIdx)}` : `SELECT SUM(${column}) as s FROM ${table}`;
15240
15205
  const q = whereParams.length > 0 ? _sql.unsafe(sumText, whereParams) : _sql.unsafe(sumText);
15241
15206
  const rows = await runWithHooks(q, "select", { signal: abortSignal, timeoutMs });
15242
15207
  const [row] = rows;
15243
15208
  return Number(row?.s ?? 0);
15244
15209
  },
15245
15210
  async max(column) {
15246
- const fromIdx = text.indexOf(" FROM ");
15247
- const maxText = fromIdx !== -1 ? `SELECT MAX(${column}) as m${text.substring(fromIdx)}` : `SELECT MAX(${column}) as m FROM ${table}`;
15211
+ const src = currentSql();
15212
+ const fromIdx = src.indexOf(" FROM ");
15213
+ const maxText = fromIdx !== -1 ? `SELECT MAX(${column}) as m${src.substring(fromIdx)}` : `SELECT MAX(${column}) as m FROM ${table}`;
15248
15214
  const q = whereParams.length > 0 ? _sql.unsafe(maxText, whereParams) : _sql.unsafe(maxText);
15249
15215
  const rows = await runWithHooks(q, "select", { signal: abortSignal, timeoutMs });
15250
15216
  const [row] = rows;
15251
15217
  return row?.m;
15252
15218
  },
15253
15219
  async min(column) {
15254
- const fromIdx = text.indexOf(" FROM ");
15255
- const minText = fromIdx !== -1 ? `SELECT MIN(${column}) as m${text.substring(fromIdx)}` : `SELECT MIN(${column}) as m FROM ${table}`;
15220
+ const src = currentSql();
15221
+ const fromIdx = src.indexOf(" FROM ");
15222
+ const minText = fromIdx !== -1 ? `SELECT MIN(${column}) as m${src.substring(fromIdx)}` : `SELECT MIN(${column}) as m FROM ${table}`;
15256
15223
  const q = whereParams.length > 0 ? _sql.unsafe(minText, whereParams) : _sql.unsafe(minText);
15257
15224
  const rows = await runWithHooks(q, "select", { signal: abortSignal, timeoutMs });
15258
15225
  const [row] = rows;
@@ -15291,7 +15258,7 @@ function createQueryBuilder(state) {
15291
15258
  return [...whereParams];
15292
15259
  },
15293
15260
  __rawState() {
15294
- return { sql: reorderSelectClauses(text), params: [...whereParams] };
15261
+ return { sql: reorderSelectClauses(currentSql()), params: [...whereParams] };
15295
15262
  },
15296
15263
  raw() {
15297
15264
  return ensureBuilt().raw();
@@ -15335,8 +15302,6 @@ function createQueryBuilder(state) {
15335
15302
  return () => receiver;
15336
15303
  const column = chosen;
15337
15304
  return (value) => {
15338
- const expr = Array.isArray(value) ? sql`${sql(column)} IN ${sql(value)}` : sql`${sql(column)} = ${value}`;
15339
- built = isOr ? sql`${ensureBuilt()} OR ${expr}` : isAnd ? sql`${ensureBuilt()} AND ${expr}` : sql`${ensureBuilt()} WHERE ${expr}`;
15340
15305
  if (Array.isArray(value)) {
15341
15306
  const phs = getPlaceholders(value.length, whereParams.length + 1);
15342
15307
  addWhereText(isOr ? "OR" : isAnd ? "AND" : "WHERE", `${column} IN (${phs})`);
@@ -15391,8 +15356,7 @@ function createQueryBuilder(state) {
15391
15356
  const subText = rawState?.sql ?? (typeof subExec === "string" ? subExec : subExec?.sql ?? String(subExec));
15392
15357
  const subParams = rawState?.params ?? (Array.isArray(subExec?.values) ? subExec.values : []);
15393
15358
  const baseText = `SELECT * FROM (${subText}) AS ${String(alias)}`;
15394
- const appendWhere = (text, params, hasWhere, expr, op, value, connector) => {
15395
- const kw = !hasWhere ? "WHERE" : connector === "WHERE" ? "AND" : connector;
15359
+ const appendWhere = (params, expr, op, value) => {
15396
15360
  const out = [...params];
15397
15361
  const cmp = (col, operator, val) => {
15398
15362
  validateIdentifier(col, "selectFromSub where(column)");
@@ -15408,61 +15372,91 @@ function createQueryBuilder(state) {
15408
15372
  return `${col} ${o} ${ph}`;
15409
15373
  };
15410
15374
  let clause;
15411
- if (typeof expr === "string" && op !== undefined)
15375
+ if (typeof expr === "string" && op !== undefined) {
15412
15376
  clause = cmp(expr, op, value);
15413
- else if (Array.isArray(expr) && expr.length === 3)
15377
+ } else if (Array.isArray(expr) && expr.length === 3) {
15414
15378
  clause = cmp(expr[0], expr[1], expr[2]);
15415
- else if (expr && typeof expr === "object")
15416
- clause = Object.entries(expr).map(([k, v]) => cmp(k, "=", v)).join(" AND ");
15417
- else
15418
- return { text, params };
15419
- return { text: `${text} ${kw} ${clause}`, params: out };
15379
+ } else if (expr && typeof expr === "object") {
15380
+ const parts = Object.entries(expr).map(([k, v]) => cmp(k, "=", v));
15381
+ clause = parts.length > 1 ? `(${parts.join(" AND ")})` : parts[0];
15382
+ } else {
15383
+ return { clause: null, params };
15384
+ }
15385
+ return { clause, params: out };
15420
15386
  };
15421
- function makeSub(text, params, hasWhere = false) {
15387
+ function makeSub(baseText2, terms, params, tail = "") {
15388
+ const body = renderWhereTerms(terms);
15389
+ const text = body ? `${baseText2} WHERE ${body}${tail}` : `${baseText2}${tail}`;
15422
15390
  const build = () => params.length > 0 ? _sql.unsafe(text, params) : _sql.unsafe(text);
15391
+ const withTerm = (conn, expr, op, value) => {
15392
+ const r = appendWhere(params, expr, op, value);
15393
+ return r.clause === null ? makeSub(baseText2, terms, params, tail) : makeSub(baseText2, [...terms, { conn, sql: r.clause }], r.params, tail);
15394
+ };
15395
+ const withGroup = (conn, cb) => {
15396
+ const gTerms = [];
15397
+ let gParams = [...params];
15398
+ const add = (c) => (expr, op, value) => {
15399
+ const r = appendWhere(gParams, expr, op, value);
15400
+ if (r.clause !== null) {
15401
+ gTerms.push({ conn: c, sql: r.clause });
15402
+ gParams = r.params;
15403
+ }
15404
+ return collector;
15405
+ };
15406
+ const collector = { where: add("AND"), andWhere: add("AND"), orWhere: add("OR") };
15407
+ cb(collector);
15408
+ const body2 = renderWhereTerms(gTerms);
15409
+ if (!body2) {
15410
+ throw new TypeError("[query-builder] selectFromSub.whereGroup(callback): the callback added no conditions. " + "Add at least one where()/orWhere() to the builder it receives.");
15411
+ }
15412
+ return makeSub(baseText2, [...terms, { conn, sql: `(${body2})` }], gParams, tail);
15413
+ };
15423
15414
  const base = {
15424
15415
  distinct() {
15425
- return makeSub(text.replace(/^SELECT\s+/i, "SELECT DISTINCT "), params, hasWhere);
15416
+ return makeSub(baseText2.replace(/^SELECT\s+/i, "SELECT DISTINCT "), terms, params, tail);
15426
15417
  },
15427
15418
  distinctOn(...columns) {
15428
15419
  const cols = columns.map(String).join(", ");
15429
- return makeSub(text.replace(/^SELECT\s+/i, `SELECT DISTINCT ON (${cols}) `), params, hasWhere);
15420
+ return makeSub(baseText2.replace(/^SELECT\s+/i, `SELECT DISTINCT ON (${cols}) `), terms, params, tail);
15430
15421
  },
15431
15422
  selectRaw(fragment) {
15432
15423
  const frag = renderRawFragment(fragment, "selectFromSub.selectRaw(fragment)");
15433
- const fromIdx = text.indexOf(" FROM ");
15434
- const newText = fromIdx !== -1 ? `${text.slice(0, fromIdx)}, ${frag}${text.slice(fromIdx)}` : `${text}, ${frag}`;
15435
- return makeSub(newText, params, hasWhere);
15424
+ const fromIdx = baseText2.indexOf(" FROM ");
15425
+ const newBase = fromIdx !== -1 ? `${baseText2.slice(0, fromIdx)}, ${frag}${baseText2.slice(fromIdx)}` : `${baseText2}, ${frag}`;
15426
+ return makeSub(newBase, terms, params, tail);
15436
15427
  },
15437
15428
  where(expr, op, value) {
15438
- const r = appendWhere(text, params, hasWhere, expr, op, value, "WHERE");
15439
- return makeSub(r.text, r.params, true);
15429
+ return withTerm("AND", expr, op, value);
15440
15430
  },
15441
15431
  andWhere(expr, op, value) {
15442
- const r = appendWhere(text, params, hasWhere, expr, op, value, "AND");
15443
- return makeSub(r.text, r.params, true);
15432
+ return withTerm("AND", expr, op, value);
15444
15433
  },
15445
15434
  orWhere(expr, op, value) {
15446
- const r = appendWhere(text, params, hasWhere, expr, op, value, "OR");
15447
- return makeSub(r.text, r.params, true);
15435
+ return withTerm("OR", expr, op, value);
15436
+ },
15437
+ whereGroup(cb) {
15438
+ return withGroup("AND", cb);
15439
+ },
15440
+ orWhereGroup(cb) {
15441
+ return withGroup("OR", cb);
15448
15442
  },
15449
15443
  orderBy(column, direction = "asc") {
15450
15444
  validateIdentifier(String(column), "selectFromSub.orderBy(column)");
15451
15445
  const dir = direction === "asc" ? "ASC" : "DESC";
15452
- const newText = SQL_PATTERNS.ORDER_BY.test(text) ? `${text}, ${column} ${dir}` : `${text} ORDER BY ${column} ${dir}`;
15453
- return makeSub(newText, params, hasWhere);
15446
+ const newTail = SQL_PATTERNS.ORDER_BY.test(tail) ? `${tail}, ${column} ${dir}` : `${tail} ORDER BY ${column} ${dir}`;
15447
+ return makeSub(baseText2, terms, params, newTail);
15454
15448
  },
15455
15449
  limit(n) {
15456
15450
  if (!Number.isInteger(n) || n < 0)
15457
15451
  throw new TypeError(`[query-builder] selectFromSub.limit(n): expected non-negative integer, got ${n}`);
15458
- const newText = SQL_PATTERNS.LIMIT.test(text) ? text.replace(SQL_PATTERNS.LIMIT, ` LIMIT ${n}`) : `${text} LIMIT ${n}`;
15459
- return makeSub(newText, params, hasWhere);
15452
+ const newTail = SQL_PATTERNS.LIMIT.test(tail) ? tail.replace(SQL_PATTERNS.LIMIT, ` LIMIT ${n}`) : `${tail} LIMIT ${n}`;
15453
+ return makeSub(baseText2, terms, params, newTail);
15460
15454
  },
15461
15455
  offset(n) {
15462
15456
  if (!Number.isInteger(n) || n < 0)
15463
15457
  throw new TypeError(`[query-builder] selectFromSub.offset(n): expected non-negative integer, got ${n}`);
15464
- const newText = SQL_PATTERNS.OFFSET.test(text) ? text.replace(SQL_PATTERNS.OFFSET, ` OFFSET ${n}`) : `${text} OFFSET ${n}`;
15465
- return makeSub(newText, params, hasWhere);
15458
+ const newTail = SQL_PATTERNS.OFFSET.test(tail) ? tail.replace(SQL_PATTERNS.OFFSET, ` OFFSET ${n}`) : `${tail} OFFSET ${n}`;
15459
+ return makeSub(baseText2, terms, params, newTail);
15466
15460
  },
15467
15461
  toSQL() {
15468
15462
  return makeExecutableQuery(build(), text);
@@ -15545,8 +15539,13 @@ function createQueryBuilder(state) {
15545
15539
  whereJsonContains: subqueryNotSupported("whereJsonContains"),
15546
15540
  whereJsonPath: subqueryNotSupported("whereJsonPath"),
15547
15541
  whereNull: subqueryNotSupported("whereNull"),
15542
+ orWhereNull: subqueryNotSupported("orWhereNull"),
15548
15543
  whereNotNull: subqueryNotSupported("whereNotNull"),
15544
+ orWhereNotNull: subqueryNotSupported("orWhereNotNull"),
15549
15545
  whereExists: subqueryNotSupported("whereExists"),
15546
+ orWhereExists: subqueryNotSupported("orWhereExists"),
15547
+ orWhereBetween: subqueryNotSupported("orWhereBetween"),
15548
+ orWhereRaw: subqueryNotSupported("orWhereRaw"),
15550
15549
  whereJsonDoesntContain: subqueryNotSupported("whereJsonDoesntContain"),
15551
15550
  whereJsonContainsKey: subqueryNotSupported("whereJsonContainsKey"),
15552
15551
  whereJsonDoesntContainKey: subqueryNotSupported("whereJsonDoesntContainKey"),
@@ -15625,7 +15624,7 @@ function createQueryBuilder(state) {
15625
15624
  };
15626
15625
  return base;
15627
15626
  }
15628
- return makeSub(baseText, subParams);
15627
+ return makeSub(baseText, [], subParams);
15629
15628
  },
15630
15629
  insertInto(table) {
15631
15630
  let built;
@@ -16730,7 +16729,7 @@ function clearQueryCache() {
16730
16729
  function setQueryCacheMaxSize(size) {
16731
16730
  queryCache.setMaxSize(size);
16732
16731
  }
16733
- var FALSE_PREDICATE = "1 = 0", TRUE_PREDICATE = "1 = 1", SQL_PATTERNS, SAFE_WHERE_OPERATORS, warnedSqlFragmentContexts, queryCache, reorderCache, REORDER_CACHE_MAX = 500;
16732
+ var SQL_PATTERNS, SAFE_WHERE_OPERATORS, warnedSqlFragmentContexts, queryCache, reorderCache, REORDER_CACHE_MAX = 500;
16734
16733
  var init_client = __esm(() => {
16735
16734
  init_config();
16736
16735
  init_db();
@@ -19465,7 +19464,7 @@ var init_migrate = __esm(() => {
19465
19464
  init_src2();
19466
19465
  init_introspect_db();
19467
19466
  init_workspace();
19468
- NON_TRANSACTIONAL_SQL = /\bCONCURRENTLY\b|^\s*VACUUM\b/im;
19467
+ NON_TRANSACTIONAL_SQL = /\bCONCURRENTLY\b|^\s*VACUUM\b|^\s*BEGIN\s*(?:;|TRANSACTION\b)|^\s*PRAGMA\s+foreign_keys\b/im;
19469
19468
  });
19470
19469
 
19471
19470
  // src/actions/migrate-generate.ts
@@ -20524,6 +20523,135 @@ var init_actions = __esm(() => {
20524
20523
  init_wait_ready();
20525
20524
  });
20526
20525
 
20526
+ // src/faker-compat.ts
20527
+ function asStringOptions(value) {
20528
+ if (typeof value === "number")
20529
+ return { length: value };
20530
+ return value;
20531
+ }
20532
+ function asNumberOptions(value) {
20533
+ if (typeof value === "number")
20534
+ return { max: value };
20535
+ return value;
20536
+ }
20537
+ function callable(value) {
20538
+ return typeof value === "function";
20539
+ }
20540
+ function flattened(name) {
20541
+ return name.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
20542
+ }
20543
+ function withFractionDigits(value, options) {
20544
+ if (!options || typeof options.fractionDigits !== "number")
20545
+ return value;
20546
+ return Number(value.toFixed(options.fractionDigits));
20547
+ }
20548
+ function compatModule(underlying, overrides = {}) {
20549
+ if (!underlying)
20550
+ return overrides;
20551
+ return new Proxy(underlying, {
20552
+ get(target, property) {
20553
+ if (property in overrides)
20554
+ return overrides[property];
20555
+ const direct = target[property];
20556
+ if (direct !== undefined)
20557
+ return direct;
20558
+ const fallback = target[flattened(property)];
20559
+ if (callable(fallback))
20560
+ return fallback.bind(target);
20561
+ return;
20562
+ }
20563
+ });
20564
+ }
20565
+ function createFakerCompatLayer(underlying) {
20566
+ const pick = (items) => {
20567
+ const list = Array.isArray(items) ? items : [];
20568
+ const index = Math.floor(Math.random() * list.length);
20569
+ return list[index];
20570
+ };
20571
+ const strings = () => underlying.string;
20572
+ const numbers = () => underlying.number;
20573
+ const random = () => underlying.random;
20574
+ const compatString = compatModule(underlying.string, {
20575
+ alpha: (options) => strings()?.alpha?.(asStringOptions(options)),
20576
+ alphanumeric: (options) => strings()?.alphanumeric?.(asStringOptions(options)),
20577
+ numeric: (options) => strings()?.numeric?.(asStringOptions(options)),
20578
+ sample: (options) => strings()?.sample?.(asStringOptions(options)),
20579
+ hexadecimal: (options) => strings()?.hexadecimal?.(asStringOptions(options))
20580
+ });
20581
+ const compatNumber = compatModule(underlying.number, {
20582
+ int: (options) => numbers()?.int?.(asNumberOptions(options)),
20583
+ float: (options) => {
20584
+ const parsed = asNumberOptions(options);
20585
+ return withFractionDigits(Number(numbers()?.float?.(parsed) ?? 0), parsed);
20586
+ }
20587
+ });
20588
+ const compatHelpers = compatModule(underlying.helpers, {
20589
+ arrayElement: pick,
20590
+ arrayElements: (items, count) => {
20591
+ const list = [...Array.isArray(items) ? items : []];
20592
+ const wanted = typeof count === "number" ? count : Math.max(1, Math.floor(Math.random() * list.length));
20593
+ for (let at = list.length - 1;at > 0; at -= 1) {
20594
+ const swap = Math.floor(Math.random() * (at + 1));
20595
+ [list[at], list[swap]] = [list[swap], list[at]];
20596
+ }
20597
+ return list.slice(0, Math.min(wanted, list.length));
20598
+ },
20599
+ shuffle: (items) => {
20600
+ const list = [...Array.isArray(items) ? items : []];
20601
+ for (let at = list.length - 1;at > 0; at -= 1) {
20602
+ const swap = Math.floor(Math.random() * (at + 1));
20603
+ [list[at], list[swap]] = [list[swap], list[at]];
20604
+ }
20605
+ return list;
20606
+ },
20607
+ maybe: (produce, options) => {
20608
+ const probability = typeof options?.probability === "number" ? options.probability : 0.5;
20609
+ return Math.random() < probability ? produce() : undefined;
20610
+ },
20611
+ slugify: (text) => String(text ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "")
20612
+ });
20613
+ const compatDatatype = {
20614
+ boolean: (options) => {
20615
+ const probability = typeof options === "number" ? options : options?.probability;
20616
+ if (typeof probability === "number")
20617
+ return Math.random() < probability;
20618
+ return Boolean(random()?.boolean?.());
20619
+ },
20620
+ number: (options) => Number(numbers()?.int?.(asNumberOptions(options)) ?? 0),
20621
+ float: (options) => withFractionDigits(Number(numbers()?.float?.(options) ?? 0), options),
20622
+ uuid: () => crypto.randomUUID(),
20623
+ string: (length) => String(strings()?.alphanumeric?.({ length: length ?? 10 }) ?? ""),
20624
+ hexadecimal: (options) => String(strings()?.hexadecimal?.(asStringOptions(options)) ?? ""),
20625
+ array: (length) => Array.from({ length: length ?? 3 }, () => strings()?.alphanumeric?.({ length: 8 })),
20626
+ json: () => JSON.stringify({ value: strings()?.alphanumeric?.({ length: 8 }) })
20627
+ };
20628
+ const modules = {
20629
+ string: compatString,
20630
+ number: compatNumber,
20631
+ helpers: compatHelpers,
20632
+ datatype: compatDatatype,
20633
+ location: compatModule(underlying.address),
20634
+ address: compatModule(underlying.address),
20635
+ vehicle: compatModule(underlying.vehicle, {
20636
+ vrm: () => underlying.vehicle?.registration?.()
20637
+ }),
20638
+ company: compatModule(underlying.company, {
20639
+ catchPhrase: () => underlying.company?.catchphrase?.(),
20640
+ buzzPhrase: () => underlying.company?.bs?.() ?? underlying.company?.buzzword?.()
20641
+ })
20642
+ };
20643
+ return new Proxy(underlying, {
20644
+ get(target, property) {
20645
+ if (property in modules)
20646
+ return modules[property];
20647
+ const direct = target[property];
20648
+ if (direct && typeof direct === "object")
20649
+ return compatModule(direct);
20650
+ return direct;
20651
+ }
20652
+ });
20653
+ }
20654
+
20527
20655
  // src/relation-utils.ts
20528
20656
  function normalizeRelationEntry(entry) {
20529
20657
  if (typeof entry === "string")
@@ -26231,9 +26359,8 @@ class ModelQueryBuilder {
26231
26359
  return this._withRelations;
26232
26360
  }
26233
26361
  buildWhereClauses(params) {
26234
- const clauses = [];
26235
- for (let i2 = 0;i2 < this._wheres.length; i2++) {
26236
- const w = this._wheres[i2];
26362
+ const terms = [];
26363
+ for (const w of this._wheres) {
26237
26364
  let clause;
26238
26365
  if (w.raw) {
26239
26366
  clause = w.raw;
@@ -26244,15 +26371,15 @@ class ModelQueryBuilder {
26244
26371
  clause = w.operator === "=" ? `${col} IS NULL` : `${col} IS NOT NULL`;
26245
26372
  } else if (w.operator === "in" || w.operator === "not in") {
26246
26373
  const arr = w.value;
26247
- clause = `${sqlColumn(w.column)} ${w.operator.toUpperCase()} (${arr.map(() => "?").join(", ")})`;
26374
+ clause = renderInPredicate(sqlColumn(w.column), arr, w.operator === "not in", arr.map(() => "?").join(", "));
26248
26375
  params.push(...arr);
26249
26376
  } else {
26250
26377
  clause = `${sqlColumn(w.column)} ${w.operator} ?`;
26251
26378
  params.push(w.value);
26252
26379
  }
26253
- clauses.push(i2 === 0 ? clause : `${w.boolean.toUpperCase()} ${clause}`);
26380
+ terms.push({ conn: w.boolean === "or" ? "OR" : "AND", sql: clause });
26254
26381
  }
26255
- return clauses.join(" ");
26382
+ return renderWhereTerms(terms);
26256
26383
  }
26257
26384
  softDeleteClause() {
26258
26385
  if (this._trashed === "include" || !softDeletesEnabled(this._definition))
@@ -26844,27 +26971,6 @@ async function createTableFromModel(definition) {
26844
26971
  }
26845
26972
  await exec.run(`CREATE TABLE IF NOT EXISTS ${definition.table} (${columns.join(", ")})`, []);
26846
26973
  }
26847
- function createFakerCompatLayer(underlying) {
26848
- return new Proxy(underlying, {
26849
- get(target, prop) {
26850
- if (prop === "location")
26851
- return target.address;
26852
- if (prop === "datatype") {
26853
- const rng = target.random;
26854
- const num = target.number;
26855
- const str = target.string;
26856
- return {
26857
- boolean: () => rng?.boolean?.(),
26858
- number: (opts) => num?.int?.(opts),
26859
- float: (opts) => num?.float?.(opts),
26860
- uuid: () => crypto.randomUUID(),
26861
- string: (length) => str?.alphanumeric?.(length ?? 10)
26862
- };
26863
- }
26864
- return target[prop];
26865
- }
26866
- });
26867
- }
26868
26974
  async function seedModel(definition, count, faker) {
26869
26975
  const exec = getExecutor();
26870
26976
  const seeder = definition.traits?.useSeeder;
@@ -29912,6 +30018,7 @@ export {
29912
30018
  createQueryBuilder,
29913
30019
  createModel,
29914
30020
  createMigrationDriver,
30021
+ createFakerCompatLayer,
29915
30022
  createDynamoDBToolingAdapter,
29916
30023
  createDynamoDBQueryBuilder,
29917
30024
  createDynamoDBItemBuilder,