OpraFilter
Package: @opra/common
OpraFilter is a namespace that provides a filter expression parser and an AST builder. It is used internally by FindMany, UpdateMany, and DeleteMany operations to parse the $filter query parameter sent by clients, and can also be used programmatically to build filter expressions.
Filter syntax
The filter expression language supports comparison, logical, and arithmetic expressions. It is passed as the $filter query string parameter on collection endpoints.
GET /customers?$filter=status = 'active' and age > 18
GET /customers?$filter=email like '*@example.com'
GET /customers?$filter=_id in [1, 2, 3]
GET /customers?$filter=(score >= 80 and score <= 100)
Operators
| Operator | Meaning |
|---|---|
= | Equal |
!= | Not equal |
< | Less than |
> | Greater than |
<= | Less than or equal |
>= | Greater than or equal |
in | Value is in the list |
!in | Value is not in the list |
like | Pattern match (case-sensitive, * wildcard) |
!like | Does not match pattern |
ilike | Case-insensitive pattern match |
!ilike | Case-insensitive does not match |
Logical operators
| Operator | Meaning |
|---|---|
and | Both conditions must be true |
or | At least one condition must be true |
Use parentheses to control precedence:
(status = 'active' or status = 'pending') and age > 18
Literal types
| Literal | Example |
|---|---|
| String | 'hello' |
| Number | 42, 3.14 |
| Boolean | true, false |
| Null | null |
| Date | #2024-01-01# |
| Time | #T10:30:00# |
| Array | [1, 2, 3] |
Parsing
Use OpraFilter.parse() to parse a filter string into an AST.
import { OpraFilter } from '@opra/common';
const ast = OpraFilter.parse("status = 'active' and age > 18");
OpraFilter.parse(text: string): Expression
Throws SyntaxError if the filter string is invalid.
Building filter expressions
The builder functions produce AST nodes that can be used programmatically — for example, to construct filters server-side before passing them to a data layer.
import { OpraFilter } from '@opra/common';
const { $and, $eq, $gt, $field } = OpraFilter;
const filter = $and(
$eq('status', 'active'),
$gt($field('age'), 18),
);
Logical builders
| Function | Description |
|---|---|
$and(...items) | Logical AND of multiple expressions |
$or(...items) | Logical OR of multiple expressions |
$paren(expr) | Wraps expression in parentheses |
Comparison builders
All comparison builders accept field names (strings), literals, or nested expressions as arguments.
| Function | Operator |
|---|---|
$eq(left, right) | = |
$ne(left, right) | != |
$gt(left, right) | > |
$gte(left, right) | >= |
$lt(left, right) | < |
$lte(left, right) | <= |
$in(left, right) | in |
$notIn(left, right) | !in |
$like(left, right) | like |
$notLike(left, right) | !like |
$ilike(left, right) | ilike |
$notILike(left, right) | !ilike |
Literal builders
| Function | Description |
|---|---|
$field(name) | A qualified field identifier (not a string literal) |
$number(v) | A number literal |
$date(v) | A date literal — v is an ISO date string or Date |
$time(v) | A time literal — v is an ISO time string |
$array(...items) | An array literal |
Arithmetic builder
const expr = $arithmetic(price).mul(quantity).add(tax);
$arithmetic(initial) returns a chainable object with .add(), .sub(), .mul(), .div() methods, each of which appends an arithmetic operation.
Declaring filterable fields
Filterable fields and their allowed operators are declared on collection operations using .Filter():
import { HttpOperation } from '@opra/common';
@(HttpOperation.Entity.FindMany(Customer)
.Filter('status', ['=', '!=', 'in'])
.Filter('givenName', ['=', '!=', 'like', 'ilike'])
.Filter('age', ['=', '!=', '<', '>', '<=', '>='])
.SortFields('givenName', 'familyName', 'age')
.DefaultSort('givenName'))
async findMany(ctx: HttpContext) { }
Clients that submit a $filter expression referencing an undeclared field or an unsupported operator receive a 400 Bad Request error.
→ See HTTP API for full FindMany / UpdateMany / DeleteMany documentation.