A powerful and intuitive utility for building Prisma where conditions dynamically. Simplify your query construction with a fluent API that handles type conversion, null checking, and Vietnamese text normalization automatically.
- Fluent API: Chain multiple conditions with method chaining
- Automatic Type Conversion: Convert strings to numbers, booleans automatically
- Null Safety: Skip null/undefined/empty values automatically
- Vietnamese Text Support: Built-in Vietnamese diacritics removal for search
- TypeScript Support: Full TypeScript support with proper type definitions
- Prisma Optimized: Designed specifically for Prisma ORM where conditions
npm install prisma-where-builderyarn add prisma-where-builderpnpm add prisma-where-builderimport WhereBuilder from 'prisma-where-builder';
// Initialize with default conditions
const defaultConditions = { deleted_at: null };
const whereBuilder = new WhereBuilder(defaultConditions);
// Build conditions dynamically
whereBuilder
.addConditionLike('title_vi', query.title_vi, { isNonField: true })
.addConditionLike('title_en', query.title_en)
.addConditionEqual('status', query.status)
.addConditionEqual('category_id', query.category_id, { isNumber: true })
.addConditionEqual('author_id', query.author_id, { isNumber: true });
// Get the final where object
const where = whereBuilder.build();
// Use with Prisma
const posts = await prisma.post.findMany({
where,
include: {
category: true,
author: true,
}
});const WhereBuilder = require('prisma-where-builder');
// Initialize with default conditions
const defaultConditions = { deleted_at: null };
const whereBuilder = new WhereBuilder(defaultConditions);
// Build conditions dynamically
whereBuilder
.addConditionLike('title_vi', query.title_vi, { isNonField: true })
.addConditionLike('title_en', query.title_en)
.addConditionEqual('status', query.status)
.addConditionEqual('category_id', query.category_id, { isNumber: true })
.addConditionEqual('author_id', query.author_id, { isNumber: true });
// Get the final where object
const where = whereBuilder.build();
// Use with Prisma
const posts = await prisma.post.findMany({
where,
include: {
category: true,
author: true,
}
});import WhereBuilder from 'prisma-where-builder';
// Rest of the code is the same as TypeScript example abovenew WhereBuilder(defaultConditions?: Record<string, any>)Create a new WhereBuilder instance with optional default conditions.
Parameters:
defaultConditions(optional): Initial conditions to include in all queries
Example:
const builder = new WhereBuilder({ deleted_at: null, active: true });Add an equality condition.
Parameters:
field: Field namevalue: Value to compareoptions:isNumber?: boolean- Convert value to numberisBoolean?: boolean- Convert value to boolean
Example:
builder.addConditionEqual('status', 'active');
builder.addConditionEqual('category_id', '123', { isNumber: true });
builder.addConditionEqual('is_published', 'true', { isBoolean: true });Add a not-equal condition.
Parameters:
field: Field namevalue: Value to compareoptions:isNumber?: boolean- Convert value to number
Example:
builder.addConditionNotEqual('status', 'deleted');
builder.addConditionNotEqual('user_id', '0', { isNumber: true });Add a contains/like condition for text search.
Parameters:
field: Field namevalue: Text to search foroptions:isNonField?: boolean- Remove Vietnamese diacritics for search
Example:
builder.addConditionLike('title', 'search term');
builder.addConditionLike('title_vi', 'tìm kiếm', { isNonField: true });Add a greater-than condition.
Parameters:
field: Field namevalue: Value to compareoptions:isNumber?: boolean- Convert value to number
Example:
builder.addConditionGreaterThan('price', '100', { isNumber: true });
builder.addConditionGreaterThan('created_at', new Date('2023-01-01'));Add a less-than condition.
Parameters:
field: Field namevalue: Value to compareoptions:isNumber?: boolean- Convert value to number
Example:
builder.addConditionLessThan('price', '1000', { isNumber: true });
builder.addConditionLessThan('expires_at', new Date());Build and return the final where conditions object.
Returns: Record<string, any> - Prisma-compatible where object
Example:
const whereConditions = builder.build();// Works the same for both TypeScript and JavaScript
const query = {
title: 'product',
category_id: '5',
min_price: '100',
max_price: '500',
status: 'active',
is_featured: 'true'
};
const whereBuilder = new WhereBuilder({ deleted_at: null });
whereBuilder
.addConditionLike('title', query.title)
.addConditionEqual('category_id', query.category_id, { isNumber: true })
.addConditionGreaterThan('price', query.min_price, { isNumber: true })
.addConditionLessThan('price', query.max_price, { isNumber: true })
.addConditionEqual('status', query.status)
.addConditionEqual('is_featured', query.is_featured, { isBoolean: true });
const products = await prisma.product.findMany({
where: whereBuilder.build(),
orderBy: { created_at: 'desc' }
});const searchBuilder = new WhereBuilder();
// Regular search
searchBuilder.addConditionLike('title_en', 'coffee shop');
// Vietnamese search with diacritics removal
// "cà phê" becomes "ca phe" for broader matching
searchBuilder.addConditionLike('title_vi', 'cà phê', { isNonField: true });
const results = await prisma.business.findMany({
where: searchBuilder.build()
});
// Output where conditions:
// {
// title_en: { contains: '%coffee shop%', mode: 'insensitive' },
// title_vi_non: { contains: '%ca phe%', mode: 'insensitive' }
// }const buildUserQuery = (filters) => {
const builder = new WhereBuilder({ active: true });
builder.addConditionLike('name', filters.name);
builder.addConditionLike('email', filters.email);
builder.addConditionEqual('role', filters.role);
builder.addConditionGreaterThan('age', filters.min_age, { isNumber: true });
builder.addConditionLessThan('age', filters.max_age, { isNumber: true });
return builder.build();
};
// Usage
const userFilters = { name: 'john', role: 'admin', min_age: '18', min_age: '90' };
const users = await prisma.user.findMany({
where: buildUserQuery(userFilters)
});
// Output where conditions:
// {
// active: true,
// name: { contains: '%john%', mode: 'insensitive' },
// role: 'admin',
// age: { gt: 18 }
// }- Reduced Boilerplate: Eliminate repetitive null checks and type conversions
- Cleaner Code: Fluent API makes query building more readable
- Type Safety: Automatic type conversion with proper TypeScript support
- Vietnamese Support: Built-in support for Vietnamese text search
- Error Prevention: Automatic handling of null/undefined values
- Consistent: Standardized way to build where conditions across your application
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built for Prisma ORM
- Inspired by the need for cleaner query building in Node.js applications
- Vietnamese text normalization for better search experience