UNPKG

react-querybuilder

Version:

React Query Builder component for constructing queries and filters, with utilities for executing them in various database and evaluation contexts

948 lines (916 loc) 234 kB
// src/context/QueryBuilderContext.ts import { createContext } from "react"; var QueryBuilderContext = /* @__PURE__ */ createContext({}); // src/components/ActionElement.tsx import { jsx } from "react/jsx-runtime"; var ActionElement = (props) => /* @__PURE__ */ jsx("button", { type: "button", "data-testid": props.testID, disabled: props.disabled && !props.disabledTranslation, className: props.className, title: props.disabledTranslation && props.disabled ? props.disabledTranslation.title : props.title, onClick: (e) => props.handleOnClick(e), children: props.disabledTranslation && props.disabled ? props.disabledTranslation.label : props.label }); // src/components/DragHandle.tsx import { jsx as jsx2 } from "react/jsx-runtime"; import { forwardRef } from "react"; var DragHandle = /* @__PURE__ */ forwardRef((props, dragRef) => /* @__PURE__ */ jsx2("span", { "data-testid": props.testID, ref: dragRef, className: props.className, title: props.title, children: props.label })); // src/defaults.ts var defaultPlaceholderName = "~"; var defaultPlaceholderLabel = "------"; var defaultPlaceholderFieldName = defaultPlaceholderName; var defaultPlaceholderFieldLabel = defaultPlaceholderLabel; var defaultPlaceholderFieldGroupLabel = defaultPlaceholderLabel; var defaultPlaceholderOperatorName = defaultPlaceholderName; var defaultPlaceholderOperatorLabel = defaultPlaceholderLabel; var defaultPlaceholderOperatorGroupLabel = defaultPlaceholderLabel; var defaultJoinChar = ","; var defaultTranslations = { fields: { title: "Fields", placeholderName: defaultPlaceholderFieldName, placeholderLabel: defaultPlaceholderFieldLabel, placeholderGroupLabel: defaultPlaceholderFieldGroupLabel }, operators: { title: "Operators", placeholderName: defaultPlaceholderOperatorName, placeholderLabel: defaultPlaceholderOperatorLabel, placeholderGroupLabel: defaultPlaceholderOperatorGroupLabel }, value: { title: "Value" }, removeRule: { label: "\u2A2F", title: "Remove rule" }, removeGroup: { label: "\u2A2F", title: "Remove group" }, addRule: { label: "+ Rule", title: "Add rule" }, addGroup: { label: "+ Group", title: "Add group" }, combinators: { title: "Combinators" }, notToggle: { label: "Not", title: "Invert this group" }, cloneRule: { label: "\u29C9", title: "Clone rule" }, cloneRuleGroup: { label: "\u29C9", title: "Clone group" }, shiftActionUp: { label: "\u02C4", title: "Shift up" }, shiftActionDown: { label: "\u02C5", title: "Shift down" }, dragHandle: { label: "\u205E\u205E", title: "Drag handle" }, lockRule: { label: "\u{1F513}", title: "Lock rule" }, lockGroup: { label: "\u{1F513}", title: "Lock group" }, lockRuleDisabled: { label: "\u{1F512}", title: "Unlock rule" }, lockGroupDisabled: { label: "\u{1F512}", title: "Unlock group" }, valueSourceSelector: { title: "Value source" } }; var defaultOperators = [{ name: "=", value: "=", label: "=" }, { name: "!=", value: "!=", label: "!=" }, { name: "<", value: "<", label: "<" }, { name: ">", value: ">", label: ">" }, { name: "<=", value: "<=", label: "<=" }, { name: ">=", value: ">=", label: ">=" }, { name: "contains", value: "contains", label: "contains" }, { name: "beginsWith", value: "beginsWith", label: "begins with" }, { name: "endsWith", value: "endsWith", label: "ends with" }, { name: "doesNotContain", value: "doesNotContain", label: "does not contain" }, { name: "doesNotBeginWith", value: "doesNotBeginWith", label: "does not begin with" }, { name: "doesNotEndWith", value: "doesNotEndWith", label: "does not end with" }, { name: "null", value: "null", label: "is null" }, { name: "notNull", value: "notNull", label: "is not null" }, { name: "in", value: "in", label: "in" }, { name: "notIn", value: "notIn", label: "not in" }, { name: "between", value: "between", label: "between" }, { name: "notBetween", value: "notBetween", label: "not between" }]; var defaultOperatorNegationMap = { "=": "!=", "!=": "=", "<": ">=", "<=": ">", ">": "<=", ">=": "<", beginsWith: "doesNotBeginWith", doesNotBeginWith: "beginsWith", endsWith: "doesNotEndWith", doesNotEndWith: "endsWith", contains: "doesNotContain", doesNotContain: "contains", between: "notBetween", notBetween: "between", in: "notIn", notIn: "in", notNull: "null", null: "notNull" }; var defaultCombinators = [{ name: "and", value: "and", label: "AND" }, { name: "or", value: "or", label: "OR" }]; var defaultCombinatorsExtended = [...defaultCombinators, { name: "xor", value: "xor", label: "XOR" }]; var standardClassnames = { queryBuilder: "queryBuilder", ruleGroup: "ruleGroup", header: "ruleGroup-header", body: "ruleGroup-body", combinators: "ruleGroup-combinators", addRule: "ruleGroup-addRule", addGroup: "ruleGroup-addGroup", cloneRule: "rule-cloneRule", cloneGroup: "ruleGroup-cloneGroup", removeGroup: "ruleGroup-remove", notToggle: "ruleGroup-notToggle", rule: "rule", fields: "rule-fields", operators: "rule-operators", value: "rule-value", removeRule: "rule-remove", betweenRules: "betweenRules", valid: "queryBuilder-valid", invalid: "queryBuilder-invalid", shiftActions: "shiftActions", dndDragging: "dndDragging", dndOver: "dndOver", dndCopy: "dndCopy", dragHandle: "queryBuilder-dragHandle", disabled: "queryBuilder-disabled", lockRule: "rule-lock", lockGroup: "ruleGroup-lock", valueSource: "rule-valueSource", valueListItem: "rule-value-list-item", branches: "queryBuilder-branches" }; var defaultControlClassnames = { queryBuilder: "", ruleGroup: "", header: "", body: "", combinators: "", addRule: "", addGroup: "", cloneRule: "", cloneGroup: "", removeGroup: "", notToggle: "", rule: "", fields: "", operators: "", value: "", removeRule: "", shiftActions: "", dragHandle: "", lockRule: "", lockGroup: "", valueSource: "", actionElement: "", valueSelector: "", betweenRules: "", valid: "", invalid: "", dndDragging: "", dndOver: "", dndCopy: "", disabled: "", valueListItem: "", branches: "" }; var groupInvalidReasons = { empty: "empty", invalidCombinator: "invalid combinator", invalidIndependentCombinators: "invalid independent combinators" }; var TestID = { rule: "rule", ruleGroup: "rule-group", inlineCombinator: "inline-combinator", addGroup: "add-group", removeGroup: "remove-group", cloneGroup: "clone-group", cloneRule: "clone-rule", addRule: "add-rule", removeRule: "remove-rule", combinators: "combinators", fields: "fields", operators: "operators", valueEditor: "value-editor", notToggle: "not-toggle", shiftActions: "shift-actions", dragHandle: "drag-handle", lockRule: "lock-rule", lockGroup: "lock-group", valueSourceSelector: "value-source-selector" }; var LogType = { parentPathDisabled: "action aborted: parent path disabled", pathDisabled: "action aborted: path is disabled", queryUpdate: "query updated", onAddRuleFalse: "onAddRule callback returned false", onAddGroupFalse: "onAddGroup callback returned false", onMoveRuleFalse: "onMoveRule callback returned false", onMoveGroupFalse: "onMoveGroup callback returned false", onRemoveFalse: "onRemove callback returned false", add: "rule or group added", remove: "rule or group removed", update: "rule or group updated", move: "rule or group moved" }; var rootPath = []; // src/components/InlineCombinator.tsx import { jsx as jsx3 } from "react/jsx-runtime"; // src/utils/clsx.ts function toVal(mix) { let k; let y; let str = ""; if (typeof mix === "string" || typeof mix === "number") { str += mix; } else if (typeof mix === "object") { if (Array.isArray(mix)) { const len = mix.length; for (k = 0; k < len; k++) { if (mix[k] && (y = toVal(mix[k]))) { str && (str += " "); str += y; } } } else { for (y in mix) { if (mix[y]) { str && (str += " "); str += y; } } } } return str; } function clsx() { let i = 0; let tmp; let x; let str = ""; const len = arguments.length; for (; i < len; i++) { if ((tmp = i < 0 || arguments.length <= i ? void 0 : arguments[i]) && (x = toVal(tmp))) { str && (str += " "); str += x; } } return str; } var clsx_default = clsx; // src/components/InlineCombinator.tsx var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var InlineCombinator = (allProps) => { const _a = allProps, { component: CombinatorSelectorComponent } = _a, props = __objRest(_a, ["component"]); const className = clsx(props.schema.suppressStandardClassnames || standardClassnames.betweenRules, props.schema.classNames.betweenRules); return /* @__PURE__ */ jsx3("div", { className, "data-testid": TestID.inlineCombinator, children: /* @__PURE__ */ jsx3(CombinatorSelectorComponent, __spreadProps(__spreadValues({}, props), { testID: TestID.combinators })) }); }; // src/components/NotToggle.tsx import { jsx as jsx4, jsxs } from "react/jsx-runtime"; var NotToggle = (props) => /* @__PURE__ */ jsxs("label", { "data-testid": props.testID, className: props.className, title: props.title, children: [/* @__PURE__ */ jsx4("input", { type: "checkbox", onChange: (e) => props.handleOnChange(e.target.checked), checked: !!props.checked, disabled: props.disabled }), props.label] }); // src/messages.ts var messages = { errorInvalidIndependentCombinatorsProp: "QueryBuilder was rendered with a truthy independentCombinators prop. This prop is deprecated and unnecessary. Furthermore, the initial query/defaultQuery prop was of type RuleGroupType instead of type RuleGroupIC. More info: https://react-querybuilder.js.org/docs/components/querybuilder#independent-combinators", errorUnnecessaryIndependentCombinatorsProp: "QueryBuilder was rendered with the deprecated and unnecessary independentCombinators prop. To use independent combinators, make sure the query/defaultQuery prop is of type RuleGroupIC when the component mounts. More info: https://react-querybuilder.js.org/docs/components/querybuilder#independent-combinators", errorDeprecatedRuleGroupProps: "A custom RuleGroup component has rendered a standard RuleGroup component with deprecated props. The combinator, not, and rules props should not be used. Instead, the full group object should be passed as the ruleGroup prop.", errorDeprecatedRuleProps: "A custom RuleGroup component has rendered a standard Rule component with deprecated props. The field, operator, value, and valueSource props should not be used. Instead, the full rule object should be passed as the rule prop.", errorBothQueryDefaultQuery: "QueryBuilder was rendered with both query and defaultQuery props. QueryBuilder must be either controlled or uncontrolled (specify either the query prop, or the defaultQuery prop, but not both). Decide between using a controlled or uncontrolled query builder and remove one of these props. More info: https://reactjs.org/link/controlled-components", errorUncontrolledToControlled: "QueryBuilder is changing from an uncontrolled component to be controlled. This is likely caused by the query changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled query builder for the lifetime of the component. More info: https://reactjs.org/link/controlled-components", errorControlledToUncontrolled: "QueryBuilder is changing from a controlled component to be uncontrolled. This is likely caused by the query changing from defined to undefined, which should not happen. Decide between using a controlled or uncontrolled query builder for the lifetime of the component. More info: https://reactjs.org/link/controlled-components", errorEnabledDndWithoutReactDnD: "QueryBuilder was rendered with the enableDragAndDrop prop set to true, but either react-dnd or react-dnd-html5-backend (or both) was not installed. To enable drag-and-drop functionality, install both packages and wrap QueryBuilder in QueryBuilderDnD from @react-querybuilder/dnd." }; // src/redux/QueryBuilderStateContext.ts import * as React from "react"; var QueryBuilderStateContext = /* @__PURE__ */ React.createContext(null); // src/redux/_internal.ts import { createDispatchHook, createStoreHook } from "react-redux"; // src/redux/queriesSlice.ts import { createSlice } from "@reduxjs/toolkit"; var initialState = {}; var queriesSlice = createSlice({ name: "queries", initialState, reducers: { setQueryState: (state, _ref) => { let { payload: { qbId, query } } = _ref; state[qbId] = query; } }, selectors: { getQuerySelectorById: (state, qbId) => state[qbId] } }); // src/redux/warningsSlice.ts import { createSlice as createSlice2 } from "@reduxjs/toolkit"; var initialState2 = { [messages.errorInvalidIndependentCombinatorsProp]: false, [messages.errorUnnecessaryIndependentCombinatorsProp]: false, [messages.errorDeprecatedRuleGroupProps]: false, [messages.errorDeprecatedRuleProps]: false, [messages.errorBothQueryDefaultQuery]: false, [messages.errorUncontrolledToControlled]: false, [messages.errorControlledToUncontrolled]: false, [messages.errorEnabledDndWithoutReactDnD]: false }; var warningsSlice = createSlice2({ name: "warnings", initialState: initialState2, reducers: { rqbWarn: (state, _ref) => { let { payload } = _ref; if (!state[payload]) { console.error(payload); state[payload] = true; } } } }); // src/redux/_internal.ts var _RQB_INTERNAL_dispatchThunk = (_ref) => { let { payload, onQueryChange } = _ref; return (dispatch) => { dispatch(queriesSlice.actions.setQueryState(payload)); if (typeof onQueryChange === "function") { onQueryChange( payload.query /* ??? */ ); } }; }; var useRQB_INTERNAL_QueryBuilderDispatch = createDispatchHook(QueryBuilderStateContext); var useRQB_INTERNAL_QueryBuilderStore = createStoreHook(QueryBuilderStateContext); var { rqbWarn: _SYNC_rqbWarn } = warningsSlice.actions; var rqbWarn = (msg) => (dispatch) => { setTimeout(() => dispatch(_SYNC_rqbWarn(msg))); }; var preloadedState = { queries: queriesSlice.getInitialState(), warnings: warningsSlice.getInitialState() }; var storeCommon = { reducer: { queries: queriesSlice.reducer, warnings: warningsSlice.reducer }, preloadedState, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ // Ignore non-serializable values in setQueryState actions and rule `value`s // https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data serializableCheck: { ignoredActions: [queriesSlice.actions.setQueryState.type], ignoredPaths: [/^queries\b.*\.rules\.\d+\.value$/] } }) }; // src/hooks/useDeprecatedProps.ts function useDeprecatedProps(type, logWarning, otherParams) { const dispatch = useRQB_INTERNAL_QueryBuilderDispatch(); if (process.env.NODE_ENV !== "production" && logWarning) { if (type === "independentCombinators") { if (otherParams === "invalid") { dispatch(rqbWarn(messages.errorInvalidIndependentCombinatorsProp)); } if (otherParams === "unnecessary") { dispatch(rqbWarn(messages.errorUnnecessaryIndependentCombinatorsProp)); } } if (type === "rule") { dispatch(rqbWarn(messages.errorDeprecatedRuleProps)); } if (type === "ruleGroup") { dispatch(rqbWarn(messages.errorDeprecatedRuleGroupProps)); } } } // src/hooks/useReactDndWarning.ts var didWarnEnabledDndWithoutReactDnD = false; var useReactDndWarning = (enableDragAndDrop, dndRefs) => { if (process.env.NODE_ENV !== "production" && !didWarnEnabledDndWithoutReactDnD && enableDragAndDrop && !dndRefs) { console.error(messages.errorEnabledDndWithoutReactDnD); didWarnEnabledDndWithoutReactDnD = true; } }; // ../../utils/react-compiler/react-compiler-runtime.ts import * as React2 from "react"; var $empty = Symbol.for("react.memo_cache_sentinel"); function c(size) { return React2.useMemo( () => { const $ = Array.from({ length: size }); for (let ii = 0; ii < size; ii++) { $[ii] = $empty; } $[$empty] = true; return $; }, // eslint-disable-next-line react-hooks/exhaustive-deps [] ); } // src/hooks/useStopEventPropagation.ts import { useCallback } from "react"; var useStopEventPropagation = (method) => { const $ = c(2); let t0; if ($[0] !== method) { t0 = (event, context) => { event == null ? void 0 : event.preventDefault(); event == null ? void 0 : event.stopPropagation(); method(event, context); }; $[0] = method; $[1] = t0; } else { t0 = $[1]; } return t0; }; // src/utils/arrayUtils.ts var splitBy = function(str) { let splitChar = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : defaultJoinChar; return typeof str === "string" ? str.split(`\\${splitChar}`).map((c2) => c2.split(splitChar)).reduce((prev, curr, idx) => { if (idx === 0) { return curr; } return [...prev.slice(0, -1), `${prev.at(-1)}${splitChar}${curr[0]}`, ...curr.slice(1)]; }, []) : []; }; var joinWith = function(strArr) { let joinChar = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : defaultJoinChar; return strArr.map((str) => `${str != null ? str : ""}`.replaceAll(joinChar[0], `\\${joinChar[0]}`)).join(joinChar); }; var trimIfString = (val) => typeof val === "string" ? val.trim() : val; var toArray = function(v) { let { retainEmptyStrings } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; return Array.isArray(v) ? v.map((v2) => trimIfString(v2)) : typeof v === "string" ? splitBy(v, defaultJoinChar).filter(retainEmptyStrings ? () => true : (s) => !/^\s*$/.test(s)).map((s) => s.trim()) : typeof v === "number" ? [v] : []; }; var nullFreeArray = (arr) => arr.every((el) => el === false || (el != null ? el : false) !== false); // src/utils/misc.ts import { numericRegex as numericQuantityRegex } from "numeric-quantity"; var numericRegex = new RegExp(numericQuantityRegex.source.replace(/^\^/, String.raw`^\s*`).replace(/\$$/, String.raw`\s*$`)); var isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype; // src/utils/isRuleGroup.ts var isRuleGroup = (rg) => isPojo(rg) && Array.isArray(rg.rules); var isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "string"; var isRuleGroupTypeIC = (rg) => isRuleGroup(rg) && rg.combinator === void 0; // src/utils/convertQuery.ts import { produce } from "immer"; var __defProp2 = Object.defineProperty; var __defProps2 = Object.defineProperties; var __getOwnPropDescs2 = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols2 = Object.getOwnPropertySymbols; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __propIsEnum2 = Object.prototype.propertyIsEnumerable; var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues2 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp2.call(b, prop)) __defNormalProp2(a, prop, b[prop]); if (__getOwnPropSymbols2) for (var prop of __getOwnPropSymbols2(b)) { if (__propIsEnum2.call(b, prop)) __defNormalProp2(a, prop, b[prop]); } return a; }; var __spreadProps2 = (a, b) => __defProps2(a, __getOwnPropDescs2(b)); var __objRest2 = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp2.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols2) for (var prop of __getOwnPropSymbols2(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum2.call(source, prop)) target[prop] = source[prop]; } return target; }; var combinatorLevels = ["or", "xor", "and"]; var isSameString = (a, b) => typeof a === "string" && a.toLowerCase() === b; var generateRuleGroupICWithConsistentCombinators = function(rg) { let baseCombinatorLevel = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0; const baseCombinator = combinatorLevels[baseCombinatorLevel]; if (!rg.rules.includes(baseCombinator)) { return baseCombinatorLevel < combinatorLevels.length - 2 ? generateRuleGroupICWithConsistentCombinators(rg, baseCombinatorLevel + 1) : rg; } return produce(rg, (draft) => { let cursor = 0; while (cursor < draft.rules.length - 2) { if (isSameString(draft.rules[cursor + 1], baseCombinator)) { cursor += 2; continue; } const nextBaseCombinatorIndex = draft.rules.findIndex((r, i) => i > cursor && typeof r === "string" && r.toLowerCase() === baseCombinator); if (nextBaseCombinatorIndex === -1) { draft.rules.splice(cursor, draft.rules.length, generateRuleGroupICWithConsistentCombinators( // eslint-disable-next-line @typescript-eslint/no-explicit-any { rules: draft.rules.slice(cursor) }, baseCombinatorLevel + 1 )); break; } else { draft.rules.splice(cursor, nextBaseCombinatorIndex - cursor, generateRuleGroupICWithConsistentCombinators( // eslint-disable-next-line @typescript-eslint/no-explicit-any { rules: draft.rules.slice(cursor, nextBaseCombinatorIndex) }, baseCombinatorLevel + 1 )); } } }); }; var convertFromIC = (rg) => { if (isRuleGroupType(rg)) { return rg; } const processedRG = generateRuleGroupICWithConsistentCombinators(rg); const rulesAsMixedList = processedRG.rules.map((r) => typeof r === "string" || !isRuleGroup(r) ? r : convertFromIC(r)); const combinator = rulesAsMixedList.length < 2 ? "and" : rulesAsMixedList[1]; const rules = rulesAsMixedList.filter((r) => typeof r !== "string"); return __spreadProps2(__spreadValues2({}, processedRG), { combinator, rules }); }; var convertToIC = (rg) => { if (isRuleGroupTypeIC(rg)) { return rg; } const _a = rg, { combinator } = _a, queryWithoutCombinator = __objRest2(_a, ["combinator"]); const rules = []; const { length } = rg.rules; for (const [idx, r] of rg.rules.entries()) { if (isRuleGroup(r)) { rules.push(convertToIC(r)); } else { rules.push(r); } if (combinator && idx < length - 1) { rules.push(combinator); } } return __spreadProps2(__spreadValues2({}, queryWithoutCombinator), { rules }); }; function convertQuery(query) { return isRuleGroupTypeIC(query) ? convertFromIC(query) : convertToIC(query); } // src/utils/defaultValidator.ts var defaultValidator = (query) => { const result = {}; const validateRule = (_rule) => { }; const validateGroup = (rg) => { const reasons = []; if (rg.rules.length === 0) { reasons.push(groupInvalidReasons.empty); } else if (!isRuleGroupType(rg)) { let invalidICs = false; for (let i = 0; i < rg.rules.length && !invalidICs; i++) { if (i % 2 === 0 && typeof rg.rules[i] === "string" || i % 2 === 1 && typeof rg.rules[i] !== "string" || i % 2 === 1 && typeof rg.rules[i] === "string" && !defaultCombinators.map((c2) => c2.name).includes(rg.rules[i])) { invalidICs = true; } } if (invalidICs) { reasons.push(groupInvalidReasons.invalidIndependentCombinators); } } if (isRuleGroupType(rg) && !defaultCombinators.map((c2) => c2.name).includes(rg.combinator) && rg.rules.length > 1) { reasons.push(groupInvalidReasons.invalidCombinator); } if (rg.id) { result[rg.id] = reasons.length > 0 ? { valid: false, reasons } : true; } for (const r of rg.rules) { if (typeof r === "string") { } else if (isRuleGroup(r)) { validateGroup(r); } else { validateRule(r); } } }; validateGroup(query); return result; }; // src/utils/optGroupUtils.ts import { produce as produce2 } from "immer"; var __defProp3 = Object.defineProperty; var __defProps3 = Object.defineProperties; var __getOwnPropDescs3 = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols3 = Object.getOwnPropertySymbols; var __hasOwnProp3 = Object.prototype.hasOwnProperty; var __propIsEnum3 = Object.prototype.propertyIsEnumerable; var __defNormalProp3 = (obj, key, value) => key in obj ? __defProp3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues3 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp3.call(b, prop)) __defNormalProp3(a, prop, b[prop]); if (__getOwnPropSymbols3) for (var prop of __getOwnPropSymbols3(b)) { if (__propIsEnum3.call(b, prop)) __defNormalProp3(a, prop, b[prop]); } return a; }; var __spreadProps3 = (a, b) => __defProps3(a, __getOwnPropDescs3(b)); var isOptionWithName = (opt) => isPojo(opt) && "name" in opt && typeof opt.name === "string"; var isOptionWithValue = (opt) => isPojo(opt) && "value" in opt && typeof opt.value === "string"; function toFullOption(opt, baseProperties) { const recipe = produce2((draft) => { const idObj = {}; let needsUpdating = !!baseProperties; if (isOptionWithName(draft) && !isOptionWithValue(draft)) { idObj.value = draft.name; needsUpdating = true; } else if (!isOptionWithName(draft) && isOptionWithValue(draft)) { idObj.name = draft.value; needsUpdating = true; } if (needsUpdating) { return Object.assign({}, baseProperties, draft, idObj); } }); return recipe(opt); } function toFullOptionList(optList, baseProperties) { if (!Array.isArray(optList)) { return []; } const recipe = produce2((draft) => { if (isFlexibleOptionGroupArray(draft)) { for (const optGroup of draft) { for (const [idx, opt] of optGroup.options.entries()) optGroup.options[idx] = toFullOption(opt, baseProperties); } } else { for (const [idx, opt] of draft.entries()) draft[idx] = toFullOption(opt, baseProperties); } }); return recipe(optList); } function toFullOptionMap(optMap, baseProperties) { return Object.fromEntries(Object.entries(optMap).map((_ref) => { let [k, v] = _ref; return [k, toFullOption(v, baseProperties)]; })); } var uniqByName = (originalArray) => uniqByIdentifier(originalArray); var uniqByIdentifier = (originalArray) => { var _a, _b; const names = /* @__PURE__ */ new Set(); const newArray = []; for (const el of originalArray) { if (!names.has((_a = el.value) != null ? _a : el.name)) { names.add((_b = el.value) != null ? _b : el.name); newArray.push(el); } } return originalArray.length === newArray.length ? originalArray : newArray; }; var isOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0] && Array.isArray(arr[0].options); var isFlexibleOptionArray = (arr) => { let isFOA = false; if (Array.isArray(arr)) { for (const o of arr) { if (isOptionWithName(o) || isOptionWithValue(o)) { isFOA = true; } else { return false; } } } return isFOA; }; var isFullOptionArray = (arr) => { let isFOA = false; if (Array.isArray(arr)) { for (const o of arr) { if (isOptionWithName(o) && isOptionWithValue(o)) { isFOA = true; } else { return false; } } } return isFOA; }; var isFlexibleOptionGroupArray = function(arr) { let { allowEmpty = false } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; let isFOGA = false; if (Array.isArray(arr)) { for (const og of arr) { if (isPojo(og) && "options" in og && (isFlexibleOptionArray(og.options) || allowEmpty && Array.isArray(og.options) && og.options.length === 0)) { isFOGA = true; } else { return false; } } } return isFOGA; }; var isFullOptionGroupArray = function(arr) { let { allowEmpty = false } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; let isFOGA = false; if (Array.isArray(arr)) { for (const og of arr) { if (isPojo(og) && "options" in og && (isFullOptionArray(og.options) || allowEmpty && Array.isArray(og.options) && og.options.length === 0)) { isFOGA = true; } else { return false; } } } return isFOGA; }; var getOption = (arr, name) => (isFlexibleOptionGroupArray(arr, { allowEmpty: true }) ? arr.flatMap((og) => og.options) : arr).find((op) => op.value === name || op.name === name); var getFirstOption = (arr) => { var _a, _b; if (!Array.isArray(arr) || arr.length === 0) { return null; } else if (isFlexibleOptionGroupArray(arr, { allowEmpty: true })) { for (const og of arr) { if (og.options.length > 0) { return (_a = og.options[0].value) != null ? _a : og.options[0].name; } } return null; } return (_b = arr[0].value) != null ? _b : arr[0].name; }; var toFlatOptionArray = (arr) => uniqByIdentifier(isOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr); var uniqOptGroups = (originalArray) => { var _a, _b; const labels = /* @__PURE__ */ new Set(); const names = /* @__PURE__ */ new Set(); const newArray = []; for (const el of originalArray) { if (!labels.has(el.label)) { labels.add(el.label); const optionsForThisGroup = []; for (const opt of el.options) { if (!names.has((_a = opt.value) != null ? _a : opt.name)) { names.add((_b = opt.value) != null ? _b : opt.name); optionsForThisGroup.push(toFullOption(opt)); } } newArray.push(__spreadProps3(__spreadValues3({}, el), { options: optionsForThisGroup })); } } return newArray; }; var uniqOptList = (originalArray) => { if (isFlexibleOptionGroupArray(originalArray)) { return uniqOptGroups(originalArray); } return uniqByIdentifier(originalArray.map((o) => toFullOption(o))); }; // src/utils/filterFieldsByComparator.ts var __defProp4 = Object.defineProperty; var __defProps4 = Object.defineProperties; var __getOwnPropDescs4 = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols4 = Object.getOwnPropertySymbols; var __hasOwnProp4 = Object.prototype.hasOwnProperty; var __propIsEnum4 = Object.prototype.propertyIsEnumerable; var __defNormalProp4 = (obj, key, value) => key in obj ? __defProp4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues4 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp4.call(b, prop)) __defNormalProp4(a, prop, b[prop]); if (__getOwnPropSymbols4) for (var prop of __getOwnPropSymbols4(b)) { if (__propIsEnum4.call(b, prop)) __defNormalProp4(a, prop, b[prop]); } return a; }; var __spreadProps4 = (a, b) => __defProps4(a, __getOwnPropDescs4(b)); var filterByComparator = (field, operator, fieldToCompare) => { var _a, _b; const fullField = toFullOption(field); const fullFieldToCompare = toFullOption(fieldToCompare); if (fullField.value === fullFieldToCompare.value) { return false; } if (typeof fullField.comparator === "string") { return fullField[fullField.comparator] === fullFieldToCompare[fullField.comparator]; } return (_b = (_a = fullField.comparator) == null ? void 0 : _a.call(fullField, fullFieldToCompare, operator)) != null ? _b : ( /* istanbul ignore next */ false ); }; var filterFieldsByComparator = (field, fields, operator) => { if (!field.comparator) { const filterOutSameField = (f) => { var _a, _b; return ((_a = f.value) != null ? _a : ( /* istanbul ignore next */ f.name )) !== ((_b = field.value) != null ? _b : ( /* istanbul ignore next */ field.name )); }; if (isFlexibleOptionGroupArray(fields)) { return fields.map((og) => __spreadProps4(__spreadValues4({}, og), { options: og.options.filter((v) => filterOutSameField(v)) })); } return fields.filter((v) => filterOutSameField(v)); } if (isFlexibleOptionGroupArray(fields)) { return fields.map((og) => __spreadProps4(__spreadValues4({}, og), { options: og.options.filter((f) => filterByComparator(field, operator, f)) })).filter((og) => og.options.length > 0); } return fields.filter((f) => filterByComparator(field, operator, f)); }; // src/utils/parseNumber.ts import { numericQuantity } from "numeric-quantity"; var parseNumber = function(val) { let { parseNumbers } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; if (!parseNumbers || typeof val === "bigint" || typeof val === "number") { return val; } if (parseNumbers === "native") { return parseFloat(val); } const valAsNum = ( // TODO: Should these options be configurable? numericQuantity(val, { allowTrailingInvalid: parseNumbers === "enhanced", romanNumerals: false, round: false }) ); return isNaN(valAsNum) ? val : valAsNum; }; // src/utils/getParseNumberMethod.ts var getParseNumberMethod = (_ref) => { let { parseNumbers, inputType } = _ref; if (typeof parseNumbers === "string") { const [method, level] = parseNumbers.split("-"); if (level === "limited") { return inputType === "number" ? method : false; } return method; } return parseNumbers ? "strict" : false; }; // src/utils/formatQuery/utils.ts var __defProp5 = Object.defineProperty; var __defProps5 = Object.defineProperties; var __getOwnPropDescs5 = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols5 = Object.getOwnPropertySymbols; var __hasOwnProp5 = Object.prototype.hasOwnProperty; var __propIsEnum5 = Object.prototype.propertyIsEnumerable; var __defNormalProp5 = (obj, key, value) => key in obj ? __defProp5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues5 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp5.call(b, prop)) __defNormalProp5(a, prop, b[prop]); if (__getOwnPropSymbols5) for (var prop of __getOwnPropSymbols5(b)) { if (__propIsEnum5.call(b, prop)) __defNormalProp5(a, prop, b[prop]); } return a; }; var __spreadProps5 = (a, b) => __defProps5(a, __getOwnPropDescs5(b)); var mapSQLOperator = (rqbOperator) => { switch (rqbOperator.toLowerCase()) { case "null": return "is null"; case "notnull": return "is not null"; case "notin": return "not in"; case "notbetween": return "not between"; case "contains": case "beginswith": case "endswith": return "like"; case "doesnotcontain": case "doesnotbeginwith": case "doesnotendwith": return "not like"; default: return rqbOperator; } }; var mongoOperators = { "=": "$eq", "!=": "$ne", "<": "$lt", "<=": "$lte", ">": "$gt", ">=": "$gte", in: "$in", notin: "$nin", notIn: "$nin" // only here for backwards compatibility }; var celCombinatorMap = { and: "&&", or: "||" }; var jsonLogicAdditionalOperators = { startsWith: (a, b) => typeof a === "string" && a.startsWith(b), endsWith: (a, b) => typeof a === "string" && a.endsWith(b) }; var numerifyValues = (rg, options) => __spreadProps5(__spreadValues5({}, rg), { // @ts-expect-error TS doesn't keep track of odd/even indexes here rules: rg.rules.map((r) => { if (typeof r === "string") { return r; } if (isRuleGroup(r)) { return numerifyValues(r, options); } const fieldData = getOption(options.fields, r.field); const parseNumbers = getParseNumberMethod({ parseNumbers: options.parseNumbers, inputType: fieldData == null ? void 0 : fieldData.inputType }); if (Array.isArray(r.value)) { return __spreadProps5(__spreadValues5({}, r), { value: r.value.map((v) => parseNumber(v, { parseNumbers })) }); } const valAsArray = toArray(r.value, { retainEmptyStrings: true }).map((v) => parseNumber(v, { parseNumbers })); if (valAsArray.every((v) => typeof v === "number")) { if (valAsArray.length > 1) { return __spreadProps5(__spreadValues5({}, r), { value: valAsArray }); } else if (valAsArray.length === 1) { return __spreadProps5(__spreadValues5({}, r), { value: valAsArray[0] }); } } return r; }) }); var isValidValue = (value) => typeof value === "string" && value.length > 0 || typeof value === "number" && !isNaN(value) || typeof value !== "string" && typeof value !== "number"; var shouldRenderAsNumber = (value, parseNumbers) => !!parseNumbers && (typeof value === "number" || typeof value === "bigint" || typeof value === "string" && numericRegex.test(value)); var isValueProcessorLegacy = (valueProcessor) => valueProcessor.length >= 3; var getQuoteFieldNamesWithArray = function() { let quoteFieldNamesWith = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : ["", ""]; return Array.isArray(quoteFieldNamesWith) ? quoteFieldNamesWith : typeof quoteFieldNamesWith === "string" ? [quoteFieldNamesWith, quoteFieldNamesWith] : quoteFieldNamesWith != null ? quoteFieldNamesWith : ["", ""]; }; var getQuotedFieldName = (fieldName, _ref) => { let { quoteFieldNamesWith, fieldIdentifierSeparator } = _ref; const [qPre, qPost] = getQuoteFieldNamesWithArray(quoteFieldNamesWith); return typeof fieldIdentifierSeparator === "string" && fieldIdentifierSeparator.length > 0 ? joinWith(splitBy(fieldName, fieldIdentifierSeparator).map((part) => `${qPre}${part}${qPost}`), fieldIdentifierSeparator) : `${qPre}${fieldName}${qPost}`; }; var nullOrUndefinedOrEmpty = (value) => value === null || value === void 0 || value === ""; // src/utils/formatQuery/defaultRuleProcessorCEL.ts var shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot"); var escapeDoubleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? v : v.replaceAll(`"`, `\\"`); var defaultRuleProcessorCEL = function(_ref) { let { field, operator, value, valueSource } = _ref; let { escapeQuotes, parseNumbers, preserveValueOrder } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; const valueIsField = valueSource === "field"; const operatorTL = (operator === "=" ? "==" : operator).toLowerCase(); const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers); switch (operatorTL) { case "<": case "<=": case "==": case "!=": case ">": case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`}`; case "contains": case "doesnotcontain": { const negate2 = shouldNegate(operatorTL) ? "!" : ""; return `${negate2}${field}.contains(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`; } case "beginswith": case "doesnotbeginwith": { const negate2 = shouldNegate(operatorTL) ? "!" : ""; return `${negate2}${field}.startsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`; } case "endswith": case "doesnotendwith": { const negate2 = shouldNegate(operatorTL) ? "!" : ""; return `${negate2}${field}.endsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`; } case "null": return `${field} == null`; case "notnull": return `${field} != null`; case "in": case "notin": { const [prefix, suffix] = shouldNegate(operatorTL) ? ["!(", ")"] : ["", ""]; const valueAsArray = toArray(value); return `${prefix}${field} in [${valueAsArray.map((val) => valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `"${escapeDoubleQuotes(val, escapeQuotes)}"`).join(", ")}]${suffix}`; } case "between": case "notbetween": { const valueAsArray = toArray(value); if (valueAsArray.length >= 2 && !nullOrUndefinedOrEmpty(valueAsArray[0]) && !nullOrUndefinedOrEmpty(valueAsArray[1])) { const [first, second] = valueAsArray; const firstNum = shouldRenderAsNumber(first, true) ? parseNumber(first, { parseNumbers: true }) : NaN; const secondNum = shouldRenderAsNumber(second, true) ? parseNumber(second, { parseNumbers: true }) : NaN; let firstValue = isNaN(firstNum) ? valueIsField ? `${first}` : `"${escapeDoubleQuotes(first, escapeQuotes)}"` : firstNum; let secondValue = isNaN(secondNum) ? valueIsField ? `${second}` : `"${escapeDoubleQuotes(second, escapeQuotes)}"` : secondNum; if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) { const tempNum = secondNum; secondValue = firstNum; firstValue = tempNum; } return operatorTL === "between" ? `(${field} >= ${firstValue} && ${field} <= ${secondValue})` : `(${field} < ${firstValue} || ${field} > ${secondValue})`; } else { return ""; } } } return ""; }; // src/utils/formatQuery/defaultRuleProcessorMongoDBQuery.ts var defaultRuleProcessorMongoDBQuery = function(_ref) { let { field, operator, value, valueSource } = _ref; let { parseNumbers, preserveValueOrder } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; const valueIsField = valueSource === "field"; if (operator === "=" && !valueIsField) { return { [field]: shouldRenderAsNumber(value, parseNumbers) ? parseNumber(value, { parseNumbers: "strict" }) : value }; } const operatorLC = operator.toLowerCase(); switch (operatorLC) { case "<": case "<=": case "=": case "!=": case ">": case ">=": { const mongoOperator = mongoOperators[operatorLC]; return valueIsField ? { $expr: { [mongoOperator]: [`$${field}`, `$${value}`] } } : { [field]: { [mongoOperator]: shouldRenderAsNumber(value, parseNumbers) ? parseNumber(value, { parseNumbers: "strict" }) : value } }; } case "contains": return valueIsField ? { $where: `this.${field}.includes(this.${value})` } : { [field]: { $regex: value } }; case "beginswith": return valueIsField ? { $where: `this.${field}.startsWith(this.${value})` } : { [field]: { $regex: `^${value}` } }; case "endswith": return valueIsField ? { $where: `this.${field}.endsWith(this.${value})` } : { [field]: { $regex: `${value}$` } }; case "doesnotcontain": return valueIsField ? { $where: `!this.${field}.includes(this.${value})` } : { [field]: { $not: { $regex: value } } }; case "doesnotbeginwith": return valueIsField ? { $where: `!this.${field}.startsWith(this.${value})` } : { [field]: { $not: { $regex: `^${value}` } } }; case "doesnotendwith": return valueIsField ? { $where: `!this.${field}.endsWith(this.${value})` } : { [field]: { $not: { $regex: `${value}$` } } }; case "null": return { [field]: null }; case "notnull": return { [field]: { $ne: null } }; case "in": case "notin": { const valueAsArray = toArray(value); return valueIsField ? { $where: `${operatorLC === "notin" ? "!" : ""}[${valueAsArray.map((val) => `this.${val}`).join(",")}].includes(this.${field})` } : { [field]: { [mongoOperators[operatorLC]]: valueAsArray.map((val) => shouldRenderAsNumber(val, parseNumbers) ? parseNumber(val, { parseNumbers: "strict" }) : val) } }; } case "between": case "notbetween": { const valueAsArray = toArray(value); if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) { const [first, second] = valueAsArray; const firstNum = shouldRenderAsNumber(first, true) ? parseNumber(first, { parseNumbers: "strict" }) : NaN; const secondNum = shouldRenderAsNumber(second, true) ? parseNumber(second, { parseNumbers: "strict" }) : NaN; let firstValue = valueIsField ? first : isNaN(firstNum) ? first : firstNum; let secondValue = valueIsField ? second : isNaN(secondNum) ? second : secondNum; if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) { const tempNum = secondNum; secondValue = firstNum; firstValue = tempNum; } if (operatorLC === "between") { return valueIsField ? { $and: [{ $expr: { $gte: [`$${field}`, `$${firstValue}`] } }, { $expr: { $lte: [`$${field}`, `$${secondValue}`] } }] } : { [field]: { $gte: firstValue, $lte: secondValue } }; } else { return valueIsField ? { $or: [{ $expr: { $lt: [`$${field}`, `$${firstValue}`] } }, { $expr: { $gt: [`$${field}`, `$${secondValue}`] } }] } : { $or: [{ [field]: { $lt: firstValue } }, { [field]: { $gt: secondValue } }] }; } } else { return ""; } } } return ""; }; // src/utils/formatQuery/defaultRuleProcessorMongoDB.ts var defaultRuleProcessorMongoDB = (rule, options) => { const queryObj = defaultRuleProcessorMongoDBQuery(rule, options); return queryObj ? JSON.stringify(queryObj) : ""; }; // src/utils/formatQuery/defaultRuleProcessorSpEL.ts var shouldNegate2 = (op) => op.startsWith("not") || op.startsWith("doesnot"); var wrapInNegation = (clause, negate2) => negate2 ? `!(${clause})` : `${clause}`; var escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? v : v.replaceAll(`'`, `\\'`); var defaultRuleProcessorSpEL = function(_ref) { let { field, operator, value, valueSource } = _ref; let { escapeQuotes, parseNumbers, preserveValueOrder } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; const valueIsField = valueSource === "field"; const operatorTL = (operator === "=" ? "==" : operator).toLowerCase(); const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers); switch (operatorTL) { case "<": case "<=": case "==": case "!=": case ">": case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`; case "contains": case "doesnotcontain": return wrapInNegation(`${field} matches ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate2(operatorTL)); case "beginswith": case "doesnotbeginwith": { const valueTL = valueIsField ? `'^'.concat(${trimIfString(value)})` : `'${typeof value === "string" && !value.startsWith("^") || useBareValue ? "^" : ""}${escapeSingleQuotes(value, escapeQuotes)}'`; return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate2(operatorTL)); } case "endswith": case "doesnotendwith": { const valueTL = valueIsField ? `${trimIfString(value)}.concat('$')` : `'${escapeSingleQuotes(value, escapeQuotes)}${typeof value === "string" && !value.endsWith("$") || useBareValue ? "$" : ""}'`; return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate2(operatorTL)); } case "null": return `${field} == null`; case "notnull": return `${field} != null`; case "in": case "notin": { const negate2 = shouldNegate2(operatorTL) ? "!" : ""; const valueAsArray = toArray(value); return valueAsArray.length > 0 ? `${negate2}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : ""; } case "between": case "notbetween": { const valueAsArray = toArray(value); if (valueAsArray.length >= 2 && !nullOrUndefinedOrEmpty(valueAsArray[0]) && !nullOrUndefinedOrEmpty(valueAsArray[1])) { const [first, second] = valueAsArray; const firstNum = shouldRenderAsNumber(first, true) ? parseNumber(first, { parseNumbers: true }) : NaN; const secondNum = shouldRenderAsNumber(second, true) ? parseNumber(second, { parseNumbers: true }) : NaN; let firstValue = isNaN(firstNum) ? valueIsField ? `${first}` : `'${escapeSingleQuotes(first, escapeQuotes)}'` : firstNum; let secondValue = isNaN(secondNum) ? valueIsField ? `${second}` : `'${escapeSingleQuotes(second, escapeQuotes)}'` : secondNum; if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) { const tempNum = secondNum; secondValue = firstNum; firstValue = tempNum; } return operatorTL === "between" ? `(${field} >= ${firstValue} and ${field} <= ${secondValue})` : `(${field} < ${firstValue} or ${field} > ${secondValue})`; } else { return ""; } } } return ""; }; // src/utils/formatQuery/defaultValueProcessorByRule.ts var escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v; var defaultValueProcessorByRule = function(_ref) { let { operator, value, valueSource } = _ref; let { escapeQuotes, parseNumbers, preserveValueOrder, quoteFieldNamesWith, quoteValuesWith, concatOperator = "||", fieldIdentifierSep