* Filter rows based on a condition * * @param callback - A function that receives table references and returns an expression * @returns A QueryBuilder with the where condition applied * * @example * ```ts * // Simple condition * query * .from({ users: usersCollection })
(callback: WhereCallback<TContext>)
| 447 | * ``` |
| 448 | */ |
| 449 | where(callback: WhereCallback<TContext>): QueryBuilder<TContext> { |
| 450 | const aliases = this._getCurrentAliases() |
| 451 | const refProxy = createRefProxy(aliases) as RefsForContext<TContext> |
| 452 | const rawExpression = callback(refProxy) |
| 453 | |
| 454 | // Allow bare boolean column references like `.where(({ u }) => u.active)` |
| 455 | // by converting ref proxies to PropRef expressions, the same way helper |
| 456 | // functions like `not()` and `eq()` do via `toExpression()`. |
| 457 | const expression = isRefProxy(rawExpression) |
| 458 | ? toExpression(rawExpression) |
| 459 | : rawExpression |
| 460 | |
| 461 | // Validate that the callback returned a valid expression |
| 462 | // This catches common mistakes like using JavaScript comparison operators (===, !==, etc.) |
| 463 | // which return boolean primitives instead of expression objects |
| 464 | if (!isExpressionLike(expression)) { |
| 465 | throw new InvalidWhereExpressionError(getValueTypeName(expression)) |
| 466 | } |
| 467 | |
| 468 | const existingWhere = this.query.where || [] |
| 469 | |
| 470 | return new BaseQueryBuilder({ |
| 471 | ...this.query, |
| 472 | where: [...existingWhere, expression], |
| 473 | }) as any |
| 474 | } |
| 475 | |
| 476 | /** |
| 477 | * Filter grouped rows based on aggregate conditions |