216 lines
5.9 KiB
TypeScript
216 lines
5.9 KiB
TypeScript
export default class ParseParamService {
|
|
LIKE = 'like';
|
|
EQUAL = 'eq';
|
|
NOT_EQUAL = 'ne';
|
|
GREATER_THAN = 'gt';
|
|
GREATER_THAN_EQUAL = 'gte';
|
|
LESS_THAN = 'lt';
|
|
LESS_THAN_EQUAL = 'lte';
|
|
BETWEEN = 'between';
|
|
|
|
OPERATOR_LIKE = 'ILIKE';
|
|
OPERATOR_EQUAL = '=';
|
|
OPERATOR_NOT_EQUAL = '!=';
|
|
OPERATOR_GREATER_THAN = '>';
|
|
OPERATOR_GREATER_THAN_EQUAL = '>=';
|
|
OPERATOR_LESS_THAN = '<';
|
|
OPERATOR_LESS_THAN_EQUAL = '<=';
|
|
|
|
OPERATION_DEFAULT = "and";
|
|
|
|
parse(data: { sort: any; fields: any; embed: any; search: any; page: any; limit: any; }) {
|
|
const paginateParams = this.parsePaginateParams(data)
|
|
const sortParams = this.parseSortParams(data.sort)
|
|
const filterParams = this.parseFilterParams(data)
|
|
const projectionParams = this.parseProjectionParams(data.fields)
|
|
const relationParams = this.parseRelationParams(data.embed)
|
|
const relationOptionParams = this.parseRelationOptionParams(data)
|
|
const searchParams = this.parseSearch(data.search)
|
|
|
|
const results = {
|
|
pagination: paginateParams,
|
|
sort: sortParams,
|
|
filter: filterParams,
|
|
fields: projectionParams,
|
|
relation: relationParams,
|
|
search: searchParams,
|
|
relationOptions: relationOptionParams
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
parsePaginateParams(data: { page: any; limit: any; }) {
|
|
return {
|
|
page: data.page ?? null,
|
|
limit: data.limit ?? null
|
|
}
|
|
}
|
|
|
|
parseSortParams(data: string) {
|
|
if (data) {
|
|
const sorts = data.split(',')
|
|
const parsedSort: any[] = []
|
|
|
|
sorts.forEach((sort: string) => {
|
|
if (sort.includes('-')) {
|
|
parsedSort.push({
|
|
order: 'desc',
|
|
attribute: sort.split('-')[1]
|
|
})
|
|
} else {
|
|
parsedSort.push({
|
|
order: 'asc',
|
|
attribute: sort
|
|
})
|
|
}
|
|
});
|
|
|
|
return parsedSort
|
|
}
|
|
}
|
|
|
|
parseFilterParams(data: { [x: string]: { [x: string]: any; }; operation?: any; }) {
|
|
const filters: any[] = []
|
|
|
|
Object.keys(data).forEach(key => {
|
|
if (key != 'page' && key != 'limit' && key != 'sort' && key != 'fields' && key != 'embed' && key != 'operation' && key != 'search' && !key.includes('.')) {
|
|
Object.keys(data[key]).forEach(k => {
|
|
if (k == 'between') {
|
|
const values = data[key][k].split(',')
|
|
if (values.length != 2) {
|
|
return
|
|
} else {
|
|
filters.push({
|
|
attribute: key,
|
|
operator: this.BETWEEN,
|
|
value: values
|
|
})
|
|
}
|
|
} else {
|
|
if (data[key][k].includes(',')) {
|
|
const values = data[key][k].split(',')
|
|
values.forEach((val: any) => {
|
|
filters.push(this.parseFilter(key, k, val))
|
|
});
|
|
} else {
|
|
filters.push(this.parseFilter(key, k, data[key][k]))
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
return {
|
|
operation: data.operation || 'and',
|
|
data: filters
|
|
}
|
|
}
|
|
|
|
parseProjectionParams(data: string) {
|
|
if (data) {
|
|
return data.split(',')
|
|
}
|
|
}
|
|
|
|
parseRelationParams(data: string) {
|
|
if (data) {
|
|
return data.split(',')
|
|
}
|
|
}
|
|
|
|
parseRelationOptionParams(data: { [x: string]: any; embed: any; }) {
|
|
const relationOptions: any[] = []
|
|
if (data.embed) {
|
|
data.embed.replace(/\./g, ',').split(',').forEach((relation: string) => {
|
|
const option: any = {}
|
|
option.relation = relation
|
|
|
|
if (data[`${relation}.fields`]) {
|
|
option.fields = data[`${relation}.fields`].split(',')
|
|
}
|
|
|
|
if (data[`${relation}.sort`]) {
|
|
option.sort = data[`${relation}.sort`].replace('-', '')
|
|
option.order = data[`${relation}.sort`].includes('-') ? 'desc' : 'asc'
|
|
}
|
|
|
|
const filterParams = Object.keys(data).filter((key: string) => key.split('.')[0] == relation && key != `${relation}.operation` && key != `${relation}.limit` && key != `${relation}.search` && key != `${relation}.fields` && key != `${relation}.sort`).map(key => {
|
|
const filter: any = {}
|
|
const operator: any = Object.keys(data[key])[0]
|
|
filter.attribute = key.split('.')[1]
|
|
filter.operator = this.parseOperator(operator)
|
|
filter.value = data[key][operator]
|
|
return filter
|
|
})
|
|
|
|
if (filterParams.length > 0) {
|
|
option.filter = {
|
|
operation: data[`${relation}.operation`] || 'and',
|
|
data: filterParams
|
|
}
|
|
}
|
|
|
|
if (data[`${relation}.limit`]) {
|
|
option.limit = data[`${relation}.limit`]
|
|
}
|
|
|
|
if (data[`${relation}.search`]) {
|
|
option.search = this.parseSearch(data[`${relation}.search`])
|
|
}
|
|
|
|
relationOptions.push(option)
|
|
})
|
|
}
|
|
return relationOptions
|
|
}
|
|
|
|
parseSearch(data: { [x: string]: any; }) {
|
|
if (data) {
|
|
const search: any = {
|
|
data: null,
|
|
attributes: [],
|
|
operator: this.OPERATOR_LIKE
|
|
}
|
|
|
|
Object.keys(data).forEach(key => {
|
|
search.data = `%${data[key]}%`
|
|
search.attributes = key.split(',')
|
|
})
|
|
|
|
return search
|
|
}
|
|
}
|
|
|
|
parseFilter(attribute: string, operator: string, value: string) {
|
|
if (operator == this.LIKE) {
|
|
value = `%${value}%`
|
|
}
|
|
|
|
return {
|
|
attribute: attribute,
|
|
operator: this.parseOperator(operator),
|
|
value: value
|
|
}
|
|
}
|
|
|
|
parseOperator(operator: any) {
|
|
switch (operator) {
|
|
case this.LIKE:
|
|
return this.OPERATOR_LIKE
|
|
case this.EQUAL:
|
|
return this.OPERATOR_EQUAL
|
|
case this.NOT_EQUAL:
|
|
return this.OPERATOR_NOT_EQUAL
|
|
case this.GREATER_THAN:
|
|
return this.OPERATOR_GREATER_THAN
|
|
case this.GREATER_THAN_EQUAL:
|
|
return this.OPERATOR_GREATER_THAN_EQUAL
|
|
case this.LESS_THAN:
|
|
return this.OPERATOR_LESS_THAN
|
|
case this.LESS_THAN_EQUAL:
|
|
return this.OPERATOR_LESS_THAN_EQUAL
|
|
}
|
|
}
|
|
}
|