-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
114 lines (106 loc) · 2.8 KB
/
index.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
'use strict';
var _ = require('lodash');
var Validator = require('jsonschema').Validator;
var validator = new Validator();
function isDefined(value) {
return typeof value !== 'undefined';
}
/**
* Tightens a schema by:
*
* * Setting `type: 'object'` for instances where `properties` is defined and
* `type` is not.
* * Setting `type: 'string'` where `pattern` is defined and `type` is not.
* * Setting `type: 'string'` where `minLength` or `maxLength` are defined.
* * Setting `type: 'string'` where `enum` values are all strings.
* * Setting `type: 'array'` where `items` is defined.
* * Setting `required: true` for properties where `required` is not defined.
* * Setting `additionalProperties: false` where `additionalProperties` is
* not defined.
*/
function tighten(schema) {
if (!isDefined(schema.type)) {
if (isDefined(schema.properties)) {
schema.type = 'object';
}
if (isDefined(schema.pattern)) {
schema.type = 'string';
}
if (isDefined(schema.minLength) || isDefined(schema.maxLength)) {
schema.type = 'string';
}
if (isDefined(schema.enum)) {
var allStrings = _(schema.enum).all(function (item) {
return typeof item === 'string';
});
if (allStrings) {
schema.type = 'string';
}
}
if (isDefined(schema.items)) {
schema.type = 'array';
}
} else {
if (_.isArray(schema.type)) {
_.each(schema.type, function (unionType) {
tighten(unionType);
});
}
}
if (!isDefined(schema.required)) {
schema.required = true;
}
if (isDefined(schema.properties)) {
_(schema.properties).each(function (propertySchema) {
tighten(propertySchema);
});
if (!isDefined(schema.additionalProperties)) {
schema.additionalProperties = false;
}
}
if (isDefined(schema.items)) {
if (_.isArray(schema.items)) {
_.each(schema.items, function (item) {
tighten(item);
});
if (!isDefined(schema.additionalItems)) {
schema.additionalItems = false;
}
} else {
tighten(schema.items);
}
}
return schema;
}
validator.addSchema(tighten({
type: 'string',
pattern: /^[0-9a-fA-F]{24}$/
}), '/MongoDB#ObjectID');
/**
* Validate an instance against a JSON Schema.
*/
function validate(instance, schema, tightenSchema) {
if (!schema || !_.isObject(schema)) {
return {
valid: false,
errors: [
'Invalid schema.'
]
};
}
if (_.isUndefined(tightenSchema) || tightenSchema) {
schema = tighten(schema);
}
if (!instance || !_.isObject(instance)) {
return {
valid: false,
errors: [
'Invalid instance.'
]
};
}
return validator.validate(instance, schema);
}
exports.validator = validator;
exports.validate = validate;
exports.tighten = tighten;