simple-body-validator
Version:
This package is inspired by Laravel validation, and aims to make body validation easier for Javascript developers
132 lines (131 loc) • 5.21 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const validationData_1 = __importDefault(require("./validationData"));
const closureValidationRule_1 = __importDefault(require("../rules/closureValidationRule"));
const ruleContract_1 = __importDefault(require("../rules/ruleContract"));
const validationRuleParser = {
/**
* Convert rules to array
*/
explodeRules: function (rules, data = {}) {
let implicitAttributes = {};
for (let key in rules) {
if (key.indexOf('*') !== -1) {
rules = this.explodeWildCardRules(rules, key, data, implicitAttributes);
delete rules[key];
}
else if (rules.hasOwnProperty(key)) {
rules[key] = this.explodeExplicitRules(rules[key]);
}
}
return {
rules, implicitAttributes
};
},
/**
* Define a set of rules that apply to each element in an array attribute.
*/
explodeWildCardRules: function (results, attribute, masterData, implicitAttributes) {
const pattern = new RegExp('^' + attribute.replace(/\*/g, '[^.]*') + '$');
const data = validationData_1.default.initializeAndGatherData(attribute, masterData);
const rule = results[attribute];
for (let key in data) {
if (key.slice(0, attribute.length) === attribute || key.match(pattern) !== null) {
if (Array.isArray(implicitAttributes[attribute])) {
implicitAttributes[attribute].push(key);
}
else {
implicitAttributes[attribute] = [key];
}
results = this.mergeRulesForAttribute(results, key, rule);
}
}
return results;
},
/**
* Merge additional rules into a given attribute.
*/
mergeRulesForAttribute(results, attribute, rules) {
const merge = this.explodeRules([rules]).rules[0];
results[attribute] = [...results[attribute] ? this.explodeExplicitRules(results[attribute]) : [], ...merge];
return results;
},
/**
* In case the rules specified by the user are a string seperated with '|' - convert them to an array
*/
explodeExplicitRules: function (rules) {
if (typeof rules === 'string') {
return rules.split('|');
}
if (!Array.isArray(rules)) {
return [this.prepareRule(rules)];
}
return rules.map((rule) => this.prepareRule(rule));
},
/**
* Prepare the given rule for the Validator.
*/
prepareRule(rule) {
if (typeof rule === 'function') {
return new closureValidationRule_1.default(rule);
}
if (rule instanceof ruleContract_1.default) {
return rule;
}
return rule.toString();
},
/**
* Extract the rule name and parameters from a rule.
*/
parse(rule) {
if (rule instanceof ruleContract_1.default) {
return [rule, []];
}
return this.parseStringRule(rule);
},
/**
* Parse the parameters associated with a rule
*/
parseStringRule: function (rule) {
let parameters = [];
let parameter;
if (rule.indexOf(':') !== -1) {
[rule, parameter] = rule.split(/:(.+)/);
parameters = parameter.split(',');
}
return [rule, parameters];
},
/**
* Get a rule and its parameters for a given attribute.
*/
getRule: function (attribute, searchRules, availableRules) {
// The available rules are all the rules specified by the uer for example -
// { name: ['requied', 'string'], age: ['required', 'gt:10']}
// A valid attribute in that case would be age
if (!availableRules[attribute]) {
return [];
}
// The search rule can be either a string or an array - lets say we want check if the 'gt' rule exists for
// the age attrtibute - in that case the serachRules will be equal to 'gt' - In case an array is used
// the method will return the data for the first matched rule
searchRules = Array.isArray(searchRules) ? searchRules : [searchRules];
for (let i = 0; i < availableRules[attribute].length; i++) {
let [rule, parameters] = this.parse(availableRules[attribute][i]);
if (searchRules.indexOf(rule) !== -1) {
// return the rule and parameters for the first match
return [rule, parameters];
}
}
return [];
},
/**
* Determine if the given attribute has a rule in the given set of available rules.
*/
hasRule: function (attribute, searchRules, availableRules) {
return this.getRule(attribute, searchRules, availableRules).length > 0;
},
};
exports.default = validationRuleParser;