From 8bf5e41a1168debd224bf06ee4ec68d5ae2a4046 Mon Sep 17 00:00:00 2001 From: ppetzold Date: Mon, 14 Mar 2022 20:02:55 +0100 Subject: [PATCH] fix: between and in operator for relations --- README.md | 31 +++++++++++++++++++++++++++ src/paginate.spec.ts | 50 +++++++++++++++++++++++++++++++++++++++++++- src/paginate.ts | 22 +++++++++++++++---- 3 files changed, 98 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 91a382f..fe0eb76 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,13 @@ const paginateConfig: PaginateConfig { * https://typeorm.io/#/find-options/advanced-options */ filterableColumns: { age: [FilterOperator.EQ, FilterOperator.IN] } + + /** + * Required: false + * Type: RelationColumn + * Description: Indicates what relations of entity should be loaded. + */ + relations: [], } ``` @@ -215,3 +222,27 @@ const queryBuilder = repo const result = await paginate(query, queryBuilder, config) ``` + +## Usage with Relations + +### Example + +#### Endpoint + +```url +http://localhost:3000/cats?filter.toys.name=$in:Mouse,String +``` + +#### Code + +```typescript +const config: PaginateConfig = { + relations: ['toys'], + sortableColumns: ['id', 'name', 'toys.name'], + filterableColumns: { + 'toys.name': [FilterOperator.IN], + }, +} + +const result = await paginate(query, catRepo, config) +``` diff --git a/src/paginate.spec.ts b/src/paginate.spec.ts index fcc1969..38eb9f7 100644 --- a/src/paginate.spec.ts +++ b/src/paginate.spec.ts @@ -462,7 +462,7 @@ describe('paginate', () => { expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.toys.name=$not:Stuffed Mouse') }) - it('should return result based on where config and filter on one-to-one relation', async () => { + it('should return result based on filter on one-to-one relation', async () => { const config: PaginateConfig = { relations: ['cat'], sortableColumns: ['id', 'name'], @@ -486,6 +486,54 @@ describe('paginate', () => { expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.name=$not:Garfield') }) + it('should return result based on $in filter on one-to-one relation', async () => { + const config: PaginateConfig = { + relations: ['cat'], + sortableColumns: ['id', 'name'], + filterableColumns: { + 'cat.age': [FilterOperator.IN], + }, + } + const query: PaginateQuery = { + path: '', + filter: { + 'cat.age': '$in:4,6', + }, + } + + const result = await paginate(query, catHomeRepo, config) + + expect(result.meta.filter).toStrictEqual({ + 'cat.age': '$in:4,6', + }) + expect(result.data).toStrictEqual([catHomes[0]]) + expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.age=$in:4,6') + }) + + it('should return result based on $btw filter on one-to-one relation', async () => { + const config: PaginateConfig = { + relations: ['cat'], + sortableColumns: ['id', 'name'], + filterableColumns: { + 'cat.age': [FilterOperator.BTW], + }, + } + const query: PaginateQuery = { + path: '', + filter: { + 'cat.age': '$btw:6,10', + }, + } + + const result = await paginate(query, catHomeRepo, config) + + expect(result.meta.filter).toStrictEqual({ + 'cat.age': '$btw:6,10', + }) + expect(result.data).toStrictEqual([catHomes[0]]) + expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.age=$btw:6,10') + }) + it('should return result based on where array and filter', async () => { const config: PaginateConfig = { sortableColumns: ['id'], diff --git a/src/paginate.ts b/src/paginate.ts index 788864d..ccd7108 100644 --- a/src/paginate.ts +++ b/src/paginate.ts @@ -288,10 +288,24 @@ export async function paginate( column, filter[column] ) as WherePredicateOperator - condition.parameters = [`${qb.alias}_${column}`, `:${column}`] - qb.andWhere(qb['createWhereConditionExpression'](condition), { - [column]: filter[column].value, - }) + let parameters = { [column]: filter[column].value } + // TODO: refactor below + switch (condition.operator) { + case 'between': + condition.parameters = [`${qb.alias}_${column}`, `:${column}_from`, `:${column}_to`] + parameters = { + [column + '_from']: filter[column].value[0], + [column + '_to']: filter[column].value[1], + } + break + case 'in': + condition.parameters = [`${qb.alias}_${column}`, `:...${column}`] + break + default: + condition.parameters = [`${qb.alias}_${column}`, `:${column}`] + break + } + qb.andWhere(qb['createWhereConditionExpression'](condition), parameters) } else { qb.andWhere({ [column]: filter[column],