prisma-query
convert query params to prisma args
Usage
processFindAllQuery
import { processFindAllQuery } from 'prisma-query';
const req = {
query: {
_sort: 'likes',
_expand: 'comments',
_page: '9',
_limit: '10',
},
};
const args = processFindAllQuery(req.query);
console.log(args);
const posts = await prismaClient.posts.findMany(args);
processFindOneQuery
import { processFindOneQuery } from 'prisma-query';
const req = {
query: { _expand: 'comments', 'comments.user.name': 'justin' },
};
const args = processFindOneQuery(req.query);
console.log(JSON.stringify(args, null, 2));
const post = await prismaClient.post.findUnique(args);
QueryModifier
when passing numeric values in query, distinction can't be made between numeric or string values, we have two ways to solve for this
First ->
in case of number, we can wrap the value in num() function like ?id=num(12)
in case of boolean, we can wrap the value in bool() function like ?vip=bool(true)
Second ->
we can define queryModifier for the model and pass it as second argument of processFindAllQuery or processFindOneQuery
NOTE: this will work only for first level, for filters in nested models wrapping with num() and bool() is necessary
import { processFindAllQuery, QueryModifier } from 'prisma-query';
export type Guest = {
id: number;
fans: number;
name: string;
vip: boolean;
eventId: number;
eventSignupId: number | null;
createdAt: Date;
updatedAt: Date;
};
const guestQueryModifier: QueryModifier<Guest> = {
numericValues: ['id', 'fans', 'eventId', 'eventSignupId'],
booleanValues: ['vip'],
};
const req = {
query: {
eventId: '1',
fans_gt: '1000',
vip: 'true',
'eventSignup.verified': 'bool(true)',
_expand: 'events',
'events.attendees_gt': 'num(1000)',
},
};
const args = processFindAllQuery(req.query, guestQueryModifier);
console.log(JSON.stringify(args, null, 2));
Examples
const routeToFindManyArgs = {
'/events?id=6&id=7': { where: { id: { in: [6, 7] } } },
'/events?_expand=guests&guests.name_like=John': {
include: {
guests: {
where: { name: { contains: 'John', mode: 'insensitive' } },
},
},
},
'/events?_expand=guests&guests.vip=bool(false)': {
include: { guests: { where: { vip: false } } },
},
'/events?hosts.every.name_like=Hitesh&_expand=hosts': {
where: {
hosts: { every: { name: { contains: 'Hitesh', mode: 'insensitive' } } },
},
include: {
hosts: true,
},
},
'/events?_expand=hosts&hosts.name_like=Hitesh': {
include: {
hosts: { where: { name: { contains: 'Hitesh', mode: 'insensitive' } } },
},
},
'/events?_expand=guests&guests.name_like=Rahul&guests.vip=bool(true)': {
include: {
guests: {
where: {
vip: true,
name: { contains: 'Rahul', mode: 'insensitive' },
},
},
},
},
'/guests?eventSignupId_ne=null': {
where: { eventSignupId: { not: null } },
},
'/eventCategories?_expand=events.hosts&_expand=events.eventMetadata': {
include: {
events: { include: { eventMetadata: true, hosts: true } },
},
},
'/events?_sort=startTime&_sort=id&_order=asc': {
orderBy: [{ startTime: 'asc' }, { id: 'asc' }],
},
'/events?_sort=duration,id&_order=desc': {
orderBy: [{ duration: 'desc' }, { id: 'asc' }],
},
'/guests?_page=2&_limit=5': { skip: 5, take: 5 },
'/guests?_start=0&_end=10': {
skip: 0,
take: 10,
},
'/events?_expand=guests&guests.fans_gt=num(21000)': {
include: { guests: { where: { fans: { gt: 21000 } } } },
},
'/guests?eventId=1&fans_gt=21000': {
where: { eventId: 1, fans: { gt: 21000 } },
},
};