@react-querybuilder/core
Version:
React Query Builder component for constructing queries and filters, with utilities for executing them in various database and evaluation contexts
185 lines (181 loc) • 5.7 kB
JavaScript
import { i as isPojo } from "./isRuleGroup-CYcfPgbg.mjs";
import { produce } from "immer";
//#region src/defaults.ts
/**
* @group Defaults
*/
const defaultPlaceholderName = "~";
/**
* Default `name` for placeholder option in the `fields` array.
*
* @group Defaults
*/
const defaultPlaceholderFieldName = defaultPlaceholderName;
/**
* Default `name` for placeholder option in the `operators` array.
*
* @group Defaults
*/
const defaultPlaceholderOperatorName = defaultPlaceholderName;
/**
* Default character used to `.join` and `.split` arrays.
*
* @group Defaults
*/
const defaultJoinChar = ",";
/**
* Map of default operators to their respective opposite/negating operators.
*
* @group Defaults
*/
const 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"
};
/**
* Default combinator list.
*
* @group Defaults
*/
const defaultCombinators = [{
name: "and",
value: "and",
label: "AND"
}, {
name: "or",
value: "or",
label: "OR"
}];
/**
* Default combinator list, with `XOR` added.
*
* @group Defaults
*/
const defaultCombinatorsExtended = [...defaultCombinators, {
name: "xor",
value: "xor",
label: "XOR"
}];
//#endregion
//#region src/utils/objectUtils.ts
/**
* A strongly-typed version of `Object.keys()`.
*
* [Original source](https://github.com/sindresorhus/ts-extras/blob/44f57392c5f027268330771996c4fdf9260b22d6/source/object-keys.ts)
*/
const objectKeys = Object.keys;
//#endregion
//#region src/utils/optGroupUtils.ts
const isOptionWithName = (opt) => isPojo(opt) && "name" in opt && typeof opt.name === "string";
const isOptionWithValue = (opt) => isPojo(opt) && "value" in opt && typeof opt.value === "string";
/**
* Converts an {@link Option} or {@link ValueOption} (i.e., {@link BaseOption})
* into a {@link FullOption}. Full options are left unchanged.
*
* @group Option Lists
*/
function toFullOption(opt, baseProperties, labelMap) {
return produce((draft) => {
const idObj = {};
let needsUpdating = !!baseProperties;
if (typeof draft === "string") return {
...baseProperties,
name: draft,
value: draft,
label: labelMap?.[draft] ?? draft
};
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);
})(opt);
}
/**
* Converts an {@link OptionList} or {@link FlexibleOptionList} into a {@link FullOptionList}.
* Lists of full options are left unchanged.
*
* @group Option Lists
*/
function toFullOptionList(optList, baseProperties, labelMap) {
if (!Array.isArray(optList)) return [];
return produce((draft) => {
if (isFlexibleOptionGroupArray(draft)) for (const optGroup of draft) for (const [idx, opt] of optGroup.options.entries()) optGroup.options[idx] = toFullOption(opt, baseProperties, labelMap);
else for (const [idx, opt] of draft.entries()) draft[idx] = toFullOption(opt, baseProperties, labelMap);
})(optList);
}
/**
* Generates a new array of objects with duplicates removed based
* on the identifying property (`value` or `name`)
*
* @group Option Lists
*/
const uniqByIdentifier = (originalArray) => {
const names = /* @__PURE__ */ new Set();
const newArray = [];
for (const el of originalArray) if (!names.has(el.value ?? el.name)) {
names.add(el.value ?? el.name);
newArray.push(el);
}
return originalArray.length === newArray.length ? originalArray : newArray;
};
/**
* Determines if an {@link OptionList} is an {@link OptionGroup} array.
*
* @group Option Lists
*/
const isOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0] && Array.isArray(arr[0].options);
/**
* Determines if an array is a flat array of {@link FlexibleOption}.
*
* @group Option Lists
*/
const 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;
};
/**
* Determines if a {@link FlexibleOptionList} is a {@link FlexibleOptionGroup} array.
*
* @group Option Lists
*/
const isFlexibleOptionGroupArray = (arr, { allowEmpty = false } = {}) => {
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;
};
function getOption(arr, name) {
return (isFlexibleOptionGroupArray(arr, { allowEmpty: true }) ? arr.flatMap((og) => og.options) : arr).find((op) => op.value === name || op.name === name);
}
/**
* Flattens {@link FlexibleOptionGroup} arrays into {@link BaseOption} arrays.
* If the array is already flat, it is returned as is.
*
* @group Option Lists
*/
const toFlatOptionArray = (arr) => uniqByIdentifier(isOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr);
//#endregion
export { toFullOption as a, defaultJoinChar as c, defaultPlaceholderOperatorName as d, toFlatOptionArray as i, defaultOperatorNegationMap as l, isFlexibleOptionArray as n, toFullOptionList as o, isFlexibleOptionGroupArray as r, objectKeys as s, getOption as t, defaultPlaceholderFieldName as u };
//# sourceMappingURL=optGroupUtils-VeZ3k7-1.mjs.map