UNPKG

3.16 kBJavaScriptView Raw
1var ValidaInvalidError = require('./valida-invalid-error');
2var async = require('async');
3
4
5var Context = module.exports = function(valida, obj, schema, cb, groups) {
6 this.valida = valida;
7 this.obj = obj;
8 this.schema = schema;
9 this.cb = cb;
10 this.groups = typeof groups == 'string' ? [groups] : groups;
11
12 this.status = {
13 errors: {},
14 valid: true
15 };
16};
17
18
19Context.prototype.isValid = function() {
20 return this.status && this.status.valid;
21};
22
23
24Context.prototype.errors = function() {
25 if (!this.status || this.status.valid) return;
26 return this.status.errors;
27};
28
29
30Context.prototype.invalidError = function () {
31 return new ValidaInvalidError(this.status.errors);
32};
33
34
35Context.prototype.addError = function(key, error) {
36 this.status.errors[key] = this.status.errors[key] || [];
37 this.status.errors[key].push(error);
38 this.status.valid = false;
39};
40
41
42Context.prototype.groupsValid = function(groups) {
43 var checkGroupsEmpty = !this.groups || this.groups.length === 0;
44 var ruleGroupsEmpty = !groups || groups.length === 0;
45
46 if (checkGroupsEmpty && ruleGroupsEmpty) return true;
47 if (!checkGroupsEmpty && ruleGroupsEmpty) return true;
48 if (!checkGroupsEmpty && !ruleGroupsEmpty) {
49 for (var i = 0, len = this.groups.length; i < len; i++) {
50 if (groups.indexOf(this.groups[i]) != -1) return true;
51 }
52 }
53
54 return false;
55};
56
57
58Context.prototype.run = function() {
59 Object.keys(this.schema).forEach(function (key) {
60 var rules = this.schema[key];
61
62 // sanitizers
63 for (var i = 0, len = rules.length; i < len; i++) {
64 if (!rules[i].sanitizer) continue;
65 if (typeof this.obj[key] == 'undefined') continue;
66 if (!this.groupsValid(rules[i].groups)) continue;
67
68 var fn = rules[i].sanitizer;
69 if (typeof fn === 'string') fn = this.valida.sanitizers[fn];
70 if (!fn) return this.cb(new Error('invalid sanitizer ' + rules[i].sanitizer));
71
72 this.obj[key] = fn(this, rules[i], this.obj[key]);
73 }
74 }, this);
75
76 var asyncValidators = [];
77 Object.keys(this.schema).forEach(function (key) {
78 var rules = this.schema[key];
79
80 // validators
81 for (var i = 0, len = rules.length; i < len; i++) {
82 if (!rules[i].validator) continue;
83 if (!this.groupsValid(rules[i].groups)) continue;
84
85 var fn = rules[i].validator;
86 if (typeof fn === 'string') fn = this.valida.validators[fn];
87 if (!fn) return this.cb(new Error('invalid validator ' + rules[i].validator));
88
89 if (fn.length == 4) {
90 asyncValidators.push(asyncCall.bind(null, fn, this, key, rules[i], this.obj[key]));
91 } else {
92 var result = fn(this, rules[i], this.obj[key]);
93 if (typeof result != 'undefined') this.addError(key, result);
94 }
95 }
96 }, this);
97
98 if (asyncValidators.length > 0) {
99 var that = this;
100 async.parallel(asyncValidators, function(err) {
101 that.cb(err, that);
102 });
103 } else {
104 this.cb(null, this);
105 }
106};
107
108
109var asyncCall = function (fn, ctx, key, options, value, cb) {
110 fn(ctx, options, value, function(err, result) {
111 if (err) return cb(err);
112 if (typeof result != 'undefined') ctx.addError(key, result);
113 cb();
114 });
115};