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

1,066 lines (1,049 loc) 120 kB
const require_isRuleGroup = require('./isRuleGroup-DqAs2x4E.js'); const require_optGroupUtils = require('./optGroupUtils-B0hTpodo.js'); const require_arrayUtils = require('./arrayUtils-QxZOZTf6.js'); const require_parseNumber = require('./parseNumber-D4iQDxK-.js'); const require_transformQuery = require('./transformQuery-CWDPogO5.js'); const require_convertQuery = require('./convertQuery-DAqoID3O.js'); let immer = require("immer"); immer = require_isRuleGroup.__toESM(immer); //#region src/utils/isRuleOrGroupValid.ts /** * Determines if an object is useful as a validation result. */ const isValidationResult = (vr) => require_isRuleGroup.isPojo(vr) && typeof vr.valid === "boolean"; /** * Determines if a rule or group is valid based on a validation result (if defined) * or a validator function. Returns `true` if neither are defined and the `muted` * property is not `true`. */ const isRuleOrGroupValid = (rg, validationResult, validator) => { if (rg.muted) return false; if (typeof validationResult === "boolean") return validationResult; if (isValidationResult(validationResult)) return validationResult.valid; if (typeof validator === "function" && !require_isRuleGroup.isRuleGroup(rg)) { const vr = validator(rg); if (typeof vr === "boolean") return vr; // istanbul ignore else if (isValidationResult(vr)) return vr.valid; } return true; }; //#endregion //#region src/utils/getParseNumberMethod.ts const getParseNumberMethod = ({ parseNumbers, inputType }) => { if (typeof parseNumbers === "string") { const [method, level] = parseNumbers.split("-"); if (level === "limited") return inputType === "number" ? method : false; return method; } return parseNumbers ? "strict" : false; }; //#endregion //#region src/utils/formatQuery/utils.ts /** * Maps a {@link DefaultOperatorName} to a SQL operator. * * @group Export */ const mapSQLOperator = (rqbOperator) => { switch (require_isRuleGroup.lc(rqbOperator)) { 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; } }; /** * Maps a (lowercase) {@link DefaultOperatorName} to a MongoDB operator. * * @group Export */ const mongoOperators = { "=": "$eq", "!=": "$ne", "<": "$lt", "<=": "$lte", ">": "$gt", ">=": "$gte", in: "$in", notin: "$nin", notIn: "$nin" }; /** * Maps a (lowercase) {@link DefaultOperatorName} to a Prisma ORM operator. * * @group Export */ const prismaOperators = { "=": "equals", "!=": "not", "<": "lt", "<=": "lte", ">": "gt", ">=": "gte", in: "in", notin: "notIn" }; /** * Maps a {@link DefaultCombinatorName} to a CEL combinator. * * @group Export */ const celCombinatorMap = { and: "&&", or: "||" }; /** * Register these operators with `jsonLogic` before applying the result * of `formatQuery(query, 'jsonlogic')`. * * @example * ``` * for (const [op, func] of Object.entries(jsonLogicAdditionalOperators)) { * jsonLogic.add_operation(op, func); * } * jsonLogic.apply({ "startsWith": [{ "var": "firstName" }, "Stev"] }, data); * ``` * * @group Export */ const jsonLogicAdditionalOperators = { startsWith: (a, b) => typeof a === "string" && a.startsWith(b), endsWith: (a, b) => typeof a === "string" && a.endsWith(b) }; /** * Converts all `string`-type `value` properties of a query object into `number` where appropriate. * * Used by {@link formatQuery} for the `json*` formats when `parseNumbers` is `true`. * * @group Export */ const numerifyValues = (rg, options) => ({ ...rg, rules: rg.rules.map((r) => { if (typeof r === "string") return r; if (require_isRuleGroup.isRuleGroup(r)) return numerifyValues(r, options); const fieldData = require_optGroupUtils.getOption(options.fields, r.field); const parseNumbers = getParseNumberMethod({ parseNumbers: options.parseNumbers, inputType: fieldData?.inputType }); if (Array.isArray(r.value)) return { ...r, value: r.value.map((v) => require_parseNumber.parseNumber(v, { parseNumbers })) }; const valAsArray = require_arrayUtils.toArray(r.value, { retainEmptyStrings: true }).map((v) => require_parseNumber.parseNumber(v, { parseNumbers })); if (valAsArray.every((v) => typeof v === "number")) { // istanbul ignore else if (valAsArray.length > 1) return { ...r, value: valAsArray }; else if (valAsArray.length === 1) return { ...r, value: valAsArray[0] }; } return r; }) }); /** * Determines whether a value is _anything_ except an empty `string` or `NaN`. * * @group Export */ const isValidValue = (value) => typeof value === "string" && value.length > 0 || typeof value === "number" && !Number.isNaN(value) || typeof value !== "string" && typeof value !== "number"; /** * Determines whether {@link formatQuery} should render the given value as a number. * As long as `parseNumbers` is `true`, `number` and `bigint` values will return `true` and * `string` values will return `true` if they test positive against {@link numericRegex}. * * @group Export */ const shouldRenderAsNumber = (value, parseNumbers) => !!parseNumbers && (typeof value === "number" || typeof value === "bigint" || typeof value === "string" && require_isRuleGroup.numericRegex.test(value)); /** * Used by {@link formatQuery} to determine whether the given value processor is a * "legacy" value processor by counting the number of arguments. Legacy value * processors take 3 arguments (not counting any arguments with default values), while * rule-based value processors take no more than 2 arguments. * * @group Export */ const isValueProcessorLegacy = (valueProcessor) => valueProcessor.length >= 3; /** * Converts the `quoteFieldNamesWith` option into an array of two strings. * If the option is a string, the array elements are both that string. * * @default * ['', ''] * * @group Export */ const getQuoteFieldNamesWithArray = (quoteFieldNamesWith = ["", ""]) => Array.isArray(quoteFieldNamesWith) ? quoteFieldNamesWith : typeof quoteFieldNamesWith === "string" ? [quoteFieldNamesWith, quoteFieldNamesWith] : quoteFieldNamesWith ?? ["", ""]; /** * Given a field name and relevant {@link ValueProcessorOptions}, returns the field name * wrapped in the configured quote character(s). * * @group Export */ const getQuotedFieldName = (fieldName, { quoteFieldNamesWith, fieldIdentifierSeparator }) => { const [qPre, qPost] = getQuoteFieldNamesWithArray(quoteFieldNamesWith); return typeof fieldIdentifierSeparator === "string" && fieldIdentifierSeparator.length > 0 ? require_arrayUtils.joinWith(require_arrayUtils.splitBy(fieldName, fieldIdentifierSeparator).map((part) => `${qPre}${part}${qPost}`), fieldIdentifierSeparator) : `${qPre}${fieldName}${qPost}`; }; const defaultWordOrder = [ "S", "V", "O" ]; /** * Given a [Constituent word order](https://en.wikipedia.org/wiki/Word_order#Constituent_word_orders) * like "svo" or "sov", returns a permutation of `["S", "V", "O"]` based on the first occurrence of * each letter in the input string (case insensitive). This widens the valid input from abbreviations * like "svo" to more expressive strings like "subject-verb-object" or "sub ver obj". Any missing * letters are appended in the default order "SVO" (e.g., "object" would yield `["O", "S", "V"]`). * * @group Export */ const normalizeConstituentWordOrder = (input) => { const result = []; const letterSet = new Set(defaultWordOrder); for (const char of input.toUpperCase()) if (letterSet.has(char)) { result.push(char); letterSet.delete(char); if (letterSet.size === 0) break; } for (const letter of defaultWordOrder) if (letterSet.has(letter)) result.push(letter); return result; }; /** * Default translations used by {@link formatQuery} for "natural_language" format. * * @group Export */ const defaultNLTranslations = { groupPrefix: "", groupPrefix_not_xor: "either zero or more than one of", groupPrefix_xor: "exactly one of", groupSuffix: "is true", groupSuffix_not: "is not true" }; /** * Note: This function assumes `conditions.length > 0` */ const translationMatchFilter = (key, keyToTest, conditions) => keyToTest.startsWith(key) && conditions.every((c) => keyToTest.includes(`_${c}`) && keyToTest.match(/_/g)?.length === conditions.length); /** * Used by {@link formatQuery} to get a translation based on certain conditions * for the "natural_language" format. * * @group Export */ const getNLTranslataion = (key, translations, conditions = []) => conditions.length === 0 ? translations[key] ?? defaultNLTranslations[key] ?? "" : Object.entries(translations).find(([keyToTest]) => translationMatchFilter(key, keyToTest, conditions))?.[1] ?? Object.entries(defaultNLTranslations).find(([keyToTest]) => translationMatchFilter(key, keyToTest, conditions))?.[1] ?? defaultNLTranslations[key] ?? ""; const processMatchMode = (rule) => { const { mode, threshold } = rule.match ?? {}; if (mode) { if (!require_isRuleGroup.isRuleGroup(rule.value)) return false; const matchModeLC = require_isRuleGroup.lc(mode); const matchModeCoerced = matchModeLC === "atleast" && threshold === 1 ? "some" : matchModeLC === "atmost" && threshold === 0 ? "none" : matchModeLC; if ((matchModeCoerced === "atleast" || matchModeCoerced === "atmost" || matchModeCoerced === "exactly") && (typeof threshold !== "number" || threshold < 0)) return false; return { mode: matchModeCoerced, threshold }; } }; /** * "Replacer" method for JSON.stringify's second argument. Converts `bigint` values to * objects with a `$bigint` property having a value of a string representation of * the actual `bigint`-type value. * * Inverse of {@link bigIntJsonParseReviver}. * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json */ const bigIntJsonStringifyReplacer = (_key, value) => typeof value === "bigint" ? { $bigint: value.toString() } : value; /** * "Reviver" method for JSON.parse's second argument. Converts objects having a single * `$bigint: string` property to an actual `bigint` value. * * Inverse of {@link bigIntJsonStringifyReplacer}. * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json */ const bigIntJsonParseReviver = (_key, value) => require_isRuleGroup.isPojo(value) && Object.keys(value).length === 1 && typeof value.$bigint === "string" ? BigInt(value.$bigint) : value; //#endregion //#region src/utils/formatQuery/defaultRuleGroupProcessorCEL.ts /** * Rule group processor used by {@link formatQuery} for "cel" format. * * @group Export */ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => { const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options; const processRuleGroup = (rg, outermost) => { if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : ""; const processedRules = []; let precedingCombinator = ""; let firstRule = true; for (const rule of rg.rules) { if (typeof rule === "string") { precedingCombinator = celCombinatorMap[rule]; continue; } if (require_isRuleGroup.isRuleGroup(rule)) { const processedGroup = processRuleGroup(rule); if (processedGroup) { if (!firstRule && precedingCombinator) { processedRules.push(precedingCombinator); precedingCombinator = ""; } firstRule = false; processedRules.push(processedGroup); } continue; } const [validationResult, fieldValidator] = validateRule(rule); if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) continue; const fieldData = require_optGroupUtils.getOption(fields, rule.field); const processedRule = ruleProcessor(rule, { ...options, parseNumbers: getParseNumberBoolean(fieldData?.inputType), escapeQuotes: (rule.valueSource ?? "value") === "value", fieldData }); if (processedRule) { if (!firstRule && precedingCombinator) { processedRules.push(precedingCombinator); precedingCombinator = ""; } firstRule = false; processedRules.push(processedRule); } } const expression = processedRules.join(require_isRuleGroup.isRuleGroupType(rg) ? ` ${celCombinatorMap[rg.combinator]} ` : " "); const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "!" : ""}(`, ")"] : ["", ""]; return expression ? `${prefix}${expression}${suffix}` : fallbackExpression; }; return processRuleGroup(ruleGroup, true); }; //#endregion //#region src/utils/formatQuery/defaultRuleProcessorCEL.ts const shouldNegate$2 = (op) => op.startsWith("not") || op.startsWith("doesnot"); const escapeDoubleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`); /** * Default rule processor used by {@link formatQuery} for "cel" format. * * @group Export */ const defaultRuleProcessorCEL = (rule, opts = {}) => { const { escapeQuotes, parseNumbers, preserveValueOrder } = opts; const { field, operator, value, valueSource } = rule; const valueIsField = valueSource === "field"; const operatorTL = require_isRuleGroup.lc(operator === "=" ? "==" : operator); const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers); const matchEval = processMatchMode(rule); if (matchEval === false) return ""; else if (matchEval) { const { mode, threshold } = matchEval; const arrayElementAlias = "elem_alias"; const nestedArrayFilter = defaultRuleGroupProcessorCEL(require_transformQuery.transformQuery(rule.value, { ruleProcessor: (r) => ({ ...r, field: `${arrayElementAlias}${r.field ? `.${r.field}` : ""}` }) }), opts); switch (mode) { case "all": return `${field}.all(${arrayElementAlias}, ${nestedArrayFilter})`; case "none": case "some": return `${mode === "none" ? "!" : ""}${field}.exists(${arrayElementAlias}, ${nestedArrayFilter})`; case "atleast": case "atmost": case "exactly": { const totalCount = `double(${field}.size())`; const filteredCount = `${field}.filter(${arrayElementAlias}, ${nestedArrayFilter}).size()`; const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=="; if (threshold > 0 && threshold < 1) return `${filteredCount} ${op} (${totalCount} * ${threshold})`; return `${filteredCount} ${op} ${threshold}`; } } } switch (operatorTL) { case "<": case "<=": case "==": case "!=": case ">": case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? require_arrayUtils.trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`}`; case "contains": case "doesnotcontain": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.contains(${valueIsField ? require_arrayUtils.trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`; case "beginswith": case "doesnotbeginwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.startsWith(${valueIsField ? require_arrayUtils.trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`; case "endswith": case "doesnotendwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.endsWith(${valueIsField ? require_arrayUtils.trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`; case "null": return `${field} == null`; case "notnull": return `${field} != null`; case "in": case "notin": { const [prefix, suffix] = shouldNegate$2(operatorTL) ? ["!(", ")"] : ["", ""]; return `${prefix}${field} in [${require_arrayUtils.toArray(value).map((val) => valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${require_arrayUtils.trimIfString(val)}` : `"${escapeDoubleQuotes(val, escapeQuotes)}"`).join(", ")}]${suffix}`; } case "between": case "notbetween": { const valueAsArray = require_arrayUtils.toArray(value); if (valueAsArray.length >= 2 && !require_isRuleGroup.nullOrUndefinedOrEmpty(valueAsArray[0]) && !require_isRuleGroup.nullOrUndefinedOrEmpty(valueAsArray[1])) { const [first, second] = valueAsArray; const shouldParseNumbers = !(parseNumbers === false); const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? require_parseNumber.parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN; const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? require_parseNumber.parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN; let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `"${escapeDoubleQuotes(first, escapeQuotes)}"` : firstNum; let secondValue = Number.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 ""; }; //#endregion //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDBQuery.ts /** * Default fallback object used by {@link formatQuery} for "mongodb_query" format. * * @group Export */ const mongoDbFallback = { $and: [{ $expr: true }] }; /** * Rule group processor used by {@link formatQuery} for "mongodb_query" format. * * @group Export */ const defaultRuleGroupProcessorMongoDBQuery = (ruleGroup, options, meta) => { const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options; const processRuleGroup = (rg, outermost) => { if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? mongoDbFallback : false; const combinator = `$${require_isRuleGroup.lc(rg.combinator)}`; let hasChildRules = false; const expressions = rg.rules.map((rule) => { if (require_isRuleGroup.isRuleGroup(rule)) { const processedRuleGroup = processRuleGroup(rule); if (processedRuleGroup) { hasChildRules = true; return processedRuleGroup; } return false; } const [validationResult, fieldValidator] = validateRule(rule); if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false; const fieldData = require_optGroupUtils.getOption(fields, rule.field); return ruleProcessor(rule, { ...options, parseNumbers: getParseNumberBoolean(fieldData?.inputType), fieldData }, meta); }).filter(Boolean); return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback; }; return processRuleGroup(require_convertQuery.convertFromIC(ruleGroup), true); }; //#endregion //#region src/utils/formatQuery/defaultRuleProcessorMongoDBQuery.ts const processNumber$1 = (value, fallback, parseNumbers = false) => shouldRenderAsNumber(value, parseNumbers || typeof value === "bigint") ? Number(require_parseNumber.parseNumber(value, { parseNumbers: "strict" })) : fallback; /** * Default rule processor used by {@link formatQuery} for "mongodb_query" format. * * @group Export */ const defaultRuleProcessorMongoDBQuery = (rule, options = {}) => { const { field, operator, value, valueSource } = rule; const { parseNumbers, preserveValueOrder, context } = options; const valueIsField = valueSource === "field"; const { avoidFieldsAsKeys } = context ?? {}; const matchEval = processMatchMode(rule); if (matchEval === false) return; else if (matchEval) { const { mode, threshold } = matchEval; const totalCount = { $size: { $ifNull: [`$${field}`, []] } }; const subQueryNoAggCtx = defaultRuleGroupProcessorMongoDBQuery(require_transformQuery.transformQuery(value, { ruleProcessor: (r) => ({ ...r, field: r.field ? `${field}.${r.field}` : field }) }), { ...options, ruleProcessor: defaultRuleProcessorMongoDBQuery, context: { ...options.context, avoidFieldsAsKeys: false } }); const subQueryWithAggCtx = defaultRuleGroupProcessorMongoDBQuery(require_transformQuery.transformQuery(value, { ruleProcessor: (r) => ({ ...r, field: r.field ? `$item.${r.field}` : "$item" }) }), { ...options, ruleProcessor: defaultRuleProcessorMongoDBQuery, context: { ...options.context, avoidFieldsAsKeys: true } }); const filteredCount = { $size: { $ifNull: [{ $filter: { input: `$${field}`, as: "item", cond: { $and: [subQueryWithAggCtx] } } }, []] } }; switch (mode) { case "all": return { $expr: { $eq: [filteredCount, totalCount] } }; case "none": return { $nor: [subQueryNoAggCtx] }; case "some": return subQueryNoAggCtx; case "atleast": case "atmost": case "exactly": { const op = mode === "atleast" ? mongoOperators[">="] : mode === "atmost" ? mongoOperators["<="] : mongoOperators["="]; if (threshold > 0 && threshold < 1) return { $expr: { [op]: [filteredCount, { $multiply: [totalCount, threshold] }] } }; return { $expr: { [op]: [filteredCount, threshold] } }; } } } if (operator === "=" && !valueIsField) return avoidFieldsAsKeys ? { $eq: [`$${field}`, processNumber$1(value, value, parseNumbers)] } : { [field]: processNumber$1(value, value, parseNumbers) }; const operatorLC = require_isRuleGroup.lc(operator); switch (operatorLC) { case "<": case "<=": case "=": case "!=": case ">": case ">=": { const mongoOperator = mongoOperators[operatorLC]; return valueIsField ? { [mongoOperator]: [`$${field}`, `$${value}`] } : avoidFieldsAsKeys ? { $and: [{ $ne: [`$${field}`, null] }, { [mongoOperator]: [`$${field}`, processNumber$1(value, value, parseNumbers)] }] } : { [field]: { [mongoOperator]: processNumber$1(value, value, parseNumbers) } }; } case "contains": return valueIsField ? { $where: `this.${field}.includes(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: { input: `$${field}`, regex: value } } : { [field]: { $regex: value } }; case "beginswith": return valueIsField ? { $where: `this.${field}.startsWith(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: { input: `$${field}`, regex: `^${value}` } } : { [field]: { $regex: `^${value}` } }; case "endswith": return valueIsField ? { $where: `this.${field}.endsWith(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: { input: `$${field}`, regex: `${value}$` } } : { [field]: { $regex: `${value}$` } }; case "doesnotcontain": return valueIsField ? { $where: `!this.${field}.includes(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: { input: `$${field}`, regex: value } } } : { [field]: { $not: { $regex: value } } }; case "doesnotbeginwith": return valueIsField ? { $where: `!this.${field}.startsWith(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: { input: `$${field}`, regex: `^${value}` } } } : { [field]: { $not: { $regex: `^${value}` } } }; case "doesnotendwith": return valueIsField ? { $where: `!this.${field}.endsWith(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: { input: `$${field}`, regex: `${value}$` } } } : { [field]: { $not: { $regex: `${value}$` } } }; case "null": return avoidFieldsAsKeys ? { $eq: [`$${field}`, null] } : { [field]: null }; case "notnull": return avoidFieldsAsKeys ? { $ne: [`$${field}`, null] } : { [field]: { $ne: null } }; case "in": case "notin": { const valueAsArray = require_arrayUtils.toArray(value); return valueIsField ? { $where: `${operatorLC === "notin" ? "!" : ""}[${valueAsArray.map((val) => `this.${val}`).join(",")}].includes(this.${field})` } : avoidFieldsAsKeys ? operatorLC === "notin" ? { $not: { [mongoOperators.in]: [`$${field}`, valueAsArray.map((val) => processNumber$1(val, val, parseNumbers))] } } : { [mongoOperators[operatorLC]]: [`$${field}`, valueAsArray.map((val) => processNumber$1(val, val, parseNumbers))] } : { [field]: { [mongoOperators[operatorLC]]: valueAsArray.map((val) => processNumber$1(val, val, parseNumbers)) } }; } case "between": case "notbetween": { const valueAsArray = require_arrayUtils.toArray(value); if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) { const [first, second] = valueAsArray; const firstNum = processNumber$1(first, NaN, true); const secondNum = processNumber$1(second, NaN, true); let firstValue = valueIsField ? first : Number.isNaN(firstNum) ? first : firstNum; let secondValue = valueIsField ? second : Number.isNaN(secondNum) ? second : secondNum; if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) { const tempNum = secondNum; secondValue = firstNum; firstValue = tempNum; } if (operatorLC === "between") return valueIsField ? { $gte: [`$${field}`, `$${firstValue}`], $lte: [`$${field}`, `$${secondValue}`] } : avoidFieldsAsKeys ? { $and: [{ $gte: [`$${field}`, firstValue] }, { $lte: [`$${field}`, secondValue] }] } : { [field]: { $gte: firstValue, $lte: secondValue } }; else return valueIsField ? { $or: [{ $lt: [`$${field}`, `$${firstValue}`] }, { $gt: [`$${field}`, `$${secondValue}`] }] } : avoidFieldsAsKeys ? { $or: [{ $lt: [`$${field}`, firstValue] }, { $gt: [`$${field}`, secondValue] }] } : { $or: [{ [field]: { $lt: firstValue } }, { [field]: { $gt: secondValue } }] }; } else return ""; } } return ""; }; //#endregion //#region src/utils/formatQuery/defaultRuleProcessorMongoDB.ts /** * Default rule processor used by {@link formatQuery} for "mongodb" format. * * Note that the "mongodb" format is deprecated in favor of the "mongodb_query" format. * * @group Export */ const defaultRuleProcessorMongoDB = (rule, options) => { const queryObj = defaultRuleProcessorMongoDBQuery(rule, options); return queryObj ? JSON.stringify(queryObj) : ""; }; //#endregion //#region src/utils/formatQuery/defaultRuleGroupProcessorSpEL.ts /** * Default rule processor used by {@link formatQuery} for "spel" format. * * @group Export */ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => { const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options; const processRuleGroup = (rg, outermost) => { if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : ""; const processedRules = []; let precedingCombinator = ""; let firstRule = true; for (const rule of rg.rules) { if (typeof rule === "string") { precedingCombinator = rule; continue; } if (require_isRuleGroup.isRuleGroup(rule)) { const processedGroup = processRuleGroup(rule); if (processedGroup) { if (!firstRule && precedingCombinator) { processedRules.push(precedingCombinator); precedingCombinator = ""; } firstRule = false; processedRules.push(processedGroup); } continue; } const [validationResult, fieldValidator] = validateRule(rule); if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) continue; const fieldData = require_optGroupUtils.getOption(fields, rule.field); const processedRule = ruleProcessor(rule, { ...options, parseNumbers: getParseNumberBoolean(fieldData?.inputType), escapeQuotes: (rule.valueSource ?? "value") === "value", fieldData }); if (processedRule) { if (!firstRule && precedingCombinator) { processedRules.push(precedingCombinator); precedingCombinator = ""; } firstRule = false; processedRules.push(processedRule); } } const expression = processedRules.join(require_isRuleGroup.isRuleGroupType(rg) ? ` ${rg.combinator} ` : " "); const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "!" : ""}(`, ")"] : ["", ""]; return expression ? `${prefix}${expression}${suffix}` : fallbackExpression; }; return processRuleGroup(ruleGroup, true); }; //#endregion //#region src/utils/formatQuery/defaultRuleProcessorSpEL.ts const shouldNegate$1 = (op) => op.startsWith("not") || op.startsWith("doesnot"); const wrapInNegation = (clause, negate$1) => negate$1 ? `!(${clause})` : clause; const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`); /** * Default rule processor used by {@link formatQuery} for "spel" format. * * @group Export */ const defaultRuleProcessorSpEL = (rule, opts = {}) => { const { field, operator, value, valueSource } = rule; const { escapeQuotes, parseNumbers, preserveValueOrder } = opts; const valueIsField = valueSource === "field"; const operatorTL = require_isRuleGroup.lc(operator === "=" ? "==" : operator); const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers); const matchEval = processMatchMode(rule); if (matchEval === false) return ""; else if (matchEval) { const { mode, threshold } = matchEval; const nestedArrayFilter = defaultRuleGroupProcessorSpEL(require_transformQuery.transformQuery(rule.value, { ruleProcessor: (r) => ({ ...r, field: r.field || "#this" }) }), opts); const totalCount = `${field}.size()`; const filteredCount = `${field}.?[${nestedArrayFilter}].size()`; switch (mode) { case "all": return `${filteredCount} == ${totalCount}`; case "none": return `${filteredCount} == 0`; case "some": return `${filteredCount} >= 1`; case "atleast": case "atmost": case "exactly": { const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=="; if (threshold > 0 && threshold < 1) return `${filteredCount} ${op} (${totalCount} * ${threshold})`; return `${filteredCount} ${op} ${threshold}`; } } } switch (operatorTL) { case "<": case "<=": case "==": case "!=": case ">": case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? require_arrayUtils.trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`; case "contains": case "doesnotcontain": return wrapInNegation(`${field} matches ${valueIsField || useBareValue ? require_arrayUtils.trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL)); case "beginswith": case "doesnotbeginwith": return wrapInNegation(`${field} matches ${valueIsField ? `'^'.concat(${require_arrayUtils.trimIfString(value)})` : `'${typeof value === "string" && !value.startsWith("^") || useBareValue ? "^" : ""}${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL)); case "endswith": case "doesnotendwith": return wrapInNegation(`${field} matches ${valueIsField ? `${require_arrayUtils.trimIfString(value)}.concat('$')` : `'${escapeSingleQuotes(value, escapeQuotes)}${typeof value === "string" && !value.endsWith("$") || useBareValue ? "$" : ""}'`}`, shouldNegate$1(operatorTL)); case "null": return `${field} == null`; case "notnull": return `${field} != null`; case "in": case "notin": { const negate$1 = shouldNegate$1(operatorTL) ? "!" : ""; const valueAsArray = require_arrayUtils.toArray(value); return valueAsArray.length > 0 ? `${negate$1}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${require_arrayUtils.trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : ""; } case "between": case "notbetween": { const valueAsArray = require_arrayUtils.toArray(value); if (valueAsArray.length >= 2 && !require_isRuleGroup.nullOrUndefinedOrEmpty(valueAsArray[0]) && !require_isRuleGroup.nullOrUndefinedOrEmpty(valueAsArray[1])) { const [first, second] = valueAsArray; const shouldParseNumbers = !(parseNumbers === false); const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? require_parseNumber.parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN; const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? require_parseNumber.parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN; let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `'${escapeSingleQuotes(first, escapeQuotes)}'` : firstNum; let secondValue = Number.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 ""; }; //#endregion //#region src/utils/formatQuery/defaultValueProcessorByRule.ts const escapeStringValueQuotes$1 = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v; /** * Default value processor used by {@link formatQuery} for "sql" format. * * @group Export */ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQuotes, parseNumbers, preserveValueOrder, quoteFieldNamesWith, quoteValuesWith, concatOperator = "||", fieldIdentifierSeparator, wrapValueWith = ["", ""], translations } = {}) => { const valueIsField = valueSource === "field"; const operatorLowerCase = require_isRuleGroup.lc(operator); const quoteChar = quoteValuesWith || "'"; const quoteValue = (v) => `${wrapValueWith[0]}${quoteChar}${v}${quoteChar}${wrapValueWith[1]}`; const escapeValue = (v) => escapeStringValueQuotes$1(v, quoteChar, escapeQuotes); const wrapAndEscape = (v) => quoteValue(escapeValue(v)); const wrapFieldName = (v) => getQuotedFieldName(v, { quoteFieldNamesWith, fieldIdentifierSeparator }); const concat = (...values) => concatOperator.toUpperCase() === "CONCAT" ? `CONCAT(${values.join(", ")})` : values.join(` ${concatOperator} `); switch (operatorLowerCase) { case "null": case "notnull": return ""; case "in": case "notin": { const valueAsArray = require_arrayUtils.toArray(value); if (valueAsArray.length > 0) return `(${valueAsArray.map((v) => valueIsField ? wrapFieldName(v) : shouldRenderAsNumber(v, parseNumbers) ? `${require_arrayUtils.trimIfString(v)}` : `${wrapAndEscape(v)}`).join(", ")})`; return ""; } case "between": case "notbetween": { const valueAsArray = require_arrayUtils.toArray(value, { retainEmptyStrings: true }); if (valueAsArray.length < 2 || !isValidValue(valueAsArray[0]) || !isValidValue(valueAsArray[1])) return ""; const [first, second] = valueAsArray; const firstNum = shouldRenderAsNumber(first, parseNumbers) ? require_parseNumber.parseNumber(first, { parseNumbers: "strict" }) : NaN; const secondNum = shouldRenderAsNumber(second, parseNumbers) ? require_parseNumber.parseNumber(second, { parseNumbers: "strict" }) : NaN; const firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : first : firstNum; const secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : second : secondNum; const valsOneAndTwoOnly = [firstValue, secondValue]; if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) { valsOneAndTwoOnly[0] = secondNum; valsOneAndTwoOnly[1] = firstNum; } return (valueIsField ? valsOneAndTwoOnly.map((v) => wrapFieldName(v)) : valsOneAndTwoOnly.every((v) => shouldRenderAsNumber(v, parseNumbers)) ? valsOneAndTwoOnly.map((v) => require_parseNumber.parseNumber(v, { parseNumbers: "strict" })) : valsOneAndTwoOnly.map((v) => wrapAndEscape(v))).join(` ${translations?.and ?? "and"} `); } case "contains": case "doesnotcontain": return valueIsField ? concat(quoteValue("%"), wrapFieldName(value), quoteValue("%")) : quoteValue(`%${escapeValue(value)}%`); case "beginswith": case "doesnotbeginwith": return valueIsField ? concat(wrapFieldName(value), quoteValue("%")) : quoteValue(`${escapeValue(value)}%`); case "endswith": case "doesnotendwith": return valueIsField ? concat(quoteValue("%"), wrapFieldName(value)) : quoteValue(`%${escapeValue(value)}`); } if (typeof value === "boolean") return value ? "TRUE" : "FALSE"; return valueIsField ? wrapFieldName(value) : shouldRenderAsNumber(value, parseNumbers) ? `${require_arrayUtils.trimIfString(value)}` : `${wrapAndEscape(value)}`; }; //#endregion //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts /** * Default rule processor used by {@link formatQuery} for the "drizzle" format. * * @group Export */ const defaultRuleProcessorDrizzle = (rule, _options) => { const opts = _options ?? ( /* istanbul ignore next */ {}); // istanbul ignore next const { parseNumbers, preserveValueOrder, context = {} } = opts; const { columns, drizzleOperators, useRawFields } = context; if (!columns || !drizzleOperators) return; const { between, eq, gt, gte, inArray, isNotNull, isNull, like, lt, lte, ne, notBetween, notInArray, notLike, sql } = drizzleOperators; const { field, operator, value, valueSource } = rule; const column = useRawFields && /[a-z][a-z0-9]*/i.test(field) ? sql.raw(field) : columns[field]; const operatorLC = require_isRuleGroup.lc(operator); const valueIsField = valueSource === "field"; const asFieldOrValue = (v) => valueIsField ? columns[v] : v; if (!column) return; const matchEval = processMatchMode(rule); if (matchEval === false) return; else if (matchEval) { if (opts.preset !== "postgresql") return; const { mode, threshold } = matchEval; const arrayElementAlias = "elem_alias"; const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(require_transformQuery.transformQuery(rule.value, { ruleProcessor: (r) => ({ ...r, field: arrayElementAlias }) }), { ...opts, context: { ...opts.context, useRawFields: true } }); switch (mode) { case "all": return sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) = array_length(${column}, 1)`; case "none": return sql`not exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`; case "some": return sql`exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`; case "atleast": case "atmost": case "exactly": { const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "="; return threshold > 0 && threshold < 1 ? sql`(select count(*) / array_length(${column}, 1) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}` : sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}`; } } } switch (operatorLC) { case "=": return eq(column, asFieldOrValue(value)); case "!=": return ne(column, asFieldOrValue(value)); case ">": return gt(column, asFieldOrValue(value)); case "<": return lt(column, asFieldOrValue(value)); case ">=": return gte(column, asFieldOrValue(value)); case "<=": return lte(column, asFieldOrValue(value)); case "beginswith": case "doesnotbeginwith": return (operatorLC === "doesnotbeginwith" ? notLike : like)(column, valueIsField ? sql`${asFieldOrValue(value)} || '%'` : `${value}%`); case "contains": case "doesnotcontain": return (operatorLC === "doesnotcontain" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)} || '%'` : `%${value}%`); case "endswith": case "doesnotendwith": return (operatorLC === "doesnotendwith" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)}` : `%${value}`); case "null": return isNull(column); case "notnull": return isNotNull(column); case "in": case "notin": { const valueAsArray = require_arrayUtils.toArray(value).map((v) => asFieldOrValue(v)); return operatorLC === "notin" ? notInArray(column, valueAsArray) : inArray(column, valueAsArray); } case "between": case "notbetween": { const valueAsArray = require_arrayUtils.toArray(value); if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) { let [first, second] = valueAsArray; const shouldParseNumbers = !(parseNumbers === false); if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) { const firstNum = require_parseNumber.parseNumber(first, { parseNumbers: shouldParseNumbers }); const secondNum = require_parseNumber.parseNumber(second, { parseNumbers: shouldParseNumbers }); if (!preserveValueOrder && secondNum < firstNum) { const tempNum = secondNum; second = firstNum; first = tempNum; } else { first = firstNum; second = secondNum; } } else if (valueIsField) { first = asFieldOrValue(first); second = asFieldOrValue(second); } return operatorLC === "notbetween" ? notBetween(column, first, second) : between(column, first, second); } return; } default: return; } }; //#endregion //#region src/utils/formatQuery/defaultRuleGroupProcessorDrizzle.ts /** * Default rule group processor used by {@link formatQuery} for the "drizzle" format. The returned * function can be assigned to the `where` property in the Drizzle relational queries API. * * @example * const where = formatQuery(query, 'drizzle'); * const results = db.query.users.findMany({ where }); * * @returns Function that takes a Drizzle table config and an object of Drizzle operators. * * @group Export */ const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns, drizzleOperators) => { const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap } = options; if (!columns || !drizzleOperators) return; const { and, not, or } = drizzleOperators; const ruleProcessor = defaultRuleProcessorDrizzle; const processRuleGroup = (rg, _outermost) => { if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return; const processedRules = rg.rules.map((rule) => { if (require_isRuleGroup.isRuleGroup(rule)) return processRuleGroup(rule); const [validationResult, fieldValidator] = validateRule(rule); if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return; const fieldData = require_optGroupUtils.getOption(fields, rule.field); return ruleProcessor(rule, { ...options, parseNumbers: getParseNumberBoolean(fieldData?.inputType), fieldData, context: { ...options.context, columns, drizzleOperators } }); }).filter(Boolean); if (processedRules.length === 0) return; const ruleGroupSQL = rg.combinator === "or" ? or(...processedRules) : and(...processedRules); return rg.not ? not(ruleGroupSQL) : ruleGroupSQL; }; return processRuleGroup(require_convertQuery.convertFromIC(ruleGroup), true); }; //#endregion //#region src/utils/formatQuery/defaultRuleGroupProcessorElasticSearch.ts /** * Rule group processor used by {@link formatQuery} for "elasticsearch" format. * * @group Export */ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => { const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options; const processRuleGroup = (rg) => { if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return false; const processedRules = rg.rules.map((rule) => { if (require_isRuleGroup.isRuleGroup(rule)) return processRuleGroup(rule); const [validationResult, fieldValidator] = validateRule(rule); if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false; const fieldData = require_optGroupUtils.getOption(fields, rule.field); return ruleProcessor(rule, { ...options, parseNumbers: getParseNumberBoolean(fieldData?.inputType), fieldData }); }).filter(Boolean); if (processedRules.length === 0) return false; return { bool: rg.not ? { must_not: /^or$/i.test(rg.combinator) ? { bool: { should: processedRules } } : processedRules } : { [/^or$/i.test(rg.combinator) ? "should" : "must"]: processedRules } }; }; const processedRuleGroup = processRuleGroup(require_convertQuery.convertFromIC(ruleGroup)); return processedRuleGroup === false ? {} : processedRuleGroup; }; //#endregion //#region src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts /** * Rule group processor used by {@link formatQuery} for "jsonata" format. * * @group Export */ const defaultRuleGroupProcessorJSONata = (ruleGroup, options) => { const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options; const processRuleGroup = (rg, outermost) => { if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : ""; const processedRules = []; let precedingCombinator = ""; let firstRule = true; for (const rule of rg.rules) { if (typeof rule === "string") { precedingCombinator = rule; continue; } if (require_isRuleGroup.isRuleGroup(rule)) { const processedGroup = processRuleGroup(rule); if (processedGroup) { if (!firstRule && precedingCombinator) { processedRules.push(precedingCombinator); precedingCombinator = ""; } firstRule = false; processedRules.push(processedGroup); } continue; } const [validationResult, fieldValidator] = validateRule(rule); if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) continue; const fieldData = require_optGroupUtils.getOption(fields, rule.field); const processedRule = ruleProcessor(rule, { ...options, parseNumbers: getParseNumberBoolean(fieldData?.inputType), escapeQuotes: (rule.valueSource ?? "value") === "value", fieldData }); if (processedRule) { if (!firstRule && precedingCombinator) { processedRules.push(precedingCombinator); precedingCombinator = ""; } firstRule = false; processedRules.push(processedRule); } } const expression = processedRules.join(require_isRuleGroup.isRuleGroupType(rg) ? ` ${rg.combinator} ` : " "); const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "$not" : ""}(`, ")"] : ["", ""]; return expression ? `${prefix}${expression}${suffix}` : fallbackExpression; }; return processRuleGroup(ruleGroup, true); }; //#endregion //#region src/utils/formatQuery/defaultRuleGroupProcessorJsonLogic.ts /** * Rule group processor used by {@link formatQuery} for "jsonlogic" format. * * @group Export */ const defaultRuleGroupProcessorJsonLogic = (ruleGroup, options) => { const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options; const query = require_convertQuery.convertFromIC(ruleGroup); const processRuleGroup = (rg, _outermost) => { if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return false; const processedRules = rg.rules.map((rule) => { if (require_isRuleGroup.isRuleGroup(rule)) return processRuleGroup(rule); const [validationResult, fieldValidator] = validateRule(rule); if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false; const fieldData = require_optGroupUtils.getOption(fields, rule.field); return ruleProcessor(rule, { ...options, parseNumbers: getParseNumberBoolean(fieldData?.inputType), fieldData }); }).filter(Boolean); if (processedRules.length === 0) return false; const jsonRuleGroup = { [rg.combinator]: processedRules }; return rg.not ? { "!": jsonRuleGroup } : jsonRuleGroup; }; return processRuleGroup(query, true); }; //#endregion //#region src/utils/formatQuery/defaultRuleGroupProcessorLDAP.ts /** * Rule group processor used by {@link formatQuery} for "ldap" format. * * @group Export */ const defaultRuleGroupProcessorLDAP = (ruleGroup, options) => { const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options; const processRuleGroup = (rg, outermost) => { if (!isRuleOrGroupValid(