Skip to main content

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

OperatorMeaning
=Equal
!=Not equal
<Less than
>Greater than
<=Less than or equal
>=Greater than or equal
inValue is in the list
!inValue is not in the list
likePattern match (case-sensitive, * wildcard)
!likeDoes not match pattern
ilikeCase-insensitive pattern match
!ilikeCase-insensitive does not match

Logical operators

OperatorMeaning
andBoth conditions must be true
orAt least one condition must be true

Use parentheses to control precedence:

(status = 'active' or status = 'pending') and age > 18

Literal types

LiteralExample
String'hello'
Number42, 3.14
Booleantrue, false
Nullnull
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

FunctionDescription
$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.

FunctionOperator
$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

FunctionDescription
$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.