nestjs-paginate/src/filter.ts

86 lines
3.1 KiB
TypeScript
Raw Normal View History

2023-01-30 11:17:14 +00:00
import { FindOperator, SelectQueryBuilder } from 'typeorm'
import { WherePredicateOperator } from 'typeorm/query-builder/WhereClause'
import { checkIsRelation, extractVirtualProperty, fixColumnAlias, getPropertiesByColumnName } from './helper'
export type Filter = { [columnName: string]: FindOperator<string> }
export function generatePredicateCondition(
qb: SelectQueryBuilder<unknown>,
column: string,
filter: Filter,
alias: string,
isVirtualProperty = false
): WherePredicateOperator {
return qb['getWherePredicateCondition'](
isVirtualProperty ? column : alias,
filter[column]
) as WherePredicateOperator
}
// This function is used to fix the query parameters when using relation, embeded or virtual properties
// It will replace the column name with the alias name and return the new parameters
function fixQueryParam(
alias: string,
column: string,
filter: Filter,
condition: WherePredicateOperator,
parameters: { [key: string]: string }
): { [key: string]: string } {
const isNotOperator = (condition.operator as string) === 'not'
const conditionFixer = (
alias: string,
column: string,
filter: Filter,
operator: WherePredicateOperator['operator'],
parameters: { [key: string]: string }
): { condition_params: any; params: any } => {
let condition_params: any = undefined
let params = parameters
switch (operator) {
case 'between':
condition_params = [alias, `:${column}_from`, `:${column}_to`]
params = {
[column + '_from']: filter[column].value[0],
[column + '_to']: filter[column].value[1],
}
break
case 'in':
condition_params = [alias, `:...${column}`]
break
default:
condition_params = [alias, `:${column}`]
break
}
return { condition_params, params }
}
const { condition_params, params } = conditionFixer(
alias,
column,
filter,
isNotOperator ? condition['condition']['operator'] : condition.operator,
parameters
)
if (isNotOperator) {
condition['condition']['parameters'] = condition_params
} else {
condition.parameters = condition_params
}
return params
}
export function addWhereCondition(qb: SelectQueryBuilder<unknown>, column: string, filter: Filter) {
const columnProperties = getPropertiesByColumnName(column)
const { isVirtualProperty, query: virtualQuery } = extractVirtualProperty(qb, columnProperties)
const isRelation = checkIsRelation(qb, columnProperties.propertyPath)
const alias = fixColumnAlias(columnProperties, qb.alias, isRelation, isVirtualProperty, virtualQuery)
const condition = generatePredicateCondition(qb, column, filter, alias, isVirtualProperty)
const parameters = fixQueryParam(alias, column, filter, condition, {
[column]: filter[column].value,
})
qb.andWhere(qb['createWhereConditionExpression'](condition), parameters)
}