fix: between and in operator for relations

This commit is contained in:
ppetzold 2022-03-14 20:02:55 +01:00
parent e84d71e540
commit 8bf5e41a11
3 changed files with 98 additions and 5 deletions

View File

@ -200,6 +200,13 @@ const paginateConfig: PaginateConfig<CatEntity> {
* https://typeorm.io/#/find-options/advanced-options
*/
filterableColumns: { age: [FilterOperator.EQ, FilterOperator.IN] }
/**
* Required: false
* Type: RelationColumn<CatEntity>
* Description: Indicates what relations of entity should be loaded.
*/
relations: [],
}
```
@ -215,3 +222,27 @@ const queryBuilder = repo
const result = await paginate<CatEntity>(query, queryBuilder, config)
```
## Usage with Relations
### Example
#### Endpoint
```url
http://localhost:3000/cats?filter.toys.name=$in:Mouse,String
```
#### Code
```typescript
const config: PaginateConfig<CatEntity> = {
relations: ['toys'],
sortableColumns: ['id', 'name', 'toys.name'],
filterableColumns: {
'toys.name': [FilterOperator.IN],
},
}
const result = await paginate<CatEntity>(query, catRepo, config)
```

View File

@ -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<CatHomeEntity> = {
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<CatHomeEntity> = {
relations: ['cat'],
sortableColumns: ['id', 'name'],
filterableColumns: {
'cat.age': [FilterOperator.IN],
},
}
const query: PaginateQuery = {
path: '',
filter: {
'cat.age': '$in:4,6',
},
}
const result = await paginate<CatHomeEntity>(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<CatHomeEntity> = {
relations: ['cat'],
sortableColumns: ['id', 'name'],
filterableColumns: {
'cat.age': [FilterOperator.BTW],
},
}
const query: PaginateQuery = {
path: '',
filter: {
'cat.age': '$btw:6,10',
},
}
const result = await paginate<CatHomeEntity>(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<CatEntity> = {
sortableColumns: ['id'],

View File

@ -288,10 +288,24 @@ export async function paginate<T>(
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],