-
Notifications
You must be signed in to change notification settings - Fork 84
/
index.js
101 lines (85 loc) · 2.71 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
'use strict';
var Joi = require('joi');
var assignIn = require('lodash/assignIn');
var find = require('lodash/find');
var defaults = require('lodash/defaults');
var ValidationError = require('./validation-error');
var defaultOptions = {
contextRequest: false,
allowUnknownHeaders: true,
allowUnknownBody: true,
allowUnknownQuery: true,
allowUnknownParams: true,
allowUnknownCookies: true,
status: 400,
statusText: 'Bad Request'
};
var globalOptions = {};
// maps the corresponding request object to an `express-validation` option
var unknownMap = {
headers: 'allowUnknownHeaders',
body: 'allowUnknownBody',
query: 'allowUnknownQuery',
params: 'allowUnknownParams',
cookies: 'allowUnknownCookies'
};
exports = module.exports = function expressValidation (schema) {
if (!schema) throw new Error('Please provide a validation schema');
return function (req, res, next) {
var errors = [];
// Set default options
var options = defaults({}, schema.options || {}, globalOptions, defaultOptions);
// NOTE: mutates `errors`
['headers', 'body', 'query', 'params', 'cookies'].forEach(function (key) {
var allowUnknown = options[unknownMap[key]];
var entireContext = options.contextRequest ? req : null;
if (schema[key]) validate(errors, req[key], schema[key], key, allowUnknown, entireContext);
});
if (errors && errors.length === 0) return next();
return next(new ValidationError(errors, options));
};
};
exports.ValidationError = ValidationError;
exports.options = function (opts) {
if (!opts) {
globalOptions = {};
return;
}
globalOptions = defaults({}, globalOptions, opts);
};
/**
* validate checks the current `Request` for validations
* NOTE: mutates `request` in case the object is valid.
*/
function validate (errObj, request, schema, location, allowUnknown, context) {
if (!request || !schema) return;
var joiOptions = {
context: context || request,
allowUnknown: allowUnknown,
abortEarly: false
};
Joi.validate(request, schema, joiOptions, function (errors, value) {
if (!errors || errors.details.length === 0) {
assignIn(request, value); // joi responses are parsed into JSON
return;
}
errors.details.forEach(function (error) {
var errorExists = find(errObj, function (item) {
if (item && item.field === error.path && item.location === location) {
item.messages.push(error.message);
item.types.push(error.type);
return item;
}
return;
});
if (!errorExists) {
errObj.push({
field: error.path,
location: location,
messages: [error.message],
types: [error.type]
});
}
});
});
};