@coocoon/react-awesome-query-builder
Version:
User-friendly query builder for React. Demo: https://ukrbublik.github.io/react-awesome-query-builder
494 lines (391 loc) • 19.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validateValue = exports.validateTree = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _configUtils = require("./configUtils");
var _ruleUtils = require("../utils/ruleUtils");
var _stuff = require("../utils/stuff");
var _defaultUtils = require("../utils/defaultUtils");
var _omit = _interopRequireDefault(require("lodash/omit"));
var _immutable = require("immutable");
var _lodash = _interopRequireDefault(require("lodash"));
var typeOf = function typeOf(v) {
if ((0, _typeof2["default"])(v) == "object" && v !== null && Array.isArray(v)) return "array";else return (0, _typeof2["default"])(v);
};
var isTypeOf = function isTypeOf(v, type) {
if (typeOf(v) == type) return true;
if (type == "number" && !isNaN(v)) return true; //can be casted
return false;
};
var validateTree = function validateTree(tree, _oldTree, config, oldConfig, removeEmptyGroups, removeIncompleteRules) {
if (removeEmptyGroups === undefined) {
removeEmptyGroups = config.settings.removeEmptyGroupsOnLoad;
}
if (removeIncompleteRules === undefined) {
removeIncompleteRules = config.settings.removeIncompleteRulesOnLoad;
}
var c = {
config: config,
oldConfig: oldConfig,
removeEmptyGroups: removeEmptyGroups,
removeIncompleteRules: removeIncompleteRules
};
return validateItem(tree, [], null, {}, c);
};
exports.validateTree = validateTree;
function validateItem(item, path, itemId, meta, c) {
var type = item.get("type");
var children = item.get("children1");
if ((type === "group" || type === "rule_group" || type == "case_group" || type == "switch_group") && children && children.size) {
return validateGroup(item, path, itemId, meta, c);
} else if (type === "rule") {
return validateRule(item, path, itemId, meta, c);
} else {
return item;
}
}
function validateGroup(item, path, itemId, meta, c) {
var removeEmptyGroups = c.removeEmptyGroups;
var id = item.get("id");
var children = item.get("children1");
var oldChildren = children;
if (!id && itemId) {
id = itemId;
item = item.set("id", id);
meta.sanitized = true;
} //validate children
var submeta = {};
children = children.map(function (currentChild, childId) {
return validateItem(currentChild, path.concat(id), childId, submeta, c);
});
if (removeEmptyGroups) children = children.filter(function (currentChild) {
return currentChild != undefined;
});
var sanitized = submeta.sanitized || oldChildren.size != children.size;
if (!children.size && removeEmptyGroups && path.length) {
sanitized = true;
item = undefined;
}
if (sanitized) meta.sanitized = true;
if (sanitized && item) item = item.set("children1", children);
return item;
}
function validateRule(item, path, itemId, meta, c) {
var removeIncompleteRules = c.removeIncompleteRules,
config = c.config,
oldConfig = c.oldConfig;
var showErrorMessage = config.settings.showErrorMessage;
var id = item.get("id");
var properties = item.get("properties");
var field = properties.get("field") || null;
var operator = properties.get("operator") || null;
var operatorOptions = properties.get("operatorOptions");
var valueSrc = properties.get("valueSrc");
var value = properties.get("value");
var valueError = properties.get("valueError");
var isFunc = properties.get("isFunc");
var oldSerialized = {
field: field,
operator: operator,
operatorOptions: operatorOptions ? operatorOptions.toJS() : {},
valueSrc: valueSrc ? valueSrc.toJS() : null,
value: value ? value.toJS() : null,
valueError: valueError ? valueError.toJS() : null
};
var _wasValid = field && operator && value && !value.includes(undefined);
if (!id && itemId) {
id = itemId;
item = item.set("id", id);
meta.sanitized = true;
} //validate field
var fieldDefinition = field ? (0, _configUtils.getFieldConfig)(config, field) : null;
if (isFunc) {
var _config$funcs;
var methodConfig = (_config$funcs = config.funcs) === null || _config$funcs === void 0 ? void 0 : _config$funcs[field];
if (!methodConfig) {
_stuff.logger.warn("No config for method ".concat(field));
field = null;
}
} else {
if (field && !fieldDefinition) {
_stuff.logger.warn("No config for field ".concat(field));
field = null;
}
}
if (field == null) {
properties = ["operator", "operatorOptions", "valueSrc", "value"].reduce(function (map, key) {
return map["delete"](key);
}, properties);
operator = null;
} //validate operator
// Backward compatibility: obsolete operator range_between
if (operator == "range_between" || operator == "range_not_between") {
operator = operator == "range_between" ? "between" : "not_between";
console.info("Fixed operator ".concat(properties.get("operator"), " to ").concat(operator));
properties = properties.set("operator", operator);
}
var operatorDefinition = operator ? (0, _configUtils.getOperatorConfig)(config, operator, field) : null;
if (operator && !operatorDefinition) {
console.warn("No config for operator ".concat(operator));
operator = null;
}
var availOps = field ? (0, _ruleUtils.getOperatorsForField)(config, field) : [];
if (!availOps) {
console.warn("Type of field ".concat(field, " is not supported"));
operator = null;
} else if (operator && availOps.indexOf(operator) == -1) {
if (isFunc) {
var _config$funcs2;
var operatorsConfig = (_config$funcs2 = config.funcs) === null || _config$funcs2 === void 0 ? void 0 : _config$funcs2[field].operators;
if (!operatorsConfig) {
_stuff.logger.warn("No operators for method ".concat(field));
operator = null;
} else {
if (_lodash["default"].indexOf(operatorsConfig, operator) < 0) {
_stuff.logger.warn("Operator ".concat(operator, " of method ").concat(field, " is not supported"));
operator = null;
}
}
} else {
//func
if (operator == "is_empty" || operator == "is_not_empty") {
// Backward compatibility: is_empty #494
operator = operator == "is_empty" ? "is_null" : "is_not_null";
console.info("Fixed operator ".concat(properties.get("operator"), " to ").concat(operator, " for ").concat(field));
properties = properties.set("operator", operator);
} else {
console.warn("Operator ".concat(operator, " is not supported for field ").concat(field));
operator = null;
}
}
}
if (operator == null) {
properties = properties["delete"]("operatorOptions");
properties = properties["delete"]("valueSrc");
properties = properties["delete"]("value");
} //validate operator options
operatorOptions = properties.get("operatorOptions");
var _operatorCardinality = operator ? (0, _stuff.defaultValue)(operatorDefinition.cardinality, 1) : null;
if (!operator || operatorOptions && !operatorDefinition.options) {
operatorOptions = null;
properties = properties["delete"]("operatorOptions");
} else if (operator && !operatorOptions && operatorDefinition.options) {
operatorOptions = (0, _defaultUtils.defaultOperatorOptions)(config, operator, field);
properties = properties.set("operatorOptions", operatorOptions);
}
if (!isFunc) {
//validate values
valueSrc = properties.get("valueSrc");
value = properties.get("value");
var _getNewValueForFieldO = (0, _ruleUtils.getNewValueForFieldOp)(config, oldConfig, properties, field, operator, null, true),
newValue = _getNewValueForFieldO.newValue,
newValueSrc = _getNewValueForFieldO.newValueSrc,
newValueError = _getNewValueForFieldO.newValueError;
value = newValue;
valueSrc = newValueSrc;
valueError = newValueError;
properties = properties.set("value", value);
properties = properties.set("valueSrc", valueSrc);
if (showErrorMessage) {
properties = properties.set("valueError", valueError);
}
}
var newSerialized = {
field: field,
operator: operator,
operatorOptions: operatorOptions ? operatorOptions.toJS() : {},
valueSrc: valueSrc ? valueSrc.toJS() : null,
value: value ? value.toJS() : null,
valueError: valueError ? valueError.toJS() : null
};
var sanitized = !(0, _stuff.deepEqual)(oldSerialized, newSerialized);
var isComplete = field && operator && value && !value.includes(undefined);
if (sanitized) meta.sanitized = true;
if (!isComplete && removeIncompleteRules) item = undefined;else if (sanitized) item = item.set("properties", properties);
return item;
}
/**
*
* @param {bool} canFix true is useful for func values to remove bad args
* @param {bool} isEndValue false if value is in process of editing by user
* @param {bool} isRawValue false is used only internally from validateFuncValue
* @return {array} [validError, fixedValue] - if validError === null and canFix == true, fixedValue can differ from value if was fixed
*/
var validateValue = function validateValue(config, leftField, field, operator, value, valueType, valueSrc, asyncListValues) {
var canFix = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : false;
var isEndValue = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
var isRawValue = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : true;
var isFunc = arguments.length > 11 && arguments[11] !== undefined ? arguments[11] : false;
var validError = null;
var fixedValue = value;
if (value != null) {
if (valueSrc == "field") {
var _validateFieldValue = validateFieldValue(leftField, field, value, valueSrc, valueType, asyncListValues, config, operator, isEndValue, canFix);
var _validateFieldValue2 = (0, _slicedToArray2["default"])(_validateFieldValue, 2);
validError = _validateFieldValue2[0];
fixedValue = _validateFieldValue2[1];
} else if (valueSrc == "func") {
var _validateFuncValue = validateFuncValue(leftField, field, value, valueSrc, valueType, asyncListValues, config, operator, isEndValue, canFix);
var _validateFuncValue2 = (0, _slicedToArray2["default"])(_validateFuncValue, 2);
validError = _validateFuncValue2[0];
fixedValue = _validateFuncValue2[1];
} else if (valueSrc == "value" || !valueSrc) {
var _validateNormalValue = validateNormalValue(leftField, field, value, valueSrc, valueType, asyncListValues, config, operator, isEndValue, canFix, isFunc);
var _validateNormalValue2 = (0, _slicedToArray2["default"])(_validateNormalValue, 2);
validError = _validateNormalValue2[0];
fixedValue = _validateNormalValue2[1];
}
if (!validError) {
var fieldConfig = (0, _configUtils.getFieldConfig)(config, field);
var w = (0, _ruleUtils.getWidgetForFieldOp)(config, field, operator, valueSrc);
var operatorDefinition = operator ? (0, _configUtils.getOperatorConfig)(config, operator, field) : null;
var fieldWidgetDefinition = (0, _omit["default"])((0, _configUtils.getFieldWidgetConfig)(config, field, operator, w, valueSrc), ["factory"]);
var rightFieldDefinition = valueSrc == "field" ? (0, _configUtils.getFieldConfig)(config, value) : null;
var fieldSettings = fieldWidgetDefinition; // widget definition merged with fieldSettings
var fn = fieldWidgetDefinition.validateValue;
if (typeof fn == "function") {
var args = [fixedValue, fieldSettings, operator, operatorDefinition];
if (valueSrc == "field") args.push(rightFieldDefinition);
var validResult = fn.apply(void 0, args);
if (typeof validResult == "boolean") {
if (validResult == false) validError = "Invalid value";
} else {
validError = validResult;
}
}
}
}
if (isRawValue && validError) {
console.warn("[RAQB validate]", "Field ".concat(field, ": ").concat(validError));
}
return [validError, validError ? value : fixedValue];
};
exports.validateValue = validateValue;
var validateValueInList = function validateValueInList(value, listValues) {
var values = _immutable.List.isList(value) ? value.toJS() : value instanceof Array ? (0, _toConsumableArray2["default"])(value) : undefined;
if (values) {
for (var i = 0; i < values.length; i++) {
var vv = (0, _stuff.getItemInListValues)(listValues, values[i]);
if (vv == undefined) {
return ["Value ".concat(value[i], " is not in list of values"), values];
} else {
values[i] = vv.value;
}
}
return [null, values];
} else {
var _vv = (0, _stuff.getItemInListValues)(listValues, value);
if (_vv == undefined) {
return ["Value ".concat(value, " is not in list of values"), value];
} else {
value = _vv.value;
}
return [null, value];
}
};
/**
*
*/
var validateNormalValue = function validateNormalValue(leftField, field, value, valueSrc, valueType, asyncListValues, config) {
var operator = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
var isEndValue = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : false;
var canFix = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
var isFunc = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false;
var fixedValue = value;
if (field) {
var fieldConfig = (0, _configUtils.getFieldConfig)(config, field, isFunc);
var w = (0, _ruleUtils.getWidgetForFieldOp)(config, field, operator, valueSrc, isFunc);
var wConfig = config.widgets[w];
var wType = wConfig.type;
var jsType = wConfig.jsType;
var fieldSettings = fieldConfig.fieldSettings;
if (valueType != wType) return ["Value should have type ".concat(wType, ", but got value of type ").concat(valueType), value];
if (jsType && !isTypeOf(value, jsType) && !fieldSettings.listValues) {
//tip: can skip tye check for listValues
return ["Value should have JS type ".concat(jsType, ", but got value of type ").concat((0, _typeof2["default"])(value)), value];
}
if (fieldSettings) {
var listValues = asyncListValues || fieldSettings.listValues;
if (listValues && !fieldSettings.allowCustomValues) {
return validateValueInList(value, listValues);
}
if (fieldSettings.min != null && value < fieldSettings.min) {
return ["Value ".concat(value, " < min ").concat(fieldSettings.min), value];
}
if (fieldSettings.max != null && value > fieldSettings.max) {
return ["Value ".concat(value, " > max ").concat(fieldSettings.max), value];
}
}
}
return [null, value];
};
/**
*
*/
var validateFieldValue = function validateFieldValue(leftField, field, value, _valueSrc, valueType, asyncListValues, config) {
var operator = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
var isEndValue = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : false;
var canFix = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
var fieldSeparator = config.settings.fieldSeparator;
var isFuncArg = (0, _typeof2["default"])(field) == "object" && (field === null || field === void 0 ? void 0 : field._isFuncArg);
var leftFieldStr = Array.isArray(leftField) ? leftField.join(fieldSeparator) : leftField;
var rightFieldStr = Array.isArray(value) ? value.join(fieldSeparator) : value;
var rightFieldDefinition = (0, _configUtils.getFieldConfig)(config, value);
if (!rightFieldDefinition) return ["Unknown field ".concat(value), value];
if (rightFieldStr == leftFieldStr && !isFuncArg) return ["Can't compare field ".concat(leftField, " with itself"), value];
if (valueType && valueType != rightFieldDefinition.type) return ["Field ".concat(value, " is of type ").concat(rightFieldDefinition.type, ", but expected ").concat(valueType), value];
return [null, value];
};
/**
*
*/
var validateFuncValue = function validateFuncValue(leftField, field, value, _valueSrc, valueType, asyncListValues, config) {
var operator = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
var isEndValue = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : false;
var canFix = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
var fixedValue = value;
if (value) {
var funcKey = value.get("func");
if (funcKey) {
var funcConfig = (0, _configUtils.getFuncConfig)(config, funcKey);
if (funcConfig) {
if (valueType && funcConfig.returnType != valueType) return ["Function ".concat(funcKey, " should return value of type ").concat(funcConfig.returnType, ", but got ").concat(valueType), value];
for (var argKey in funcConfig.args) {
var argConfig = funcConfig.args[argKey];
var args = fixedValue.get("args");
var argVal = args ? args.get(argKey) : undefined;
var fieldDef = (0, _configUtils.getFieldConfig)(config, argConfig);
var argValue = argVal ? argVal.get("value") : undefined;
var argValueSrc = argVal ? argVal.get("valueSrc") : undefined;
if (argValue !== undefined) {
var _validateValue = validateValue(config, leftField, fieldDef, operator, argValue, argConfig.type, argValueSrc, asyncListValues, canFix, isEndValue, false),
_validateValue2 = (0, _slicedToArray2["default"])(_validateValue, 2),
argValidError = _validateValue2[0],
fixedArgVal = _validateValue2[1];
if (argValidError !== null) {
if (canFix) {
fixedValue = fixedValue.deleteIn(["args", argKey]);
if (argConfig.defaultValue !== undefined) {
fixedValue = fixedValue.setIn(["args", argKey, "value"], argConfig.defaultValue);
fixedValue = fixedValue.setIn(["args", argKey, "valueSrc"], "value");
}
} else {
return ["Invalid value of arg ".concat(argKey, " for func ").concat(funcKey, ": ").concat(argValidError), value];
}
} else if (fixedArgVal !== argValue) {
fixedValue = fixedValue.setIn(["args", argKey, "value"], fixedArgVal);
}
} else if (isEndValue && argConfig.defaultValue === undefined && !canFix) {
return ["Value of arg ".concat(argKey, " for func ").concat(funcKey, " is required"), value];
}
}
} else return ["Unknown function ".concat(funcKey), value];
} // else it's not function value
} // empty value
return [null, fixedValue];
};