প্রকল্প সম্পর্কে

# @querry-kit/nest Query Kit API-এর জন্য একত্রিত NestJS helper: fields projection, Prisma-ধাঁচের query service, CASL policy, OpenAPI decorator, pipe, pagination DTO এবং object utility। ## 🌐 Querry Kit ইকোসিস্টেম [Querry Kit overview](https://querry-kit.github.io/querry-kit/) তিনটি মূল প্যাকেজকে সংযুক্ত করে: - [`@querry-kit/nest`](https://github.com/querry-kit/nest) NestJS API ও controller pattern প্রদান করে। - [`@querry-kit/nuxt`](https://github.com/querry-kit/nuxt) typed API client এবং headless Vue/Nuxt data primitive প্রদান করে। - [`@querry-kit/nuxt-ui`](https://github.com/querry-kit/nuxt-ui) সেই primitive-এর উপর নির্মিত Nuxt UI table control প্রদান করে। ## 📦 ইনস্টল ```sh pnpm add @querry-kit/nest pnpm add @nestjs/common @nestjs/core @nestjs/swagger class-transformer class-validator reflect-metadata ``` ঐচ্ছিক CASL adapter-এর জন্য: ```sh pnpm add @casl/ability @casl/prisma ``` বর্তমান প্যাকেজ সংস্করণ npm-এ প্রকাশিত। npm হলো প্রধান distribution channel। GitHub release tag fallback হিসেবে উপলব্ধ থাকে: ```sh pnpm add github:querry-kit/nest#v0.0.1 ``` ## 🚀 Release Workflow Release পরিচালিত হয় Changesets এবং GitHub Actions দ্বারা। `main` branch-এ committed `dist` ফাইল থাকে না; এতে শুধু source, README এবং workflow configuration থাকে। Package-visible পরিবর্তনে changeset থাকা উচিত: ```sh pnpm changeset ``` পরিবর্তন `main`-এ এলে `changesets` workflow একটি release PR তৈরি বা update করে। সেই PR-এ version bump এবং changelog update থাকে, যা তৈরি হয়: ```sh pnpm changeset version ``` npm publish workflow GitHub Actions OIDC-এর মাধ্যমে npm Trusted Publishing ব্যবহার করে। npm package publishing settings-এ npm package-টি এই repository ও workflow-এর সাথে সংযুক্ত থাকতে হবে: - Repository: `querry-kit/nest` - Workflow file: `release.yml` - Environment: unset Release PR merge হওয়ার পর `npm publish` workflow version/changelog পরিবর্তনের জন্য চলে। এটি package check চালায়, CI-তে `dist` build করে, `@querry-kit/nest` npm-এ publish করে, release commit-কে `vX.Y.Z` হিসেবে tag করে এবং GitHub Release তৈরি করে। ব্যবহারকারীদের npm থেকে ইনস্টল করা উচিত: ```sh pnpm add @querry-kit/nest ``` ## 🧩 ব্যবহার `ResourceQuery` সাধারণ controller flow কভার করে: ঐচ্ছিক `fields` parse করা, endpoint-required include-এর সাথে client `include` মান merge করা, নির্বাচিত relation-এর জন্য Prisma include তৈরি করা, `QueryService` call করা, model থেকে DTO mapping করা এবং response project করা। ```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), }); } ``` `QueryService` এবং Prisma-compatible delegate দিয়ে resource service তৈরি করুন: ```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); } } ``` ছোট import-এর জন্য focused subpath উপলব্ধ: ```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 ঐচ্ছিক। `ability` শুধু তখনই pass করুন যখন endpoint `QueryService`-এর মাধ্যমে authorization-aware `where` clause merge করবে; CASL ব্যবহার না করা API-এর জন্য এটি omit করুন। ```ts import { createCaslAccessibleWhere } from '@querry-kit/nest/casl'; super(prisma.customer, { subject: 'Customer', accessibleWhere: createCaslAccessibleWhere({ action: 'read' }), }); ``` `query`-তে ability pass করা হলে service CASL where clause এবং user filter-কে `{ AND: [accessibleWhere, parsedWhere] }` হিসেবে combine করে। Field-level response permission-এর জন্য completed DTO mutate না করে filter করুন: ```ts return filterCaslFields(dto, 'Customer', ability); ``` Helper ডিফল্টভাবে `read` action ব্যবহার করে। Application uppercase বা enum-backed action ব্যবহার করলে `{ action: RoleAction.READ }` pass করুন। এটি শুধু serialized DTO field filter করে; database read constrain করতেও `QueryService`-এ ability pass করা চালিয়ে যান। ## 🎯 Fields `fields` ডিফল্টভাবে ঐচ্ছিক। Omit করলে Query Kit সম্পূর্ণ DTO response return করে। Present থাকলে এটি syntax ও selected field validate করে, required relation include যোগ করে এবং returned DTO project করে। Outer brace ঐচ্ছিক, তাই `{id,title}` এবং `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} ``` স্পষ্ট empty value (`?fields=`) বা empty outer selection (`?fields={}`) `{}` return করে। Empty nested selection-ও বৈধ: `items{}` empty item object তৈরি করে, আর `meta{page}` শুধু requested page metadata রাখে। শুধু whitespace থাকা value invalid থাকে। Controller-এ custom service orchestration দরকার হলে সরাসরি `prepareFieldsQuery` ব্যবহার করুন: ```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), }; ``` ## 📖 ডকুমেন্টেশন - [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/) ## 🛠 Development ```sh pnpm install pnpm lint pnpm check pnpm test pnpm test:coverage pnpm build ``` Workspace build allowlist test এবং documentation toolchain-এর প্রয়োজনীয় native script অনুমোদন করে, যার মধ্যে Parcel-এর file watcher আছে। `pnpm test:coverage` সব source file সংগ্রহ করে, coverage summary print করে এবং `coverage/`-এ HTML ও LCOV report লেখে। GitHub Actions একই command চালায় এবং report workflow artifact হিসেবে রাখে।