-
Notifications
You must be signed in to change notification settings - Fork 0
/
treeValidator.js
104 lines (93 loc) · 2.46 KB
/
treeValidator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
'use strict';
let _ = require('underscore'),
fs = require('fs'),
itemValidator = require('./itemValidator')
;
class TreeValidator {
constructor() {
/**
* Errors holder
*/
this.errors;
/**
* Rules difinitions holder
*/
this.rules = {};
}
/**
* Validate if rules are correct
* @param {Object} data to be checked
* @param {Object} rules to check if data is matched to
* @return {Validator} Validator instance
*/
validate(data, rules) {
let ruleValidator;
this.errors = {};
let gen = this.getGenerator(rules, data);
for (let [field, rule, value] of gen) {
ruleValidator = this.getItemValidator(rule);
if (!ruleValidator.isValid(value)) {
this.errors[field] = ruleValidator.error;
}
}
return this;
}
getItemValidator(rule) {
return new itemValidator(rule);
}
/**
* Recursively goes through the tree of rules
* @return {Generator}
*/
*getGenerator(rules, data, parent) {
let value = null;
for (let field in rules) {
let fieldName = field;
if (parent) {
fieldName = parent + '.' + fieldName;
}
value = null;
if (_.has(data, field)) {
value = data[field];
}
if (rules[field].type || rules[field].required) {
yield [fieldName, rules[field], value];
} else {
yield* this.getGenerator(rules[field], value, fieldName);
}
}
}
/**
* Rules setter
*/
setRules(rules) {
this.rules = rules;
}
/**
* Whether data is valid
* @param object optional data to be validated
* @return boolean
*/
isValid(data) {
if (data) {
this.validate(data, this.rules);
}
return _.isEmpty(this.errors);
}
/**
* Get validation errors
* @return array
*/
getErrors() {
return this.errors;
}
readRulesFromFile(fileName) {
fileName = fileName || 'rules.json';
this.setRules(JSON.parse(fs.readFileSync(fileName, 'utf8')));
}
addCustomRule(name, checker) {
let rulesCollection = this.getItemValidator({}).getRulesCollection()
rulesCollection.add(name, checker);
}
};
module.exports = new TreeValidator();