UNPKG

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