lara-validator
Version:
Validating data based on Laravel validation style
300 lines (265 loc) • 14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _wrappers = require('./rules/wrappers');
var _wrappers2 = _interopRequireDefault(_wrappers);
var _RuleMeta = require('./rules/RuleMeta');
var _RuleMeta2 = _interopRequireDefault(_RuleMeta);
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var LaraValidator = function () {
/**
* Validator
* @param {Object} rules - the rules config
* @param {Object} data - the data which going to valid
* @param {Object} expansionValidators - the expansion validation rules
* @param {Object|undefined} customRulesMessage - the custom rules message, it's useful for i18n
*/
function LaraValidator(rules, data) {
var expansionValidators = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var customRulesMessage = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
_classCallCheck(this, LaraValidator);
this.setRules(rules);
this.setData(data);
this.wrappers = _lodash2.default.clone(_wrappers2.default);
this.setExpansionValidators(expansionValidators);
this.setCustomRulesMessage(customRulesMessage);
this.errorMessage = {};
}
_createClass(LaraValidator, [{
key: 'setRules',
value: function setRules(rules) {
this.ruleConfig = rules || {};
}
}, {
key: 'setData',
value: function setData(data) {
this.data = data || {};
}
}, {
key: 'setExpansionValidators',
value: function setExpansionValidators() {
var expansionWrappers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
this.wrappers = _lodash2.default.merge(this.wrappers, expansionWrappers);
}
}, {
key: 'setCustomRulesMessage',
value: function setCustomRulesMessage(customRulesMessage) {
this.customRulesMessage = customRulesMessage;
}
}, {
key: 'valid',
/**
*
* @return {boolean|*}
*/
value: function valid() {
this.errorMessage = {};
this._recursive(this.ruleConfig, []);
this.isValid = Object.keys(this.errorMessage).length <= 0;
return this.isValid;
}
}, {
key: '_recursive',
/**
*
* @param ruleConfig
* @param parentPath
* @private
*/
value: function _recursive(ruleConfig) {
var _this = this;
var parentPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
Object.keys(ruleConfig).forEach(function (fieldName) {
if (fieldName !== 'rules') {
var ruleValues = ruleConfig[fieldName];
var ruleValuesIsString = typeof ruleValues === 'string';
var ruleValuesIsArray = Array.isArray(ruleValues);
var hasSubFields = (typeof ruleValues === 'undefined' ? 'undefined' : _typeof(ruleValues)) === 'object';
if (ruleValuesIsString) {
// field validation
var fieldAllRules = ruleValues.split('|');
_this._fieldValidation(fieldAllRules, parentPath, fieldName, 'string', ruleConfig);
} else {
// deep sub field rules validation
if (ruleValuesIsArray) {
var arrayElement = ruleValues[0];
_this._recursive(arrayElement, [].concat(_toConsumableArray(parentPath), [fieldName, '*']));
} else if (hasSubFields) {
_this._recursive(ruleValues, [].concat(_toConsumableArray(parentPath), [fieldName]));
}
}
} else {
// field validation
var _fieldAllRules = Object.keys(ruleConfig.rules);
var lastBasePathIndex = parentPath.length - 1;
var _fieldName = parentPath[lastBasePathIndex];
var originParentPath = [].concat(_toConsumableArray(parentPath));
originParentPath.pop();
_this._fieldValidation(_fieldAllRules, originParentPath, _fieldName, 'object', ruleConfig.rules);
}
});
}
}, {
key: '_fieldValidation',
/**
*
* @param fieldAllRules
* @param parentPath
* @param fieldName
* @param ruleType
* @param fieldRulesConfig
* @private
*/
value: function _fieldValidation(fieldAllRules, parentPath, fieldName, ruleType, fieldRulesConfig) {
var _this2 = this;
var bail = fieldAllRules.includes('bail');
var isNullable = fieldAllRules.includes('nullable');
var presentOnly = fieldAllRules.includes('present');
var ruleMeta = new _RuleMeta2.default(this.data);
ruleMeta.setFieldPath(parentPath, fieldName).setParentValues();
fieldAllRules.every(function (ruleWithOptions) {
ruleMeta.resetRule().setRule(ruleWithOptions, isNullable, presentOnly);
var ruleIsExist = _this2.wrappers.hasOwnProperty(ruleMeta.ruleName);
if (ruleIsExist) {
// validation
var ruleValidation = _this2.wrappers[ruleMeta.ruleName](ruleMeta);
// set error message
if (!ruleValidation.result) {
ruleValidation.fail.forEach(function (failDataPath) {
var errorMessage = undefined;
switch (ruleType) {
case 'string':
errorMessage = _this2._getDefaultErrorMessage(ruleMeta.ruleName, ruleMeta.ruleOptions);
break;
case 'object':
var errorMessageInRuleConfig = fieldRulesConfig[ruleWithOptions];
errorMessage = _this2._getDefaultErrorMessage(ruleMeta.ruleName, ruleMeta.ruleOptions, errorMessageInRuleConfig);
break;
}
_this2._setErrorMessage(failDataPath, errorMessage);
});
if (bail) {
return false;
}
}
}
return true;
});
}
/**
*
* @param ruleName
* @param ruleOptionValues
* @param errorMessageInRuleConfig
* @return {string}
* @private
*/
}, {
key: '_getDefaultErrorMessage',
value: function _getDefaultErrorMessage(ruleName, ruleOptionValues, errorMessageInRuleConfig) {
if (LaraValidator.rules[ruleName]) {
// rule
var ruleOptionValuesIsString = typeof ruleOptionValues === 'string';
var ruleOptionValuesIsArray = Array.isArray(ruleOptionValues);
// static rule information
var staticRule = LaraValidator.rules[ruleName];
var staticOptionsIsString = typeof staticRule.options === 'string';
var staticOptionsIsArrayWithElement = Array.isArray(staticRule.options) && staticRule.options.length > 0;
var hasStaticErrorMessage = staticRule.errorMessage;
// error message
var errorMessage = errorMessageInRuleConfig ? errorMessageInRuleConfig : hasStaticErrorMessage ? staticRule.errorMessage : ruleName + ' fail';
// post-processing for replacing rule options
var staticRuleOptions = staticOptionsIsString ? [staticRule.options] : staticOptionsIsArrayWithElement ? staticRule.options : [];
ruleOptionValues = ruleOptionValuesIsString ? [ruleOptionValues] : ruleOptionValuesIsArray ? ruleOptionValues : [];
ruleOptionValues.forEach(function (ruleOptionValue, index) {
var staticRuleOption = staticRuleOptions[index] || staticRuleOptions[0] || 'NO_MAPPING_RULE_OPTIONS';
staticRuleOption = staticRuleOption.replace(/\./gi, '\\.');
errorMessage = errorMessage.replace(new RegExp(':' + staticRuleOption, 'i'), ruleOptionValue);
});
// return
return errorMessage;
} else {
throw Error('No such a rule named "' + ruleName + '"');
}
}
/**
*
* @param fieldPath
* @param errorMessage
* @private
*/
}, {
key: '_setErrorMessage',
value: function _setErrorMessage(fieldPath, errorMessage) {
var pathString = fieldPath.join('.');
if (!this.errorMessage[pathString]) {
this.errorMessage[pathString] = [];
}
this.errorMessage[pathString].push(errorMessage);
}
}]);
return LaraValidator;
}();
exports.default = LaraValidator;
;
LaraValidator.rules = {
accepted: { options: undefined, errorMessage: undefined },
alpha: { options: undefined, errorMessage: undefined },
alpha_dash: { options: undefined, errorMessage: undefined },
alpha_num: { options: undefined, errorMessage: undefined },
array: { options: undefined, errorMessage: undefined },
in_array: { options: 'anotherfield', errorMessage: undefined },
in: { options: 'foo', errorMessage: undefined },
not_in: { options: 'foo', errorMessage: undefined },
distinct: { options: undefined, errorMessage: undefined },
same: { options: 'field', errorMessage: undefined },
different: { options: 'field', errorMessage: undefined },
date: { options: undefined, errorMessage: undefined },
after: { options: 'date', errorMessage: undefined },
after_or_equal: { options: 'date', errorMessage: undefined },
date_equals: { options: 'date', errorMessage: undefined },
before_or_equal: { options: 'date', errorMessage: undefined },
before: { options: 'date', errorMessage: undefined },
regex: { options: 'pattern', errorMessage: undefined },
not_regex: { options: 'pattern', errorMessage: undefined },
starts_with: { options: 'foo', errorMessage: undefined },
present: { options: undefined, errorMessage: undefined },
required: { options: undefined, errorMessage: undefined },
required_if: { options: 'anotherfield', errorMessage: undefined },
required_unless: { options: 'anotherfield', errorMessage: undefined },
required_with: { options: 'foo', errorMessage: undefined },
required_with_all: { options: 'foo', errorMessage: undefined },
required_without: { options: 'foo', errorMessage: undefined },
required_without_all: { options: 'foo', errorMessage: undefined },
gt: { options: 'field', errorMessage: undefined },
gte: { options: 'field', errorMessage: undefined },
lt: { options: 'field', errorMessage: undefined },
lte: { options: 'field', errorMessage: undefined },
max: { options: 'max', errorMessage: undefined },
between: { options: 'min,max', errorMessage: undefined },
min: { options: 'min', errorMessage: undefined },
boolean: { options: undefined, errorMessage: undefined },
numeric: { options: undefined, errorMessage: undefined },
digits: { options: 'digits', errorMessage: undefined },
digits_between: { options: 'min,max', errorMessage: undefined },
integer: { options: undefined, errorMessage: undefined },
string: { options: undefined, errorMessage: undefined },
url: { options: undefined, errorMessage: undefined },
uuid: { options: undefined, errorMessage: undefined },
email: { options: undefined, errorMessage: undefined },
size: { options: 'size', errorMessage: undefined },
ip: { options: undefined, errorMessage: undefined },
confirmed: { options: undefined, errorMessage: undefined },
filled: { options: undefined, errorMessage: undefined },
file: { options: undefined, errorMessage: undefined },
image: { options: undefined, errorMessage: undefined },
mimetypes: { options: 'text/plain', errorMessage: undefined },
mimes: { options: 'foo', errorMessage: undefined }
};