leonardocaldas / composable-query-builder
Installs: 2 704
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Type:composer-plugin
pkg:composer/leonardocaldas/composable-query-builder
Requires
- php: ^8.2
- composer-plugin-api: ^2.0
- laravel/framework: ^11.0
README
A composable, type-safe query builder for TypeScript and Prisma. Efficiently handles filtering, sorting, and pagination from request parameters.
Installation
npm install @arcanalabs/query-builder
Usage
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