@arcanalabs/query-builder
v0.0.7
Published
Composable Query Builder for TypeScript
Maintainers
Readme
@arcanalabs/query-builder
A composable, type-safe query builder for TypeScript and Prisma. Efficiently handles filtering, sorting, and pagination from request parameters.
Installation
npm install @arcanalabs/query-builderUsage
Basic Usage
Import QueryBuilder and QueryBuilderParams to start transforming request objects into Prisma-compatible arguments.
import { QueryBuilder, QueryBuilderParams } from '@arcanalabs/query-builder';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Assume 'request.query' comes from your API framework (Express, Fastify, etc.)
// e.g. ?filter[name]=Alice&page=2&perPage=10
async function getUsers(requestQuery: any) {
const params = QueryBuilderParams.fromRequest(requestQuery);
// Create params, applying logic like allowed filters
params.setAllowedFilters(['name', 'email']);
const qb = QueryBuilder.for(prisma.user, params);
// Execute query
const result = await qb.get();
return result;
// Returns: { data: [...], meta: { total, page, per_page, last_page }, aggregates: {} }
}Advanced Filtering
Name Mapping
Map public API parameters to different internal database fields.
const params = QueryBuilderParams.fromRequest(requestQuery)
.filterNameMapping({
'q': 'name', // ?filter[q]=Alice -> where: { name: 'Alice' }
'active': 'status'
});Custom Behaviors
Define custom logic for specific fields, such as date ranges or complex lookups.
const params = QueryBuilderParams.fromRequest(requestQuery)
.setFilterBehaviors({
'created_at': (value) => {
// ?filter[created_at]=2023-01-01
return {
gte: `${value}T00:00:00.000Z`,
lte: `${value}T23:59:59.999Z`
};
}
});Where In
Pass comma-separated values or an array to automatically generate in clauses.
// ?filter[status]=active,pending
// OR ?filter[status][]=active&filter[status][]=pending
// Generates: where: { status: { in: ['active', 'pending'] } }Relation Filtering
Use dot notation to filter by related records.
// ?filter[profile.age]=25
// Generates: where: { profile: { age: 25 } }Pagination
Pagination is handled automatically.
- Default
page: 1 - Default
perPage: 15 (Configurable viaparams.setPerPage(20))
Supports both per_page (snake_case) and perPage (camelCase) in query parameters.
License
MIT
