react-querybuilder
Advanced tools
Comparing version 7.0.0-alpha.1 to 7.0.0-alpha.2
@@ -1,3 +0,3 @@ | ||
import { R as RuleProcessor, V as ValueProcessorByRule, a as ValueProcessorOptions, F as FormatQueryOptions, P as ParameterizedSQL, b as ParameterizedNamedSQL, c as RQBJsonLogic, E as ExportFormat, d as ValueProcessorLegacy } from './importExport-a9d37060.js'; | ||
import { R as RuleType, a as RuleGroupTypeAny } from './basic-6d3f4384.js'; | ||
import { R as RuleProcessor, V as ValueProcessorByRule, a as ValueProcessorOptions, F as FormatQueryOptions, P as ParameterizedSQL, b as ParameterizedNamedSQL, c as RQBJsonLogic, E as ExportFormat, d as ValueProcessorLegacy } from './importExport-d9a9bdde.js'; | ||
import { R as RuleType, a as RuleGroupTypeAny } from './basic-57f4a0e5.js'; | ||
@@ -61,2 +61,12 @@ /** | ||
/** | ||
* Generates an ElasticSearch query object from an RQB query object. | ||
* | ||
* NOTE: Support for the ElasticSearch format is experimental. | ||
* You may have better results exporting "sql" format then using | ||
* [ElasticSearch SQL](https://www.elastic.co/guide/en/elasticsearch/reference/current/xpack-sql.html). | ||
*/ | ||
declare function formatQuery(ruleGroup: RuleGroupTypeAny, options: 'elasticsearch' | (Omit<FormatQueryOptions, 'format'> & { | ||
format: 'elasticsearch'; | ||
})): Record<string, any>; | ||
/** | ||
* Generates a formatted (indented two spaces) JSON string from a query object. | ||
@@ -68,3 +78,3 @@ */ | ||
*/ | ||
declare function formatQuery(ruleGroup: RuleGroupTypeAny, options: Exclude<ExportFormat, 'parameterized' | 'parameterized_named' | 'jsonlogic'>): string; | ||
declare function formatQuery(ruleGroup: RuleGroupTypeAny, options: Exclude<ExportFormat, 'parameterized' | 'parameterized_named' | 'jsonlogic' | 'elasticsearch'>): string; | ||
/** | ||
@@ -74,3 +84,3 @@ * Generates a query string in the requested format. | ||
declare function formatQuery(ruleGroup: RuleGroupTypeAny, options: Omit<FormatQueryOptions, 'format'> & { | ||
format: Exclude<ExportFormat, 'parameterized' | 'parameterized_named' | 'jsonlogic'>; | ||
format: Exclude<ExportFormat, 'parameterized' | 'parameterized_named' | 'jsonlogic' | 'elasticsearch'>; | ||
}): string; | ||
@@ -77,0 +87,0 @@ |
@@ -47,8 +47,8 @@ "use strict"; | ||
var defaultCombinators = [ | ||
{ name: "and", label: "AND" }, | ||
{ name: "or", label: "OR" } | ||
{ name: "and", value: "and", label: "AND" }, | ||
{ name: "or", value: "or", label: "OR" } | ||
]; | ||
var defaultCombinatorsExtended = [ | ||
...defaultCombinators, | ||
{ name: "xor", label: "XOR" } | ||
{ name: "xor", value: "xor", label: "XOR" } | ||
]; | ||
@@ -70,6 +70,2 @@ | ||
// src/utils/isRuleGroup.ts | ||
var isRuleGroup = (rg) => !!rg && typeof rg === "object" && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroupType = (rg) => isRuleGroup(rg) && !!rg.combinator; | ||
// src/utils/misc.ts | ||
@@ -79,2 +75,6 @@ var numericRegex = /^\s*[+-]?(\d+|\d*\.\d+|\d+\.\d*)([Ee][+-]?\d+)?\s*$/; | ||
// src/utils/isRuleGroup.ts | ||
var isRuleGroup = (rg) => isPojo(rg) && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "string"; | ||
// src/utils/parseNumber.ts | ||
@@ -597,15 +597,199 @@ var parseNumber = (v, { parseNumbers }) => { | ||
// src/utils/toFullOption.ts | ||
var import_immer = require("immer"); | ||
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) { | ||
const recipe = (0, import_immer.produce)((draft) => { | ||
if (isOptionWithName(draft) && !isOptionWithValue(draft)) { | ||
draft.value = draft.name; | ||
} else if (!isOptionWithName(draft) && isOptionWithValue(draft)) { | ||
draft.name = draft.value; | ||
} | ||
}); | ||
return recipe(opt); | ||
} | ||
function toFullOptionList(optList) { | ||
if (!Array.isArray(optList)) { | ||
return []; | ||
} | ||
const recipe = (0, import_immer.produce)((draft) => { | ||
if (isFlexibleOptionGroupArray(draft)) { | ||
for (const optGroup of draft) { | ||
optGroup.options.forEach((opt, idx) => optGroup.options[idx] = toFullOption(opt)); | ||
} | ||
} else { | ||
draft.forEach((opt, idx) => draft[idx] = toFullOption(opt)); | ||
} | ||
}); | ||
return recipe(optList); | ||
} | ||
// src/utils/uniq.ts | ||
var uniqByName = (originalArray) => { | ||
var uniqByIdentifier = (originalArray) => { | ||
const names = /* @__PURE__ */ new Set(); | ||
const newArray = []; | ||
originalArray.forEach((el) => { | ||
if (!names.has(el.name)) { | ||
names.add(el.name); | ||
if (!names.has(el.value ?? el.name)) { | ||
names.add(el.value ?? el.name); | ||
newArray.push(el); | ||
} | ||
}); | ||
return newArray; | ||
return originalArray.length === newArray.length ? originalArray : newArray; | ||
}; | ||
// src/utils/optGroupUtils.ts | ||
var isOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0]; | ||
var isFlexibleOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0] && (isPojo(arr[0].options[0]) && "name" in arr[0].options[0] || isPojo(arr[0].options[0]) && "value" in arr[0].options[0]); | ||
var getOption = (arr, name) => (isOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr).find((op) => op.name === name); | ||
var toFlatOptionArray = (arr) => uniqByIdentifier(isFlexibleOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr); | ||
// src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts | ||
var rangeOperatorMap = { "<": "lt", "<=": "lte", ">": "gt", ">=": "gte" }; | ||
var negateIfNotOp2 = (op, elasticSearchRule) => /^(does)?not/i.test(op) ? { bool: { must_not: elasticSearchRule } } : elasticSearchRule; | ||
var escapeSQ = (s) => s?.replace(/('|\\)/g, `\\$1`); | ||
var textFunctionMap = { | ||
beginsWith: "startsWith", | ||
doesNotContain: "contains", | ||
doesNotBeginWith: "startsWith", | ||
doesNotEndWith: "endsWith" | ||
}; | ||
var getTextScript = (f, o, v) => { | ||
const script = `doc['${f}'].${textFunctionMap[o] ?? o}(doc['${v}'])`; | ||
return o.startsWith("d") ? `!${script}` : script; | ||
}; | ||
var defaultRuleProcessorElasticSearch = ({ field, operator, value, valueSource }, { parseNumbers } = {}) => { | ||
if (valueSource === "field") { | ||
if (toArray(value).some((v) => typeof v !== "string")) | ||
return false; | ||
const fieldForScript = escapeSQ(field); | ||
switch (operator) { | ||
case "=": | ||
case "!=": | ||
case ">": | ||
case ">=": | ||
case "<": | ||
case "<=": { | ||
const operatorForScript = operator === "=" ? "==" : operator; | ||
const valueForScript = escapeSQ(value); | ||
return !valueForScript ? false : { | ||
bool: { | ||
filter: { | ||
script: { | ||
script: `doc['${fieldForScript}'] ${operatorForScript} doc['${valueForScript}']` | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
case "in": | ||
case "notIn": { | ||
const valueAsArray = toArray(value); | ||
if (valueAsArray.length > 0) { | ||
const arr = valueAsArray.map((v) => ({ | ||
bool: { filter: { script: { script: `doc['${fieldForScript}'] == doc['${v}']` } } } | ||
})); | ||
return { bool: operator === "in" ? { should: arr } : { must_not: arr } }; | ||
} | ||
return false; | ||
} | ||
case "between": | ||
case "notBetween": { | ||
const valueAsArray = toArray(value); | ||
if (valueAsArray.length >= 2 && valueAsArray[0] && valueAsArray[1]) { | ||
const script = `doc['${fieldForScript}'] >= doc['${valueAsArray[0]}'] && doc['${fieldForScript}'] <= doc['${valueAsArray[1]}']`; | ||
return { | ||
bool: { | ||
filter: { script: { script: operator === "notBetween" ? `!(${script})` : script } } | ||
} | ||
}; | ||
} | ||
return false; | ||
} | ||
case "contains": | ||
case "doesNotContain": | ||
case "beginsWith": | ||
case "doesNotBeginWith": | ||
case "endsWith": | ||
case "doesNotEndWith": { | ||
const valueForScript = escapeSQ(value); | ||
if (!valueForScript) | ||
return false; | ||
const script = getTextScript(fieldForScript, operator, valueForScript); | ||
return { | ||
bool: { | ||
filter: { | ||
script: { | ||
script | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
} | ||
} | ||
const valueRenderer = (v) => typeof value === "boolean" ? value : shouldRenderAsNumber(v, parseNumbers) ? parseFloat(v) : v; | ||
switch (operator) { | ||
case "<": | ||
case "<=": | ||
case ">": | ||
case ">=": | ||
return { | ||
range: { | ||
[field]: { | ||
[rangeOperatorMap[operator]]: valueRenderer(value) | ||
} | ||
} | ||
}; | ||
case "=": | ||
return { term: { [field]: valueRenderer(value) } }; | ||
case "!=": | ||
return { bool: { must_not: { term: { [field]: valueRenderer(value) } } } }; | ||
case "null": | ||
return { bool: { must_not: { exists: { field } } } }; | ||
case "notNull": | ||
return { exists: { field } }; | ||
case "in": | ||
case "notIn": { | ||
const valueAsArray = toArray(value).map(valueRenderer); | ||
if (valueAsArray.length > 0) { | ||
const arr = valueAsArray.map((v) => ({ term: { [field]: valueRenderer(v) } })); | ||
return { bool: operator === "in" ? { should: arr } : { must_not: arr } }; | ||
} | ||
return false; | ||
} | ||
case "between": | ||
case "notBetween": { | ||
const valueAsArray = toArray(value); | ||
if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) { | ||
let [first, second] = valueAsArray; | ||
if (shouldRenderAsNumber(first, true) && shouldRenderAsNumber(second, true)) { | ||
const firstNum = parseFloat(first); | ||
const secondNum = parseFloat(second); | ||
if (secondNum < firstNum) { | ||
const tempNum = secondNum; | ||
second = firstNum; | ||
first = tempNum; | ||
} else { | ||
first = firstNum; | ||
second = secondNum; | ||
} | ||
} | ||
return negateIfNotOp2(operator, { range: { [field]: { gte: first, lte: second } } }); | ||
} | ||
return false; | ||
} | ||
case "contains": | ||
case "doesNotContain": | ||
return negateIfNotOp2(operator, { regexp: { [field]: { value } } }); | ||
case "beginsWith": | ||
case "doesNotBeginWith": | ||
return negateIfNotOp2(operator, { regexp: { [field]: { value: `^${value}` } } }); | ||
case "endsWith": | ||
case "doesNotEndWith": | ||
return negateIfNotOp2(operator, { regexp: { [field]: { value: `${value}$` } } }); | ||
} | ||
return false; | ||
}; | ||
// src/utils/formatQuery/formatQuery.ts | ||
@@ -636,2 +820,4 @@ function formatQuery(ruleGroup, options = {}) { | ||
ruleProcessorInternal = defaultRuleProcessorJsonLogic; | ||
} else if (format === "elasticsearch") { | ||
ruleProcessorInternal = defaultRuleProcessorElasticSearch; | ||
} | ||
@@ -644,6 +830,6 @@ } else { | ||
} | ||
valueProcessorInternal = typeof valueProcessor === "function" ? (r, opts) => isValueProcessorLegacy(valueProcessor) ? valueProcessor(r.field, r.operator, r.value, r.valueSource) : valueProcessor(r, opts) : format === "mongodb" ? ruleProcessorInternal ?? defaultRuleProcessorMongoDB : format === "cel" ? ruleProcessorInternal ?? defaultRuleProcessorCEL : format === "spel" ? ruleProcessorInternal ?? defaultRuleProcessorSpEL : format === "jsonlogic" ? ruleProcessorInternal ?? defaultRuleProcessorJsonLogic : defaultValueProcessorByRule; | ||
valueProcessorInternal = typeof valueProcessor === "function" ? (r, opts) => isValueProcessorLegacy(valueProcessor) ? valueProcessor(r.field, r.operator, r.value, r.valueSource) : valueProcessor(r, opts) : format === "mongodb" ? ruleProcessorInternal ?? defaultRuleProcessorMongoDB : format === "cel" ? ruleProcessorInternal ?? defaultRuleProcessorCEL : format === "spel" ? ruleProcessorInternal ?? defaultRuleProcessorSpEL : format === "jsonlogic" ? ruleProcessorInternal ?? defaultRuleProcessorJsonLogic : format == "elasticsearch" ? ruleProcessorInternal ?? defaultRuleProcessorElasticSearch : defaultValueProcessorByRule; | ||
quoteFieldNamesWith = quoteFieldNamesWithArray(options.quoteFieldNamesWith); | ||
validator = options.validator ?? (() => true); | ||
fields = options.fields ?? []; | ||
fields = toFullOptionList(options.fields ?? []); | ||
fallbackExpression = options.fallbackExpression ?? ""; | ||
@@ -678,3 +864,3 @@ paramPrefix = options.paramPrefix ?? ":"; | ||
if (validationResult === false) { | ||
return format === "parameterized" ? { sql: fallbackExpression, params: [] } : format === "parameterized_named" ? { sql: fallbackExpression, params: {} } : format === "mongodb" ? `{${fallbackExpression}}` : format === "jsonlogic" ? false : fallbackExpression; | ||
return format === "parameterized" ? { sql: fallbackExpression, params: [] } : format === "parameterized_named" ? { sql: fallbackExpression, params: {} } : format === "mongodb" ? `{${fallbackExpression}}` : format === "jsonlogic" ? false : format === "elasticsearch" ? {} : fallbackExpression; | ||
} | ||
@@ -686,6 +872,7 @@ } else { | ||
const validatorMap = {}; | ||
const uniqueFields = uniqByName(fields); | ||
const uniqueFields = toFlatOptionArray(fields); | ||
uniqueFields.forEach((f) => { | ||
if (typeof f.validator === "function") { | ||
validatorMap[f.name] = f.validator; | ||
validatorMap[f.value ?? /* istanbul ignore next */ | ||
f.name] = f.validator; | ||
} | ||
@@ -699,4 +886,4 @@ }); | ||
} | ||
if (fields.length) { | ||
const fieldArr = fields.filter((f) => f.name === rule.field); | ||
if (uniqueFields.length) { | ||
const fieldArr = uniqueFields.filter((f) => f.name === rule.field); | ||
if (fieldArr.length) { | ||
@@ -729,4 +916,10 @@ const field = fieldArr[0]; | ||
const escapeQuotes = (rule.valueSource ?? "value") === "value"; | ||
const fieldData = getOption(fields, rule.field); | ||
if (typeof ruleProcessorInternal === "function") { | ||
return ruleProcessorInternal(rule, { parseNumbers, escapeQuotes, quoteFieldNamesWith }); | ||
return ruleProcessorInternal(rule, { | ||
parseNumbers, | ||
escapeQuotes, | ||
quoteFieldNamesWith, | ||
fieldData | ||
}); | ||
} | ||
@@ -737,3 +930,4 @@ return defaultRuleProcessorSQL(rule, { | ||
valueProcessor: valueProcessorInternal, | ||
quoteFieldNamesWith | ||
quoteFieldNamesWith, | ||
fieldData | ||
}); | ||
@@ -762,3 +956,4 @@ }); | ||
} | ||
const value = valueProcessorInternal(rule, { parseNumbers, quoteFieldNamesWith }); | ||
const fieldData = getOption(fields, rule.field); | ||
const value = valueProcessorInternal(rule, { parseNumbers, quoteFieldNamesWith, fieldData }); | ||
const operator = mapSQLOperator(rule.operator); | ||
@@ -877,3 +1072,7 @@ if ((rule.valueSource ?? "value") === "value") { | ||
} | ||
return (ruleProcessorInternal ?? valueProcessorInternal)(rule, { parseNumbers }); | ||
const fieldData = getOption(fields, rule.field); | ||
return (ruleProcessorInternal ?? valueProcessorInternal)(rule, { | ||
parseNumbers, | ||
fieldData | ||
}); | ||
}).filter(Boolean); | ||
@@ -903,5 +1102,7 @@ return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression; | ||
} | ||
const fieldData = getOption(fields, rule.field); | ||
return (ruleProcessorInternal ?? valueProcessorInternal)(rule, { | ||
parseNumbers, | ||
escapeQuotes: (rule.valueSource ?? "value") === "value" | ||
escapeQuotes: (rule.valueSource ?? "value") === "value", | ||
fieldData | ||
}); | ||
@@ -933,5 +1134,7 @@ }).filter(Boolean).join( | ||
} | ||
const fieldData = getOption(fields, rule.field); | ||
return (ruleProcessorInternal ?? valueProcessorInternal)(rule, { | ||
parseNumbers, | ||
escapeQuotes: (rule.valueSource ?? "value") === "value" | ||
escapeQuotes: (rule.valueSource ?? "value") === "value", | ||
fieldData | ||
}); | ||
@@ -959,3 +1162,7 @@ }).filter(Boolean).join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " "); | ||
} | ||
return (ruleProcessorInternal ?? valueProcessorInternal)(rule, { parseNumbers }); | ||
const fieldData = getOption(fields, rule.field); | ||
return (ruleProcessorInternal ?? valueProcessorInternal)(rule, { | ||
parseNumbers, | ||
fieldData | ||
}); | ||
}).filter(Boolean); | ||
@@ -972,2 +1179,35 @@ if (processedRules.length === 0) { | ||
} | ||
if (format === "elasticsearch") { | ||
const query = isRuleGroupType(ruleGroup) ? ruleGroup : convertFromIC(ruleGroup); | ||
const processRuleGroup = (rg) => { | ||
if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? /* istanbul ignore next */ | ||
""])) { | ||
return false; | ||
} | ||
const processedRules = rg.rules.map((rule) => { | ||
if (isRuleGroup(rule)) { | ||
return processRuleGroup(rule); | ||
} | ||
const [validationResult, fieldValidator] = validateRule(rule); | ||
if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName) { | ||
return false; | ||
} | ||
const fieldData = getOption(fields, rule.field); | ||
return (ruleProcessorInternal ?? valueProcessorInternal)(rule, { | ||
parseNumbers, | ||
fieldData | ||
}); | ||
}).filter(Boolean); | ||
if (processedRules.length === 0) { | ||
return false; | ||
} | ||
return { | ||
bool: rg.not ? { | ||
must_not: rg.combinator === "or" ? { bool: { should: processedRules } } : processedRules | ||
} : { [rg.combinator === "or" ? "should" : "must"]: processedRules } | ||
}; | ||
}; | ||
const processedRuleGroup = processRuleGroup(query); | ||
return processedRuleGroup === false ? {} : processedRuleGroup; | ||
} | ||
return ""; | ||
@@ -974,0 +1214,0 @@ } |
@@ -1,3 +0,3 @@ | ||
import { D as DefaultRuleGroupType, b as DefaultRuleGroupTypeIC } from './basic-6d3f4384.js'; | ||
import { e as ParseCELOptions } from './importExport-a9d37060.js'; | ||
import { D as DefaultRuleGroupType, b as DefaultRuleGroupTypeIC } from './basic-57f4a0e5.js'; | ||
import { e as ParseCELOptions } from './importExport-d9a9bdde.js'; | ||
@@ -4,0 +4,0 @@ /** |
@@ -27,7 +27,39 @@ "use strict"; | ||
// src/utils/misc.ts | ||
var isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype; | ||
// src/utils/isRuleGroup.ts | ||
var isRuleGroup = (rg) => !!rg && typeof rg === "object" && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroup = (rg) => isPojo(rg) && "rules" in rg && Array.isArray(rg.rules); | ||
// src/utils/toFullOption.ts | ||
var import_immer = require("immer"); | ||
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) { | ||
const recipe = (0, import_immer.produce)((draft) => { | ||
if (isOptionWithName(draft) && !isOptionWithValue(draft)) { | ||
draft.value = draft.name; | ||
} else if (!isOptionWithName(draft) && isOptionWithValue(draft)) { | ||
draft.name = draft.value; | ||
} | ||
}); | ||
return recipe(opt); | ||
} | ||
// src/utils/uniq.ts | ||
var uniqByIdentifier = (originalArray) => { | ||
const names = /* @__PURE__ */ new Set(); | ||
const newArray = []; | ||
originalArray.forEach((el) => { | ||
if (!names.has(el.value ?? el.name)) { | ||
names.add(el.value ?? el.name); | ||
newArray.push(el); | ||
} | ||
}); | ||
return originalArray.length === newArray.length ? originalArray : newArray; | ||
}; | ||
// src/utils/optGroupUtils.ts | ||
var isOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && "options" in arr[0]; | ||
var isFlexibleOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0] && (isPojo(arr[0].options[0]) && "name" in arr[0].options[0] || isPojo(arr[0].options[0]) && "value" in arr[0].options[0]); | ||
var toFlatOptionArray = (arr) => uniqByIdentifier(isFlexibleOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr); | ||
@@ -37,10 +69,10 @@ // src/utils/filterFieldsByComparator.ts | ||
if (!field.comparator) { | ||
const filterOutSameName = (f) => f.name !== field.name; | ||
if (isOptionGroupArray(fields)) { | ||
const filterOutSameField = (f) => (f.value ?? f.name) !== (field.value ?? field.name); | ||
if (isFlexibleOptionGroupArray(fields)) { | ||
return fields.map((og) => ({ | ||
...og, | ||
options: og.options.filter(filterOutSameName) | ||
options: og.options.filter(filterOutSameField) | ||
})); | ||
} | ||
return fields.filter(filterOutSameName); | ||
return fields.filter(filterOutSameField); | ||
} | ||
@@ -56,3 +88,3 @@ const filterByComparator = (fieldToCompare) => { | ||
}; | ||
if (isOptionGroupArray(fields)) { | ||
if (isFlexibleOptionGroupArray(fields)) { | ||
return fields.map((og) => ({ ...og, options: og.options.filter(filterByComparator) })).filter((og) => og.options.length > 0); | ||
@@ -65,5 +97,13 @@ } | ||
var defaultValueSourcesArray = ["value"]; | ||
var dummyFD = { | ||
name: "name", | ||
value: "name", | ||
valueSources: null, | ||
label: "label" | ||
}; | ||
var getValueSourcesUtil = (fieldData, operator, getValueSources) => { | ||
const fd = fieldData ?? /* istanbul ignore else */ | ||
{}; | ||
const fd = fieldData ? toFullOption(fieldData) : ( | ||
/* istanbul ignore else */ | ||
dummyFD | ||
); | ||
if (fd.valueSources) { | ||
@@ -76,3 +116,5 @@ if (typeof fd.valueSources === "function") { | ||
if (getValueSources) { | ||
const vals = getValueSources(fd.name, operator, { fieldData: fd }); | ||
const vals = getValueSources(fd.value, operator, { | ||
fieldData: toFullOption(fd) | ||
}); | ||
if (vals) | ||
@@ -84,25 +126,6 @@ return vals; | ||
// src/utils/uniq.ts | ||
var uniqByName = (originalArray) => { | ||
const names = /* @__PURE__ */ new Set(); | ||
const newArray = []; | ||
originalArray.forEach((el) => { | ||
if (!names.has(el.name)) { | ||
names.add(el.name); | ||
newArray.push(el); | ||
} | ||
}); | ||
return newArray; | ||
}; | ||
// src/utils/parserUtils.ts | ||
var getFieldsArray = (fields) => { | ||
let fieldsFlat = []; | ||
const fieldsArray = !fields ? [] : Array.isArray(fields) ? fields : Object.keys(fields).map((fld) => ({ ...fields[fld], name: fld })).sort((a, b) => a.label.localeCompare(b.label)); | ||
if (isOptionGroupArray(fieldsArray)) { | ||
fieldsFlat = uniqByName(fieldsFlat.concat(...fieldsArray.map((opt) => opt.options))); | ||
} else { | ||
fieldsFlat = uniqByName(fieldsArray); | ||
} | ||
return fieldsFlat; | ||
return toFlatOptionArray(fieldsArray); | ||
}; | ||
@@ -119,3 +142,3 @@ function fieldIsValidUtil({ | ||
let valid = false; | ||
const primaryField = fieldsFlat.find((ff) => ff.name === fieldName); | ||
const primaryField = toFullOption(fieldsFlat.find((ff) => ff.name === fieldName)); | ||
if (primaryField) { | ||
@@ -122,0 +145,0 @@ if (!subordinateFieldName && operator !== "notNull" && operator !== "null" && !getValueSourcesUtil(primaryField, operator, getValueSources).some((vs) => vs === "value")) { |
@@ -1,3 +0,3 @@ | ||
import { D as DefaultRuleGroupType, b as DefaultRuleGroupTypeIC } from './basic-6d3f4384.js'; | ||
import { c as RQBJsonLogic, f as ParseJsonLogicOptions } from './importExport-a9d37060.js'; | ||
import { D as DefaultRuleGroupType, b as DefaultRuleGroupTypeIC } from './basic-57f4a0e5.js'; | ||
import { c as RQBJsonLogic, f as ParseJsonLogicOptions } from './importExport-d9a9bdde.js'; | ||
@@ -4,0 +4,0 @@ /** |
@@ -49,13 +49,16 @@ "use strict"; | ||
var defaultCombinators = [ | ||
{ name: "and", label: "AND" }, | ||
{ name: "or", label: "OR" } | ||
{ name: "and", value: "and", label: "AND" }, | ||
{ name: "or", value: "or", label: "OR" } | ||
]; | ||
var defaultCombinatorsExtended = [ | ||
...defaultCombinators, | ||
{ name: "xor", label: "XOR" } | ||
{ name: "xor", value: "xor", label: "XOR" } | ||
]; | ||
// src/utils/misc.ts | ||
var isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype; | ||
// src/utils/isRuleGroup.ts | ||
var isRuleGroup = (rg) => !!rg && typeof rg === "object" && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroupType = (rg) => isRuleGroup(rg) && !!rg.combinator; | ||
var isRuleGroup = (rg) => isPojo(rg) && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "string"; | ||
@@ -79,10 +82,36 @@ // src/utils/convertQuery.ts | ||
// src/utils/misc.ts | ||
var isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype; | ||
// src/utils/objectUtils.ts | ||
var objectKeys = Object.keys; | ||
// src/utils/toFullOption.ts | ||
var import_immer = require("immer"); | ||
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) { | ||
const recipe = (0, import_immer.produce)((draft) => { | ||
if (isOptionWithName(draft) && !isOptionWithValue(draft)) { | ||
draft.value = draft.name; | ||
} else if (!isOptionWithName(draft) && isOptionWithValue(draft)) { | ||
draft.name = draft.value; | ||
} | ||
}); | ||
return recipe(opt); | ||
} | ||
// src/utils/uniq.ts | ||
var uniqByIdentifier = (originalArray) => { | ||
const names = /* @__PURE__ */ new Set(); | ||
const newArray = []; | ||
originalArray.forEach((el) => { | ||
if (!names.has(el.value ?? el.name)) { | ||
names.add(el.value ?? el.name); | ||
newArray.push(el); | ||
} | ||
}); | ||
return originalArray.length === newArray.length ? originalArray : newArray; | ||
}; | ||
// src/utils/optGroupUtils.ts | ||
var isOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && "options" in arr[0]; | ||
var isFlexibleOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0] && (isPojo(arr[0].options[0]) && "name" in arr[0].options[0] || isPojo(arr[0].options[0]) && "value" in arr[0].options[0]); | ||
var toFlatOptionArray = (arr) => uniqByIdentifier(isFlexibleOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr); | ||
@@ -92,10 +121,10 @@ // src/utils/filterFieldsByComparator.ts | ||
if (!field.comparator) { | ||
const filterOutSameName = (f) => f.name !== field.name; | ||
if (isOptionGroupArray(fields)) { | ||
const filterOutSameField = (f) => (f.value ?? f.name) !== (field.value ?? field.name); | ||
if (isFlexibleOptionGroupArray(fields)) { | ||
return fields.map((og) => ({ | ||
...og, | ||
options: og.options.filter(filterOutSameName) | ||
options: og.options.filter(filterOutSameField) | ||
})); | ||
} | ||
return fields.filter(filterOutSameName); | ||
return fields.filter(filterOutSameField); | ||
} | ||
@@ -111,3 +140,3 @@ const filterByComparator = (fieldToCompare) => { | ||
}; | ||
if (isOptionGroupArray(fields)) { | ||
if (isFlexibleOptionGroupArray(fields)) { | ||
return fields.map((og) => ({ ...og, options: og.options.filter(filterByComparator) })).filter((og) => og.options.length > 0); | ||
@@ -120,5 +149,13 @@ } | ||
var defaultValueSourcesArray = ["value"]; | ||
var dummyFD = { | ||
name: "name", | ||
value: "name", | ||
valueSources: null, | ||
label: "label" | ||
}; | ||
var getValueSourcesUtil = (fieldData, operator, getValueSources) => { | ||
const fd = fieldData ?? /* istanbul ignore else */ | ||
{}; | ||
const fd = fieldData ? toFullOption(fieldData) : ( | ||
/* istanbul ignore else */ | ||
dummyFD | ||
); | ||
if (fd.valueSources) { | ||
@@ -131,3 +168,5 @@ if (typeof fd.valueSources === "function") { | ||
if (getValueSources) { | ||
const vals = getValueSources(fd.name, operator, { fieldData: fd }); | ||
const vals = getValueSources(fd.value, operator, { | ||
fieldData: toFullOption(fd) | ||
}); | ||
if (vals) | ||
@@ -139,25 +178,6 @@ return vals; | ||
// src/utils/uniq.ts | ||
var uniqByName = (originalArray) => { | ||
const names = /* @__PURE__ */ new Set(); | ||
const newArray = []; | ||
originalArray.forEach((el) => { | ||
if (!names.has(el.name)) { | ||
names.add(el.name); | ||
newArray.push(el); | ||
} | ||
}); | ||
return newArray; | ||
}; | ||
// src/utils/parserUtils.ts | ||
var getFieldsArray = (fields) => { | ||
let fieldsFlat = []; | ||
const fieldsArray = !fields ? [] : Array.isArray(fields) ? fields : Object.keys(fields).map((fld) => ({ ...fields[fld], name: fld })).sort((a, b) => a.label.localeCompare(b.label)); | ||
if (isOptionGroupArray(fieldsArray)) { | ||
fieldsFlat = uniqByName(fieldsFlat.concat(...fieldsArray.map((opt) => opt.options))); | ||
} else { | ||
fieldsFlat = uniqByName(fieldsArray); | ||
} | ||
return fieldsFlat; | ||
return toFlatOptionArray(fieldsArray); | ||
}; | ||
@@ -174,3 +194,3 @@ function fieldIsValidUtil({ | ||
let valid = false; | ||
const primaryField = fieldsFlat.find((ff) => ff.name === fieldName); | ||
const primaryField = toFullOption(fieldsFlat.find((ff) => ff.name === fieldName)); | ||
if (primaryField) { | ||
@@ -177,0 +197,0 @@ if (!subordinateFieldName && operator !== "notNull" && operator !== "null" && !getValueSourcesUtil(primaryField, operator, getValueSources).some((vs) => vs === "value")) { |
@@ -1,3 +0,3 @@ | ||
import { D as DefaultRuleGroupType, b as DefaultRuleGroupTypeIC } from './basic-6d3f4384.js'; | ||
import { g as ParseMongoDbOptions } from './importExport-a9d37060.js'; | ||
import { D as DefaultRuleGroupType, b as DefaultRuleGroupTypeIC } from './basic-57f4a0e5.js'; | ||
import { g as ParseMongoDbOptions } from './importExport-d9a9bdde.js'; | ||
@@ -4,0 +4,0 @@ /** |
@@ -49,13 +49,16 @@ "use strict"; | ||
var defaultCombinators = [ | ||
{ name: "and", label: "AND" }, | ||
{ name: "or", label: "OR" } | ||
{ name: "and", value: "and", label: "AND" }, | ||
{ name: "or", value: "or", label: "OR" } | ||
]; | ||
var defaultCombinatorsExtended = [ | ||
...defaultCombinators, | ||
{ name: "xor", label: "XOR" } | ||
{ name: "xor", value: "xor", label: "XOR" } | ||
]; | ||
// src/utils/misc.ts | ||
var isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype; | ||
// src/utils/isRuleGroup.ts | ||
var isRuleGroup = (rg) => !!rg && typeof rg === "object" && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroupType = (rg) => isRuleGroup(rg) && !!rg.combinator; | ||
var isRuleGroup = (rg) => isPojo(rg) && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "string"; | ||
@@ -79,10 +82,36 @@ // src/utils/convertQuery.ts | ||
// src/utils/misc.ts | ||
var isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype; | ||
// src/utils/objectUtils.ts | ||
var objectKeys = Object.keys; | ||
// src/utils/toFullOption.ts | ||
var import_immer = require("immer"); | ||
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) { | ||
const recipe = (0, import_immer.produce)((draft) => { | ||
if (isOptionWithName(draft) && !isOptionWithValue(draft)) { | ||
draft.value = draft.name; | ||
} else if (!isOptionWithName(draft) && isOptionWithValue(draft)) { | ||
draft.name = draft.value; | ||
} | ||
}); | ||
return recipe(opt); | ||
} | ||
// src/utils/uniq.ts | ||
var uniqByIdentifier = (originalArray) => { | ||
const names = /* @__PURE__ */ new Set(); | ||
const newArray = []; | ||
originalArray.forEach((el) => { | ||
if (!names.has(el.value ?? el.name)) { | ||
names.add(el.value ?? el.name); | ||
newArray.push(el); | ||
} | ||
}); | ||
return originalArray.length === newArray.length ? originalArray : newArray; | ||
}; | ||
// src/utils/optGroupUtils.ts | ||
var isOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && "options" in arr[0]; | ||
var isFlexibleOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0] && (isPojo(arr[0].options[0]) && "name" in arr[0].options[0] || isPojo(arr[0].options[0]) && "value" in arr[0].options[0]); | ||
var toFlatOptionArray = (arr) => uniqByIdentifier(isFlexibleOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr); | ||
@@ -92,10 +121,10 @@ // src/utils/filterFieldsByComparator.ts | ||
if (!field.comparator) { | ||
const filterOutSameName = (f) => f.name !== field.name; | ||
if (isOptionGroupArray(fields)) { | ||
const filterOutSameField = (f) => (f.value ?? f.name) !== (field.value ?? field.name); | ||
if (isFlexibleOptionGroupArray(fields)) { | ||
return fields.map((og) => ({ | ||
...og, | ||
options: og.options.filter(filterOutSameName) | ||
options: og.options.filter(filterOutSameField) | ||
})); | ||
} | ||
return fields.filter(filterOutSameName); | ||
return fields.filter(filterOutSameField); | ||
} | ||
@@ -111,3 +140,3 @@ const filterByComparator = (fieldToCompare) => { | ||
}; | ||
if (isOptionGroupArray(fields)) { | ||
if (isFlexibleOptionGroupArray(fields)) { | ||
return fields.map((og) => ({ ...og, options: og.options.filter(filterByComparator) })).filter((og) => og.options.length > 0); | ||
@@ -120,5 +149,13 @@ } | ||
var defaultValueSourcesArray = ["value"]; | ||
var dummyFD = { | ||
name: "name", | ||
value: "name", | ||
valueSources: null, | ||
label: "label" | ||
}; | ||
var getValueSourcesUtil = (fieldData, operator, getValueSources) => { | ||
const fd = fieldData ?? /* istanbul ignore else */ | ||
{}; | ||
const fd = fieldData ? toFullOption(fieldData) : ( | ||
/* istanbul ignore else */ | ||
dummyFD | ||
); | ||
if (fd.valueSources) { | ||
@@ -131,3 +168,5 @@ if (typeof fd.valueSources === "function") { | ||
if (getValueSources) { | ||
const vals = getValueSources(fd.name, operator, { fieldData: fd }); | ||
const vals = getValueSources(fd.value, operator, { | ||
fieldData: toFullOption(fd) | ||
}); | ||
if (vals) | ||
@@ -139,25 +178,6 @@ return vals; | ||
// src/utils/uniq.ts | ||
var uniqByName = (originalArray) => { | ||
const names = /* @__PURE__ */ new Set(); | ||
const newArray = []; | ||
originalArray.forEach((el) => { | ||
if (!names.has(el.name)) { | ||
names.add(el.name); | ||
newArray.push(el); | ||
} | ||
}); | ||
return newArray; | ||
}; | ||
// src/utils/parserUtils.ts | ||
var getFieldsArray = (fields) => { | ||
let fieldsFlat = []; | ||
const fieldsArray = !fields ? [] : Array.isArray(fields) ? fields : Object.keys(fields).map((fld) => ({ ...fields[fld], name: fld })).sort((a, b) => a.label.localeCompare(b.label)); | ||
if (isOptionGroupArray(fieldsArray)) { | ||
fieldsFlat = uniqByName(fieldsFlat.concat(...fieldsArray.map((opt) => opt.options))); | ||
} else { | ||
fieldsFlat = uniqByName(fieldsArray); | ||
} | ||
return fieldsFlat; | ||
return toFlatOptionArray(fieldsArray); | ||
}; | ||
@@ -174,3 +194,3 @@ function fieldIsValidUtil({ | ||
let valid = false; | ||
const primaryField = fieldsFlat.find((ff) => ff.name === fieldName); | ||
const primaryField = toFullOption(fieldsFlat.find((ff) => ff.name === fieldName)); | ||
if (primaryField) { | ||
@@ -177,0 +197,0 @@ if (!subordinateFieldName && operator !== "notNull" && operator !== "null" && !getValueSourcesUtil(primaryField, operator, getValueSources).some((vs) => vs === "value")) { |
@@ -1,3 +0,3 @@ | ||
import { D as DefaultRuleGroupType, b as DefaultRuleGroupTypeIC } from './basic-6d3f4384.js'; | ||
import { h as ParseSQLOptions } from './importExport-a9d37060.js'; | ||
import { D as DefaultRuleGroupType, b as DefaultRuleGroupTypeIC } from './basic-57f4a0e5.js'; | ||
import { h as ParseSQLOptions } from './importExport-d9a9bdde.js'; | ||
@@ -4,0 +4,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
import { a as RuleGroupTypeAny, d as RuleGroupType, R as RuleType, e as RuleGroupTypeIC } from './basic-6d3f4384.js'; | ||
import { a as RuleGroupTypeAny, e as RuleGroupType, R as RuleType, f as RuleGroupTypeIC } from './basic-57f4a0e5.js'; | ||
@@ -3,0 +3,0 @@ /** |
@@ -28,5 +28,8 @@ "use strict"; | ||
// src/utils/misc.ts | ||
var isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype; | ||
// src/utils/isRuleGroup.ts | ||
var isRuleGroup = (rg) => !!rg && typeof rg === "object" && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroupType = (rg) => isRuleGroup(rg) && !!rg.combinator; | ||
var isRuleGroup = (rg) => isPojo(rg) && "rules" in rg && Array.isArray(rg.rules); | ||
var isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "string"; | ||
@@ -38,3 +41,3 @@ // src/utils/transformQuery.ts | ||
delete draft[k]; | ||
} else if (!!v && k !== v && Object.hasOwn(draft, k)) { | ||
} else if (!!v && k !== v && k in draft) { | ||
draft[v] = draft[k]; | ||
@@ -41,0 +44,0 @@ if (deleteRemappedProperties) { |
{ | ||
"name": "react-querybuilder", | ||
"version": "7.0.0-alpha.1", | ||
"version": "7.0.0-alpha.2", | ||
"description": "The React <QueryBuilder /> component for constructing queries", | ||
@@ -127,3 +127,3 @@ "main": "./dist/cjs/index.js", | ||
}, | ||
"gitHead": "07b50090de711f00f3ddeeaddb5666706a6e7c9f" | ||
"gitHead": "b2557742eb611820d453681120a2fc0f3d679692" | ||
} |
@@ -11,3 +11,3 @@ # react-querybuilder | ||
Complete documentation is available at [https://react-querybuilder.js.org]. | ||
Complete documentation is available at https://react-querybuilder.js.org. | ||
@@ -62,3 +62,3 @@ ## Demo | ||
return <QueryBuilder fields={fields} query={query} onQueryChange={q => setQuery(q)} />; | ||
return <QueryBuilder fields={fields} query={query} onQueryChange={setQuery} />; | ||
}; | ||
@@ -65,0 +65,0 @@ ``` |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
6139972
37763