[{"data":1,"prerenderedAt":1584},["ShallowReactive",2],{"content-navigation":3,"content-search":200,"\u002Fdocs\u002Fnest\u002Fapi\u002Fdtos-pagination":1112},[4],{"title":5,"path":6,"stem":7,"children":8,"page":73},"Docs","\u002Fdocs","docs",[9,95,143],{"title":10,"path":11,"stem":12,"children":13},"@querry-kit\u002Fnest","\u002Fdocs\u002Fnest","docs\u002Fnest\u002Findex",[14,15,57,60,74],{"title":10,"path":11,"stem":12},{"title":16,"path":17,"stem":18,"children":19},"API Reference","\u002Fdocs\u002Fnest\u002Fapi","docs\u002Fnest\u002Fapi\u002Findex",[20,21,25,29,33,37,41,45,49,53],{"title":16,"path":17,"stem":18},{"title":22,"path":23,"stem":24},"CASL","\u002Fdocs\u002Fnest\u002Fapi\u002Fcasl","docs\u002Fnest\u002Fapi\u002Fcasl",{"title":26,"path":27,"stem":28},"Decorators","\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators","docs\u002Fnest\u002Fapi\u002Fdecorators",{"title":30,"path":31,"stem":32},"Decorators, Pipes, Utilities","\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators-pipes-utils","docs\u002Fnest\u002Fapi\u002Fdecorators-pipes-utils",{"title":34,"path":35,"stem":36},"DTOs and Pagination","\u002Fdocs\u002Fnest\u002Fapi\u002Fdtos-pagination","docs\u002Fnest\u002Fapi\u002Fdtos-pagination",{"title":38,"path":39,"stem":40},"Fields","\u002Fdocs\u002Fnest\u002Fapi\u002Ffields","docs\u002Fnest\u002Fapi\u002Ffields",{"title":42,"path":43,"stem":44},"Object Utilities","\u002Fdocs\u002Fnest\u002Fapi\u002Fobject-utils","docs\u002Fnest\u002Fapi\u002Fobject-utils",{"title":46,"path":47,"stem":48},"OpenAPI Decorators","\u002Fdocs\u002Fnest\u002Fapi\u002Fopenapi","docs\u002Fnest\u002Fapi\u002Fopenapi",{"title":50,"path":51,"stem":52},"Pipes","\u002Fdocs\u002Fnest\u002Fapi\u002Fpipes","docs\u002Fnest\u002Fapi\u002Fpipes",{"title":54,"path":55,"stem":56},"Query Service","\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service","docs\u002Fnest\u002Fapi\u002Fquery-service",{"title":10,"path":58,"stem":59},"\u002Fdocs\u002Fnest\u002Fchangelog","docs\u002Fnest\u002Fchangelog",{"title":61,"path":62,"stem":63,"children":64,"page":73},"Concepts","\u002Fdocs\u002Fnest\u002Fconcepts","docs\u002Fnest\u002Fconcepts",[65,69],{"title":66,"path":67,"stem":68},"Fields Projection","\u002Fdocs\u002Fnest\u002Fconcepts\u002Ffields","docs\u002Fnest\u002Fconcepts\u002Ffields",{"title":70,"path":71,"stem":72},"Query Transformation","\u002Fdocs\u002Fnest\u002Fconcepts\u002Fquery-transform","docs\u002Fnest\u002Fconcepts\u002Fquery-transform",false,{"title":75,"path":76,"stem":77,"children":78,"page":73},"Guide","\u002Fdocs\u002Fnest\u002Fguide","docs\u002Fnest\u002Fguide",[79,83,87,91],{"title":80,"path":81,"stem":82},"CRUD Controller","\u002Fdocs\u002Fnest\u002Fguide\u002Fcrud-controller","docs\u002Fnest\u002Fguide\u002Fcrud-controller",{"title":84,"path":85,"stem":86},"Complete API Example","\u002Fdocs\u002Fnest\u002Fguide\u002Fexample-app","docs\u002Fnest\u002Fguide\u002Fexample-app",{"title":88,"path":89,"stem":90},"Getting Started","\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started","docs\u002Fnest\u002Fguide\u002Fgetting-started",{"title":92,"path":93,"stem":94},"NestJS main.ts","\u002Fdocs\u002Fnest\u002Fguide\u002Fmain-bootstrap","docs\u002Fnest\u002Fguide\u002Fmain-bootstrap",{"title":96,"path":97,"stem":98,"children":99},"@querry-kit\u002Fnuxt-ui","\u002Fdocs\u002Fnuxt-ui","docs\u002Fnuxt-ui\u002Findex",[100,101,110,135],{"title":96,"path":97,"stem":98},{"title":102,"path":103,"stem":104,"children":105,"page":73},"Api","\u002Fdocs\u002Fnuxt-ui\u002Fapi","docs\u002Fnuxt-ui\u002Fapi",[106],{"title":107,"path":108,"stem":109},"Types and text customization","\u002Fdocs\u002Fnuxt-ui\u002Fapi\u002Ftypes","docs\u002Fnuxt-ui\u002Fapi\u002Ftypes",{"title":111,"path":112,"stem":113,"children":114,"page":73},"Components","\u002Fdocs\u002Fnuxt-ui\u002Fcomponents","docs\u002Fnuxt-ui\u002Fcomponents",[115,119,123,127,131],{"title":116,"path":117,"stem":118},"Filtering","\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ffiltering","docs\u002Fnuxt-ui\u002Fcomponents\u002Ffiltering",{"title":120,"path":121,"stem":122},"Column options","\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Foptions","docs\u002Fnuxt-ui\u002Fcomponents\u002Foptions",{"title":124,"path":125,"stem":126},"Pagination","\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fpagination","docs\u002Fnuxt-ui\u002Fcomponents\u002Fpagination",{"title":128,"path":129,"stem":130},"Sorting","\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fsorting","docs\u002Fnuxt-ui\u002Fcomponents\u002Fsorting",{"title":132,"path":133,"stem":134},"Table toolbar","\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ftoolbar","docs\u002Fnuxt-ui\u002Fcomponents\u002Ftoolbar",{"title":75,"path":136,"stem":137,"children":138,"page":73},"\u002Fdocs\u002Fnuxt-ui\u002Fguide","docs\u002Fnuxt-ui\u002Fguide",[139],{"title":140,"path":141,"stem":142},"Getting started","\u002Fdocs\u002Fnuxt-ui\u002Fguide\u002Fgetting-started","docs\u002Fnuxt-ui\u002Fguide\u002Fgetting-started",{"title":144,"path":145,"stem":146,"children":147},"@querry-kit\u002Fnuxt","\u002Fdocs\u002Fnuxt","docs\u002Fnuxt\u002Findex",[148,149,174],{"title":144,"path":145,"stem":146},{"title":16,"path":150,"stem":151,"children":152},"\u002Fdocs\u002Fnuxt\u002Fapi","docs\u002Fnuxt\u002Fapi\u002Findex",[153,154,158,162,166,170],{"title":16,"path":150,"stem":151},{"title":155,"path":156,"stem":157},"API","\u002Fdocs\u002Fnuxt\u002Fapi\u002Fapi","docs\u002Fnuxt\u002Fapi\u002Fapi",{"title":159,"path":160,"stem":161},"Autocomplete","\u002Fdocs\u002Fnuxt\u002Fapi\u002Fautocomplete","docs\u002Fnuxt\u002Fapi\u002Fautocomplete",{"title":163,"path":164,"stem":165},"Table","\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftable","docs\u002Fnuxt\u002Fapi\u002Ftable",{"title":167,"path":168,"stem":169},"Types","\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes","docs\u002Fnuxt\u002Fapi\u002Ftypes",{"title":171,"path":172,"stem":173},"Utils","\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils","docs\u002Fnuxt\u002Fapi\u002Futils",{"title":75,"path":175,"stem":176,"children":177,"page":73},"\u002Fdocs\u002Fnuxt\u002Fguide","docs\u002Fnuxt\u002Fguide",[178,181,185,189,192,196],{"title":159,"path":179,"stem":180},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fautocomplete","docs\u002Fnuxt\u002Fguide\u002Fautocomplete",{"title":182,"path":183,"stem":184},"Controller Contract","\u002Fdocs\u002Fnuxt\u002Fguide\u002Fcontroller-contract","docs\u002Fnuxt\u002Fguide\u002Fcontroller-contract",{"title":186,"path":187,"stem":188},"Example app","\u002Fdocs\u002Fnuxt\u002Fguide\u002Fexample-app","docs\u002Fnuxt\u002Fguide\u002Fexample-app",{"title":140,"path":190,"stem":191},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fgetting-started","docs\u002Fnuxt\u002Fguide\u002Fgetting-started",{"title":193,"path":194,"stem":195},"Query conventions","\u002Fdocs\u002Fnuxt\u002Fguide\u002Fquery-conventions","docs\u002Fnuxt\u002Fguide\u002Fquery-conventions",{"title":197,"path":198,"stem":199},"Remote tables","\u002Fdocs\u002Fnuxt\u002Fguide\u002Ftable","docs\u002Fnuxt\u002Fguide\u002Ftable",[201,205,209,215,220,225,230,233,237,242,247,252,257,262,265,269,272,276,281,286,291,294,298,303,308,313,318,323,328,334,337,341,346,351,356,359,363,366,370,373,377,380,384,389,394,399,404,409,414,419,424,429,432,435,439,444,448,453,457,461,465,469,473,477,481,485,489,492,496,501,506,511,516,519,523,528,533,538,542,545,549,554,557,561,566,571,576,581,586,591,594,598,603,608,613,618,622,627,632,635,639,644,647,652,657,660,664,669,674,679,682,685,690,695,700,703,706,710,714,718,721,724,729,733,736,739,743,747,751,754,757,762,766,768,771,776,781,786,789,794,799,802,805,810,815,820,825,830,833,836,841,846,849,853,857,862,867,870,873,878,883,886,889,893,898,903,908,913,918,922,927,932,937,942,947,952,957,962,967,972,977,980,983,988,993,998,1003,1008,1013,1018,1023,1028,1031,1035,1038,1042,1047,1052,1057,1060,1064,1067,1071,1074,1077,1082,1087,1090,1094,1099,1102,1107],{"id":23,"title":22,"titles":202,"content":203,"level":204},[],"Optional CASL Prisma adapter, policy helpers, and DTO field filtering.",1,{"id":206,"title":22,"titles":207,"content":208,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Fcasl#casl",[],"The query service is CASL-agnostic until an app wires an accessibility resolver into it. The CASL helpers cover route policies, Prisma read filters, and field-level DTO filtering; applications retain ownership of their ability factories and subjects. pnpm add @casl\u002Fability @casl\u002Fprisma",{"id":210,"title":211,"titles":212,"content":213,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fcasl#service-wiring","Service Wiring",[22],"The complete runnable service from the Books API is included below. Its super call wires the CASL subject and the action-aware Prisma resolver into every ability-aware read method. It also shows that a conditional write rule must be checked against the concrete record before mutating it. @Injectable()\nexport class BooksService extends QueryService\u003CBookDelegate, BookTypeMap, BookDelegate, QueryOptionsMap\u003CBookTypeMap>, DemoAbility, 'Book'> {\n  constructor() {\n    const delegate = new BookDelegate();\n    super(delegate, {\n      subject: 'Book',\n      accessibleWhere: createCaslAccessibleWhere\u003CDemoAbility, 'Book'>({ action: BookAction.Read }),\n    });\n  }\n\n  async update(id: string, data: UpdateBookDTO, query = {}, ability?: DemoAbility) {\n    const existing = await this.findById(id, query, ability);\n    if (!ability?.can(BookAction.Update, subject('Book', existing))) {\n      throw new ForbiddenException('Insufficient permissions.');\n    }\n    return this.delegate.update({ where: { id }, data, include: query.include });\n  }\n} For a Prisma service, replace BookDelegate with your generated delegate type (for example typeof PrismaService.prototype.project) while retaining the same subject and accessibleWhere options: import { createCaslAccessibleWhere } from '@querry-kit\u002Fnest\u002Fcasl';\nimport type { QueryOptionsMap } from '@querry-kit\u002Fnest\u002Fdto';\nimport { QueryService } from '@querry-kit\u002Fnest\u002Fquery-service';\n\nexport class ProjectsService extends QueryService\u003C\n  typeof PrismaService.prototype.project,\n  ProjectTypeMap,\n  typeof PrismaService.prototype.project,\n  QueryOptionsMap\u003CProjectTypeMap>,\n  AppAbility,\n  'Project'\n> {\n  constructor(prisma: PrismaService) {\n    super(prisma.project, {\n      subject: 'Project',\n      accessibleWhere: createCaslAccessibleWhere\u003CAppAbility, 'Project'>({ action: 'read' }),\n    });\n  }\n} Pass the current ability when calling protected read methods: const result = await this.projectsService.query(query, req.ability); CASL is optional at the controller layer too. ResourceQuery.query and ResourceQuery.findById accept ability, but they do not require it. When an ability-aware DTO mapper or response policy needs relations, set them as endpoint-required includes: return ResourceQuery.query({\n  service: this.projectsService,\n  query,\n  schema: ProjectDTO,\n  ability: req.ability,\n  include: { members: true },\n  map: (project, ability) => ProjectDTO.fromModel(project, ability),\n}); Client include parameters extend those required includes, and fields adds any relation includes needed for projection. When query receives both an ability and caller filters, QueryService merges them with AND so the access rule stays mandatory. {\n  AND: [\n    { members: { some: { userId: currentUser.id } } },\n    { archived: false }\n  ]\n}",2,{"id":216,"title":217,"titles":218,"content":219,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fcasl#policy-decorator-and-guard","Policy Decorator and Guard",[22],"Use CheckPolicies to attach route-level policy handlers and PoliciesGuard to evaluate them against request.ability. @Get()\n@CheckPolicies((ability) => ability.can('read', 'Project'))\nasync query() {} PoliciesGuard throws a Nest ForbiddenException when no ability is present or any policy returns false.",{"id":221,"title":222,"titles":223,"content":224,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fcasl#dto-field-filtering","DTO Field Filtering",[22],"Use filterCaslFields at the end of a DTO mapper when field permissions should affect the JSON response. It returns a shallow copy, preserves the DTO prototype, and never mutates the mapper's DTO. import { filterCaslFields } from '@querry-kit\u002Fnest\u002Fcasl';\n\nclass ProjectDTO {\n  static fromModel(project: Project, ability?: AppAbility): ProjectDTO {\n    const dto = Object.assign(new ProjectDTO(), {\n      id: project.id,\n      name: project.name,\n      internalBudget: project.internalBudget,\n    });\n\n    return filterCaslFields(dto, 'Project', ability);\n  }\n} The helper first checks the special CASL field all. If it is not allowed, it checks every enumerable DTO field individually. Conditional CASL rules receive the DTO as a CASL subject, so they can inspect its values. DTO field filtering protects the serialized response only. Keep passing the ability to QueryService or ResourceQuery as well so the Prisma query itself is restricted. The default action is read. Applications that use a differently cased or enum-backed action must pass it explicitly: return filterCaslFields(dto, RoleSubject.PROJECT, ability, { action: RoleAction.READ });",{"id":226,"title":227,"titles":228,"content":229,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fcasl#casl-prisma-versions","CASL Prisma Versions",[22],"createCaslAccessibleWhere supports CASL Prisma subject maps and the newer accessibleBy(...).ofType(subject) shape. The package does not export an ability factory; applications keep their own CASL module, subjects, actions, and user context. html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"id":27,"title":26,"titles":231,"content":232,"level":204},[],"Reusable NestJS parameter and DTO property decorators.",{"id":234,"title":26,"titles":235,"content":236,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators#decorators",[],"The decorators subpath provides reusable OpenAPI metadata for common route parameters and DTO properties. These decorators affect the generated Swagger\u002FOpenAPI document; they do not parse a request, validate an ID, or change a controller response at runtime. import { ApiParamId, ApiPropertyCreatedAt, ApiPropertyId, ApiPropertyUpdatedAt } from '@querry-kit\u002Fnest\u002Fdecorators';",{"id":238,"title":239,"titles":240,"content":241,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators#at-a-glance","At a Glance",[26],"DecoratorTargetWhat it adds@ApiParamId()Controller methodA UUID-shaped route parameter in Swagger.@ApiPropertyId()DTO propertyAn ID description and UUID example in the DTO schema.@ApiPropertyCreatedAt()DTO propertyA default description for a creation timestamp.@ApiPropertyUpdatedAt()DTO propertyA default description for an update timestamp. All four accept Swagger options, so an application can override the defaults where its API uses a different format, description, or example.",{"id":243,"title":244,"titles":245,"content":246,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators#apiparamid","@ApiParamId()",[26],"Use ApiParamId on a route handler with an ID parameter. It adds an ApiParam entry with type: string and format: uuid to Swagger. The parameter name defaults to id. @Get(':id')\n@ApiParamId({ description: 'User ID', name: 'id' })\nfindById(@Param('id') id: string) {} This only documents the expected parameter. Use a Nest pipe such as ParseUUIDPipe when the route parameter also needs runtime validation: @Get(':id')\n@ApiParamId()\nfindById(@Param('id', new ParseUUIDPipe()) id: string) {} For routes with another parameter name, pass that name explicitly so the Swagger entry matches the route: @Get(':userId')\n@ApiParamId({ name: 'userId', description: 'User UUID' })\nfindById(@Param('userId') userId: string) {}",{"id":248,"title":249,"titles":250,"content":251,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators#apipropertyid","@ApiPropertyId()",[26],"Use ApiPropertyId for a DTO field that represents a resource ID. It sets a default description of “The ID of the item.” and a UUID example generated with crypto.randomUUID(). class UserDTO {\n  @ApiPropertyId()\n  id!: string;\n} Pass regular ApiProperty options to replace either default. This is useful when an ID is not a UUID or needs a stable example in generated documentation: class LegacyUserDTO {\n  @ApiPropertyId({\n    description: 'Legacy numeric user ID',\n    example: '42',\n  })\n  id!: string;\n}",{"id":253,"title":254,"titles":255,"content":256,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators#apipropertycreatedat-and-apipropertyupdatedat","@ApiPropertyCreatedAt() and @ApiPropertyUpdatedAt()",[26],"Use these property decorators for the conventional timestamps on a response DTO. They are small shortcuts around @ApiProperty() with helpful default descriptions: ApiPropertyCreatedAt describes when the item was created.ApiPropertyUpdatedAt describes when the item was last updated. class UserDTO {\n  @ApiPropertyId()\n  id!: string;\n\n  @ApiPropertyCreatedAt()\n  createdAt!: Date;\n\n  @ApiPropertyUpdatedAt()\n  updatedAt!: Date;\n} They do not set values or manage timestamps in the database. Set format, example, required, or the description through normal ApiProperty options when the API contract needs more detail: @ApiPropertyCreatedAt({ format: 'date-time', example: '2026-07-24T10:30:00.000Z' })\ncreatedAt!: Date;",{"id":258,"title":259,"titles":260,"content":261,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators#related-controller-decorators","Related Controller Decorators",[26],"The following decorators are exported from other focused subpaths. They have different responsibilities and are documented on their corresponding API pages: DecoratorWhat it does@ApiResourceQuery()Documents common list query parameters (fields, pagination, Prisma query options) and the related HTTP 400 response.@ApiPaginatedResponse({ model })Documents an { items, meta } response whose items use the supplied DTO model.@ApiErrorResponses()Adds configured common error responses and examples to Swagger.@ApiFieldsQuery()Documents a fields query parameter and its invalid-fields HTTP 400 response.@FieldsQuery(DTO)Reads, parses, and validates request.query.fields at runtime, then injects the resulting projection into a controller parameter.@CheckPolicies(...)Stores policy handlers as Nest metadata for PoliciesGuard to evaluate at runtime. Read OpenAPI Decorators for the resource-query and response decorators, Fields for ApiFieldsQuery and FieldsQuery, and CASL for CheckPolicies. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"id":31,"title":30,"titles":263,"content":264,"level":204},[],"Entry point for decorators, pipes, OpenAPI helpers, validation helpers, and object utilities.",{"id":266,"title":30,"titles":267,"content":268,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdecorators-pipes-utils#decorators-pipes-utilities",[],"This package includes the small NestJS utilities that were previously split into focused packages. The API docs are now grouped by concern: OpenAPI Decorators for ApiResourceQuery, ApiPaginatedResponse, and ApiErrorResponses.Decorators for route parameter and DTO property decorators.Pipes for QueryTransformPipe and EmptyStringToNullPipe.Object Utilities for object parsing, diffs, Decimal serialization, and validation helpers. The old combined page is kept as a stable entry point for existing links.",{"id":35,"title":34,"titles":270,"content":271,"level":204},[],"Request DTOs, pagination DTOs, validation, transformation, and response shapes.",{"id":273,"title":34,"titles":274,"content":275,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdtos-pagination#dtos-and-pagination",[],"The DTOs are intended for app-level controllers. They include Swagger metadata and class-validator\u002Fclass-transformer decorators where runtime validation is meaningful.",{"id":277,"title":278,"titles":279,"content":280,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdtos-pagination#pageoptionsdto","PageOptionsDTO",[34],"PageOptionsDTO defaults to page = 1 and perPage = 10. Both values are transformed to numbers and validated as integers. app.useGlobalPipes(\n  new ValidationPipe({\n    transform: true,\n    whitelist: true,\n  }),\n); The supported pagination range is: page >= 1;\nperPage >= 1;\nperPage \u003C= 1000;",{"id":282,"title":283,"titles":284,"content":285,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdtos-pagination#query-dtos","Query DTOs",[34],"Use the DTO matching the service method: FindOneDTO\u003CProjectTypeMap>;\nFindManyDTO\u003CProjectTypeMap>;\nFindByIdDTO\u003CProjectTypeMap>;\nFindUniqueDTO\u003CProjectTypeMap>;\nAggregateDTO\u003CProjectTypeMap>;\nCountDTO\u003CProjectTypeMap>;\nQueryDTO\u003CProjectTypeMap>; QueryDTO and FindByIdDTO expose fields?: string. ResourceQuery and prepareFieldsQuery use that optional value to build relation includes and project responses. QueryDTO also exposes the Prisma-style query inputs used by resource list endpoints: select, include, where, orderBy, cursor, and distinct, plus page and perPage from PageOptionsDTO. Use ApiResourceQuery() to document the public query parameter contract in OpenAPI metadata.",{"id":287,"title":288,"titles":289,"content":290,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fdtos-pagination#service-shape","Service Shape",[34],"QueryService.query returns a service-level shape: type Paginated\u003CProject> = {\n  items: Project[];\n  pageMeta: PageMetaDTO;\n}; Controllers usually return a public DTO shape: return new PaginatedDTO(projectDtos, pageMeta); PageMetaDTO computes pageCount, hasPrevPage, and hasNextPage from itemCount, page, and perPage. ResourceQuery.query supports both item shorthand and envelope projection: fields=id,name\nfields=items{id,name},meta{page,perPage,itemCount,pageCount} html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"id":39,"title":38,"titles":292,"content":293,"level":204},[],"Fields API overview for @querry-kit\u002Fnest.",{"id":295,"title":38,"titles":296,"content":297,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Ffields#fields",[],"The fields API is split into small classes and controller helpers. Most endpoints should use ResourceQuery or prepareFieldsQuery; use the low-level classes when you need fine-grained control.",{"id":299,"title":300,"titles":301,"content":302,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Ffields#resource-facade","Resource Facade",[38],"const result = await ResourceQuery.query({\n  service: this.usersService,\n  query,\n  schema: UserDTO,\n  ability: req.ability,\n  map: (user, ability) => UserDTO.fromModel(user, ability),\n}); schema accepts either a manual FieldSchema or a Swagger-decorated DTO class. The helper: parses and validates query.fields.merges endpoint-required includes, client includes, and generated relation includes into a query copy.calls service.query or service.findById.maps models to DTOs, including async mappers.applies Fields.project to the mapped DTO response. Paginated responses can project either item fields (fields=id,title or fields={id,title}) or the response envelope (fields=items{id,title},meta{page,perPage}). An explicit empty selection (fields= or fields={}) returns an empty envelope; items{} can intentionally return empty item objects.",{"id":304,"title":305,"titles":306,"content":307,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Ffields#preparefieldsquery","prepareFieldsQuery",[38],"const prepared = prepareFieldsQuery(query, UserDTO, {\n  baseInclude: {\n    organization: true,\n  },\n});\n\nawait usersService.query(prepared.query, ability);\nFields.project(dtoItems, prepared.projection); prepareFieldsQuery does not mutate the original query object. baseInclude is useful when the endpoint, CASL-aware mapper, or response policy needs relations even when the client omits fields; the client include query parameter extends that include object.",{"id":309,"title":310,"titles":311,"content":312,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Ffields#low-level-flow","Low-Level Flow",[38],"const projection = FieldsParser.parse(query.fields);\n\nif (projection) {\n  FieldsValidator.validateProjection(projection, userSchema);\n}\n\nconst include = projection ? Fields.include(projection, userSchema, query.include) : query.include;\nconst response = FieldsProjector.project(dtoItems, projection);",{"id":314,"title":315,"titles":316,"content":317,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Ffields#manual-field-schema","Manual Field Schema",[38],"import { relation, type FieldSchema } from '@querry-kit\u002Fnest\u002Ffields';\n\nconst schema: FieldSchema = {\n  id: true,\n  email: true,\n  profile: relation({\n    firstName: true,\n    lastName: true,\n  }),\n};",{"id":319,"title":320,"titles":321,"content":322,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Ffields#decorators-and-errors","Decorators and Errors",[38],"Use ApiResourceQuery() for list endpoints that expose fields, page, perPage, select, include, where, orderBy, and distinct. Use ApiFieldsQuery() for detail or mutation endpoints that only expose response projection. Use @FieldsQuery(DTO) when a controller parameter should receive a validated FieldsProjection. @Get()\n@ApiFieldsQuery()\nasync find(@FieldsQuery(UserDTO) fields?: FieldsProjection) {} Register FieldsExceptionFilter globally when invalid fields values should produce structured HTTP 400 responses.",{"id":324,"title":325,"titles":326,"content":327,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Ffields#dto-schema","DTO Schema",[38],"buildFieldSchemaFromDto(dtoClass) reads Swagger metadata from DTO classes and returns a FieldSchema. class UserDTO {\n  @ApiProperty()\n  id!: string;\n\n  @ApiProperty({ type: () => ProfileDTO })\n  profile!: ProfileDTO;\n}\n\nconst schema = buildFieldSchemaFromDto(UserDTO); Swagger-decorated nested DTO classes become relation fields. Recursive DTO references are cut off with an empty nested schema to avoid infinite traversal. Only properties decorated with @ApiProperty or compatible Swagger metadata are included.DTO classes without Swagger property metadata produce an empty schema.Arrays of DTOs are supported when Swagger exposes the array item type, for example with @ApiProperty({ type: () => [BookDTO] }). Use a manual schema with relation when the public response shape differs from Swagger metadata.",{"id":329,"title":330,"titles":331,"content":332,"level":333},"\u002Fdocs\u002Fnest\u002Fapi\u002Ffields#getdtofields","getDtoFields",[38,325],"const fields = getDtoFields(UserDTO); getDtoFields returns the Swagger-decorated property names for a DTO class. DTOs without Swagger property metadata return an empty array. html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",3,{"id":17,"title":16,"titles":335,"content":336,"level":204},[],"API overview for @querry-kit\u002Fnest.",{"id":338,"title":16,"titles":339,"content":340,"level":204},"\u002Fdocs\u002Fnest\u002Fapi#api-reference",[],"@querry-kit\u002Fnest exports a consolidated public API from the package root and focused subpaths. import {\n  ApiErrorResponses,\n  ApiPaginatedResponse,\n  ApiResourceQuery,\n  Fields,\n  QueryDTO,\n  QueryService,\n  ResourceQuery,\n  prepareFieldsQuery,\n} from '@querry-kit\u002Fnest';\n\nimport { parseObject } from '@querry-kit\u002Fnest\u002Fobject';\nimport { createCaslAccessibleWhere, filterCaslFields } from '@querry-kit\u002Fnest\u002Fcasl';",{"id":342,"title":343,"titles":344,"content":345,"level":214},"\u002Fdocs\u002Fnest\u002Fapi#main-areas","Main Areas",[16],"AreaUse forResourceQueryCommon controller read flows with fields, includes, service calls, DTO mapping, and projection.FieldsLow-level parsing, validation, include generation, and response projection.QueryServicePrisma-compatible read operations, pagination, query normalization, and error mapping.DTOs and paginationController query DTOs and PaginatedDTO response wrappers.CASLOptional accessibleBy integration, policy guards, and field-level DTO filtering.Decorators and pipesOpenAPI helpers for query parameters and responses, query transformation, body normalization, and reusable API metadata.Object utilitiesQuery object parsing, object diffing, Decimal serialization, and predicates.",{"id":347,"title":348,"titles":349,"content":350,"level":214},"\u002Fdocs\u002Fnest\u002Fapi#subpath-exports","Subpath Exports",[16],"import { Fields } from '@querry-kit\u002Fnest\u002Ffields';\nimport { QueryDTO } from '@querry-kit\u002Fnest\u002Fdto';\nimport { PageMetaDTO } from '@querry-kit\u002Fnest\u002Fpagination';\nimport { QueryService } from '@querry-kit\u002Fnest\u002Fquery-service';\nimport { createCaslAccessibleWhere, filterCaslFields } from '@querry-kit\u002Fnest\u002Fcasl';\nimport { ApiPaginatedResponse, ApiParamId } from '@querry-kit\u002Fnest\u002Fdecorators';\nimport { QueryTransformPipe } from '@querry-kit\u002Fnest\u002Fpipes';\nimport { parseObject } from '@querry-kit\u002Fnest\u002Fobject';",{"id":352,"title":353,"titles":354,"content":355,"level":214},"\u002Fdocs\u002Fnest\u002Fapi#reference-pages","Reference Pages",[16],"Fields including DTO schema generationQuery Service and complex direct QueryService examplesDTOs and PaginationCASLOpenAPI DecoratorsDecoratorsPipesObject Utilities html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":43,"title":42,"titles":357,"content":358,"level":204},[],"Object parsing, diff helpers, Decimal serialization, and validation utilities.",{"id":360,"title":42,"titles":361,"content":362,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Fobject-utils#object-utilities",[],"The object subpath contains query parsing and general object helpers. import { parseQueryObject } from '@querry-kit\u002Fnest';\nimport { diffObjects, hasObjectDifferences, parseObject, serializeDecimalValues } from '@querry-kit\u002Fnest\u002Fobject'; parseObject converts query-string values into JavaScript values and expands dotted keys. parseObject({\n  page: '1',\n  enabled: 'true',\n  deletedAt: 'null',\n  tags: ['1', '2'],\n  orderBy: '{\"createdAt\":\"desc\"}',\n  'user.name': 'Ada',\n}); parseQueryObject is the same normalization entry point used by QueryService for query-like values. serializeDecimalValues recursively converts Decimal-like objects with a toNumber() method into numbers. diffObjects and hasObjectDifferences compare nested objects and arrays. ValidationUtil.mapValidationErrorsToObject(errors) maps class-validator errors into an object keyed by property name. It does not run validation itself. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"id":47,"title":46,"titles":364,"content":365,"level":204},[],"OpenAPI decorators for resource queries, pagination responses, and common error responses.",{"id":367,"title":46,"titles":368,"content":369,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Fopenapi#openapi-decorators",[],"Query Kit includes OpenAPI decorators for common NestJS API metadata. import { ApiErrorResponses, ApiPaginatedResponse, ApiResourceQuery } from '@querry-kit\u002Fnest'; ApiResourceQuery() documents list query parameters: fields, page, perPage, select, include, where, orderBy, and distinct. It also adds the invalidResourceQuery example to the HTTP 400 response for invalid fields syntax, unknown fields, invalid include\u002Fselect, or invalid query values. @Get()\n@ApiResourceQuery()\n@ApiPaginatedResponse({ model: UserDTO })\nfindMany() {} ApiPaginatedResponse({ model }) documents a PaginatedDTO\u003CT> response with items and meta. @ApiPaginatedResponse({ model: UserDTO, description: 'Users' })\nfindMany() {} ApiErrorResponses(options?) documents common error responses for 400, 401, 403, 404, 409, 429, and optionally 500. Its code examples merge with the generic resource-query example, so Swagger UI can present both causes under one 400 response. @ApiErrorResponses({\n  badRequestCodes: ['test'],\n  notFoundDescription: 'User not found',\n  internalServerError: true,\n})\nfindOne() {} The generated 400 response contains both invalidResourceQuery and test examples, so both names are selectable in Swagger UI. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"id":51,"title":50,"titles":371,"content":372,"level":204},[],"Query and request body pipes for NestJS APIs.",{"id":374,"title":50,"titles":375,"content":376,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Fpipes#pipes",[],"Query Kit exports small pipes for common request normalization. import { EmptyStringToNullPipe, QueryTransformPipe } from '@querry-kit\u002Fnest\u002Fpipes'; QueryTransformPipe normalizes query objects with the bundled object parser. app.useGlobalPipes(new QueryTransformPipe()); It converts common query-string values into Prisma-friendly JavaScript values: {\n  page: '1',\n  enabled: 'true',\n  deletedAt: 'null',\n  orderBy: '{\"createdAt\":\"desc\"}',\n  'user.name': 'Ada',\n} becomes: {\n  page: 1,\n  enabled: true,\n  deletedAt: null,\n  orderBy: { createdAt: 'desc' },\n  user: { name: 'Ada' },\n} EmptyStringToNullPipe converts empty strings in request bodies to null, including nested objects and arrays. Non-body arguments are returned unchanged. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"id":55,"title":54,"titles":378,"content":379,"level":204},[],"QueryService setup, methods, parsing, pagination, and error behavior.",{"id":381,"title":54,"titles":382,"content":383,"level":204},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#query-service",[],"QueryService wraps a Prisma-compatible delegate. It does not import Prisma at runtime; generated Prisma types stay in your application and are connected through a small type map.",{"id":385,"title":386,"titles":387,"content":388,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#type-map","Type Map",[54],"import { Injectable } from '@nestjs\u002Fcommon';\nimport { QueryService, type BaseDelegateTypeMap } from '@querry-kit\u002Fnest';\nimport { Prisma, PrismaService } from '..\u002Fprisma';\n\ninterface ProjectTypeMap extends BaseDelegateTypeMap {\n  select: Prisma.ProjectSelect;\n  include: Prisma.ProjectInclude;\n  whereInput: Prisma.ProjectWhereInput;\n  orderByWithRelationInput: Prisma.ProjectOrderByWithRelationInput;\n  whereUniqueInput: Prisma.ProjectWhereUniqueInput;\n  scalarFieldEnum: Prisma.ProjectScalarFieldEnum;\n  aggregateInputType: Prisma.AggregateProject;\n}\n\n@Injectable()\nexport class ProjectsService extends QueryService\u003Ctypeof PrismaService.prototype.project, ProjectTypeMap> {\n  constructor(prisma: PrismaService) {\n    super(prisma.project);\n  }\n}",{"id":390,"title":391,"titles":392,"content":393,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#methods","Methods",[54],"await projectsService.findOne({ where: { slug: 'alpha' } });\nawait projectsService.findMany({ where: { archived: false }, orderBy: { name: 'asc' } });\nawait projectsService.findById('project_1', { include: { members: true } });\nawait projectsService.findUnique({ where: { slug: 'alpha' } });\nawait projectsService.aggregate({ where: { archived: false }, _count: true });\nawait projectsService.count({ where: { archived: false } }); query combines findMany, count, and PageMetaDTO. const { items, pageMeta } = await projectsService.query({\n  page: 2,\n  perPage: 25,\n  where: { archived: false },\n  orderBy: { name: 'asc' },\n});",{"id":395,"title":396,"titles":397,"content":398,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#complex-queries-without-resourcequery","Complex Queries Without ResourceQuery",[54],"Use ResourceQuery for the common controller flow. For advanced endpoints, call QueryService directly and keep the Prisma-shaped query explicit in your controller or application service. import { Controller, Get, Param, Query, Req } from '@nestjs\u002Fcommon';\nimport { Fields, PaginatedDTO, QueryDTO, prepareFieldsQuery } from '@querry-kit\u002Fnest';\nimport type { Request } from 'express';\nimport { BookDTO } from '.\u002Fdto\u002Fbook.dto';\nimport { BooksService, type BookModel, type BookTypeMap } from '.\u002Fbooks.service';\n\ntype RequestWithAbility = Request & {\n  ability?: unknown;\n};\n\n@Controller('books')\nexport class BooksController {\n  constructor(private readonly booksService: BooksService) {}\n\n  @Get('search')\n  async search(@Query() query: QueryDTO\u003CBookTypeMap>, @Req() req: RequestWithAbility) {\n    const result = await this.booksService.query\u003CBookModel>(\n      {\n        ...query,\n        where: {\n          published: true,\n          author: {\n            name: { contains: 'Ada', mode: 'insensitive' },\n          },\n          tags: {\n            some: { name: { in: ['nestjs', 'api'] } },\n          },\n        },\n        include: {\n          author: {\n            include: {\n              books: {\n                select: { id: true, title: true },\n              },\n            },\n          },\n          tags: true,\n        },\n        orderBy: [{ publishedAt: 'desc' }, { id: 'asc' }],\n        page: query.page ?? 1,\n        perPage: query.perPage ?? 20,\n      },\n      req.ability,\n    );\n\n    return new PaginatedDTO(result.items.map(BookDTO.fromModel), result.pageMeta);\n  }\n} QueryTransformPipe can parse dotted query keys and JSON-like values before the DTO reaches QueryService. GET \u002Fbooks\u002Fsearch?where.published=true&where.author.name.contains=Ada&where.author.name.mode=insensitive&include.author.include.books.select.id=true&include.author.include.books.select.title=true&include.tags=true&orderBy=[{\"publishedAt\":\"desc\"},{\"id\":\"asc\"}]&page=1&perPage=20 In real clients, URL-encode JSON arrays and objects. For local curl testing, curl -g is often useful because it prevents shell globbing for brackets.",{"id":400,"title":401,"titles":402,"content":403,"level":333},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#manual-fields-projection","Manual Fields Projection",[54,396],"prepareFieldsQuery is not tied to ResourceQuery. It can prepare includes and return the projection while you still call QueryService yourself. @Get()\nasync findAll(@Query() query: QueryDTO\u003CBookTypeMap>, @Req() req: RequestWithAbility) {\n  const prepared = prepareFieldsQuery(query, BookDTO);\n  const result = await this.booksService.query\u003CBookModel>(prepared.query, req.ability);\n  const dtoItems = result.items.map(BookDTO.fromModel);\n\n  return new PaginatedDTO(Fields.project(dtoItems, prepared.projection), result.pageMeta);\n} For example, this request asks for author data through fields. prepareFieldsQuery merges the required relation include into the query before it reaches Prisma. GET \u002Fbooks?fields=id,title,author{id,name}&where.published=true&orderBy={\"title\":\"asc\"} Existing includes are preserved. Use baseInclude when the endpoint, CASL-aware mapper, or response policy needs relations even when the client does not request those relation fields. Client include values extend that base include. const prepared = prepareFieldsQuery(\n  query,\n  BookDTO,\n  {\n    baseInclude: {\n      author: { select: { id: true, name: true } },\n      tags: true,\n    },\n  },\n); When fields is omitted, prepareFieldsQuery still returns a query copy with merged endpoint and client includes. Paginated ResourceQuery.query endpoints additionally support projecting the response envelope: GET \u002Fbooks?fields=items{id,title},meta{page,perPage,itemCount,pageCount}",{"id":405,"title":406,"titles":407,"content":408,"level":333},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#detail-queries","Detail Queries",[54,396],"Use findById when the route is ID-based and should throw Nest NotFoundException for missing records. @Get(':id')\nasync findById(\n  @Param('id') id: string,\n  @Query() query: QueryDTO\u003CBookTypeMap>,\n  @Req() req: RequestWithAbility,\n) {\n  const prepared = prepareFieldsQuery(query, BookDTO);\n  const book = await this.booksService.findById\u003CBookModel>(id, prepared.query, req.ability);\n  const dto = BookDTO.fromModel(book);\n\n  return Fields.project(dto, prepared.projection);\n} Use findUnique for natural unique keys such as isbn or slug. When an ability is passed, QueryService switches to findFirst internally so the accessibility filter can be merged into where. @Get('isbn\u002F:isbn')\nasync findByIsbn(@Param('isbn') isbn: string, @Req() req: RequestWithAbility) {\n  const book = await this.booksService.findUnique\u003CBookModel>(\n    {\n      where: { isbn },\n      include: {\n        author: true,\n        tags: true,\n      },\n    },\n    req.ability,\n  );\n\n  return BookDTO.fromModel(book);\n}",{"id":410,"title":411,"titles":412,"content":413,"level":333},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#aggregates-and-counts","Aggregates And Counts",[54,396],"aggregate returns the delegate result with Decimal-like values serialized. count can receive the same ability parameter as paginated reads. @Get('stats\u002Fsummary')\nasync summary(@Req() req: RequestWithAbility) {\n  const where = {\n    published: true,\n    tags: { some: { name: { in: ['nestjs', 'api'] } } },\n  };\n\n  const [aggregate, accessibleCount] = await Promise.all([\n    this.booksService.aggregate({\n      where,\n      _count: true,\n      _min: { publishedAt: true },\n      _max: { publishedAt: true },\n    }),\n    this.booksService.count({ where }, req.ability),\n  ]);\n\n  return {\n    aggregate,\n    accessibleCount,\n  };\n}",{"id":415,"title":416,"titles":417,"content":418,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#casl-merge-behavior","CASL Merge Behavior",[54],"When the service was created with subject and accessibleWhere, all read helpers that accept an ability merge the access filter with your query filter: \u002F\u002F Effective where shape:\n{\n  AND: [\n    accessibleWhere(ability, subject),\n    { published: true, authorId: 'author_1' },\n  ],\n} This applies to findOne, findMany, findById, findUnique with ability, query, and count. aggregate intentionally does not accept an ability parameter in V1; pass an already constrained where object when you expose aggregate endpoints.",{"id":420,"title":421,"titles":422,"content":423,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#query-parsing","Query Parsing",[54],"Inputs are normalized with parseQueryObject, a public wrapper around the bundled object utilities. parseQueryObject({\n  'owner.email': 'ada@example.com',\n  archived: 'false',\n  tags: '[\"crm\",\"internal\"]',\n});\n\n\u002F\u002F {\n\u002F\u002F   owner: { email: 'ada@example.com' },\n\u002F\u002F   archived: false,\n\u002F\u002F   tags: ['crm', 'internal']\n\u002F\u002F } Invalid JSON-like strings are preserved instead of throwing during parsing. Prisma validation errors are converted later by QueryService.",{"id":425,"title":426,"titles":427,"content":428,"level":214},"\u002Fdocs\u002Fnest\u002Fapi\u002Fquery-service#error-mapping","Error Mapping",[54],"Prisma validation-like errors become BadRequestException.Known Prisma request errors with a code become BadRequestException.Existing Nest HttpException instances pass through.Unexpected errors are logged through errorLogger when configured and then masked as InternalServerErrorException. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":58,"title":10,"titles":430,"content":431,"level":204},[],"",{"id":433,"title":10,"titles":434,"content":431,"level":204},"\u002Fdocs\u002Fnest\u002Fchangelog#querry-kitnest",[],{"id":436,"title":437,"titles":438,"content":431,"level":214},"\u002Fdocs\u002Fnest\u002Fchangelog#_031","0.3.1",[10],{"id":440,"title":441,"titles":442,"content":443,"level":333},"\u002Fdocs\u002Fnest\u002Fchangelog#patch-changes","Patch Changes",[10,437],"81a8410: Standardize the English README and contributor guidance.",{"id":445,"title":446,"titles":447,"content":431,"level":214},"\u002Fdocs\u002Fnest\u002Fchangelog#_030","0.3.0",[10],{"id":449,"title":450,"titles":451,"content":452,"level":333},"\u002Fdocs\u002Fnest\u002Fchangelog#minor-changes","Minor Changes",[10,446],"059fe27: Allow empty and outer-braced Fields projections.",{"id":454,"title":441,"titles":455,"content":456,"level":333},"\u002Fdocs\u002Fnest\u002Fchangelog#patch-changes-1",[10,446],"6e26ed5: Improve Fields coverage and assign release pull requests automatically.575a52d: Improve runtime coverage reporting and regression coverage.",{"id":458,"title":459,"titles":460,"content":431,"level":214},"\u002Fdocs\u002Fnest\u002Fchangelog#_020","0.2.0",[10],{"id":462,"title":450,"titles":463,"content":464,"level":333},"\u002Fdocs\u002Fnest\u002Fchangelog#minor-changes-1",[10,459],"3cdc028: Add CASL-aware DTO field filtering, coverage reporting, and refreshed documentation styling.",{"id":466,"title":441,"titles":467,"content":468,"level":333},"\u002Fdocs\u002Fnest\u002Fchangelog#patch-changes-2",[10,459],"96b9c10: Add package discovery keywords.12481ed: Document CASL query and conditional write service wiring.5d32bf2: Show named resource query and application error examples in OpenAPI.acee7ce: Fix CASL Prisma v1 accessibility resolver support.3d9ec19: Document the runtime coverage quality target.",{"id":470,"title":471,"titles":472,"content":431,"level":214},"\u002Fdocs\u002Fnest\u002Fchangelog#_010","0.1.0",[10],{"id":474,"title":450,"titles":475,"content":476,"level":333},"\u002Fdocs\u002Fnest\u002Fchangelog#minor-changes-2",[10,471],"5a1d093: Create the consolidated NestJS package with fields projection, Prisma query helpers, CASL utilities, decorators, pipes, and resource-query facades.cde7bce: Add ResourceQuery include merging, paginated fields envelope projection, Swagger resource query documentation, and complete fields-aware CRUD examples.",{"id":478,"title":441,"titles":479,"content":480,"level":333},"\u002Fdocs\u002Fnest\u002Fchangelog#patch-changes-3",[10,471],"9e8a740: Clean up package structure by grouping the Books API example by feature, moving query parsing into generic utilities, moving OpenAPI decorators under decorators, splitting public helper types, and reducing large decorator and resource-query files.",{"id":482,"title":483,"titles":484,"content":431,"level":214},"\u002Fdocs\u002Fnest\u002Fchangelog#_000","0.0.0",[10],{"id":486,"title":450,"titles":487,"content":488,"level":333},"\u002Fdocs\u002Fnest\u002Fchangelog#minor-changes-3",[10,483],"Initial consolidated package with fields projection, Prisma-style query services, CASL utilities, decorators, pipes, pagination DTOs, and resource-query facades.",{"id":67,"title":66,"titles":490,"content":491,"level":204},[],"Fields projection syntax and behavior for @querry-kit\u002Fnest.",{"id":493,"title":66,"titles":494,"content":495,"level":204},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Ffields#fields-projection",[],"The fields query parameter lets clients request a smaller public response shape. id,email,profile{firstName,lastName} The server still validates every requested field against an explicit schema or Swagger DTO metadata before it loads relations or projects the response.",{"id":497,"title":498,"titles":499,"content":500,"level":214},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Ffields#syntax","Syntax",[66],"RuleExampleField names start with A-Z, a-z, or _.id, _metaRemaining characters may also contain digits.line1, profile2Commas separate sibling selections.id,emailBraces select nested relation fields.profile{firstName}Outer braces are optional.id,email or {id,email}Empty selections intentionally remove all fields at that level.{}, profile{}Whitespace around tokens is ignored.id, profile { firstName } An explicit empty query value (fields=) parses as {} and projects an empty response. Whitespace-only values remain invalid. For paginated responses, {} projects the complete envelope to {}, while items{} yields empty item objects and items{},meta{page} preserves only meta.page.",{"id":502,"title":503,"titles":504,"content":505,"level":214},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Ffields#validation","Validation",[66],"Scalar fields use true. Relation fields use relation({ ... }). import { relation, type FieldSchema } from '@querry-kit\u002Fnest\u002Ffields';\n\nconst schema: FieldSchema = {\n  id: true,\n  email: true,\n  profile: relation({\n    firstName: true,\n    lastName: true,\n  }),\n}; Unknown fields and nested selections on scalar fields throw FieldsBadRequestException.",{"id":507,"title":508,"titles":509,"content":510,"level":214},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Ffields#include-generation","Include Generation",[66],"Selected relation fields can be converted into Prisma-compatible includes. Fields.include({ profile: { firstName: true } }, schema);\n\u002F\u002F { profile: true } Existing include configuration is preserved, and dotted keys are normalized through the bundled object parser. Fields.include({ profile: { firstName: true } }, schema, {\n  'profile.where.active': 'true',\n});\n\u002F\u002F { profile: { where: { active: true } } }",{"id":512,"title":513,"titles":514,"content":515,"level":214},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Ffields#projection","Projection",[66],"Projection happens after DTO mapping, so the public DTO shape remains the source of truth. Fields.project(userDto, { id: true, profile: { firstName: true } }); Arrays are projected item by item. Primitive values, null, and undefined are returned unchanged. html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":71,"title":70,"titles":517,"content":518,"level":204},[],"How query parameter transformation works in @querry-kit\u002Fnest.",{"id":520,"title":70,"titles":521,"content":522,"level":204},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Fquery-transform#query-transformation",[],"HTTP query parameters usually arrive in NestJS as strings. QueryTransformPipe turns query objects into predictable JavaScript values before controller code receives them.",{"id":524,"title":525,"titles":526,"content":527,"level":214},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Fquery-transform#pipeline","Pipeline",[70],"QueryTransformPipe only transforms Nest arguments where metadata.type === 'query'. if (metadata.type === 'query' && typeof value === 'object') {\n  return parseObject(value);\n} Route params, body values, and custom metadata types are returned unchanged.",{"id":529,"title":530,"titles":531,"content":532,"level":214},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Fquery-transform#parsing-rules","Parsing Rules",[70],"InputOutput'42'42'3.14'3.14'true'true'false'false'null'null['1', '2'][1, 2]{ 'user.name': 'Ada' }{ user: { name: 'Ada' } } Valid JSON object and array strings are parsed recursively. Invalid JSON-like strings and empty strings are preserved.",{"id":534,"title":535,"titles":536,"content":537,"level":214},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Fquery-transform#dotted-keys","Dotted Keys",[70],"parseObject({\n  'where.profile.name': 'Ada',\n  'where.active': 'true',\n});\n\n\u002F\u002F {\n\u002F\u002F   where: {\n\u002F\u002F     profile: { name: 'Ada' },\n\u002F\u002F     active: true\n\u002F\u002F   }\n\u002F\u002F } Avoid sending both dotted and nested variants for the same path; normal object assignment semantics decide the final value.",{"id":539,"title":503,"titles":540,"content":541,"level":214},"\u002Fdocs\u002Fnest\u002Fconcepts\u002Fquery-transform#validation",[70],"The pipe normalizes values; it does not validate them. Compose it with Nest's ValidationPipe and DTO classes for request validation. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":81,"title":80,"titles":543,"content":544,"level":204},[],"Complete CRUD controller example for @querry-kit\u002Fnest.",{"id":546,"title":80,"titles":547,"content":548,"level":204},"\u002Fdocs\u002Fnest\u002Fguide\u002Fcrud-controller#crud-controller",[],"This controller shows a full resource shape with list, detail, create, update, and delete routes. Read endpoints use ResourceQuery so fields, Prisma-style includes, service calls, DTO mapping, and projection stay in one small pattern. Mutations use prepareFieldsQuery and Fields.project so optional fields works on every route without hiding domain-specific write logic. @Controller('books')\n@UseGuards(PoliciesGuard)\nexport class BooksController {\n  constructor(private readonly booksService: BooksService) {}\n\n  @Get()\n  @CheckPolicies((ability) => ability.can(BookAction.Read, BookSubject))\n  @ApiResourceQuery()\n  @ApiPaginatedResponse({ model: BookDTO })\n  async query(@Req() req: DemoRequest, @Query() query: QueryDTO\u003CBookTypeMap>) {\n    return ResourceQuery.query({\n      service: this.booksService,\n      query,\n      schema: BookDTO,\n      ability: req.ability,\n      include: { author: true },\n      map: (book) => BookDTO.fromModel(book),\n    });\n  }\n}",{"id":550,"title":551,"titles":552,"content":553,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fcrud-controller#service-contract","Service Contract",[80],"ResourceQuery expects read services with the same shape as QueryService: service.query\u003CTModel>(query, ability);\nservice.findById\u003CTModel>(id, query, ability); Create, update, and delete stay resource-specific because they usually contain domain rules, transactions, unique checks, and relation writes. html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":85,"title":84,"titles":555,"content":556,"level":204},[],"A complete, copyable NestJS resource API assembled from @querry-kit\u002Fnest building blocks.",{"id":558,"title":84,"titles":559,"content":560,"level":204},"\u002Fdocs\u002Fnest\u002Fguide\u002Fexample-app#complete-api-example",[],"This example uses books, authors, and tags to show a complete resource API without relying on a separate repository example. The individual snippets are designed to be copied into an existing Nest application and adapted to its Prisma models and authorization rules.",{"id":562,"title":563,"titles":564,"content":565,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fexample-app#what-it-shows","What It Shows",[84],"ResourceQuery.query for paginated list endpoints.ResourceQuery.findById for detail endpoints.DTO-backed optional fields validation and projection on every controller route.paginated envelope projection for items and meta.generated includes for author, nested author.books, and tags.QueryService with an authorization-aware accessibleWhere resolver.CheckPolicies, PoliciesGuard, ApiResourceQuery, ApiPaginatedResponse, ApiErrorResponses, and ApiParamId.QueryTransformPipe, FieldsExceptionFilter, and Swagger setup.a complete CRUD controller with GET, POST, PATCH, and DELETE.",{"id":567,"title":568,"titles":569,"content":570,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fexample-app#dtos","DTOs",[84],"Expose only the fields that clients may select. @ApiProperty metadata gives Fields the schema it uses to validate and project the fields parameter. import { ApiProperty } from '@nestjs\u002Fswagger';\nimport { Expose } from 'class-transformer';\n\nexport class AuthorDTO {\n  @Expose()\n  @ApiProperty({ example: 'author-ada' })\n  id!: string;\n\n  @Expose()\n  @ApiProperty({ example: 'Ada Lovelace' })\n  name!: string;\n}\n\nexport class BookDTO {\n  @Expose()\n  @ApiProperty({ example: 'book-1' })\n  id!: string;\n\n  @Expose()\n  @ApiProperty({ example: 'Practical Nest Queries' })\n  title!: string;\n\n  @Expose()\n  @ApiProperty({ type: () => AuthorDTO, required: false })\n  author?: AuthorDTO;\n\n  static fromModel(book: BookModel): BookDTO {\n    return Object.assign(new BookDTO(), {\n      id: book.id,\n      title: book.title,\n      author: book.author && Object.assign(new AuthorDTO(), book.author),\n    });\n  }\n}",{"id":572,"title":573,"titles":574,"content":575,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fexample-app#service","Service",[84],"Extend QueryService with the generated Prisma delegate and a type map for the model. If the endpoint is authorization-aware, provide the CASL subject and accessibility resolver here. import { Injectable } from '@nestjs\u002Fcommon';\nimport { createCaslAccessibleWhere, QueryService, type BaseDelegateTypeMap } from '@querry-kit\u002Fnest';\n\ninterface BookTypeMap extends BaseDelegateTypeMap {\n  select: Prisma.BookSelect;\n  include: Prisma.BookInclude;\n  whereInput: Prisma.BookWhereInput;\n  orderByWithRelationInput: Prisma.BookOrderByWithRelationInput;\n  whereUniqueInput: Prisma.BookWhereUniqueInput;\n  scalarFieldEnum: Prisma.BookScalarFieldEnum;\n  aggregateInputType: Prisma.AggregateBook;\n}\n\n@Injectable()\nexport class BooksService extends QueryService\u003Ctypeof PrismaService.prototype.book, BookTypeMap> {\n  constructor(prisma: PrismaService) {\n    super(prisma.book, {\n      subject: 'Book',\n      accessibleWhere: createCaslAccessibleWhere\u003CAppAbility, 'Book'>({ action: 'read' }),\n    });\n  }\n} The CASL reference shows the equivalent setup for enum-backed actions and write rules.",{"id":577,"title":578,"titles":579,"content":580,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fexample-app#controller","Controller",[84],"Use ResourceQuery for read routes. It prepares includes, calls the service, maps models to DTOs, and applies the requested field projection. @ApiTags('books')\n@Controller('books')\nexport class BooksController {\n  constructor(private readonly booksService: BooksService) {}\n\n  @Get()\n  @ApiResourceQuery()\n  @ApiPaginatedResponse({ model: BookDTO })\n  async query(@Req() req: AuthenticatedRequest, @Query() query: QueryDTO\u003CBookTypeMap>) {\n    return ResourceQuery.query({\n      service: this.booksService,\n      query,\n      schema: BookDTO,\n      ability: req.ability,\n      include: { author: true },\n      map: (book) => BookDTO.fromModel(book),\n    });\n  }\n\n  @Get(':id')\n  @ApiParamId({ description: 'Book ID' })\n  @ApiFieldsQuery()\n  async findById(@Param('id') id: string, @Req() req: AuthenticatedRequest, @Query() query: FindByIdDTO\u003CBookTypeMap>) {\n    return ResourceQuery.findById({\n      service: this.booksService,\n      id,\n      query,\n      schema: BookDTO,\n      ability: req.ability,\n      map: (book) => BookDTO.fromModel(book),\n    });\n  }\n} For create, update, and delete routes, call prepareFieldsQuery before the domain operation and Fields.project on the mapped DTO. The CRUD Controller guide covers that shape.",{"id":582,"title":583,"titles":584,"content":585,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fexample-app#routes","Routes",[84],"Query published books: curl -g 'http:\u002F\u002Flocalhost:3000\u002Fbooks?fields=id,title,author{name},tags{name}' Find one book and request nested author books: curl -g 'http:\u002F\u002Flocalhost:3000\u002Fbooks\u002Fbook-1?fields=id,title,author{name,books{title}}' Project a paginated response envelope: curl -g 'http:\u002F\u002Flocalhost:3000\u002Fbooks?fields=items{id,title},meta{page,perPage,itemCount,pageCount}' Create a book: POST \u002Fbooks\nContent-Type: application\u002Fjson\n\n{\n  \"title\": \"Composable Nest APIs\",\n  \"isbn\": \"978-0000000004\",\n  \"authorId\": \"author-ada\",\n  \"tagIds\": [\"tag-nest\", \"tag-api\"]\n} Delete a book: DELETE \u002Fbooks\u002Fbook-2?fields=id,title Update a book: PATCH \u002Fbooks\u002Fbook-2\nContent-Type: application\u002Fjson\n\n{\n  \"title\": \"Typed Prisma Services, 2nd Edition\",\n  \"tagIds\": [\"tag-prisma\", \"tag-api\"]\n} Every route accepts fields. Unknown DTO fields return HTTP 400 during fields validation. Invalid Prisma select and include keys should likewise be reported as HTTP 400 by the service layer.",{"id":587,"title":588,"titles":589,"content":590,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fexample-app#bootstrap","Bootstrap",[84],"Register QueryTransformPipe and FieldsExceptionFilter once in the application bootstrap. The complete NestJS main.ts example includes validation and Swagger configuration. With those pieces in place, the API remains application-owned: replace BookDTO, BooksService, the Prisma types, and the ability with the equivalents from your own domain. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":89,"title":88,"titles":592,"content":593,"level":204},[],"Install and use @querry-kit\u002Fnest.",{"id":595,"title":88,"titles":596,"content":597,"level":204},"\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started#getting-started",[],"@querry-kit\u002Fnest combines the useful parts of the former Query Kit Nest packages into one import surface: fields parsing, validation, Prisma include generation, and response projection.Prisma-compatible QueryService helpers with pagination DTOs.optional CASL integration for authorization-aware read queries.OpenAPI decorators, query\u002Fbody pipes, validation helpers, and object utilities.",{"id":599,"title":600,"titles":601,"content":602,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started#installation","Installation",[88],"pnpm add @querry-kit\u002Fnest Install CASL peers only when the app uses the CASL adapter: pnpm add @casl\u002Fability @casl\u002Fprisma",{"id":604,"title":605,"titles":606,"content":607,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started#service-setup","Service Setup",[88],"Extend QueryService with a Prisma-compatible delegate and a model type map from your app. import { Injectable } from '@nestjs\u002Fcommon';\nimport { QueryService, type BaseDelegateTypeMap } from '@querry-kit\u002Fnest';\nimport { Prisma, PrismaService } from '..\u002Fprisma';\n\ninterface CustomerTypeMap extends BaseDelegateTypeMap {\n  select: Prisma.CustomerSelect;\n  include: Prisma.CustomerInclude;\n  whereInput: Prisma.CustomerWhereInput;\n  orderByWithRelationInput: Prisma.CustomerOrderByWithRelationInput;\n  whereUniqueInput: Prisma.CustomerWhereUniqueInput;\n  scalarFieldEnum: Prisma.CustomerScalarFieldEnum;\n  aggregateInputType: Prisma.AggregateCustomer;\n}\n\n@Injectable()\nexport class CustomersService extends QueryService\u003Ctypeof PrismaService.prototype.customer, CustomerTypeMap> {\n  constructor(prisma: PrismaService) {\n    super(prisma.customer);\n  }\n}",{"id":609,"title":610,"titles":611,"content":612,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started#resource-controller","Resource Controller",[88],"Use ResourceQuery.query when the endpoint follows the common pattern: parse optional fields, merge endpoint-required includes with client includes, call the service, map models to DTOs, and project the response. import { Controller, Get, Query, Req } from '@nestjs\u002Fcommon';\nimport { ApiErrorResponses, ApiPaginatedResponse, ApiResourceQuery, QueryDTO, ResourceQuery } from '@querry-kit\u002Fnest';\n\n@Controller('customers')\nexport class CustomersController {\n  constructor(private readonly customersService: CustomersService) {}\n\n  @Get()\n  @ApiResourceQuery()\n  @ApiPaginatedResponse({ model: CustomerDTO })\n  @ApiErrorResponses({ badRequestDescription: 'Invalid query parameter.' })\n  async query(@Req() req: AuthRequest, @Query() query: QueryDTO\u003CCustomerTypeMap>) {\n    return ResourceQuery.query({\n      service: this.customersService,\n      query,\n      schema: CustomerDTO,\n      ability: req.ability,\n      include: { organization: true },\n      map: (customer, ability) => CustomerDTO.fromModel(customer, ability),\n    });\n  }\n} ApiResourceQuery() documents fields, page, perPage, select, include, where, orderBy, and distinct. ResourceQuery.query keeps fields optional; when it is present, unknown DTO fields return HTTP 400 before the service runs. Invalid Prisma select or include values should be reported by the service layer as HTTP 400. Paginated responses support item shorthand and envelope projection: GET \u002Fcustomers?fields=id,name\nGET \u002Fcustomers?fields=items{id,name},meta{page,perPage,itemCount,pageCount} The ability option is optional. Omit it when an endpoint does not use CASL. The include option is for relations required by the endpoint or ability-aware mapper; client include parameters extend it. For detail endpoints, use ResourceQuery.findById with the same schema and mapper: @Get(':id')\nasync findById(@Param('id') id: string, @Req() req: AuthRequest, @Query() query: FindByIdDTO\u003CCustomerTypeMap>) {\n  return ResourceQuery.findById({\n    service: this.customersService,\n    id,\n    query,\n    schema: CustomerDTO,\n    ability: req.ability,\n    map: (customer, ability) => CustomerDTO.fromModel(customer, ability),\n  });\n}",{"id":614,"title":615,"titles":616,"content":617,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started#manual-fields-flow","Manual Fields Flow",[88],"Use prepareFieldsQuery directly when a controller needs custom service orchestration. import { Fields, PaginatedDTO, prepareFieldsQuery } from '@querry-kit\u002Fnest';\n\nconst prepared = prepareFieldsQuery(query, CustomerDTO);\nconst { items, pageMeta } = await this.customersService.query\u003CCustomerPayload>(prepared.query, req.ability);\nconst dtoItems = await Promise.all(items.map((item) => CustomerDTO.fromModel(item, req.ability)));\n\nreturn new PaginatedDTO(Fields.project(dtoItems, prepared.projection), pageMeta);",{"id":619,"title":421,"titles":620,"content":621,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started#query-parsing",[88],"Register QueryTransformPipe globally when query strings should be normalized before they reach controllers. import { QueryTransformPipe } from '@querry-kit\u002Fnest';\n\napp.useGlobalPipes(new QueryTransformPipe()); QueryTransformPipe converts values such as '1', 'false', 'null', JSON strings, arrays, and dotted keys into Prisma-friendly JavaScript objects.",{"id":623,"title":624,"titles":625,"content":626,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started#validation-pipe","Validation Pipe",[88],"PageOptionsDTO works with Nest validation and transformation. app.useGlobalPipes(\n  new ValidationPipe({\n    transform: true,\n    whitelist: true,\n  }),\n); page and perPage default to 1 and 10, are converted to numbers, and are validated as integers.",{"id":628,"title":629,"titles":630,"content":631,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fgetting-started#next-steps","Next Steps",[88],"The Complete API Example shows how the DTO, service, controller, and bootstrap fit together. It is self-contained in the documentation, so you can copy only the parts that match your application. Use the complete reference snippets for a NestJS main.ts and a CRUD Controller when wiring the pattern into an existing module. html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"id":93,"title":92,"titles":633,"content":634,"level":204},[],"Complete NestJS main.ts example for @querry-kit\u002Fnest.",{"id":636,"title":92,"titles":637,"content":638,"level":204},"\u002Fdocs\u002Fnest\u002Fguide\u002Fmain-bootstrap#nestjs-maints",[],"This bootstrap registers Query Kit's query parser, structured fields errors, validation, and Swagger documentation in a Nest application. import { ValidationPipe } from '@nestjs\u002Fcommon';\nimport { NestFactory } from '@nestjs\u002Fcore';\nimport { DocumentBuilder, SwaggerModule } from '@nestjs\u002Fswagger';\nimport { FieldsExceptionFilter, QueryTransformPipe } from '@querry-kit\u002Fnest';\nimport { AppModule } from '.\u002Fapp.module.js';\n\nasync function bootstrap(): Promise\u003Cvoid> {\n  const app = await NestFactory.create(AppModule);\n\n  app.useGlobalPipes(\n    new QueryTransformPipe(),\n    new ValidationPipe({\n      transform: true,\n      whitelist: true,\n      forbidNonWhitelisted: true,\n    }),\n  );\n\n  app.useGlobalFilters(new FieldsExceptionFilter());\n\n  const config = new DocumentBuilder()\n    .setTitle('Books API')\n    .setDescription('Example API using @querry-kit\u002Fnest resource queries and fields projection.')\n    .setVersion('1.0.0')\n    .addBearerAuth()\n    .build();\n\n  const document = SwaggerModule.createDocument(app, config);\n  SwaggerModule.setup('docs', app, document, {\n    swaggerOptions: {\n      persistAuthorization: true,\n    },\n  });\n\n  const port = Number(process.env.PORT ?? 3000);\n  await app.listen(port);\n}\n\nvoid bootstrap();",{"id":640,"title":641,"titles":642,"content":643,"level":214},"\u002Fdocs\u002Fnest\u002Fguide\u002Fmain-bootstrap#notes","Notes",[92],"QueryTransformPipe normalizes query strings before DTO validation and service calls.ValidationPipe handles DTO validation and transformation.FieldsExceptionFilter serializes invalid fields query values as structured HTTP 400 responses.SwaggerModule.createDocument works with ApiPaginatedResponse, ApiErrorResponses, and the DTO metadata used by fields schema generation.Configure PORT when the application should listen on a port other than 3000. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":11,"title":10,"titles":645,"content":646,"level":204},[],"Query Kit foundations for documented NestJS APIs.",{"id":648,"title":649,"titles":650,"content":651,"level":204},"\u002Fdocs\u002Fnest#query-kit-for-nestjs-apis","Query Kit for NestJS APIs",[],"@querry-kit\u002Fnest brings fields projection, Prisma-style query services, CASL policies, decorators, pipes, pagination DTOs, and object utilities into one focused package.",{"id":653,"title":654,"titles":655,"content":656,"level":214},"\u002Fdocs\u002Fnest#build-a-resource-api-without-repetitive-glue","Build a resource API without repetitive glue",[649],"Resource query facade prepares fields, relation includes, service calls, DTO mapping, and response projection.Prisma and CASL keep authorization-aware database queries explicit and optional.Fields projection validates requested DTO fields and returns the response shape a client asked for.NestJS utilities provide OpenAPI decorators, pipes, pagination DTOs, and parsing helpers from a single import surface. Get started\n  Browse the API",{"id":108,"title":107,"titles":658,"content":659,"level":204},[],"Import public state types from the package types entrypoint:",{"id":661,"title":107,"titles":662,"content":663,"level":204},"\u002Fdocs\u002Fnuxt-ui\u002Fapi\u002Ftypes#types-and-text-customization",[],"Import public state types from the package types entrypoint: import {\n  FilterFieldType,\n  FilteringMode,\n  type ColumnPinning,\n  type ColumnDefinition,\n  type FilterField,\n  type Filtering,\n  type SortingState,\n} from '@querry-kit\u002Fnuxt-ui\u002Ftypes'; SortingState is an ordered list of { id, desc }. Filtering combines FilteringMode.Intersect (AND) or FilteringMode.Union (OR) with typed filter entries. FilterField is the discriminated component configuration for boolean, number, enum and custom-select editors. ColumnDefinition and ColumnPinning model the values accepted by column options.",{"id":665,"title":666,"titles":667,"content":668,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fapi\u002Ftypes#texts-without-i18n","Texts without i18n",[107],"@querry-kit\u002Fnuxt-ui has no i18n runtime dependency. Every text is resolved in this order: nested texts override, host-app i18n key, then an English fallback. Pass the optional texts prop to any table control, or to QTableToolbar to forward the same overrides to its default sorting, filtering, and column-option controls. \u003CQTableToolbar\n  v-model:search=\"search\"\n  :texts=\"{\n    search: { placeholder: 'Find projects' },\n    sorting: { title: 'Order by', add: 'Add order' },\n    pagination: { summary: 'Rows {start}–{end} of {total}' },\n  }\"\n\u002F> Explicit texts values have priority over host-app i18n and English defaults. QTablePagination also keeps its summary prop for changing only the result-summary template. Slots replace a complete display region when a text override is not enough. For example, replace the sorting trigger while retaining its open state and behavior: \u003CQTableSorting v-model:sorting=\"sorting\" :fields=\"sortableFields\">\n  \u003Ctemplate #trigger=\"{ toggle, active }\">\n    \u003CUButton :color=\"active ? 'primary' : 'neutral'\" label=\"Order projects\" @click=\"toggle\" \u002F>\n  \u003C\u002Ftemplate>\n\u003C\u002FQTableSorting> The toolbar exposes breadcrumb, search, options, and new; sorting, filtering, and options expose trigger, header, items, item, and add where applicable; pagination exposes left, page-size, pagination, and right.",{"id":670,"title":671,"titles":672,"content":673,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fapi\u002Ftypes#host-app-i18n-keys","Host-app i18n keys",[107],"Install and configure an i18n provider only when the application needs translations: pnpm add @nuxtjs\u002Fi18n vue-i18n Register it before @querry-kit\u002Fnuxt-ui. The package does not merge messages or ship locale payloads; define the keys in the host application's locale files. export default defineNuxtConfig({ modules: ['@nuxt\u002Fui', '@nuxtjs\u002Fi18n', '@querry-kit\u002Fnuxt-ui'] }); All package keys are namespaced below querrykit.table, avoiding collisions with application messages.",{"id":675,"title":676,"titles":677,"content":678,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fapi\u002Ftypes#complete-message-json","Complete message JSON",[107],"Use this complete shape in an application locale file. The texts prop accepts the same nested shape without the outer querrykit.table wrapper. {\n  \"querrykit\": {\n    \"table\": {\n      \"search\": {\n        \"placeholder\": \"Search\"\n      },\n      \"sorting\": {\n        \"title\": \"Sort\",\n        \"field\": \"Select field\",\n        \"add\": \"Add sort\",\n        \"clear\": \"Clear sorting\",\n        \"remove\": \"Remove sort\",\n        \"toggle\": \"Toggle sort direction\"\n      },\n      \"filtering\": {\n        \"title\": \"Filter\",\n        \"field\": \"Select field\",\n        \"add\": \"Add filter\",\n        \"clear\": \"Clear filters\",\n        \"remove\": \"Remove filter\",\n        \"mode\": \"Toggle filter mode\"\n      },\n      \"options\": {\n        \"title\": \"Table options\",\n        \"pin\": \"Pin column\",\n        \"left\": \"Left\",\n        \"right\": \"Right\",\n        \"center\": \"Unpin\",\n        \"visibility\": \"Toggle column visibility\"\n      },\n      \"pagination\": {\n        \"summary\": \"Showing {start}–{end} of {total}\"\n      }\n    }\n  }\n} html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"id":117,"title":116,"titles":680,"content":681,"level":204},[],"QTableFiltering edits a Query Kit-compatible Filtering value. It owns the editor state and emits immutable replacements; the application serializes the result for its API.",{"id":683,"title":116,"titles":684,"content":681,"level":204},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ffiltering#filtering",[],{"id":686,"title":687,"titles":688,"content":689,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ffiltering#inputs-and-state","Inputs and state",[116],"Prop\u002FmodelDefaultDescriptionv-model:filteringrequiredFilteringMode.Intersect (AND) or FilteringMode.Union (OR) plus filters.fieldsrequiredFilterField[] definitions for the available editors.iconi-tabler-filterTrigger icon.shortcutstrueEnables Shift + F.texts—Explicit text overrides, ahead of i18n and English defaults.ui.content—Extra classes for the Nuxt UI popover content. The trigger changes to the primary color when filters are active. Disabled fields are excluded from the add selector.",{"id":691,"title":692,"titles":693,"content":694,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ffiltering#popover-actions","Popover actions",[116],"Change filter mode — the header button switches between AND and OR while retaining every filter.Clear filters — the header action resets the value to an empty AND filter group.Add filter — choose an enabled field and press the plus button. The initial operator and value are derived from its type.Edit a boolean — the default checkbox writes true or false.Edit a number — choose =, ≠, >, ≥, \u003C, or ≤, then enter a number.Edit enum and select fields — choose ∈ or ∉ and select multiple values. Enum fields may provide a custom component; select fields require one.Remove filter — press the remove button next to an entry. \u003CQTableFiltering v-model:filtering=\"filtering\" :fields=\"filterFields\" \u002F>",{"id":696,"title":697,"titles":698,"content":699,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ffiltering#slots","Slots",[116],"SlotUseful slot propstriggeropen, toggle, activeheaderfiltering, clear, toggleModeitemsfilters, remove, updateitemfilter, field, remove, updateaddfields, add Use the item slot for an entirely custom per-field editor; use a field's component when only its value input differs. html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":121,"title":120,"titles":701,"content":702,"level":204},[],"QTableOptions manages the column-order, visibility, and pinning models without requiring a particular table adapter. The application applies the emitted models to its own table.",{"id":704,"title":120,"titles":705,"content":702,"level":204},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Foptions#column-options",[],{"id":707,"title":687,"titles":708,"content":709,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Foptions#inputs-and-state",[120],"Prop\u002FmodelDefaultDescriptioncolumnsrequiredColumnDefinition[], including column IDs, labels, and optional constraints.v-model:column-orderrequiredOrdered IDs displayed by the control.v-model:invisible-columnsrequiredIDs currently hidden.v-model:column-pinningrequired{ left?: string[], right?: string[] }.iconi-tabler-adjustmentsTrigger icon.shortcutstrueEnables Shift + O.texts—Explicit text overrides, ahead of i18n and English defaults.ui.content—Extra classes for the Nuxt UI popover content. Only IDs present in column-order are shown. A column with enableHiding: false keeps a disabled visibility switch.",{"id":711,"title":692,"titles":712,"content":713,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Foptions#popover-actions",[120],"Reorder columns — drag a row onto another row. The component emits a reordered column-order array.Show or hide a column — toggle the switch. The component adds or removes its ID from invisible-columns unless hiding is disabled.Pin left or right — open the pin action and choose Left or Right. The ID is removed from the other side first, then added to the selected side.Unpin — choose Unpin to remove the ID from both pinning arrays. \u003CQTableOptions\n  v-model:column-order=\"columnOrder\"\n  v-model:invisible-columns=\"invisibleColumns\"\n  v-model:column-pinning=\"columnPinning\"\n  :columns=\"columns\"\n\u002F>",{"id":715,"title":697,"titles":716,"content":717,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Foptions#slots",[120],"SlotUseful slot propstriggeropen, toggleheadercolumnsitemscolumns, move, toggleVisibility, pinitemcolumn, index, visible, pin, toggleVisibility The slots let an application replace the whole list or a row while retaining the component's immutable state updates. html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":125,"title":124,"titles":719,"content":720,"level":204},[],"QTablePagination is a standalone footer for page-based APIs. It emits page and page-size changes; the application fetches the corresponding data.",{"id":722,"title":124,"titles":723,"content":720,"level":204},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fpagination#pagination",[],{"id":725,"title":726,"titles":727,"content":728,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fpagination#inputs-and-behavior","Inputs and behavior",[124],"Prop\u002FmodelDefaultDescriptionv-model:pagerequiredOne-based current page.v-model:items-per-pagerequiredCurrent page size.total-items0Total available rows. Hides the summary when zero.page-sizes[1, 2, 10, 25, 50, 100]Selectable page sizes.summarylocalizedReplaces only the Showing {start}–{end} of {total} template.texts—Explicit text overrides, ahead of i18n and English defaults.shortcutstrueEnables keyboard page navigation.ui—Classes for the root, left, and right footer regions. Changing the page size emits update:items-per-page and clamps the current page to the new page count. The default pagination control provides first, previous, next, and last navigation; keyboard shortcuts mirror these actions: Shift + ← \u002F → moves one page.Shift + Ctrl + ← \u002F → moves to the first or last page.",{"id":730,"title":697,"titles":731,"content":732,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fpagination#slots",[124],"SlotSlot propsUse it to replaceleftpage, itemsPerPage, totalItems, start, endThe result summary region.page-sizeitemsPerPage, setItemsPerPageThe page-size selector.paginationpage, pageCount, first, previous, next, lastThe page navigation control.rightpage, pageCountA trailing footer region.",{"id":129,"title":128,"titles":734,"content":735,"level":204},[],"QTableSorting edits an ordered v-model:sorting list. It owns only the user interaction; the consuming application turns the emitted { id, desc } entries into an API query or table sort.",{"id":737,"title":128,"titles":738,"content":735,"level":204},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fsorting#sorting",[],{"id":740,"title":687,"titles":741,"content":742,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fsorting#inputs-and-state",[128],"Prop\u002FmodelDefaultDescriptionv-model:sortingrequiredOrdered SortingState: { id: string, desc: boolean }[].fieldsrequiredAvailable { value, label, disabled? } fields.iconi-tabler-arrows-sortTrigger icon.shortcutstrueEnables Shift + S.texts—Explicit text overrides, ahead of i18n and English defaults.ui.content—Extra classes for the Nuxt UI popover content. Disabled fields and fields already in sorting are not offered by the default add selector. The trigger changes to the primary color when at least one sort is active.",{"id":744,"title":692,"titles":745,"content":746,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fsorting#popover-actions",[128],"Add sort — select one of the remaining fields and press the plus button. The component appends it with desc: false.Change direction — press the direction button on an existing entry to toggle its desc value.Remove sort — press the remove button on an entry.Clear sorting — press the header action to emit an empty list.Use a custom order editor — the items slot receives move(from, to) for an application-defined order UI. \u003CQTableSorting v-model:sorting=\"sorting\" :fields=\"sortableFields\" \u002F>",{"id":748,"title":697,"titles":749,"content":750,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Fsorting#slots",[128],"SlotUseful slot propstriggeropen, toggle, activeheadersorting, clearitemssorting, remove, toggleDirection, moveitemsort, index, remove, toggleDirectionaddavailableFields, add Use a slot when the default region needs to be replaced, not merely renamed. Use texts for labels and accessible names. html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":133,"title":132,"titles":752,"content":753,"level":204},[],"QTableToolbar arranges a breadcrumb, create region, search field, and the three table controls. It does not fetch data, perform filtering, or own table state; it forwards the models supplied by the application.",{"id":755,"title":132,"titles":756,"content":753,"level":204},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ftoolbar#table-toolbar",[],{"id":758,"title":759,"titles":760,"content":761,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ftoolbar#models-and-regions","Models and regions",[132],"Model\u002FpropPurposev-model:searchFree-text value. An empty default input emits undefined.v-model:sortingForwarded to the default sorting control when sortable-fields exists.v-model:filteringForwarded to the default filtering control when filter-fields exists.v-model:column-orderEnables default column options together with its other models.v-model:invisible-columnsHidden IDs for default column options.v-model:column-pinningPinning state for default column options.breadcrumb-itemsItems rendered by the default UBreadcrumb.search-placeholderReplaces only the default search placeholder.textsText overrides forwarded to the default child controls.shortcutsEnables or disables the default child-control shortcuts.uiClasses for the root, primary, and secondary regions. The toolbar renders each default control only when it receives the necessary model and field\u002Fcolumn definitions. It is therefore safe to use it for a search-only or partially configurable table.",{"id":763,"title":697,"titles":764,"content":765,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fcomponents\u002Ftoolbar#slots",[132],"SlotSlot propsUse it to replacebreadcrumbitemsThe breadcrumb region.new—Create or bulk-action controls.searchsearch, setSearchThe search field or search behavior.optionssorting, filtering, columnOrderThe complete group of table controls. \u003CQTableToolbar v-model:search=\"search\">\n  \u003Ctemplate #new>\u003CUButton label=\"Create project\" \u002F>\u003C\u002Ftemplate>\n  \u003Ctemplate #search=\"{ search, setSearch }\">\n    \u003CUInput :model-value=\"search\" placeholder=\"Find projects\" @update:model-value=\"setSearch\" \u002F>\n  \u003C\u002Ftemplate>\n\u003C\u002FQTableToolbar> html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":141,"title":140,"titles":767,"content":431,"level":204},[],{"id":769,"title":140,"titles":770,"content":431,"level":204},"\u002Fdocs\u002Fnuxt-ui\u002Fguide\u002Fgetting-started#getting-started",[],{"id":772,"title":773,"titles":774,"content":775,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fguide\u002Fgetting-started#install","Install",[140],"pnpm add @querry-kit\u002Fnuxt @querry-kit\u002Fnuxt-ui @nuxt\u002Fui Register Nuxt UI before this module. Components read the host application's querrykit.table.* i18n keys when present and otherwise use English fallback strings. export default defineNuxtConfig({\n  modules: ['@nuxt\u002Fui', '@querry-kit\u002Fnuxt-ui'],\n  querryKitUi: { autoImports: true },\n}); Set autoImports to false when the application registers the components itself. The module never installs, configures, or ships an i18n provider.",{"id":777,"title":778,"titles":779,"content":780,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fguide\u002Fgetting-started#compose-a-table-toolbar","Compose a table toolbar",[140],"All state remains in the consuming application. Bind only the models needed by the controls you render. \u003CQTableToolbar\n  v-model:search=\"search\"\n  v-model:sorting=\"sorting\"\n  v-model:filtering=\"filtering\"\n  v-model:column-order=\"columnOrder\"\n  v-model:invisible-columns=\"invisibleColumns\"\n  v-model:column-pinning=\"columnPinning\"\n  :sortable-fields=\"sortableFields\"\n  :filter-fields=\"filterFields\"\n  :column-definitions=\"columns\"\n\u002F> The controls emit immutable replacement values through their v-models. This keeps them independent from a particular table implementation or application store.",{"id":782,"title":783,"titles":784,"content":785,"level":214},"\u002Fdocs\u002Fnuxt-ui\u002Fguide\u002Fgetting-started#keyboard-shortcuts","Keyboard shortcuts",[140],"ControlShortcutSortingShift + SFilteringShift + FColumn optionsShift + OPaginationShift + arrow keys; add Ctrl for first\u002Flast page Pass :shortcuts=\"false\" to an individual component to disable its listener. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"id":97,"title":96,"titles":787,"content":788,"level":204},[],"Composable table controls for Nuxt UI applications.",{"id":790,"title":791,"titles":792,"content":793,"level":204},"\u002Fdocs\u002Fnuxt-ui#composable-table-controls-for-nuxt-ui","Composable table controls for Nuxt UI",[],"@querry-kit\u002Fnuxt-ui adds accessible sorting, filtering, column preferences, search, and pagination while your application retains ownership of all table data and state.",{"id":795,"title":796,"titles":797,"content":798,"level":214},"\u002Fdocs\u002Fnuxt-ui#built-for-application-owned-state","Built for application-owned state",[791],"Every public component starts with Q. It emits immutable replacement values, so it can connect to any compatible table, query, or store. Table toolbar composes breadcrumb, search, create actions, and controls.Filtering and sorting edit Query Kit-compatible state with accessible Nuxt UI popovers.Column preferences reorder, hide, and pin columns without a table-adapter dependency.Pagination and text overrides provide a flexible page footer with English fallbacks and host-app customization. Get started\n  Browse components",{"id":156,"title":155,"titles":800,"content":801,"level":204},[],"These exports create and use a typed Query Kit REST client. Import them from @querry-kit\u002Fnuxt\u002Fapi (or from the package root).",{"id":803,"title":155,"titles":804,"content":801,"level":204},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fapi#api",[],{"id":806,"title":807,"titles":808,"content":809,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fapi#apiversion","ApiVersion",[155],"type ApiVersion = 'v1'; The API path version accepted by createApiClient. The current public contract supports only v1, which produces an \u002Fapi\u002Fv1 base path.",{"id":811,"title":812,"titles":813,"content":814,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fapi#createapiclientoptions","CreateApiClientOptions",[155],"interface CreateApiClientOptions {\n  apiBaseUrl: string;\n  getToken?: () => string | null | Promise\u003Cstring | null>;\n  resolveBaseUrl?: (apiBaseUrl: string) => string;\n  requestSource?: string;\n  getTimezone?: () => string | undefined;\n} Configuration owned by the consuming application when it creates a Query Kit Axios client. PropertyRequiredPurposeapiBaseUrlYesPublic API origin, with or without a trailing slash.getTokenNoResolves the current bearer token for every request. No returned value means no Authorization header.resolveBaseUrlNoRewrites the origin before the \u002Fapi\u002Fv1 path is added, for example for a tenant-aware host.requestSourceNoValue for the Request-Source header; defaults to web.getTimezoneNoResolves the Timezone header. The browser timezone is used when it is omitted.",{"id":816,"title":817,"titles":818,"content":819,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fapi#createapiclient","createApiClient",[155],"function createApiClient(\n  options: CreateApiClientOptions,\n  version?: ApiVersion,\n): AxiosInstance; Creates an Axios instance with a base URL of \u003Cresolved origin>\u002Fapi\u002Fv1. It does not read Nuxt runtime configuration, stores, cookies, or router state. const api = createApiClient({\n  apiBaseUrl: 'https:\u002F\u002Fapi.example.com',\n  getToken: () => session.value?.accessToken ?? null,\n  requestSource: 'admin',\n}); Before each request, the client sets Request-Source, resolves a timezone, and obtains a fresh token. Pass resolveBaseUrl when the origin must change per request context.",{"id":821,"title":822,"titles":823,"content":824,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fapi#usemoduleapi","useModuleApi",[155],"function useModuleApi\u003C\n  TMap extends EndpointMap,\n  TEndpoint extends keyof TMap & string,\n>(api: AxiosInstance, endpoint: TEndpoint): ModuleApi\u003CTMap, TEndpoint>; Creates typed CRUD methods for one endpoint. Endpoint names may have a leading slash; identifiers are URL-encoded before a request is made. type Book = { id: string; title: string };\ntype Endpoints = EndpointMap & {\n  books: { item: Book; create: Pick\u003CBook, 'title'>; update: Partial\u003CPick\u003CBook, 'title'>> };\n};\n\nconst books = useModuleApi\u003CEndpoints, 'books'>(api, 'books');\nconst response = await books.query({ page: 1, perPage: 25 }); MethodRequestResponse dataquery(query?)GET \u002FendpointPaginatedResponse\u003CTItem>get(id, query?)GET \u002Fendpoint\u002F:idTItemfindById(id, query?)GET \u002Fendpoint\u002Ffind-by-id\u002F:idTItemcount(query?)GET \u002Fendpoint\u002Fcountnumbercreate(data, query?)POST \u002FendpointTItemupdate(id, data, query?)PATCH \u002Fendpoint\u002F:idTItemdelete(id, query?)DELETE \u002Fendpoint\u002F:idTItem Every method returns an AxiosResponse. Query payloads are encoded through serializeQuery.",{"id":826,"title":827,"titles":828,"content":829,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fapi#query-kit-compatibility","Query Kit compatibility",[155],"The supported list response is: type PaginatedResponse\u003CT> = {\n  items: T[];\n  meta: { itemCount: number; pageCount: number };\n}; ParameterShape emitted by this packagepage, perPagePagination numberswhereJSON string of a nested Query Kit conditionorderByJSON string of nested ascending\u002Fdescending rulesfieldsCompact field grammar, for example id,title,author{name}includeNested qs payload, for example include[author]=true where and orderBy are serialized as JSON strings and encoded with qs. The fields parameter uses the existing Query Kit selection grammar. The list response must use items, not data, and provide meta.itemCount and meta.pageCount. html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"id":160,"title":159,"titles":831,"content":832,"level":204},[],"The autocomplete composable keeps selected resources loaded independently of the active search result.",{"id":834,"title":159,"titles":835,"content":832,"level":204},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fautocomplete#autocomplete",[],{"id":837,"title":838,"titles":839,"content":840,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fautocomplete#useautocompleteoptions","UseAutocompleteOptions",[159],"interface UseAutocompleteOptions\u003CTItem extends Record\u003Cstring, unknown>> {\n  api: AxiosInstance;\n  endpoint: string;\n  query?: MaybeRef\u003CQueryParameters | undefined>;\n  currentValue?: MaybeRef\u003Cstring | number | Array\u003Cstring | number> | null | undefined>;\n  identityKey?: keyof TItem & string;\n  itemDisabled?: (item: TItem) => boolean;\n  immediate?: boolean;\n} PropertyRequiredPurposeapiYesAxios client created by the application.endpointYesResource endpoint relative to the configured API version.queryNoReactive query for search results.currentValueNoA selected identity or identities to load even when absent from the search query.identityKeyNoProperty used for selection and deduplication; defaults to id.itemDisabledNoAdds a derived disabled property to returned items.immediateNoSet to false to call initialize() manually; the default is true.",{"id":842,"title":843,"titles":844,"content":845,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Fautocomplete#useautocomplete","useAutocomplete",[159],"function useAutocomplete\u003CTItem extends Record\u003Cstring, unknown>>(\n  options: UseAutocompleteOptions\u003CTItem>,\n): AutocompleteState\u003CTItem>; Loads selected identities and search results independently, then returns selected items first and removes duplicate identities. Older responses never replace a newer result of the same request kind. const users = useAutocomplete\u003CUser>({\n  api,\n  endpoint: 'users',\n  query: computed(() => ({ where: { name: { contains: search.value } } })),\n  currentValue: selectedUserId,\n}); Returned valueMeaningitemsComputed selected items followed by unique query items. itemDisabled is applied only here.currentValueItems, queryItemsRaw cached results of the two requests.loading, errorCombined pending state and the latest request error.loadCurrentItems()Refreshes selected identities only.loadItems()Refreshes search results only.initialize() \u002F refresh()Loads both groups concurrently. html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"id":150,"title":16,"titles":847,"content":848,"level":204},[],"API overview for @querry-kit\u002Fnuxt.",{"id":850,"title":16,"titles":851,"content":852,"level":204},"\u002Fdocs\u002Fnuxt\u002Fapi#api-reference",[],"@querry-kit\u002Fnuxt exposes framework-neutral runtime primitives. Applications provide their own Axios instance, authentication, routing, storage, endpoint map, and visual components. import { createApiClient, useModuleApi } from '@querry-kit\u002Fnuxt\u002Fapi';\nimport { useTable } from '@querry-kit\u002Fnuxt\u002Ftable';\nimport { useAutocomplete } from '@querry-kit\u002Fnuxt\u002Fautocomplete';\nimport type { EndpointMap, TableColumnInput } from '@querry-kit\u002Fnuxt\u002Ftypes';",{"id":854,"title":343,"titles":855,"content":856,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi#main-areas",[16],"AreaUse forAPI clientCreating a Query Kit-aware Axios client with current token, timezone, source, and tenant-host resolution.Resource APITyped query, get, findById, count, create, update, and delete methods for one endpoint.useTableRemote pagination, fields, filtering, sorting, persistence, URL-page syncing, and stale-request protection.useAutocompleteCombining selected resources with search results without duplicate identities.Utilities and typesQuery serialization, filter\u002Forder conversion, endpoint contracts, and headless UI metadata.",{"id":858,"title":859,"titles":860,"content":861,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi#public-imports","Public Imports",[16],"ImportContents@querry-kit\u002FnuxtRe-exports all public runtime functions.@querry-kit\u002Fnuxt\u002FapicreateApiClient, useModuleApi, and client types.@querry-kit\u002Fnuxt\u002FtableuseTable; its options type is exported through .\u002Ftypes.@querry-kit\u002Fnuxt\u002FautocompleteuseAutocomplete and UseAutocompleteOptions.@querry-kit\u002Fnuxt\u002FtypesEndpoint, response, table, filter\u002Fsort field, persistence, and route-ref contracts.@querry-kit\u002Fnuxt\u002FutilsSerialization and Query Kit state helpers.",{"id":863,"title":864,"titles":865,"content":866,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi#reference-groups","Reference groups",[16],"Each reference group is kept on one page, so related types and functions can be read together. API: Axios client and endpoint methodsAutocomplete: autocomplete options and composableTable: table options and composableTypes: endpoint, response, table, persistence, and route contractsUtils: serialization and Query Kit state helpers Before wiring a composable, confirm the application backend implements the controller contract. html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":164,"title":163,"titles":868,"content":869,"level":204},[],"The headless table composable owns Query Kit request state, but consumers retain their table renderer, router, and storage adapters.",{"id":871,"title":163,"titles":872,"content":869,"level":204},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftable#table",[],{"id":874,"title":875,"titles":876,"content":877,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftable#usetableoptions","UseTableOptions",[163],"interface UseTableOptions\u003C\n  TItem extends Record\u003Cstring, unknown>,\n  TColumn extends TableColumnInput\u003CTItem, object> = TableColumnInput\u003CTItem>,\n> {\n  api: AxiosInstance;\n  endpoint: string;\n  persistenceKey?: string;\n  name?: string;\n  columns: Ref\u003Creadonly TColumn[]>;\n  staticFields?: string[];\n  staticInclude?: Record\u003Cstring, unknown>;\n  staticFilter?: MaybeRef\u003CRecord\u003Cstring, unknown> | undefined>;\n  isArchived?: boolean;\n  defaultItemsPerPage?: number;\n  storage?: StorageLike;\n  routePage?: RoutePageRef;\n  identityKey?: keyof TItem & string;\n  onInitialized?: () => void | Promise\u003Cvoid>;\n  onRefreshed?: (items: TItem[]) => void | Promise\u003Cvoid>;\n  onError?: (error: unknown) => void | Promise\u003Cvoid>;\n} PropertyPurposeapi, endpoint, columnsRequired client, endpoint, and reactive renderer-aware column definitions.persistenceKey \u002F nameNamespace local table preferences; name is retained for compatibility.staticFields, staticInclude, staticFilter, isArchivedFields and conditions merged into every Query Kit request.defaultItemsPerPage, storage, routePageInitial size and optional persistence\u002FURL adapters.identityKeyRow property used by updateRow; defaults to id.onInitialized, onRefreshed, onErrorLifecycle callbacks for the initial request, latest successful request, and latest failure.",{"id":879,"title":880,"titles":881,"content":882,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftable#usetable","useTable",[163],"function useTable\u003C\n  TItem extends Record\u003Cstring, unknown>,\n  TColumn extends TableColumnInput\u003CTItem, object> = TableColumnInput\u003CTItem>,\n>(options: UseTableOptions\u003CTItem, TColumn>): TableState\u003CTItem, TColumn>; Creates portable, headless state for a remote Query Kit table. A new request version is assigned on every refresh, so an older response cannot overwrite newer data. const table = useTable\u003CBook>({\n  api,\n  endpoint: 'books',\n  persistenceKey: 'books',\n  columns,\n  routePage,\n});\n\nawait table.initialize(); Returned valueMeaningpage, itemsPerPageCurrent pagination; page can be synchronized through routePage.sorting, filteringPersisted Query Kit UI state.columnOrder, columnVisibility, columnPinningPersisted renderer metadata.columns, fields, queryParamsDerived visible columns, fields projection, and outgoing request.items, totalItems, totalPages, loading, errorCurrent response and request state.initialize()Syncs the initial page, fetches, then runs onInitialized.refresh()Fetches the current request; only the latest response is accepted.updateRow(row)Shallow-merges the matching row without refetching. html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"id":168,"title":167,"titles":884,"content":885,"level":204},[],"Shared contracts are available from @querry-kit\u002Fnuxt\u002Ftypes and re-exported by @querry-kit\u002Fnuxt.",{"id":887,"title":167,"titles":888,"content":885,"level":204},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#types",[],{"id":890,"title":891,"titles":892,"content":431,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#resource-api","Resource API",[167],{"id":894,"title":895,"titles":896,"content":897,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#endpointdefinition","EndpointDefinition",[167,891],"interface EndpointDefinition\u003CTItem = unknown, TCreate = Partial\u003CTItem>, TUpdate = Partial\u003CTItem>> {\n  item: TItem;\n  create: TCreate;\n  update: TUpdate;\n} Associates one endpoint with its returned resource and mutation payloads. useModuleApi infers its method arguments and response data from this contract. type BookEndpoint = EndpointDefinition\u003CBook, CreateBook, UpdateBook>;",{"id":899,"title":900,"titles":901,"content":902,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#endpointmap","EndpointMap",[167,891],"type EndpointMap = Record\u003Cstring, EndpointDefinition>; Maps endpoint names to contracts and is the first generic of useModuleApi. type Endpoints = {\n  books: EndpointDefinition\u003CBook, CreateBook, UpdateBook>;\n  authors: EndpointDefinition\u003CAuthor>;\n};",{"id":904,"title":905,"titles":906,"content":907,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#paginatedresponse","PaginatedResponse",[167,891],"interface PaginatedResponse\u003CT> {\n  items: T[];\n  meta: PaginationMeta;\n} The required response shape for a Query Kit list endpoint. Both useTable and useAutocomplete read items; the table also reads the pagination metadata.",{"id":909,"title":910,"titles":911,"content":912,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#paginationmeta","PaginationMeta",[167,891],"interface PaginationMeta {\n  itemCount: number;\n  pageCount: number;\n  [key: string]: unknown;\n} Extra backend-specific keys are permitted, but itemCount and pageCount are required by useTable.",{"id":914,"title":915,"titles":916,"content":917,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#queryparameters","QueryParameters",[167,891],"type QueryParameters = Record\u003Cstring, unknown>; The open query-payload contract used by API methods and autocomplete. Values are serialized in Query Kit's bracket notation by serializeQuery. const query: QueryParameters = {\n  page: 1,\n  perPage: 25,\n  where: { status: 'active' },\n};",{"id":919,"title":920,"titles":921,"content":431,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#table-state","Table state",[167],{"id":923,"title":924,"titles":925,"content":926,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#filterfielddefinition","FilterFieldDefinition",[167,920],"type FilterFieldDefinition\u003CTType extends string = string, TMeta extends object = object> = TMeta & {\n  value: string;\n  label: string;\n  type: TType;\n}; A renderer-neutral description of a selectable filtering field. Use TMeta for application-specific details such as an options source or a custom control; the package does not depend on a UI library.",{"id":928,"title":929,"titles":930,"content":931,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#filteringfieldoperator","FilteringFieldOperator",[167,920],"type FilteringFieldOperator = 'in' | 'notIn' | 'equals' | 'not' | 'lt' | 'lte' | 'gt' | 'gte'; The operators supported by Query Kit's where convention. Consumers may use a narrower subset for a particular field editor.",{"id":933,"title":934,"titles":935,"content":936,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#filteringfield","FilteringField",[167,920],"interface FilteringField\u003CTType extends string = string, TOperator extends string = string, TValue = unknown> {\n  id: string;\n  field: string;\n  type?: TType;\n  operator?: TOperator;\n  value?: TValue;\n} Describes one UI filter before it is converted to a Query Kit where payload. field supports dotted paths such as author.name; operator becomes the nested Query Kit operator when supplied.",{"id":938,"title":939,"titles":940,"content":941,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#filteringstate","FilteringState",[167,920],"interface FilteringState\u003CTField extends FilteringField = FilteringField> {\n  operator: FilteringMode;\n  filters: TField[];\n} The table's complete UI filtering state. filteringToWhere ignores filters without a value and combines the remaining conditions using operator.",{"id":943,"title":944,"titles":945,"content":946,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#filteringmode","FilteringMode",[167,920],"type FilteringMode = 'AND' | 'OR'; The boolean operator used to combine the filtering state entries.",{"id":948,"title":949,"titles":950,"content":951,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#routepageref","RoutePageRef",[167,920],"type RoutePageRef = Ref\u003Cnumber | string | null | undefined>; A consumer-owned reactive page value. Pass it to UseTableOptions.routePage to synchronize table pagination without coupling the package to Vue Router. const routePage = computed({\n  get: () => route.query.page,\n  set: (page) => router.replace({ query: { ...route.query, page } }),\n});",{"id":953,"title":954,"titles":955,"content":956,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#sortingrule","SortingRule",[167,920],"interface SortingRule {\n  id: string;\n  desc: boolean;\n} A TanStack-compatible sorting entry. The id may be a dotted field path; desc: true becomes desc, otherwise sortingToOrderBy emits asc.",{"id":958,"title":959,"titles":960,"content":961,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#sortingfield","SortingField",[167,920],"type SortingField\u003CTMeta extends object = object> = TMeta & {\n  value: string;\n  label: string;\n}; A renderer-neutral description of a selectable sorting field. Add UI-specific metadata with TMeta.",{"id":963,"title":964,"titles":965,"content":966,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#storagelike","StorageLike",[167,920],"interface StorageLike {\n  getItem(key: string): string | null;\n  setItem(key: string, value: string): void;\n} The minimal persistence adapter accepted by UseTableOptions.storage. It is compatible with localStorage, but lets SSR or embedded applications provide a safer implementation.",{"id":968,"title":969,"titles":970,"content":971,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#tablecolumninput","TableColumnInput",[167,920],"type TableColumnInput\u003CTItem, TMeta extends object = Record\u003Cstring, unknown>> = TMeta & {\n  id?: string;\n  fields?: string[];\n}; A renderer-agnostic input column for useTable. Supply application-specific metadata through TMeta; the package keeps it intact without depending on a UI library. Omit id to exclude a conditional column from table selection and persistence. type AppColumn = TableColumnInput\u003CBook, { label: string; sortable?: boolean }>;",{"id":973,"title":974,"titles":975,"content":976,"level":333},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Ftypes#tablecolumn","TableColumn",[167,920],"type TableColumn\u003CTItem, TMeta extends object = Record\u003Cstring, unknown>> = TableColumnInput\u003CTItem, TMeta> & {\n  id: string;\n}; A visible table column with a resolved identifier. fields lists nested properties required for rendering; useTable turns them into the Query Kit fields grammar. const columns: Ref\u003Creadonly TableColumn\u003CBook, { label: string }>[]> = ref([\n  { id: 'title', label: 'Title' },\n  { id: 'author', fields: ['name'], label: 'Author' },\n]); html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"id":172,"title":171,"titles":978,"content":979,"level":204},[],"Utility functions are available from @querry-kit\u002Fnuxt\u002Futils and re-exported by the package root.",{"id":981,"title":171,"titles":982,"content":979,"level":204},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#utils",[],{"id":984,"title":985,"titles":986,"content":987,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#andwhere","andWhere",[171],"function andWhere(...conditions: Array\u003CRecord\u003Cstring, unknown> | undefined>): Record\u003Cstring, unknown> | undefined; Combines present Query Kit where fragments. No fragment returns undefined, one is returned unchanged, and multiple fragments are wrapped in AND. const where = andWhere({ isArchived: false }, { author: { name: { contains: 'Ada' } } });\n\u002F\u002F { AND: [{ isArchived: false }, { author: { name: { contains: 'Ada' } } }] }",{"id":989,"title":990,"titles":991,"content":992,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#filteringtowhere","filteringToWhere",[171],"function filteringToWhere(filtering: FilteringState): Record\u003Cstring, unknown> | undefined; Converts UI filtering state to a nested Query Kit where expression. Filters with value === undefined are ignored; dotted field paths are expanded with unflatten. const where = filteringToWhere({\n  operator: 'AND',\n  filters: [{ id: 'title', field: 'title', operator: 'contains', value: 'Query' }],\n});\n\u002F\u002F { title: { contains: 'Query' } }",{"id":994,"title":995,"titles":996,"content":997,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#isequal","isEqual",[171],"function isEqual(left: unknown, right: unknown): boolean; Performs a structural comparison of plain objects and arrays. Scalars are compared with Object.is; arrays are compared in order and object keys must match. The composables use it to avoid unnecessary reloads when reactive query state has not materially changed.",{"id":999,"title":1000,"titles":1001,"content":1002,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#mergequery","mergeQuery",[171],"function mergeQuery\u003CT extends Record\u003Cstring, unknown>>(base: T, extra: Record\u003Cstring, unknown>): T; Deeply merges object-shaped query fragments. Later scalar values replace earlier values; nested non-array objects are merged recursively. const query = mergeQuery(\n  { include: { author: true }, where: { published: true } },\n  { where: { id: { in: ['a', 'b'] } } },\n);",{"id":1004,"title":1005,"titles":1006,"content":1007,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#parsejson","parseJson",[171],"function parseJson\u003CT>(value: string | null | undefined, fallback: T): T; Safely decodes persisted or URL JSON. It returns fallback when the value is absent, empty, or invalid instead of throwing. const sorting = parseJson\u003CSortingRule[]>(storage.getItem('table:books:sort'), []);",{"id":1009,"title":1010,"titles":1011,"content":1012,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#pathstofieldsquery","pathsToFieldsQuery",[171],"function pathsToFieldsQuery(paths: Iterable\u003Cstring>): string | undefined; Builds Query Kit's compact fields grammar from dot-separated paths. Empty paths are ignored and no usable path returns undefined. pathsToFieldsQuery(['id', 'title', 'author.name']);\n\u002F\u002F 'id,title,author{name}'",{"id":1014,"title":1015,"titles":1016,"content":1017,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#serializequery","serializeQuery",[171],"function serializeQuery(query?: QueryParameters): string; Serializes a Query Kit request with qs bracket notation. It returns a leading ? for non-empty payloads and an empty string for an empty payload. serializeQuery({ page: 1, include: { author: true } });\n\u002F\u002F '?page=1&include[author]=true'",{"id":1019,"title":1020,"titles":1021,"content":1022,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#sortingtoorderby","sortingToOrderBy",[171],"function sortingToOrderBy(sorting: readonly SortingRule[]): Record\u003Cstring, unknown>[] | undefined; Converts ordered table sorting rules to Query Kit's nested orderBy array. It returns undefined when no rule is active; dotted IDs become nested objects. sortingToOrderBy([{ id: 'author.name', desc: true }]);\n\u002F\u002F [{ author: { name: 'desc' } }]",{"id":1024,"title":1025,"titles":1026,"content":1027,"level":214},"\u002Fdocs\u002Fnuxt\u002Fapi\u002Futils#unflatten","unflatten",[171],"function unflatten(value: Record\u003Cstring, unknown>): Record\u003Cstring, unknown>; Expands dotted object keys into the nested form required by Query Kit. Empty path segments are ignored. unflatten({ 'author.name': 'asc' });\n\u002F\u002F { author: { name: 'asc' } } html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"id":179,"title":159,"titles":1029,"content":1030,"level":204},[],"useAutocomplete keeps selected resources available even if they are absent from the active search query.",{"id":1032,"title":159,"titles":1033,"content":1034,"level":204},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fautocomplete#autocomplete",[],"useAutocomplete keeps selected resources available even if they are absent from the active search query. const selectedUserIds = ref\u003Cstring[]>([]);\nconst users = useAutocomplete({\n  api,\n  endpoint: 'users',\n  currentValue: selectedUserIds,\n  query: computed(() => ({ perPage: 20 })),\n  identityKey: 'id',\n}); Selected and searched results are deduplicated by identityKey. Use itemDisabled when the consumer must annotate options without changing the server response. OptionDefaultPurposequery{}Reactive request for search results.currentValueno selected requestOne identity or an array of identities to keep loaded.identityKeyidProperty used for the selected-resource condition and deduplication.itemDisablednoneProduces a derived disabled boolean per returned item.immediatetrueSet to false and call initialize() yourself. initialize() and refresh() load selected resources and query results concurrently. loadCurrentItems() and loadItems() are available when the UI needs more granular control. Empty, null, or undefined selections do not issue the selected-resource request. html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":183,"title":182,"titles":1036,"content":1037,"level":204},[],"Backend routes and response shapes required by @querry-kit\u002Fnuxt.",{"id":1039,"title":182,"titles":1040,"content":1041,"level":204},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fcontroller-contract#controller-contract",[],"@querry-kit\u002Fnuxt deliberately does not implement a backend. Its API and composables expect a Query Kit-compatible resource controller. The endpoint name passed to useModuleApi, useTable, or useAutocomplete is appended to the configured \u002Fapi\u002Fv1 base URL. For endpoint: 'books', these are the routes exposed by useModuleApi: MethodRouteUsed byRequired responseGET\u002Fbooksquery, useTable, useAutocompletePaginated listGET\u002Fbooks\u002F:idgetOne resourceGET\u002Fbooks\u002Ffind-by-id\u002F:idfindByIdOne resourceGET\u002Fbooks\u002FcountcountNumberPOST\u002FbookscreateCreated resourcePATCH\u002Fbooks\u002F:idupdateUpdated resourceDELETE\u002Fbooks\u002F:iddeleteDeleted resource The table and autocomplete only require the list route. Mutation routes are needed only when the application calls the corresponding useModuleApi method.",{"id":1043,"title":1044,"titles":1045,"content":1046,"level":214},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fcontroller-contract#paginated-list-response","Paginated List Response",[182],"The list route must return items and pagination metadata. The composables intentionally do not accept a data alias. type PaginatedResponse\u003CT> = {\n  items: T[];\n  meta: {\n    itemCount: number;\n    pageCount: number;\n  };\n}; useTable reads items, meta.itemCount, and meta.pageCount. useAutocomplete reads items from the same list response.",{"id":1048,"title":1049,"titles":1050,"content":1051,"level":214},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fcontroller-contract#query-parameters","Query Parameters",[182],"ParameterExpected byPurposepage, perPageTable and list callersPagination.whereTable, autocomplete, and list callersJSON-encoded Query Kit filter expression.orderByTable and list callersJSON-encoded nested sort rules.fieldsTable and list callersCompact field selection such as id,title,author{name}.includeTable and list callersNested relation includes encoded with qs. Read the query conventions for concrete serialized values. The controller must URL-decode those values and apply the same response contract.",{"id":1053,"title":1054,"titles":1055,"content":1056,"level":214},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fcontroller-contract#nestjs-reference","NestJS Reference",[182],"@querry-kit\u002Fnest contains the full controller pattern, including resource reads, writes, DTO mapping, fields projection, and OpenAPI metadata. Use its CRUD Controller guide as the server-side implementation reference. html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":187,"title":186,"titles":1058,"content":1059,"level":204},[],"examples\u002Fnuxt is a small Nuxt application with a mocked Axios adapter. It exercises createApiClient, useModuleApi, useTable, and useAutocomplete without requiring a server.",{"id":1061,"title":186,"titles":1062,"content":1063,"level":204},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fexample-app#example-app",[],"examples\u002Fnuxt is a small Nuxt application with a mocked Axios adapter. It exercises createApiClient, useModuleApi, useTable, and useAutocomplete without requiring a server. pnpm examples:check\npnpm examples:build It is intentionally a consumer, not a second implementation: the Nuxt plugin owns the client configuration, and the app component owns its column metadata and presentation. Use it as a reference for package imports and type checking; it does not prescribe a UI library or state-management solution. html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":190,"title":140,"titles":1065,"content":1066,"level":204},[],"Install the core package and its peers:",{"id":1068,"title":140,"titles":1069,"content":1070,"level":204},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fgetting-started#getting-started",[],"Install the core package and its peers: pnpm add @querry-kit\u002Fnuxt axios @tanstack\u002Ftable-core @vueuse\u002Fcore @vueuse\u002Frouter vue vue-router Create the HTTP client in the consumer application, where runtime configuration and authentication belong: import { createApiClient } from '@querry-kit\u002Fnuxt\u002Fapi';\n\nconst api = createApiClient({\n  apiBaseUrl: runtimeConfig.public.apiBaseUrl,\n  getToken: () => authStore.token,\n}); The client targets \u002Fapi\u002Fv1, adds Request-Source and Timezone headers, and only sends an Authorization header when getToken returns a token. OptionDefaultUse it forapiBaseUrl—The backend origin. A trailing slash is accepted.getTokenno headerResolving the latest token per request. It may be async.resolveBaseUrlidentityTenant\u002Fworkspace host rewriting before the API path is added.requestSourcewebBackends that distinguish clients through Request-Source.getTimezonebrowser timezoneAn explicit timezone; return undefined to omit it. Then model resources once and receive typed CRUD payloads: type Resources = {\n  books: {\n    item: { id: string; title: string };\n    create: { title: string };\n    update: { title?: string };\n  };\n};\n\nconst books = useModuleApi\u003CResources, 'books'>(api, 'books');\nawait books.update('book-1', { title: 'New title' }); useModuleApi exposes query, get, findById, count, create, update, and delete. Its endpoint argument accepts either books or \u002Fbooks; identifiers are URL encoded. Before integrating tables or autocompletes, verify that the backend exposes the required routes and { items, meta } response shape in the controller contract. html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"id":194,"title":193,"titles":1072,"content":1073,"level":204},[],"The primitives expect a Query Kit resource endpoint. They do not translate a backend-specific dialect; keeping that contract explicit makes the same client usable in Nuxt, plain Vue, and tests.",{"id":1075,"title":193,"titles":1076,"content":1073,"level":204},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fquery-conventions#query-conventions",[],{"id":1078,"title":1079,"titles":1080,"content":1081,"level":214},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fquery-conventions#list-response","List response",[193],"type PaginatedResponse\u003CT> = {\n  items: T[];\n  meta: { itemCount: number; pageCount: number };\n}; The table reads exactly those properties. A backend that returns data instead of items needs an adapter before it reaches useTable or useAutocomplete.",{"id":1083,"title":1084,"titles":1085,"content":1086,"level":214},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Fquery-conventions#query-encoding","Query encoding",[193],"Nested object parameters use qs bracket notation. Table filters and sort rules are JSON values because Query Kit accepts a nested expression: {\n  where: JSON.stringify({ AND: [{ isArchived: false }, { author: { name: { contains: 'Ada' } } }] }),\n  orderBy: JSON.stringify([{ author: { name: 'asc' } }]),\n  fields: 'id,title,author{name}',\n} useModuleApi accepts the same QueryParameters type, so feature-specific callers can use the exact serialization without adopting the table composable. html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"id":198,"title":197,"titles":1088,"content":1089,"level":204},[],"useTable composes resource queries from column definitions and reactive table state. It keeps column order, visibility, pinning, and page size in local storage; only the current page is reflected in the route query.",{"id":1091,"title":197,"titles":1092,"content":1093,"level":204},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Ftable#remote-tables",[],"useTable composes resource queries from column definitions and reactive table state. It keeps column order, visibility, pinning, and page size in local storage; only the current page is reflected in the route query. const table = useTable({\n  api,\n  endpoint: 'books',\n  persistenceKey: 'books',\n  columns: columnDefinitions,\n  staticInclude: { author: true },\n  isArchived: false,\n});\n\nawait table.initialize(); The composable sends where and orderBy as JSON values through qs, creates Nest-compatible fields selections, and ignores responses that finish after a newer request. Call refresh() explicitly after domain mutations or updateRow() for an in-place merge. OptionPurposepersistenceKeyRequired storage namespace. name remains a compatibility alias.columnsRequired Ref of column metadata. actions is never selected as a backend field.staticFields \u002F staticIncludeFields or relation includes always requested in addition to visible columns.staticFilter \u002F isArchivedReactive filter and archive condition applied before user filtering.routePageA Ref supplied by the application; the composable never imports a router.storagelocalStorage-compatible adapter. Storage failures do not interrupt a table.identityKeyKey used by updateRow; defaults to id.",{"id":1095,"title":1096,"titles":1097,"content":1098,"level":333},"\u002Fdocs\u002Fnuxt\u002Fguide\u002Ftable#lifecycle-and-state","Lifecycle and state",[197],"Call initialize() after the consuming view is ready. It applies the initial route page, fetches rows, then runs onInitialized. Any change to page, page size, sort, filters, columns, or static filter requests fresh data. The returned loading and error refs always reflect the latest request; an old request that completes later cannot overwrite rows or errors. To use a route query without coupling the package to Vue Router, pass the ref you already control: const routePage = computed({\n  get: () => Number(route.query.page ?? 1),\n  set: (page) => router.replace({ query: { ...route.query, page } }),\n});\n\nconst table = useTable({ api, endpoint: 'books', persistenceKey: 'books', columns, routePage }); html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"id":145,"title":144,"titles":1100,"content":1101,"level":204},[],"Typed API clients and portable remote state for Query Kit resource endpoints.",{"id":1103,"title":1104,"titles":1105,"content":1106,"level":204},"\u002Fdocs\u002Fnuxt#query-kit-for-vue-and-nuxt","Query Kit for Vue and Nuxt",[],"@querry-kit\u002Fnuxt owns the typed client and durable remote state that sit between your Nuxt interface and a Query Kit resource API.",{"id":1108,"title":1109,"titles":1110,"content":1111,"level":214},"\u002Fdocs\u002Fnuxt#portable-data-primitives","Portable data primitives",[1104],"Typed resource API configures one Axios client and exposes typed list, detail, count, and mutation methods.Headless remote tables compose pagination, fields, filters, sorting, persistence, and stale-request protection without prescribing UI.Selection-safe autocomplete keeps selected resources available while searches change.Explicit backend contract makes the required controller routes and { items, meta } response shape visible before integration. Get started\n  Read the controller contract",{"id":1113,"title":34,"body":1114,"description":271,"extension":1579,"meta":1580,"navigation":1581,"path":35,"seo":1582,"stem":36,"__hash__":1583},"docs\u002Fdocs\u002Fnest\u002Fapi\u002Fdtos-pagination.md",{"type":1115,"value":1116,"toc":1574},"minimark",[1117,1121,1124,1128,1142,1230,1233,1275,1278,1281,1367,1384,1424,1427,1433,1494,1497,1525,1547,1553,1570],[1118,1119,34],"h1",{"id":1120},"dtos-and-pagination",[1122,1123,275],"p",{},[1125,1126,278],"h2",{"id":1127},"pageoptionsdto",[1122,1129,1130,1133,1134,1137,1138,1141],{},[1131,1132,278],"code",{}," defaults to ",[1131,1135,1136],{},"page = 1"," and ",[1131,1139,1140],{},"perPage = 10",". Both values are transformed to numbers and validated as integers.",[1143,1144,1148],"pre",{"className":1145,"code":1146,"language":1147,"meta":431,"style":431},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","app.useGlobalPipes(\n  new ValidationPipe({\n    transform: true,\n    whitelist: true,\n  }),\n);\n","ts",[1131,1149,1150,1169,1183,1199,1211,1222],{"__ignoreMap":431},[1151,1152,1154,1158,1162,1166],"span",{"class":1153,"line":204},"line",[1151,1155,1157],{"class":1156},"sTEyZ","app",[1151,1159,1161],{"class":1160},"sMK4o",".",[1151,1163,1165],{"class":1164},"s2Zo4","useGlobalPipes",[1151,1167,1168],{"class":1156},"(\n",[1151,1170,1171,1174,1177,1180],{"class":1153,"line":214},[1151,1172,1173],{"class":1160},"  new",[1151,1175,1176],{"class":1164}," ValidationPipe",[1151,1178,1179],{"class":1156},"(",[1151,1181,1182],{"class":1160},"{\n",[1151,1184,1185,1189,1192,1196],{"class":1153,"line":333},[1151,1186,1188],{"class":1187},"swJcz","    transform",[1151,1190,1191],{"class":1160},":",[1151,1193,1195],{"class":1194},"sfNiH"," true",[1151,1197,1198],{"class":1160},",\n",[1151,1200,1202,1205,1207,1209],{"class":1153,"line":1201},4,[1151,1203,1204],{"class":1187},"    whitelist",[1151,1206,1191],{"class":1160},[1151,1208,1195],{"class":1194},[1151,1210,1198],{"class":1160},[1151,1212,1214,1217,1220],{"class":1153,"line":1213},5,[1151,1215,1216],{"class":1160},"  }",[1151,1218,1219],{"class":1156},")",[1151,1221,1198],{"class":1160},[1151,1223,1225,1227],{"class":1153,"line":1224},6,[1151,1226,1219],{"class":1156},[1151,1228,1229],{"class":1160},";\n",[1122,1231,1232],{},"The supported pagination range is:",[1143,1234,1236],{"className":1145,"code":1235,"language":1147,"meta":431,"style":431},"page >= 1;\nperPage >= 1;\nperPage \u003C= 1000;\n",[1131,1237,1238,1252,1263],{"__ignoreMap":431},[1151,1239,1240,1243,1246,1250],{"class":1153,"line":204},[1151,1241,1242],{"class":1156},"page ",[1151,1244,1245],{"class":1160},">=",[1151,1247,1249],{"class":1248},"sbssI"," 1",[1151,1251,1229],{"class":1160},[1151,1253,1254,1257,1259,1261],{"class":1153,"line":214},[1151,1255,1256],{"class":1156},"perPage ",[1151,1258,1245],{"class":1160},[1151,1260,1249],{"class":1248},[1151,1262,1229],{"class":1160},[1151,1264,1265,1267,1270,1273],{"class":1153,"line":333},[1151,1266,1256],{"class":1156},[1151,1268,1269],{"class":1160},"\u003C=",[1151,1271,1272],{"class":1248}," 1000",[1151,1274,1229],{"class":1160},[1125,1276,283],{"id":1277},"query-dtos",[1122,1279,1280],{},"Use the DTO matching the service method:",[1143,1282,1284],{"className":1145,"code":1283,"language":1147,"meta":431,"style":431},"FindOneDTO\u003CProjectTypeMap>;\nFindManyDTO\u003CProjectTypeMap>;\nFindByIdDTO\u003CProjectTypeMap>;\nFindUniqueDTO\u003CProjectTypeMap>;\nAggregateDTO\u003CProjectTypeMap>;\nCountDTO\u003CProjectTypeMap>;\nQueryDTO\u003CProjectTypeMap>;\n",[1131,1285,1286,1300,1311,1322,1333,1344,1355],{"__ignoreMap":431},[1151,1287,1288,1291,1294,1297],{"class":1153,"line":204},[1151,1289,1290],{"class":1156},"FindOneDTO",[1151,1292,1293],{"class":1160},"\u003C",[1151,1295,1296],{"class":1156},"ProjectTypeMap",[1151,1298,1299],{"class":1160},">;\n",[1151,1301,1302,1305,1307,1309],{"class":1153,"line":214},[1151,1303,1304],{"class":1156},"FindManyDTO",[1151,1306,1293],{"class":1160},[1151,1308,1296],{"class":1156},[1151,1310,1299],{"class":1160},[1151,1312,1313,1316,1318,1320],{"class":1153,"line":333},[1151,1314,1315],{"class":1156},"FindByIdDTO",[1151,1317,1293],{"class":1160},[1151,1319,1296],{"class":1156},[1151,1321,1299],{"class":1160},[1151,1323,1324,1327,1329,1331],{"class":1153,"line":1201},[1151,1325,1326],{"class":1156},"FindUniqueDTO",[1151,1328,1293],{"class":1160},[1151,1330,1296],{"class":1156},[1151,1332,1299],{"class":1160},[1151,1334,1335,1338,1340,1342],{"class":1153,"line":1213},[1151,1336,1337],{"class":1156},"AggregateDTO",[1151,1339,1293],{"class":1160},[1151,1341,1296],{"class":1156},[1151,1343,1299],{"class":1160},[1151,1345,1346,1349,1351,1353],{"class":1153,"line":1224},[1151,1347,1348],{"class":1156},"CountDTO",[1151,1350,1293],{"class":1160},[1151,1352,1296],{"class":1156},[1151,1354,1299],{"class":1160},[1151,1356,1358,1361,1363,1365],{"class":1153,"line":1357},7,[1151,1359,1360],{"class":1156},"QueryDTO",[1151,1362,1293],{"class":1160},[1151,1364,1296],{"class":1156},[1151,1366,1299],{"class":1160},[1122,1368,1369,1137,1371,1373,1374,1377,1378,1137,1381,1383],{},[1131,1370,1360],{},[1131,1372,1315],{}," expose ",[1131,1375,1376],{},"fields?: string",". ",[1131,1379,1380],{},"ResourceQuery",[1131,1382,305],{}," use that optional value to build relation includes and project responses.",[1122,1385,1386,1388,1389,1392,1393,1392,1396,1392,1399,1392,1402,1405,1406,1409,1410,1137,1413,1416,1417,1419,1420,1423],{},[1131,1387,1360],{}," also exposes the Prisma-style query inputs used by resource list endpoints: ",[1131,1390,1391],{},"select",", ",[1131,1394,1395],{},"include",[1131,1397,1398],{},"where",[1131,1400,1401],{},"orderBy",[1131,1403,1404],{},"cursor",", and ",[1131,1407,1408],{},"distinct",", plus ",[1131,1411,1412],{},"page",[1131,1414,1415],{},"perPage"," from ",[1131,1418,278],{},". Use ",[1131,1421,1422],{},"ApiResourceQuery()"," to document the public query parameter contract in OpenAPI metadata.",[1125,1425,288],{"id":1426},"service-shape",[1122,1428,1429,1432],{},[1131,1430,1431],{},"QueryService.query"," returns a service-level shape:",[1143,1434,1436],{"className":1145,"code":1435,"language":1147,"meta":431,"style":431},"type Paginated\u003CProject> = {\n  items: Project[];\n  pageMeta: PageMetaDTO;\n};\n",[1131,1437,1438,1462,1477,1489],{"__ignoreMap":431},[1151,1439,1440,1444,1448,1450,1453,1456,1459],{"class":1153,"line":204},[1151,1441,1443],{"class":1442},"spNyl","type",[1151,1445,1447],{"class":1446},"sBMFI"," Paginated",[1151,1449,1293],{"class":1160},[1151,1451,1452],{"class":1446},"Project",[1151,1454,1455],{"class":1160},">",[1151,1457,1458],{"class":1160}," =",[1151,1460,1461],{"class":1160}," {\n",[1151,1463,1464,1467,1469,1472,1475],{"class":1153,"line":214},[1151,1465,1466],{"class":1187},"  items",[1151,1468,1191],{"class":1160},[1151,1470,1471],{"class":1446}," Project",[1151,1473,1474],{"class":1156},"[]",[1151,1476,1229],{"class":1160},[1151,1478,1479,1482,1484,1487],{"class":1153,"line":333},[1151,1480,1481],{"class":1187},"  pageMeta",[1151,1483,1191],{"class":1160},[1151,1485,1486],{"class":1446}," PageMetaDTO",[1151,1488,1229],{"class":1160},[1151,1490,1491],{"class":1153,"line":1201},[1151,1492,1493],{"class":1160},"};\n",[1122,1495,1496],{},"Controllers usually return a public DTO shape:",[1143,1498,1500],{"className":1145,"code":1499,"language":1147,"meta":431,"style":431},"return new PaginatedDTO(projectDtos, pageMeta);\n",[1131,1501,1502],{"__ignoreMap":431},[1151,1503,1504,1508,1511,1514,1517,1520,1523],{"class":1153,"line":204},[1151,1505,1507],{"class":1506},"s7zQu","return",[1151,1509,1510],{"class":1160}," new",[1151,1512,1513],{"class":1164}," PaginatedDTO",[1151,1515,1516],{"class":1156},"(projectDtos",[1151,1518,1519],{"class":1160},",",[1151,1521,1522],{"class":1156}," pageMeta)",[1151,1524,1229],{"class":1160},[1122,1526,1527,1530,1531,1392,1534,1405,1537,1416,1540,1392,1543,1405,1545,1161],{},[1131,1528,1529],{},"PageMetaDTO"," computes ",[1131,1532,1533],{},"pageCount",[1131,1535,1536],{},"hasPrevPage",[1131,1538,1539],{},"hasNextPage",[1131,1541,1542],{},"itemCount",[1131,1544,1412],{},[1131,1546,1415],{},[1122,1548,1549,1552],{},[1131,1550,1551],{},"ResourceQuery.query"," supports both item shorthand and envelope projection:",[1143,1554,1558],{"className":1555,"code":1556,"language":1557,"meta":431,"style":431},"language-txt shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","fields=id,name\nfields=items{id,name},meta{page,perPage,itemCount,pageCount}\n","txt",[1131,1559,1560,1565],{"__ignoreMap":431},[1151,1561,1562],{"class":1153,"line":204},[1151,1563,1564],{},"fields=id,name\n",[1151,1566,1567],{"class":1153,"line":214},[1151,1568,1569],{},"fields=items{id,name},meta{page,perPage,itemCount,pageCount}\n",[1571,1572,1573],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":431,"searchDepth":214,"depth":214,"links":1575},[1576,1577,1578],{"id":1127,"depth":214,"text":278},{"id":1277,"depth":214,"text":283},{"id":1426,"depth":214,"text":288},"md",{},true,{"title":34,"description":271},"heWtdkIvvzAUdyeWLORUKqiP8SFhRUBxnMg9gAWcQ4E",1784870011833]