A powerful DataTable integration for Prisma ORM with advanced filtering, sorting, pagination, global search, and relation support
npm install prisma-dtbash
npm install @your-org/prisma-datatable
or
yarn add @your-org/prisma-datatable
or
pnpm add @your-org/prisma-datatable
`
Quick Start
$3
`typescript
import { SchemaConfig } from "@your-org/prisma-datatable";
const USER_SCHEMA: SchemaConfig = {
model: "User",
searchableFields: ["name", "email", "posts.title"],
relations: {
posts: {
model: "Post",
isArray: true, // One-to-many relation
},
},
};
`
$3
`typescript
import { DTReqAdapter, DTResAdapter } from "@your-org/prisma-datatable";
import { prisma } from "./prisma";
async function getUsersDataTable(request: DataTableRequest) {
const adapter = new DTReqAdapter(request, USER_SCHEMA);
const prismaQuery = adapter.toPrismaQuery();
const [data, total] = await Promise.all([
prisma.user.findMany(prismaQuery),
prisma.user.count({ where: prismaQuery.where }),
]);
return DTResAdapter.fromPrisma(data, total, request);
}
`
$3
`typescript
// Express example
app.post("/users/datatable", async (req, res) => {
const result = await getUsersDataTable(req.body);
res.json(result);
});
// Fastify example
fastify.post("/users/datatable", async (request, reply) => {
const result = await getUsersDataTable(request.body);
return reply.send(result);
});
`
Request Examples
$3
`json
{
"page": 1,
"perPage": 10
}
`
$3
`json
{
"globalSearch": "john",
"page": 1,
"perPage": 10
}
`
Searches across all fields defined in searchableFields.
$3
`json
{
"filters": {
"status": { "type": "eq", "value": "active" },
"age": { "type": "gte", "value": 18 },
"email": { "type": "like", "value": "@gmail.com" },
"posts.published": { "type": "eq", "value": true }
}
}
`
$3
`json
{
"sort": [
{ "column": "createdAt", "direction": "desc" },
{ "column": "name", "direction": "asc" }
]
}
`
$3
`json
{
"includeRelations": ["posts", "profile"],
"page": 1
}
`
$3
`json
{
"selectColumns": ["id", "name", "email", "posts.title", "posts.createdAt"]
}
`
$3
`json
{
"page": 1,
"perPage": 20,
"globalSearch": "developer",
"filters": {
"status": { "type": "eq", "value": "active" },
"posts.published": { "type": "eq", "value": true }
},
"sort": [{ "column": "createdAt", "direction": "desc" }],
"includeRelations": ["posts", "profile"]
}
`
Response Format
`json
{
"data": [...],
"meta": {
"current_page": 1,
"per_page": 10,
"from": 1,
"to": 10,
"total": 45,
"last_page": 5
}
}
`
Filter Types
| Type | Description | Example |
| ----------- | --------------------------- | -------------------------------------------------- |
| eq | Equals | { "type": "eq", "value": "active" } |
| neq | Not equals | { "type": "neq", "value": "deleted" } |
| like | Contains (case-insensitive) | { "type": "like", "value": "john" } |
| gt | Greater than | { "type": "gt", "value": 18 } |
| gte | Greater than or equal | { "type": "gte", "value": 18 } |
| lt | Less than | { "type": "lt", "value": 65 } |
| lte | Less than or equal | { "type": "lte", "value": 65 } |
| in | In array | { "type": "in", "value": ["active", "pending"] } |
| notIn | Not in array | { "type": "notIn", "value": ["deleted"] } |
| between | Between range | { "type": "between", "value": [18, 65] } |
| isNull | Is null | { "type": "isNull" } |
| isNotNull | Is not null | { "type": "isNotNull" } |
Schema Config Options
`typescript
interface SchemaConfig {
model: string; // Prisma model name
jsonFields?: string[]; // JSON field names for JSON filtering
relations?: Record; // Nested relations
searchableFields?: string[]; // Fields for global search
isArray?: boolean; // Mark as array relation (one-to-many)
}
`
TypeScript Support
Full TypeScript support with type inference:
`typescript
import type {
DataTableRequest,
DataTableResponse,
} from "@your-org/prisma-datatable";
// Type-safe request
const request: DataTableRequest = {
page: 1,
perPage: 10,
filters: {
status: { type: "eq", value: "active" },
},
};
// Type-safe response
const response: DataTableResponse = await getUsersDataTable(request);
``