backend-roadreport-main/app/Base/Services/ParseParamService.ts
2024-12-31 10:16:45 +07:00

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
}
}
}