@equantic/linq
Version:
eQuantic Linq for JavaScript
88 lines (87 loc) • 3.6 kB
JavaScript
import { flatten } from 'flat';
import { Filtering } from './Filtering.js';
import { FilteringCollection } from './FilteringCollection.js';
import { OrFiltering } from './OrFiltering.js';
import { CompositeFiltering } from './CompositeFiltering.js';
import { parseExpression } from './base.js';
import { CompositeFilteringParser } from './CompositeFilteringParser.js';
export class FilteringParser {
static parseQueryString(queryFilter) {
const result = new FilteringCollection();
if (!queryFilter)
return result;
if (!Array.isArray(queryFilter))
queryFilter = [queryFilter.toString()];
for (const k in queryFilter) {
if (!k)
continue;
const f = queryFilter[k];
const exp = f.toString();
if (CompositeFilteringParser.parse(exp, result))
continue;
FilteringParser.parseExpression(exp, result);
}
return result;
}
static parseObject(data, options) {
const collection = new FilteringCollection();
if (!data)
return collection;
const flattenObj = flatten(data, { safe: true });
for (const key in flattenObj) {
if (!key)
continue;
let value = flattenObj[key];
const info = options?.parseProperty?.(key) || {
column: key,
operator: 'eq',
};
if (Array.isArray(value)) {
if (value.length > 1) {
const composite = new OrFiltering();
for (const idx in value) {
if (FilteringParser.validateValue(value[idx], options))
composite.addValue(new Filtering(info.column, value[idx], info.operator));
}
collection.push(composite);
continue;
}
value = value[0];
}
if (FilteringParser.validateValue(value, options))
collection.push(new Filtering(info.column, value, info.operator));
}
return collection;
}
static parse(source, options) {
if (source instanceof CompositeFiltering) {
return new CompositeFiltering(source.compositeOperator, source.values.map((value) => FilteringParser.parse(value, options)));
}
const convertedColumn = options?.parseProperty(source.column) || source.column;
const convertedValue = source.value;
return new Filtering(convertedColumn, convertedValue, source.operator);
}
static parseCollection(source, options) {
return new FilteringCollection(source.map((s) => FilteringParser.parse(s, options)));
}
static parseExpression(exp, result) {
const f = parseExpression(exp);
const filtering = new Filtering(f.column, f.value, f.operator);
result.push(filtering);
}
static toQueryString(filtering) {
if (!filtering || filtering.length === 0)
return undefined;
const newFiltering = FilteringParser.parseCollection(new FilteringCollection(filtering));
return newFiltering.length > 1
? new CompositeFiltering('and', newFiltering).toString()
: newFiltering[0].toString();
}
static validateValue(value, options) {
if (value == null)
return options?.consideringNullValues ? true : false;
if (value == '')
return options?.consideringEmptyValues ? true : false;
return true;
}
}