Skip to content

πŸš€ Getting Started ​

Install the package and peer dependencies:

sh
pnpm add @querry-kit/nest-prisma-query
pnpm add @nestjs/common @nestjs/swagger class-transformer class-validator

🧩 Service Setup ​

Pass a Prisma-compatible delegate to QueryService. The type map binds generated Prisma model types to the generic query DTOs.

ts
import { Injectable } from '@nestjs/common';
import { QueryService, type BaseDelegateTypeMap } from '@querry-kit/nest-prisma-query';
import { Prisma, PrismaService } from '../prisma';

interface RecipeTypeMap extends BaseDelegateTypeMap {
  select: Prisma.RecipeSelect;
  include: Prisma.RecipeInclude;
  whereInput: Prisma.RecipeWhereInput;
  orderByWithRelationInput: Prisma.RecipeOrderByWithRelationInput;
  whereUniqueInput: Prisma.RecipeWhereUniqueInput;
  scalarFieldEnum: Prisma.RecipeScalarFieldEnum;
}

@Injectable()
export class RecipesService extends QueryService<typeof PrismaService.prototype.recipe, RecipeTypeMap> {
  constructor(prisma: PrismaService) {
    super(prisma.recipe);
  }
}

πŸ“„ Controller Pagination ​

Use QueryDTO, PaginatedDTO, and ApiPaginatedResponse in app-level controllers.

ts
import { Controller, Get, Query } from '@nestjs/common';
import { ApiPaginatedResponse, PaginatedDTO, QueryDTO } from '@querry-kit/nest-prisma-query';

@Controller('recipes')
export class RecipesController {
  constructor(private readonly recipesService: RecipesService) {}

  @Get()
  @ApiPaginatedResponse({ model: RecipeDTO })
  async query(@Query() query: QueryDTO<RecipeTypeMap>): Promise<PaginatedDTO<RecipeDTO>> {
    const { items, pageMeta } = await this.recipesService.query(query);
    return new PaginatedDTO(items.map(RecipeDTO.fromModel), pageMeta);
  }
}

βœ… Validation Pipe ​

PageOptionsDTO supports Nest's validation and transformation flow.

ts
app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }));

page and perPage are converted to numbers, default to 1 and 10, and reject invalid values.

🎯 Fields Query Integration ​

QueryDTO exposes fields?: string, but this package intentionally does not parse or project it. Use @querry-kit/nest-fields-query in the controller:

ts
const projection = Fields.parseAndValidate(query.fields, recipeSchema);
const include = projection ? Fields.include(projection, recipeSchema, query.include) : query.include;
const { items, pageMeta } = await recipesService.query({ ...query, include });

return new PaginatedDTO(Fields.project(items.map(RecipeDTO.fromModel), projection), pageMeta);

πŸ” CASL Adapter ​

Install CASL only when the app needs it:

sh
pnpm add @casl/ability @casl/prisma

Then wire the optional adapter into QueryService.

ts
import { createCaslAccessibleWhere } from '@querry-kit/nest-prisma-query/casl';

super(prisma.recipe, {
  subject: 'Recipe',
  accessibleWhere: createCaslAccessibleWhere({ action: 'read' }),
});

πŸ“˜ Example Project ​

The repository includes a small in-memory NestJS API:

sh
pnpm examples:check
pnpm examples:build

Continue with the focused guides for service methods, pagination DTOs, Swagger, CASL, fields-query integration, and the example project.

Released under the MIT License.