From 33df5f294f4f4bc562e6926a5d43f46ea17119f5 Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Tue, 31 Jan 2023 16:54:14 +0000 Subject: [PATCH] feat: introduce starts with () operator (#466) --- README.md | 4 +++- src/paginate.spec.ts | 29 ++++++++++++++++++++++++++--- src/paginate.ts | 5 +++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 15ea96d..5c5bcae 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Pagination and filtering helper method for TypeORM repositories or query builder - Pagination conforms to [JSON:API](https://jsonapi.org/) - Sort by multiple 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 - 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=$sw:term` where column `summary` starts with `term` + `?filter.seenAt=$null` where column `seenAt` is `NULL` `?filter.seenAt=$not:$null` where column `seenAt` is **not** `NULL` diff --git a/src/paginate.spec.ts b/src/paginate.spec.ts index ad49212..de5a821 100644 --- a/src/paginate.spec.ts +++ b/src/paginate.spec.ts @@ -1281,17 +1281,40 @@ describe('paginate', () => { const query: PaginateQuery = { path: '', filter: { - name: '$ilike:Garf', + name: '$ilike:arf', }, } const result = await paginate(query, catRepo, config) expect(result.meta.filter).toStrictEqual({ - name: '$ilike:Garf', + name: '$ilike:arf', }) 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 = { + sortableColumns: ['id'], + filterableColumns: { + name: [FilterOperator.SW], + }, + } + const query: PaginateQuery = { + path: '', + filter: { + name: '$sw:Ga', + }, + } + + const result = await paginate(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 () => { diff --git a/src/paginate.ts b/src/paginate.ts index 7464ca8..398d197 100644 --- a/src/paginate.ts +++ b/src/paginate.ts @@ -84,6 +84,7 @@ export enum FilterOperator { BTW = '$btw', NOT = '$not', ILIKE = '$ilike', + SW = '$sw', } export function isOperator(value: unknown): value is FilterOperator { @@ -101,6 +102,7 @@ export const OperatorSymbolToFunction = new Map(query: PaginateQuery, config: PaginateConfig): Filter case FilterOperator.ILIKE: filter[column] = OperatorSymbolToFunction.get(op1)(`%${value}%`) break + case FilterOperator.SW: + filter[column] = OperatorSymbolToFunction.get(op1)(`${value}%`) + break default: filter[column] = OperatorSymbolToFunction.get(op1)(value) break