Skip to content

Commit

Permalink
Merge pull request #33 from zero21xxx/middleware-options
Browse files Browse the repository at this point in the history
Middleware Options
  • Loading branch information
Adam Bretz committed Jun 7, 2013
2 parents e739e2b + 8fe0862 commit 6816d5b
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 107 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var util = require('util'),
app = express.createServer();

app.use(express.bodyParser());
app.use(expressValidator);
app.use(expressValidator([options]));

app.post('/:urlparam', function(req, res) {

Expand Down Expand Up @@ -69,6 +69,32 @@ There have been validation errors: [
{ param: 'postparam', msg: 'Invalid postparam', value: undefined} ]
```

### Middleware Options
####`errorFormatter`
_function(param,msg,value)_

The `errorFormatter` option can be used to specify a function that can be used to formate the objects that populate the error arrow that is returned in `req.validationErrors()`. It should return an `Object` that has `param`, `msg`, and `value` keys defined.

```javascript
// In this example, the formParam value is going to get morphed into form body format useful for printing.
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;

while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
```

### Validation errors

You have two choices on how to get the validation errors:
Expand Down
218 changes: 114 additions & 104 deletions lib/express_validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,128 +25,138 @@ var Validator = require('validator').Validator,

var validator = new Validator();

function checkParam(req, getter) {
return function(param, fail_msg) {

var value;

// If param is not an array, then split by dot notation
// returning an array. It will return an array even if
// param doesn't have the dot notation.
// 'blogpost' = ['blogpost']
// 'login.username' = ['login', 'username']
// For regex matches you can access the parameters using numbers.
if (!Array.isArray(param)) {
param = typeof param === 'number' ?
[param] :
param.split('.').filter(function(e){
return e !== '';
});
}
var expressValidator = function(options) {
options = options || {};

// Extract value from params
param.map(function(item) {
if (value === undefined) {
value = getter(item)
} else {
value = value[item];
}
});
param = param.join('.');
var _options = {};

validator.error = function(msg) {
var error = {
param: param,
msg: msg,
value: value
};
if (req._validationErrors === undefined) {
req._validationErrors = [];
_options.errorFormatter = options.errorFormatter || function(param, msg, value) {
return {
param : param,
msg : msg,
value : value
};
};

function checkParam(req, getter) {
return function(param, fail_msg) {

var value;

// If param is not an array, then split by dot notation
// returning an array. It will return an array even if
// param doesn't have the dot notation.
// 'blogpost' = ['blogpost']
// 'login.username' = ['login', 'username']
// For regex matches you can access the parameters using numbers.
if (!Array.isArray(param)) {
param = typeof param === 'number' ?
[param] :
param.split('.').filter(function(e){
return e !== '';
});
}
req._validationErrors.push(error);

if (req.onErrorCallback) {
req.onErrorCallback(msg);
// Extract value from params
param.map(function(item) {
if (value === undefined) {
value = getter(item)
} else {
value = value[item];
}
});
param = param.join('.');

validator.error = function(msg) {
var error = _options.errorFormatter(param, msg, value);

if (req._validationErrors === undefined) {
req._validationErrors = [];
}
req._validationErrors.push(error);

if (req.onErrorCallback) {
req.onErrorCallback(msg);
}
return this;
}
return this;
return validator.check(value, fail_msg);
}
return validator.check(value, fail_msg);
}
}

var expressValidator = function(req, res, next) {
return function(req, res, next) {

req.updateParam = function(name, value) {
// route params like /user/:id
if (this.params && this.params.hasOwnProperty(name) &&
undefined !== this.params[name]) {
return this.params[name] = value;
}
// query string params
if (undefined !== this.query[name]) {
return this.query[name] = value;
}
// request body params via connect.bodyParser
if (this.body && undefined !== this.body[name]) {
return this.body[name] = value;
}
return false;
};
req.updateParam = function(name, value) {
// route params like /user/:id
if (this.params && this.params.hasOwnProperty(name) &&
undefined !== this.params[name]) {
return this.params[name] = value;
}
// query string params
if (undefined !== this.query[name]) {
return this.query[name] = value;
}
// request body params via connect.bodyParser
if (this.body && undefined !== this.body[name]) {
return this.body[name] = value;
}
return false;
};

req.check = checkParam(req, function(item) {
return req.param(item);
});
req.check = checkParam(req, function(item) {
return req.param(item);
});

req.checkBody = checkParam(req, function(item) {
return req.body[item];
});
req.checkBody = checkParam(req, function(item) {
return req.body[item];
});

req.checkHeader = function(header, fail_msg) {
var to_check;
if (header === 'referrer' || header === 'referer') {
to_check = this.headers.referer;
} else {
to_check = this.headers[header];
}
return validator.check(to_check || '', fail_msg);
};
req.checkHeader = function(header, fail_msg) {
var to_check;
if (header === 'referrer' || header === 'referer') {
to_check = this.headers.referer;
} else {
to_check = this.headers[header];
}
return validator.check(to_check || '', fail_msg);
};

req.onValidationError = function(errback) {
req.onErrorCallback = errback;
};
req.onValidationError = function(errback) {
req.onErrorCallback = errback;
};

req.validationErrors = function(mapped) {
if (req._validationErrors === undefined) {
return null;
}
if (mapped) {
var errors = {};
req._validationErrors.forEach(function(err) {
errors[err.param] = err;
});
return errors;
req.validationErrors = function(mapped) {
if (req._validationErrors === undefined) {
return null;
}
if (mapped) {
var errors = {};
req._validationErrors.forEach(function(err) {
errors[err.param] = err;
});
return errors;
}
return req._validationErrors;
}
return req._validationErrors;
}

req.filter = function(param) {
var self = this;
var filter = new Filter();
filter.modify = function(str) {
this.str = str;
// Replace the param with the filtered version
self.updateParam(param, str);
req.filter = function(param) {
var self = this;
var filter = new Filter();
filter.modify = function(str) {
this.str = str;
// Replace the param with the filtered version
self.updateParam(param, str);
};
return filter.sanitize(this.param(param));
};
return filter.sanitize(this.param(param));
};

// Create some aliases - might help with code readability
req.sanitize = req.filter;
req.assert = req.check;
req.validate = req.check;
// Create some aliases - might help with code readability
req.sanitize = req.filter;
req.assert = req.check;
req.validate = req.check;

return next();
};
return next();
};
}
module.exports = expressValidator;
module.exports.Validator = Validator;
module.exports.Filter = Filter;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"@orfaust",
"@zero21xxx"
],
"version": "0.4.1",
"version": "0.5.0",
"homepage": "https://github.com/ctavan/express-validator",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion test/helpers/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ App.prototype.start = function() {
self.app = express.createServer();

self.app.use(express.bodyParser());
self.app.use(expressValidator);
self.app.use(expressValidator());

self.app.get(/\/test(\d+)/, self.validation);
self.app.get('/:testparam?', self.validation);
Expand Down

0 comments on commit 6816d5b

Please sign in to comment.