UNPKG

nestjs-paginate

Version:

Pagination and filtering helper method for TypeORM repositories or query builders using Nest.js framework.

301 lines 16.5 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); const common_1 = require("@nestjs/common"); const swagger_1 = require("@nestjs/swagger"); const paginate_1 = require("../paginate"); const testing_1 = require("@nestjs/testing"); const api_paginated_swagger_docs_decorator_1 = require("./api-paginated-swagger-docs.decorator"); const api_paginated_query_decorator_1 = require("./api-paginated-query.decorator"); const api_ok_paginated_response_decorator_1 = require("./api-ok-paginated-response.decorator"); const BASE_PAGINATION_CONFIG = { sortableColumns: ['id'], }; const FULL_CONFIG = Object.assign(Object.assign({}, BASE_PAGINATION_CONFIG), { defaultSortBy: [['id', 'DESC']], defaultLimit: 20, maxLimit: 100, filterableColumns: { id: true, name: [paginate_1.FilterOperator.EQ, paginate_1.FilterSuffix.NOT], }, searchableColumns: ['name'], select: ['id', 'name'] }); class TestDto { } // eslint-disable-next-line @typescript-eslint/ban-types async function getSwaggerDefinitionForEndpoint(entityType, config) { class TestController { test() { // } testPost() { // } } __decorate([ (0, api_paginated_swagger_docs_decorator_1.PaginatedSwaggerDocs)(entityType, config), (0, common_1.Get)('/test'), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], TestController.prototype, "test", null); __decorate([ (0, api_paginated_query_decorator_1.ApiPaginationQuery)(config), (0, api_ok_paginated_response_decorator_1.ApiOkPaginatedResponse)(entityType, config), (0, common_1.Post)('/test'), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], TestController.prototype, "testPost", null); const fakeAppModule = await testing_1.Test.createTestingModule({ controllers: [TestController], }).compile(); const fakeApp = fakeAppModule.createNestApplication(); return swagger_1.SwaggerModule.createDocument(fakeApp, new swagger_1.DocumentBuilder().build()); } describe('PaginatedEndpoint decorator', () => { it('post and get definition should be the same', async () => { const openApiDefinition = await getSwaggerDefinitionForEndpoint(TestDto, BASE_PAGINATION_CONFIG); expect(openApiDefinition.paths['/test'].get.parameters).toStrictEqual(openApiDefinition.paths['/test'].post.parameters); }); it('should annotate endpoint with OpenApi documentation with limited config', async () => { const openApiDefinition = await getSwaggerDefinitionForEndpoint(TestDto, BASE_PAGINATION_CONFIG); const params = openApiDefinition.paths['/test'].get.parameters; expect(params).toStrictEqual([ { name: 'page', required: false, in: 'query', description: 'Page number to retrieve.If you provide invalid value the default page number will applied\n <p>\n <b>Example: </b> 1\n </p>\n <p>\n <b>Default Value: </b> 1\n </p>\n ', schema: { type: 'number', }, }, { name: 'limit', required: false, in: 'query', description: 'Number of records per page.\n <p>\n <b>Example: </b> 20\n </p>\n <p>\n <b>Default Value: </b> 20\n </p>\n <p>\n <b>Max Value: </b> 100\n </p>\n\n If provided value is greater than max value, max value will be applied.\n ', schema: { type: 'number', }, }, { name: 'sortBy', required: false, in: 'query', description: 'Parameter to sort by.\n <p>To sort by multiple fields, just provide query param multiple types. The order in url defines an order of sorting</p>\n <p>\n <b>Format: </b> fieldName:DIRECTION\n </p>\n <p>\n <b>Example: </b> sortBy=id:DESC&sortBy=createdAt:ASC\n </p>\n <p>\n <b>Default Value: </b> No default sorting specified, the result order is not guaranteed\n </p>\n <h4>Available Fields</h4><ul><li>id</li></ul>\n ', schema: { type: 'array', items: { type: 'string', enum: ['id:ASC', 'id:DESC'], }, }, }, ]); expect(openApiDefinition.paths['/test'].get.responses).toEqual({ '200': { description: '', content: { 'application/json': { schema: { allOf: [ { $ref: '#/components/schemas/PaginatedDocumented', }, { properties: { data: { type: 'array', items: { $ref: '#/components/schemas/TestDto', }, }, meta: { properties: { select: { type: 'array', items: { type: 'string', }, }, filter: { type: 'object', properties: {}, }, }, }, }, }, ], }, }, }, }, }); }); it('should annotate endpoint with OpenApi documentation with full config', async () => { const openApiDefinition = await getSwaggerDefinitionForEndpoint(TestDto, FULL_CONFIG); const params = openApiDefinition.paths['/test'].get.parameters; expect(params).toStrictEqual([ { name: 'page', required: false, in: 'query', description: 'Page number to retrieve.If you provide invalid value the default page number will applied\n <p>\n <b>Example: </b> 1\n </p>\n <p>\n <b>Default Value: </b> 1\n </p>\n ', schema: { type: 'number', }, }, { name: 'limit', required: false, in: 'query', description: 'Number of records per page.\n <p>\n <b>Example: </b> 20\n </p>\n <p>\n <b>Default Value: </b> 20\n </p>\n <p>\n <b>Max Value: </b> 100\n </p>\n\n If provided value is greater than max value, max value will be applied.\n ', schema: { type: 'number', }, }, { name: 'filter.id', required: false, in: 'query', description: 'Filter by id query param.\n <p>\n <b>Format: </b> filter.id={$not}:OPERATION:VALUE\n </p>\n <p>\n <b>Example: </b> filter.id=$not:$like:John Doe&filter.id=like:John\n </p>\n <h4>Available Operations</h4><ul><li>$and</li>\n<li>$or</li>\n<li>$not</li>\n<li>$eq</li>\n<li>$gt</li>\n<li>$gte</li>\n<li>$in</li>\n<li>$null</li>\n<li>$lt</li>\n<li>$lte</li>\n<li>$btw</li>\n<li>$ilike</li>\n<li>$sw</li>\n<li>$contains</li></ul>', schema: { type: 'array', items: { type: 'string', }, }, }, { name: 'filter.name', required: false, in: 'query', description: 'Filter by name query param.\n <p>\n <b>Format: </b> filter.name={$not}:OPERATION:VALUE\n </p>\n <p>\n <b>Example: </b> filter.name=$not:$like:John Doe&filter.name=like:John\n </p>\n <h4>Available Operations</h4><ul><li>$eq</li>\n<li>$not</li></ul>', schema: { type: 'array', items: { type: 'string', }, }, }, { name: 'sortBy', required: false, in: 'query', description: 'Parameter to sort by.\n <p>To sort by multiple fields, just provide query param multiple types. The order in url defines an order of sorting</p>\n <p>\n <b>Format: </b> fieldName:DIRECTION\n </p>\n <p>\n <b>Example: </b> sortBy=id:DESC&sortBy=createdAt:ASC\n </p>\n <p>\n <b>Default Value: </b> id:DESC\n </p>\n <h4>Available Fields</h4><ul><li>id</li></ul>\n ', schema: { type: 'array', items: { type: 'string', enum: ['id:ASC', 'id:DESC'], }, }, }, { name: 'search', required: false, in: 'query', description: 'Search term to filter result values\n <p>\n <b>Example: </b> John\n </p>\n <p>\n <b>Default Value: </b> No default value\n </p>\n ', schema: { type: 'string', }, }, { name: 'searchBy', required: false, in: 'query', description: 'List of fields to search by term to filter result values\n <p>\n <b>Example: </b> name\n </p>\n <p>\n <b>Default Value: </b> By default all fields mentioned below will be used to search by term\n </p>\n <h4>Available Fields</h4><ul><li>name</li></ul>\n ', schema: { type: 'array', items: { type: 'string', }, }, }, { name: 'select', required: false, in: 'query', description: 'List of fields to select.\n <p>\n <b>Example: </b> id,name\n </p>\n <p>\n <b>Default Value: </b> By default all fields returns. If you want to select only some fields, provide them in query param\n </p>\n ', schema: { type: 'string', }, }, ]); expect(openApiDefinition.paths['/test'].get.responses).toEqual({ '200': { description: '', content: { 'application/json': { schema: { allOf: [ { $ref: '#/components/schemas/PaginatedDocumented', }, { properties: { data: { type: 'array', items: { $ref: '#/components/schemas/TestDto', }, }, meta: { properties: { select: { type: 'array', items: { type: 'string', enum: ['id', 'name'], }, }, filter: { type: 'object', properties: { id: { oneOf: [ { type: 'string', }, { type: 'array', items: { type: 'string', }, }, ], }, name: { oneOf: [ { type: 'string', }, { type: 'array', items: { type: 'string', }, }, ], }, }, }, }, }, }, }, ], }, }, }, }, }); }); }); //# sourceMappingURL=pagination-docs.spec.js.map