@mcabreradev/filter
Version:
A powerful, SQL-like array filtering library for TypeScript and JavaScript with advanced pattern matching, MongoDB-style operators, deep object comparison, and zero dependencies
117 lines • 3.79 kB
JavaScript
import { OPERATORS } from '../constants';
import { isString, isObject, isFunction, isOperatorExpression } from '../utils';
export const buildDebugTree = (expression, config) => {
if (isFunction(expression)) {
return {
type: 'primitive',
operator: 'function',
value: '<custom predicate>',
};
}
if (isString(expression) || typeof expression === 'number' || typeof expression === 'boolean') {
return {
type: 'primitive',
value: expression,
};
}
if (isObject(expression)) {
const expr = expression;
const children = [];
let hasLogicalOps = false;
if (OPERATORS.AND in expr) {
hasLogicalOps = true;
const andExpressions = expr[OPERATORS.AND];
children.push({
type: 'logical',
operator: OPERATORS.AND,
children: andExpressions.map((e) => buildDebugTree(e, config)),
});
}
if (OPERATORS.OR in expr) {
hasLogicalOps = true;
const orExpressions = expr[OPERATORS.OR];
children.push({
type: 'logical',
operator: OPERATORS.OR,
children: orExpressions.map((e) => buildDebugTree(e, config)),
});
}
if (OPERATORS.NOT in expr) {
hasLogicalOps = true;
const notExpression = expr[OPERATORS.NOT];
children.push({
type: 'logical',
operator: OPERATORS.NOT,
children: [buildDebugTree(notExpression, config)],
});
}
for (const key in expr) {
if (key === OPERATORS.AND || key === OPERATORS.OR || key === OPERATORS.NOT) {
continue;
}
const value = expr[key];
if (Array.isArray(value)) {
children.push({
type: 'field',
field: key,
operator: 'OR',
children: value.map((v) => ({
type: 'primitive',
value: v,
})),
});
continue;
}
if (isObject(value) && isOperatorExpression(value)) {
const operatorChildren = [];
for (const op in value) {
operatorChildren.push({
type: 'operator',
operator: op,
field: key,
value: value[op],
});
}
children.push({
type: 'field',
field: key,
children: operatorChildren,
});
continue;
}
if (isObject(value) && !isOperatorExpression(value)) {
children.push({
type: 'field',
field: key,
children: [buildDebugTree(value, config)],
});
continue;
}
children.push({
type: 'field',
field: key,
value,
});
}
if (hasLogicalOps && children.length > 1) {
return {
type: 'logical',
operator: 'ROOT',
children,
};
}
if (children.length === 1) {
return children[0];
}
return {
type: 'logical',
operator: 'AND',
children,
};
}
return {
type: 'primitive',
value: expression,
};
};
//# sourceMappingURL=debug-tree-builder.js.map