npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@querry-kit/nest

v1.0.0

Published

Consolidated NestJS helpers for Query Kit fields, Prisma-style query services, CASL policies, decorators, pipes, and response projection.

Readme

@querry-kit/nest

npm npm downloads license node bundle size TypeScript Buy Me a Coffee

build test coverage lint changesets npm publish

Consolidated NestJS helpers for Query Kit APIs: fields projection, Prisma-style query services, CASL policies, OpenAPI decorators, pipes, pagination DTOs, and object utilities.

📖 Documentation: Querry Kit Nest documentation

🌐 Querry Kit Ecosystem

The Querry Kit overview connects the three core packages:

📚 Table of Contents

📦 Install

pnpm add @querry-kit/nest
pnpm add @nestjs/common @nestjs/core @nestjs/swagger class-transformer class-validator reflect-metadata

For the optional CASL adapter:

pnpm add @casl/ability @casl/prisma

The current package version is published on npm. npm is the primary distribution channel.

GitHub release tags remain available as a fallback:

pnpm add github:querry-kit/nest#v0.0.1

🚀 Release Workflow

Releases are driven by Changesets and GitHub Actions. The main branch does not contain committed dist files; it only contains source, the README, and workflow configuration.

Package-visible changes should include a changeset:

pnpm changeset

When changes land on main, the changesets workflow creates or updates a release PR. That PR contains the version bump and changelog updates produced by:

pnpm changeset version

The npm publish workflow uses npm Trusted Publishing through GitHub Actions OIDC. The npm package must be connected to this repository and workflow in the npm package publishing settings:

  • Repository: querry-kit/nest
  • Workflow file: release.yml
  • Environment: unset

After the release PR is merged, the npm publish workflow runs for the version/changelog changes. It runs package checks, builds dist in CI, publishes @querry-kit/nest to npm, tags the release commit as vX.Y.Z, and creates a GitHub Release.

Consumers should install from npm:

pnpm add @querry-kit/nest

🧩 Usage

ResourceQuery covers the common controller flow: parse optional fields, merge endpoint-required includes with client include values, generate Prisma includes for selected relations, call a QueryService, map models to DTOs, and project the response.

import { Get, Query, Req } from '@nestjs/common';
import { ApiErrorResponses, ApiPaginatedResponse, ApiResourceQuery, QueryDTO, ResourceQuery } from '@querry-kit/nest';

@Get()
@ApiResourceQuery()
@ApiPaginatedResponse({ model: CustomerDTO })
@ApiErrorResponses({ badRequestDescription: 'Invalid query parameter.' })
async query(@Req() req: AuthRequest, @Query() query: QueryDTO<CustomerTypeMap>) {
  return ResourceQuery.query({
    service: this.customersService,
    query,
    schema: CustomerDTO,
    ability: req.ability,
    map: (customer, ability) => CustomerDTO.fromModel(customer, ability),
  });
}

Create resource services with QueryService and a Prisma-compatible delegate:

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

interface CustomerTypeMap extends BaseDelegateTypeMap {
  select: Prisma.CustomerSelect;
  include: Prisma.CustomerInclude;
  whereInput: Prisma.CustomerWhereInput;
  orderByWithRelationInput: Prisma.CustomerOrderByWithRelationInput;
  whereUniqueInput: Prisma.CustomerWhereUniqueInput;
  scalarFieldEnum: Prisma.CustomerScalarFieldEnum;
}

@Injectable()
export class CustomersService extends QueryService<typeof PrismaService.prototype.customer, CustomerTypeMap> {
  constructor(prisma: PrismaService) {
    super(prisma.customer);
  }
}

Focused subpaths are available for smaller imports:

import { createCaslAccessibleWhere, filterCaslFields } from '@querry-kit/nest/casl';
import { ApiResourceQuery } from '@querry-kit/nest/decorators';
import { Fields } from '@querry-kit/nest/fields';
import { parseObject } from '@querry-kit/nest/object';
import { QueryService } from '@querry-kit/nest/query-service';

🔐 CASL

CASL is optional. Pass ability only when the endpoint should merge an authorization-aware where clause through QueryService; omit it for APIs that do not use CASL.

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

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

When an ability is passed to query, the service combines the CASL where clause with user filters as { AND: [accessibleWhere, parsedWhere] }.

For field-level response permissions, filter the completed DTO without mutating it:

return filterCaslFields(dto, 'Customer', ability);

The helper uses the read action by default. Pass { action: RoleAction.READ } when an application uses uppercase or enum-backed actions. It filters serialized DTO fields only; keep passing the ability to QueryService to constrain database reads too.

🎯 Fields

fields is optional by default. When omitted, Query Kit returns the complete DTO response. When present, it validates the syntax and selected fields, adds required relation includes, and projects the returned DTOs. Outer braces are optional, so {id,title} is equivalent to id,title.

GET /books?fields=id,title
GET /books?fields={id,title}
GET /books?fields=items{id,title},meta{page,perPage,itemCount,pageCount}
GET /books?fields=items{},meta{page}

An explicit empty value (?fields=) or empty outer selection (?fields={}) returns {}. Empty nested selections are also valid: items{} produces empty item objects, while meta{page} keeps only the requested page metadata. A value containing only whitespace remains invalid.

Use prepareFieldsQuery directly when a controller needs custom service orchestration:

import { Fields, prepareFieldsQuery } from '@querry-kit/nest/fields';

const prepared = prepareFieldsQuery({
  fields: query.fields,
  include: query.include,
  schema: BookDTO,
  requiredInclude: { author: true },
});

const { items, pageMeta } = await booksService.query({ ...query, include: prepared.include });

return {
  items: Fields.project(items.map(BookDTO.fromModel), prepared.projection),
  meta: Fields.project(pageMeta, prepared.metaProjection),
};

📖 Documentation

🛠 Development

pnpm install
pnpm lint
pnpm check
pnpm test
pnpm test:coverage
pnpm build

pnpm test:coverage collects all source files, prints the coverage summary, and writes HTML and LCOV reports to coverage/. GitHub Actions runs the same command and retains the report as a workflow artifact.