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