feat: add support of betweet operator (#149)

This commit is contained in:
burdinbogdan 2022-01-27 14:32:51 +02:00 committed by GitHub
parent e76166b68e
commit 5239b7b0b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 2 deletions

View File

@ -13,7 +13,7 @@ Pagination and filtering helper method for TypeORM repositories or query builder
- Pagination conforms to [JSON:API](https://jsonapi.org/) - Pagination conforms to [JSON:API](https://jsonapi.org/)
- Sort by multiple columns - Sort by multiple columns
- Search across columns - Search across columns
- Filter using operators (`$eq`, `$not`, `$null`, `$in`, `$gt`, `$gte`, `$lt`, `$lte`) - Filter using operators (`$eq`, `$not`, `$null`, `$in`, `$gt`, `$gte`, `$lt`, `$lte`, `$btw`)
## Installation ## Installation

View File

@ -346,6 +346,26 @@ describe('paginate', () => {
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$gte:4') expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$gte:4')
}) })
it('should return result based on between range filter', async () => {
const config: PaginateConfig<CatEntity> = {
sortableColumns: ['id'],
filterableColumns: {
age: [FilterOperator.BTW],
},
}
const query: PaginateQuery = {
path: '',
filter: {
age: '$btw:4,6',
},
}
const result = await paginate<CatEntity>(query, repo, config)
expect(result.data).toStrictEqual([cats[0], cats[2]])
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$btw:4,6')
})
it('should return result based on is null query', async () => { it('should return result based on is null query', async () => {
const config: PaginateConfig<CatEntity> = { const config: PaginateConfig<CatEntity> = {
sortableColumns: ['id'], sortableColumns: ['id'],
@ -449,6 +469,7 @@ describe('paginate', () => {
{ operator: '$null', result: true }, { operator: '$null', result: true },
{ operator: '$lt', result: true }, { operator: '$lt', result: true },
{ operator: '$lte', result: true }, { operator: '$lte', result: true },
{ operator: '$btw', result: true },
{ operator: '$not', result: true }, { operator: '$not', result: true },
{ operator: '$fake', result: false }, { operator: '$fake', result: false },
])('should check operator "$operator" valid is $result', ({ operator, result }) => { ])('should check operator "$operator" valid is $result', ({ operator, result }) => {
@ -463,6 +484,7 @@ describe('paginate', () => {
{ operator: '$null', name: 'IsNull' }, { operator: '$null', name: 'IsNull' },
{ operator: '$lt', name: 'LessThan' }, { operator: '$lt', name: 'LessThan' },
{ operator: '$lte', name: 'LessThanOrEqual' }, { operator: '$lte', name: 'LessThanOrEqual' },
{ operator: '$btw', name: 'Between' },
{ operator: '$not', name: 'Not' }, { operator: '$not', name: 'Not' },
])('should get operator function $name for "$operator"', ({ operator, name }) => { ])('should get operator function $name for "$operator"', ({ operator, name }) => {
const func = getOperatorFn<CatEntity>(operator as FilterOperator) const func = getOperatorFn<CatEntity>(operator as FilterOperator)

View File

@ -14,6 +14,7 @@ import {
Not, Not,
ILike, ILike,
Brackets, Brackets,
Between,
} from 'typeorm' } from 'typeorm'
import { PaginateQuery } from './decorator' import { PaginateQuery } from './decorator'
import { ServiceUnavailableException } from '@nestjs/common' import { ServiceUnavailableException } from '@nestjs/common'
@ -63,6 +64,7 @@ export enum FilterOperator {
NULL = '$null', NULL = '$null',
LT = '$lt', LT = '$lt',
LTE = '$lte', LTE = '$lte',
BTW = '$btw',
NOT = '$not', NOT = '$not',
} }
@ -86,6 +88,8 @@ export function getOperatorFn<T>(op: FilterOperator): (...args: any[]) => FindOp
return LessThan return LessThan
case FilterOperator.LTE: case FilterOperator.LTE:
return LessThanOrEqual return LessThanOrEqual
case FilterOperator.BTW:
return Between
case FilterOperator.NOT: case FilterOperator.NOT:
return Not return Not
} }
@ -144,7 +148,8 @@ function parseFilter<T>(query: PaginateQuery, config: PaginateConfig<T>) {
} }
if (isOperator(op1)) { if (isOperator(op1)) {
const args = op1 === FilterOperator.IN ? value.split(',') : value const args = op1 === FilterOperator.IN ? value.split(',') : value
filter[column] = getOperatorFn<T>(op1)(args) filter[column] =
op1 === FilterOperator.BTW ? getOperatorFn<T>(op1)(args[0], args[1]) : getOperatorFn<T>(op1)(args)
} }
if (isOperator(op2)) { if (isOperator(op2)) {
filter[column] = getOperatorFn<T>(op2)(filter[column]) filter[column] = getOperatorFn<T>(op2)(filter[column])