À propos du projet
# @querry-kit/nest
Assistants NestJS consolidés pour les API Query Kit : projection de champs, services de requête de style Prisma, politiques CASL, décorateurs OpenAPI, pipes, DTO de pagination et utilitaires d’objet.
## 🌐 Écosystème Querry Kit
La [vue d’ensemble Querry Kit](https://querry-kit.github.io/querry-kit/) relie les trois packages principaux :
- [`@querry-kit/nest`](https://github.com/querry-kit/nest) fournit l’API NestJS et les patterns de contrôleur.
- [`@querry-kit/nuxt`](https://github.com/querry-kit/nuxt) fournit des clients API typés et des primitives de données Vue/Nuxt headless.
- [`@querry-kit/nuxt-ui`](https://github.com/querry-kit/nuxt-ui) fournit des contrôles de table Nuxt UI construits sur ces primitives.
## 📦 Installation
```sh
pnpm add @querry-kit/nest
pnpm add @nestjs/common @nestjs/core @nestjs/swagger class-transformer class-validator reflect-metadata
```
Pour l’adaptateur CASL optionnel :
```sh
pnpm add @casl/ability @casl/prisma
```
La version actuelle du package est publiée sur npm. npm est le canal de distribution principal.
Les tags de release GitHub restent disponibles comme solution de repli :
```sh
pnpm add github:querry-kit/nest#v0.0.1
```
## 🚀 Workflow de release
Les releases sont pilotées par Changesets et GitHub Actions. La branche `main` ne contient pas de fichiers `dist` commités ; elle contient uniquement la source, le README et la configuration des workflows.
Les changements visibles dans le package doivent inclure un changeset :
```sh
pnpm changeset
```
Lorsque des changements arrivent sur `main`, le workflow `changesets` crée ou met à jour une PR de release. Cette PR contient le bump de version et les mises à jour du changelog produites par :
```sh
pnpm changeset version
```
Le workflow de publication npm utilise npm Trusted Publishing via GitHub Actions OIDC. Le package npm doit être connecté à ce dépôt et à ce workflow dans les paramètres de publication du package npm :
- Dépôt : `querry-kit/nest`
- Fichier de workflow : `release.yml`
- Environnement : non défini
Après la fusion de la PR de release, le workflow `npm publish` s’exécute pour les changements de version/changelog. Il exécute les vérifications du package, construit `dist` en CI, publie `@querry-kit/nest` sur npm, tague le commit de release en `vX.Y.Z` et crée une GitHub Release.
Les consommateurs doivent installer depuis npm :
```sh
pnpm add @querry-kit/nest
```
## 🧩 Utilisation
`ResourceQuery` couvre le flux de contrôleur courant : analyser les `fields` optionnels, fusionner les includes requis par l’endpoint avec les valeurs `include` du client, générer les includes Prisma pour les relations sélectionnées, appeler un `QueryService`, mapper les modèles vers des DTO et projeter la réponse.
```ts
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),
});
}
```
Créez des services de ressource avec `QueryService` et un délégué compatible Prisma :
```ts
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);
}
}
```
Des sous-chemins ciblés sont disponibles pour des imports plus légers :
```ts
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 est optionnel. Passez `ability` uniquement lorsque l’endpoint doit fusionner une clause `where` tenant compte de l’autorisation via `QueryService` ; omettez-le pour les API qui n’utilisent pas CASL.
```ts
import { createCaslAccessibleWhere } from '@querry-kit/nest/casl';
super(prisma.customer, {
subject: 'Customer',
accessibleWhere: createCaslAccessibleWhere({ action: 'read' }),
});
```
Lorsqu’une ability est passée à `query`, le service combine la clause where CASL avec les filtres utilisateur sous la forme `{ AND: [accessibleWhere, parsedWhere] }`.
Pour les permissions de réponse au niveau des champs, filtrez le DTO complété sans le muter :
```ts
return filterCaslFields(dto, 'Customer', ability);
```
L’assistant utilise l’action `read` par défaut. Passez `{ action: RoleAction.READ }` lorsqu’une application utilise des actions en majuscules ou basées sur des enums. Il filtre uniquement les champs DTO sérialisés ; continuez à passer l’ability à `QueryService` pour contraindre aussi les lectures en base de données.
## 🎯 Fields
`fields` est optionnel par défaut. Lorsqu’il est omis, Query Kit renvoie la réponse DTO complète. Lorsqu’il est présent, il valide la syntaxe et les champs sélectionnés, ajoute les includes de relation requis et projette les DTO renvoyés. Les accolades externes sont optionnelles, donc `{id,title}` est équivalent à `id,title`.
```txt
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}
```
Une valeur vide explicite (`?fields=`) ou une sélection externe vide (`?fields={}`) renvoie `{}`. Les sélections imbriquées vides sont également valides : `items{}` produit des objets item vides, tandis que `meta{page}` ne conserve que les métadonnées de page demandées. Une valeur contenant uniquement des espaces reste invalide.
Utilisez `prepareFieldsQuery` directement lorsqu’un contrôleur a besoin d’une orchestration de service personnalisée :
```ts
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
- [Getting Started](https://querry-kit.github.io/querry-kit/docs/nest/guide/getting-started)
- [Complete API Example](https://querry-kit.github.io/querry-kit/docs/nest/guide/example-app)
- [CRUD Controller](https://querry-kit.github.io/querry-kit/docs/nest/guide/crud-controller)
- [Fields](https://querry-kit.github.io/querry-kit/docs/nest/api/fields/)
- [Query Service](https://querry-kit.github.io/querry-kit/docs/nest/api/query-service)
- [DTOs and Pagination](https://querry-kit.github.io/querry-kit/docs/nest/api/dtos-pagination)
- [OpenAPI Decorators](https://querry-kit.github.io/querry-kit/docs/nest/api/openapi)
- [CASL](https://querry-kit.github.io/querry-kit/docs/nest/api/casl)
- [API Reference](https://querry-kit.github.io/querry-kit/docs/nest/api/)
## 🛠 Développement
```sh
pnpm install
pnpm lint
pnpm check
pnpm test
pnpm test:coverage
pnpm build
```
La liste d’autorisation de build du workspace permet les scripts natifs requis par la chaîne d’outils de test et de documentation, y compris le watcher de fichiers de Parcel.
`pnpm test:coverage` collecte tous les fichiers source, affiche le résumé de couverture et écrit les rapports HTML et LCOV dans `coverage/`. GitHub Actions exécute la même commande et conserve le rapport comme artefact de workflow.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.