This repository has been archived by the owner on Nov 15, 2020. It is now read-only.
/
schema.js
121 lines (104 loc) · 3.19 KB
/
schema.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
var _ = require('underscore');
var rules = require('./rules.js');
var Schema = function(schema) {
this.schema = schema;
};
var checkObject = function(schema, key, errors, values, get) {
var value;
_.keys(schema.schema).forEach(function(param) {
try {
// if undefined, don't store it
value = rules.create(key + "." + param, schema.schema[param]).apply(get(key)[param]);
if (!_.isUndefined(value)) {
values[key][param] = value;
}
} catch (error) {
if (!errors[key] || typeof(errors[key]) != 'object') errors[key] = {};
errors[key][param] = error;
}
});
};
var checkArray = function(schema, key, errors, values, get) {
values[key].forEach(function(value, index) {
try {
if(schema.schema.schema) {
// if array has another schema, then we want objects!
value = rules.create(key, {type:'object'}).apply(value);
var results = (new Schema(schema.schema.schema)).validate(value);
if(!results.valid)
{
errors[key] = errors[key] || [];
errors[key][index] = results.errors;
}
values[key][index] = results.data;
}
else
values[key][index] = rules.create(key + "[" + index + "]", schema.schema).apply(value);
} catch (error) {
if (!_.isArray(errors[key])) errors[key] = [];
errors[key][index] = error;
}
});
};
/*jshint loopfunc:true*/
Schema.prototype.validate = function(data) {
var params = _.keys(this.schema);
var errors = {};
var values = {};
var value;
var get = typeof(data) == "function" ? data : function(p) {
return data[p];
};
for (var i = 0; i < params.length; i++) {
var schema = this.schema[params[i]];
try {
// if undefined, don't store it.
value = rules.create(params[i], schema).apply(get(params[i]));
if (!_.isUndefined(value)) {
values[params[i]] = value;
}
// does this rule contain embedded schemas
if (typeof(schema.schema) == "object" &&
!_.isArray(schema.schema) &&
_.keys(schema.schema).length &&
!_.isUndefined(values[params[i]])) {
if(!(schema.allownull && _.isNull(values[params[i]]))) {
if (schema.type == "object") {
var results = (new Schema(schema.schema)).validate(values[params[i]]);
if(!results.valid)
errors[params[i]] = results.errors;
values[params[i]] = results.data;
} else if (schema.type == "array") {
checkArray(schema, params[i], errors, values, get);
}
}
}
} catch (error) {
errors[params[i]] = error;
}
}
return {
data: values,
errors: errors,
valid: _.keys(errors).length === 0
};
};
exports.types = rules.types;
exports.test = function(value, schema) {
return (new Schema({
input: schema
})).validate({
input: value
});
};
exports.properties = rules.properties;
exports.filters = rules.filters;
exports.create = function(schema) {
return new Schema(schema);
};
exports.middleware = function(schema) {
return function(req, res, next) {
req.form = new Schema(schema).validate(req.route.method == "post" ? req.body : req.query);
next();
};
};