-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathverifier.js
More file actions
114 lines (85 loc) · 2.7 KB
/
verifier.js
File metadata and controls
114 lines (85 loc) · 2.7 KB
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
var _ = require("underscore");
var primitives = ["string", "number", "boolean", "undefined", "function"];
function ObjectTemplateMismatch(obj, template) {
this.value = obj;
this.message = " does not match template '" + JSON.stringify(template) + "'";
this.toString = function () {
return JSON.stringify(this.value) + this.message;
};
}
function hasOnly (obj, propList) {
var retval = _.reduce(propList, function (memo, prop) {
return memo && _.has(obj, prop);
}, true);
if(retval && _.keys(obj).length === propList.length) return true;
return false;
}
function template(obj) {
var temp;
// base case, check to see if object is a primitive
if(_.indexOf(primitives, typeof obj) >= 0){
return typeof obj;
}
// if obj is null, return null;
if(!obj) return null;
// if object is an array, return an array of unique templates to match all
// possible elements in the array
if(obj instanceof Array){
return _.uniq(_.map(obj, template));
}
// object must be a javascript object
temp = {};
_.each(obj, function (v,k) {
temp[k] = template(v);
});
return temp;
}
// export the template function
exports.template = template;
function validateRec(obj, template) {
// base case, check to see if object is a primitive
if(_.indexOf(primitives, typeof obj) >= 0){
if((typeof obj) === template) return;
throw new ObjectTemplateMismatch(obj, template);
}
// check if obj equals template exactly, if so return
if(_.isEqual(obj, template)) return;
// check if obj is an array, if so match each element to the template
if(obj instanceof Array){
if(template instanceof Array){
// find the first template that matches each element in obj. if no
// template matches, either throw or drop element
_.each(obj, function (e) {
var match = _.find(template, function (t) {
return validate(e,t) !== null;
});
if(match === undefined) throw new ObjectTemplateMismatch(obj, template);
});
return;
}
throw new ObjectTemplateMismatch(obj, template);
}
// object is a true javascript object, check against template
if(!hasOnly(obj, _.keys(template)))
throw new ObjectTemplateMismatch(obj, template);
_.each(obj, function(v,k) {
validateRec(v, template[k]);
});
return;
}
// wrapper around validateRec, catching thrown ObjectTemplateMismatchs
function validate(obj, template, opt_onError) {
try{
validateRec(obj, template);
}
catch (e) {
if(e instanceof ObjectTemplateMismatch){
if(opt_onError) opt_onError(e.toString());
return null;
}
throw e; // rethrow exception
}
return obj;
}
// export the validate function
exports.validate = validate;