@react-querybuilder/core
Version:
React Query Builder component for constructing queries and filters, with utilities for executing them in various database and evaluation contexts
190 lines (187 loc) • 9.17 kB
JavaScript
import { l as defaultOperatorNegationMap, s as objectKeys } from "./optGroupUtils-VeZ3k7-1.mjs";
import { t as joinWith } from "./arrayUtils-A_OXU9W1.mjs";
import { i as isPojo, n as isRuleGroupType, t as isRuleGroup } from "./isRuleGroup-CYcfPgbg.mjs";
import { n as convertToIC } from "./convertQuery-CqX3rPvj.mjs";
import { n as fieldIsValidUtil, r as getFieldsArray, t as prepareRuleGroup } from "./prepareQueryObjects-DPCC-iHp.mjs";
//#region src/utils/parseJsonLogic/utils.ts
const isJsonLogicVar = (logic) => isPojo(logic) && "var" in logic;
const isRQBJsonLogicVar = (logic) => isJsonLogicVar(logic) && typeof logic.var === "string";
const isJsonLogicEqual = (logic) => isPojo(logic) && "==" in logic;
const isJsonLogicStrictEqual = (logic) => isPojo(logic) && "===" in logic;
const isJsonLogicNotEqual = (logic) => isPojo(logic) && "!=" in logic;
const isJsonLogicStrictNotEqual = (logic) => isPojo(logic) && "!==" in logic;
const isJsonLogicNegation = (logic) => isPojo(logic) && "!" in logic;
const isJsonLogicDoubleNegation = (logic) => isPojo(logic) && "!!" in logic;
const isJsonLogicOr = (logic) => isPojo(logic) && "or" in logic;
const isJsonLogicAnd = (logic) => isPojo(logic) && "and" in logic;
const isJsonLogicGreaterThan = (logic) => isPojo(logic) && ">" in logic;
const isJsonLogicGreaterThanOrEqual = (logic) => isPojo(logic) && ">=" in logic;
const isJsonLogicLessThan = (logic) => isPojo(logic) && "<" in logic && logic["<"].length === 2;
const isJsonLogicLessThanOrEqual = (logic) => isPojo(logic) && "<=" in logic && logic["<="].length === 2;
const isJsonLogicInArray = (logic) => isPojo(logic) && "in" in logic && Array.isArray(logic.in[1]);
const isJsonLogicInString = (logic) => isPojo(logic) && "in" in logic && !Array.isArray(logic.in[1]);
const isJsonLogicAll = (logic) => isPojo(logic) && "all" in logic;
const isJsonLogicNone = (logic) => isPojo(logic) && "none" in logic;
const isJsonLogicSome = (logic) => isPojo(logic) && "some" in logic;
const isJsonLogicBetweenExclusive = (logic) => isPojo(logic) && "<" in logic && Array.isArray(logic["<"]) && logic["<"].length === 3;
const isJsonLogicBetweenInclusive = (logic) => isPojo(logic) && "<=" in logic && Array.isArray(logic["<="]) && logic["<="].length === 3;
const isRQBJsonLogicStartsWith = (logic) => isPojo(logic) && "startsWith" in logic;
const isRQBJsonLogicEndsWith = (logic) => isPojo(logic) && "endsWith" in logic;
//#endregion
//#region src/utils/parseJsonLogic/parseJsonLogic.ts
const emptyRuleGroup = {
combinator: "and",
rules: []
};
function parseJsonLogic(rqbJsonLogic, options = {}) {
const fieldsFlat = getFieldsArray(options.fields);
const { getValueSources, listsAsArrays, jsonLogicOperations } = options;
const fieldIsValid = (fieldName, operator, subordinateFieldName) => fieldIsValidUtil({
fieldName,
fieldsFlat,
operator,
subordinateFieldName,
getValueSources
});
function processLogic(logic, outermost) {
if (outermost && !isPojo(logic)) return false;
const [key, keyValue] = Object.entries(logic || {})?.[0] ?? [];
if (jsonLogicOperations && objectKeys(jsonLogicOperations).includes(key)) {
const rule$1 = jsonLogicOperations[key](keyValue);
return rule$1 ? outermost && !isRuleGroup(rule$1) ? {
combinator: "and",
rules: [rule$1]
} : rule$1 : false;
}
if (isJsonLogicAnd(logic)) return {
combinator: "and",
rules: logic.and.map((l) => processLogic(l)).filter(Boolean)
};
else if (isJsonLogicOr(logic)) return {
combinator: "or",
rules: logic.or.map((l) => processLogic(l)).filter(Boolean)
};
else if (isJsonLogicNegation(logic)) {
const rule$1 = processLogic(logic["!"]);
if (rule$1) {
if (!isRuleGroupType(rule$1) && (rule$1.operator === "between" || rule$1.operator === "in" || rule$1.operator === "contains" || rule$1.operator === "beginsWith" || rule$1.operator === "endsWith")) {
const newRule = {
...rule$1,
operator: defaultOperatorNegationMap[rule$1.operator]
};
if (outermost) return {
combinator: "and",
rules: [newRule]
};
return newRule;
} else if (isJsonLogicBetweenExclusive(logic["!"]) || isRuleGroupType(rule$1)) return {
...rule$1,
not: true
};
return {
combinator: "and",
rules: [rule$1],
not: true
};
}
return false;
} else if (isJsonLogicDoubleNegation(logic)) return processLogic(logic["!!"]) || false;
let rule = false;
let field = "";
let operator = "=";
let value = "";
let valueSource = void 0;
if (isJsonLogicEqual(logic) || isJsonLogicStrictEqual(logic) || isJsonLogicNotEqual(logic) || isJsonLogicStrictNotEqual(logic) || isJsonLogicGreaterThan(logic) || isJsonLogicGreaterThanOrEqual(logic) || isJsonLogicLessThan(logic) || isJsonLogicLessThanOrEqual(logic) || isJsonLogicInString(logic) || isRQBJsonLogicStartsWith(logic) || isRQBJsonLogicEndsWith(logic)) {
const [first, second] = keyValue;
if (isRQBJsonLogicVar(first) && !isPojo(second)) {
field = first.var;
value = second;
} else if (!isPojo(first) && isRQBJsonLogicVar(second)) {
field = second.var;
value = first;
} else if (isRQBJsonLogicVar(first) && isRQBJsonLogicVar(second)) {
field = first.var;
value = second.var;
valueSource = "field";
} else return false;
if (isJsonLogicEqual(logic) || isJsonLogicStrictEqual(logic)) operator = value === null ? "null" : "=";
else if (isJsonLogicNotEqual(logic) || isJsonLogicStrictNotEqual(logic)) operator = value === null ? "notNull" : "!=";
else if (isJsonLogicInString(logic)) operator = "contains";
else if (isRQBJsonLogicStartsWith(logic)) operator = "beginsWith";
else if (isRQBJsonLogicEndsWith(logic)) operator = "endsWith";
else operator = key;
if (fieldIsValid(field, operator, valueSource === "field" ? value : void 0)) rule = {
field,
operator,
value,
valueSource
};
} else if (isJsonLogicAll(logic) && isRQBJsonLogicVar(logic["all"][0]) || isJsonLogicNone(logic) && isRQBJsonLogicVar(logic["none"][0]) || isJsonLogicSome(logic) && isRQBJsonLogicVar(logic["some"][0])) {
const match = { mode: isJsonLogicNone(logic) ? "none" : isJsonLogicSome(logic) ? "some" : "all" };
const [{ var: field$1 }, operation] = logic[match.mode];
const matcher = processLogic(operation);
if (!matcher) return false;
rule = {
field: field$1,
operator: "=",
match,
value: isRuleGroup(matcher) ? matcher : {
combinator: "and",
rules: [matcher]
}
};
} else if (isJsonLogicBetweenExclusive(logic) && isRQBJsonLogicVar(logic["<"][1])) {
field = logic["<"][1].var;
const values = [logic["<"][0], logic["<"][2]];
// istanbul ignore else
if (values.every((v) => isRQBJsonLogicVar(v)) || values.every((el) => typeof el === "string") || values.every((el) => typeof el === "number") || values.every((el) => typeof el === "boolean")) return processLogic({ and: [{ ">": [{ var: field }, values[0]] }, { "<": [{ var: field }, values[1]] }] }) || false;
} else if (isJsonLogicBetweenInclusive(logic) && isRQBJsonLogicVar(logic["<="][1])) {
field = logic["<="][1].var;
operator = "between";
const values = [logic["<="][0], logic["<="][2]];
if (logic["<="].every((v) => isRQBJsonLogicVar(v))) {
const vars = values;
valueSource = "field";
const fieldList = vars.map((el) => el.var).filter((sf) => fieldIsValid(field, operator, sf));
value = listsAsArrays ? fieldList : joinWith(fieldList, ",");
} else if (values.every((el) => typeof el === "string") || values.every((el) => typeof el === "number") || values.every((el) => typeof el === "boolean")) value = listsAsArrays ? values : joinWith(values.map((el) => `${el}`), ",");
if (fieldIsValid(field, operator) && value.length >= 2) rule = {
field,
operator,
value,
valueSource
};
} else if (isJsonLogicInArray(logic) && isRQBJsonLogicVar(keyValue[0])) {
field = keyValue[0].var;
operator = "in";
if (logic.in[1].every((v) => isRQBJsonLogicVar(v))) {
valueSource = "field";
const fieldList = logic.in[1].map((el) => el.var).filter((sf) => fieldIsValid(field, operator, sf));
value = listsAsArrays ? fieldList : joinWith(fieldList, ",");
} else if (logic.in[1].every((el) => typeof el === "string") || logic.in[1].every((el) => typeof el === "number") || logic.in[1].every((el) => typeof el === "boolean")) value = listsAsArrays ? logic.in[1] : joinWith(logic.in[1].map((el) => `${el}`), ",");
// istanbul ignore else
if (value.length > 0) rule = {
field,
operator,
value,
valueSource
};
}
return rule ? outermost ? {
combinator: "and",
rules: [rule]
} : rule : false;
}
const prepare = options.generateIDs ? prepareRuleGroup : (g) => g;
let logicRoot = rqbJsonLogic;
if (typeof rqbJsonLogic === "string") try {
logicRoot = JSON.parse(rqbJsonLogic);
} catch {
return prepare(emptyRuleGroup);
}
const finalQuery = processLogic(logicRoot, true) || emptyRuleGroup;
return prepare(options.independentCombinators ? convertToIC(finalQuery) : finalQuery);
}
//#endregion
export { parseJsonLogic };
//# sourceMappingURL=parseJsonLogic.mjs.map