Documentation Index Fetch the complete documentation index at: https://woltz.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
What is Criteria?
Criteria is a type-safe query builder that provides a fluent API for constructing database-agnostic queries. It handles filtering, ordering, pagination, and search in a way that’s completely decoupled from your persistence layer.
const criteria = Criteria . create < User >()
. whereEquals ( "status" , "active" )
. where ( "age" , "greaterThan" , 18 )
. whereContains ( "email" , "@company.com" )
. orderByDesc ( "createdAt" )
. paginate ( 1 , 20 );
// Use with repository
const result = await userRepository . find ( criteria );
Why Use Criteria?
Type-Safe Field paths, operators, and values are all validated by TypeScript at compile
time
ORM Agnostic Works with Prisma, Drizzle, TypeORM, or any persistence layer
Serializable Convert to/from JSON for API transport or caching
Fluent API Chain methods naturally for readable, maintainable queries
Basic Usage
Creating a Criteria
import { Criteria } from "@woltz/rich-domain" ;
// Create empty criteria
const criteria = Criteria . create < User >();
// Or with immediate filtering
const criteria = Criteria . create < User >(). whereEquals ( "status" , "active" );
Adding Filters
const criteria = Criteria . create < User >()
// Equality
. whereEquals ( "status" , "active" )
// Comparison
. where ( "age" , "greaterThan" , 18 )
. where ( "age" , "lessThanOrEqual" , 65 )
// String matching
. whereContains ( "name" , "john" )
// Array inclusion
. whereIn ( "role" , [ "admin" , "moderator" ])
// Range
. whereBetween ( "salary" , 50000 , 100000 )
// Null checks
. whereNotNull ( "email" );
Ordering Results
const criteria = Criteria . create < User >()
. orderBy ( "name" , "asc" )
. orderByDesc ( "createdAt" );
const criteria = Criteria . create < User >(). paginate ( 1 , 20 ); // page 1, 20 items per page
// Or just limit
const criteria = Criteria . create < User >(). limit ( 10 );
Search
const criteria = Criteria . create < User >(). search ( "john" );
Type Safety
Criteria leverages TypeScript to provide compile-time validation:
Field Paths
Only valid field paths from your type are allowed:
interface User {
id : string ;
name : string ;
email : string ;
profile : {
bio : string ;
avatar : string ;
};
posts : Post [];
}
const criteria = Criteria . create < User >()
. whereEquals ( "name" , "John" ) // ✅ Valid
. whereEquals ( "profile.bio" , "Hello" ) // ✅ Valid nested path
. whereEquals ( "posts.title" , "Post" ) // ✅ Valid array item path
. whereEquals ( "invalid" , "value" ); // ❌ TypeScript error
Operators Per Type
Operators are validated based on the field type:
const criteria = Criteria . create < User >()
// String fields
. where ( "name" , "contains" , "john" ) // ✅ Valid
. where ( "name" , "greaterThan" , "john" ) // ❌ Error: greaterThan not valid for string
// Number fields
. where ( "age" , "greaterThan" , 18 ) // ✅ Valid
. where ( "age" , "contains" , "18" ) // ❌ Error: contains not valid for number
// Boolean fields
. where ( "isActive" , "equals" , true ) // ✅ Valid
. where ( "isActive" , "contains" , true ); // ❌ Error: contains not valid for boolean
Value Types
Values are validated to match the field type:
const criteria = Criteria . create < User >()
. whereEquals ( "age" , 25 ) // ✅ Valid: number for number field
. whereEquals ( "age" , "25" ) // ❌ Error: string for number field
. whereEquals ( "name" , "John" ) // ✅ Valid: string for string field
. whereIn ( "age" , [ 20 , 25 , 30 ]); // ✅ Valid: number[] for number field
Serialization
To JSON
const criteria = Criteria . create < User >()
. whereEquals ( "status" , "active" )
. orderByDesc ( "createdAt" )
. paginate ( 1 , 20 );
const json = criteria . toJSON ();
// {
// filters: [{ field: "status", operator: "equals", value: "active" }],
// orders: [{ field: "createdAt", direction: "desc" }],
// pagination: { page: 1, limit: 20, offset: 0 },
// search: undefined
// }
From Object
const criteria = Criteria . fromObject < User >({
filters: [
{ field: "status" , operator: "equals" , value: "active" },
{ field: "age" , operator: "greaterThan" , value: 18 },
],
orders: [{ field: "createdAt" , direction: "desc" }],
pagination: { page: 1 , limit: 20 , offset: 0 },
});
From Query Params
Perfect for REST APIs:
const criteria = Criteria . fromQueryParams < User >({
filters: {
"status:equals" : "active" ,
"age:greaterThan" : "18" ,
},
orderBy: [ "createdAt:desc" ],
pagination: { page: 1 , limit: 20 },
});
Cloning
Create independent copies for variations:
const baseCriteria = Criteria . create < User >()
. whereEquals ( "status" , "active" )
. orderByDesc ( "createdAt" );
// Clone and add more filters
const adminCriteria = baseCriteria . clone (). whereEquals ( "role" , "admin" );
const recentCriteria = baseCriteria
. clone ()
. where ( "createdAt" , "greaterThan" , lastWeek );
Checking State
const criteria = Criteria . create < User >(). whereEquals ( "status" , "active" );
criteria . hasFilters (); // true
criteria . hasOrders (); // false
criteria . hasPagination (); // true (default pagination)
criteria . hasSearch (); // false
Getting Components
const criteria = Criteria . create < User >()
. whereEquals ( "status" , "active" )
. where ( "age" , "greaterThan" , 18 )
. orderByDesc ( "createdAt" )
. paginate ( 2 , 10 );
// Get filters
const filters = criteria . getFilters ();
// [
// { field: "status", operator: "equals", value: "active" },
// { field: "age", operator: "greaterThan", value: 18 }
// ]
// Get orders
const orders = criteria . getOrders ();
// [{ field: "createdAt", direction: "desc" }]
// Get pagination
const pagination = criteria . getPagination ();
// { page: 2, limit: 10, offset: 10 }
// Get search
const search = criteria . getSearch ();
// undefined or string
Integration with Repository
class UserRepository extends Repository < User > {
async findActive (
page : number ,
limit : number
) : Promise < PaginatedResult < User >> {
const criteria = Criteria . create < User >()
. whereEquals ( "status" , "active" )
. whereNotNull ( "email" )
. orderByDesc ( "createdAt" )
. paginate ( page , limit );
return this . find ( criteria );
}
async search ( query : string ) : Promise < PaginatedResult < User >> {
const criteria = Criteria . create < User >()
. search ( query )
. limit ( 50 );
return this . find ( criteria );
}
}
Next Steps
Filters & Operators Complete guide to all filter operators and their usage
Ordering & Pagination Learn about sorting, pagination, and search
Query Params & Adapters API integration, field adapters, and quantifiers
PaginatedResult Working with paginated query results