feat: introduce starts with () operator (#466)
This commit is contained in:
parent
0e868adb30
commit
33df5f294f
@ -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`, `$btw`, `$ilike`)
|
- Filter using operators (`$eq`, `$not`, `$null`, `$in`, `$gt`, `$gte`, `$lt`, `$lte`, `$btw`, `$ilike`, `$sw`)
|
||||||
- Include relations
|
- Include relations
|
||||||
- Virtual column support
|
- Virtual column support
|
||||||
|
|
||||||
@ -315,6 +315,8 @@ Filter operators must be whitelisted per column in `PaginateConfig`.
|
|||||||
|
|
||||||
`?filter.summary=$not:$ilike:term` where column `summary` does **not** contain `term`
|
`?filter.summary=$not:$ilike:term` where column `summary` does **not** contain `term`
|
||||||
|
|
||||||
|
`?filter.summary=$sw:term` where column `summary` starts with `term`
|
||||||
|
|
||||||
`?filter.seenAt=$null` where column `seenAt` is `NULL`
|
`?filter.seenAt=$null` where column `seenAt` is `NULL`
|
||||||
|
|
||||||
`?filter.seenAt=$not:$null` where column `seenAt` is **not** `NULL`
|
`?filter.seenAt=$not:$null` where column `seenAt` is **not** `NULL`
|
||||||
|
@ -1281,17 +1281,40 @@ describe('paginate', () => {
|
|||||||
const query: PaginateQuery = {
|
const query: PaginateQuery = {
|
||||||
path: '',
|
path: '',
|
||||||
filter: {
|
filter: {
|
||||||
name: '$ilike:Garf',
|
name: '$ilike:arf',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await paginate<CatEntity>(query, catRepo, config)
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
||||||
|
|
||||||
expect(result.meta.filter).toStrictEqual({
|
expect(result.meta.filter).toStrictEqual({
|
||||||
name: '$ilike:Garf',
|
name: '$ilike:arf',
|
||||||
})
|
})
|
||||||
expect(result.data).toStrictEqual([cats[1]])
|
expect(result.data).toStrictEqual([cats[1]])
|
||||||
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.name=$ilike:Garf')
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.name=$ilike:arf')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return result based on $sw filter', async () => {
|
||||||
|
const config: PaginateConfig<CatEntity> = {
|
||||||
|
sortableColumns: ['id'],
|
||||||
|
filterableColumns: {
|
||||||
|
name: [FilterOperator.SW],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const query: PaginateQuery = {
|
||||||
|
path: '',
|
||||||
|
filter: {
|
||||||
|
name: '$sw:Ga',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
||||||
|
|
||||||
|
expect(result.meta.filter).toStrictEqual({
|
||||||
|
name: '$sw:Ga',
|
||||||
|
})
|
||||||
|
expect(result.data).toStrictEqual([cats[1]])
|
||||||
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.name=$sw:Ga')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return result based on filter and search term', async () => {
|
it('should return result based on filter and search term', async () => {
|
||||||
|
@ -84,6 +84,7 @@ export enum FilterOperator {
|
|||||||
BTW = '$btw',
|
BTW = '$btw',
|
||||||
NOT = '$not',
|
NOT = '$not',
|
||||||
ILIKE = '$ilike',
|
ILIKE = '$ilike',
|
||||||
|
SW = '$sw',
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isOperator(value: unknown): value is FilterOperator {
|
export function isOperator(value: unknown): value is FilterOperator {
|
||||||
@ -101,6 +102,7 @@ export const OperatorSymbolToFunction = new Map<FilterOperator, (...args: any[])
|
|||||||
[FilterOperator.BTW, Between],
|
[FilterOperator.BTW, Between],
|
||||||
[FilterOperator.NOT, Not],
|
[FilterOperator.NOT, Not],
|
||||||
[FilterOperator.ILIKE, ILike],
|
[FilterOperator.ILIKE, ILike],
|
||||||
|
[FilterOperator.SW, ILike],
|
||||||
])
|
])
|
||||||
|
|
||||||
export function getFilterTokens(raw: string): string[] {
|
export function getFilterTokens(raw: string): string[] {
|
||||||
@ -169,6 +171,9 @@ function parseFilter<T>(query: PaginateQuery, config: PaginateConfig<T>): Filter
|
|||||||
case FilterOperator.ILIKE:
|
case FilterOperator.ILIKE:
|
||||||
filter[column] = OperatorSymbolToFunction.get(op1)(`%${value}%`)
|
filter[column] = OperatorSymbolToFunction.get(op1)(`%${value}%`)
|
||||||
break
|
break
|
||||||
|
case FilterOperator.SW:
|
||||||
|
filter[column] = OperatorSymbolToFunction.get(op1)(`${value}%`)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
filter[column] = OperatorSymbolToFunction.get(op1)(value)
|
filter[column] = OperatorSymbolToFunction.get(op1)(value)
|
||||||
break
|
break
|
||||||
|
Loading…
Reference in New Issue
Block a user