nestjs-paginate
Version:
Pagination and filtering helper method for TypeORM repositories or query builders using Nest.js framework.
301 lines • 16.5 kB
JavaScript
"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