fix: between and in operator for relations
This commit is contained in:
parent
e84d71e540
commit
8bf5e41a11
31
README.md
31
README.md
@ -200,6 +200,13 @@ const paginateConfig: PaginateConfig<CatEntity> {
|
|||||||
* https://typeorm.io/#/find-options/advanced-options
|
* https://typeorm.io/#/find-options/advanced-options
|
||||||
*/
|
*/
|
||||||
filterableColumns: { age: [FilterOperator.EQ, FilterOperator.IN] }
|
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)
|
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)
|
||||||
|
```
|
||||||
|
@ -462,7 +462,7 @@ describe('paginate', () => {
|
|||||||
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.toys.name=$not:Stuffed Mouse')
|
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> = {
|
const config: PaginateConfig<CatHomeEntity> = {
|
||||||
relations: ['cat'],
|
relations: ['cat'],
|
||||||
sortableColumns: ['id', 'name'],
|
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')
|
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 () => {
|
it('should return result based on where array and filter', async () => {
|
||||||
const config: PaginateConfig<CatEntity> = {
|
const config: PaginateConfig<CatEntity> = {
|
||||||
sortableColumns: ['id'],
|
sortableColumns: ['id'],
|
||||||
|
@ -288,10 +288,24 @@ export async function paginate<T>(
|
|||||||
column,
|
column,
|
||||||
filter[column]
|
filter[column]
|
||||||
) as WherePredicateOperator
|
) as WherePredicateOperator
|
||||||
|
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}`]
|
condition.parameters = [`${qb.alias}_${column}`, `:${column}`]
|
||||||
qb.andWhere(qb['createWhereConditionExpression'](condition), {
|
break
|
||||||
[column]: filter[column].value,
|
}
|
||||||
})
|
qb.andWhere(qb['createWhereConditionExpression'](condition), parameters)
|
||||||
} else {
|
} else {
|
||||||
qb.andWhere({
|
qb.andWhere({
|
||||||
[column]: filter[column],
|
[column]: filter[column],
|
||||||
|
Loading…
Reference in New Issue
Block a user