express-form
Advanced tools
Comparing version 0.6.2 to 0.6.3
@@ -29,10 +29,7 @@ var validator = require("validator") | ||
var self = this | ||
, errors = []; | ||
, errors = [] | ||
, value = utils.getProp(property, form) || utils.getProp(property, source); | ||
property = property.replace(/\[((.)*?)\]/g, ".$1"); // Convert square-bracket to dot notation. | ||
var value = utils.getProp(property, form) || utils.getProp(property, source); | ||
if (options.autoTrim) { | ||
stack.push(function (value) { | ||
stack.unshift(function (value) { | ||
if (object.isString(value)) { | ||
@@ -39,0 +36,0 @@ return FilterPrototype.trim.apply(externalFilter.sanitize(value)); |
@@ -0,3 +1,9 @@ | ||
// Convert square-bracket to dot notation. | ||
var toDotNotation = exports.toDotNotation = function (str) { | ||
return str.replace(/\[((.)*?)\]/g, ".$1"); | ||
}; | ||
// Gets nested properties without throwing errors. | ||
var getProp = exports.getProp = function (property, obj) { | ||
var levels = property.split("."); | ||
var levels = toDotNotation(property).split("."); | ||
@@ -12,4 +18,5 @@ while (obj != null && levels[0]) { | ||
// Sets nested properties. | ||
var setProp = exports.setProp = function (property, obj, value) { | ||
var levels = property.split("."); | ||
var levels = toDotNotation(property).split("."); | ||
@@ -16,0 +23,0 @@ while (levels[0]) { |
@@ -5,3 +5,3 @@ { | ||
"description": "Form validation and data filtering for Express", | ||
"version": "0.6.2", | ||
"version": "0.6.3", | ||
"homepage": "http://dandean.github.com/express-form", | ||
@@ -22,3 +22,3 @@ "repository": { | ||
"main" : "index", | ||
"bugs" : { "web" : "http://github.com/dandean/express-form/issues" }, | ||
"bugs" : { "url" : "http://github.com/dandean/express-form/issues" }, | ||
"scripts": { "test": "expresso" }, | ||
@@ -25,0 +25,0 @@ "engines": { "node": ">=0.2.2" }, |
143
README.md
@@ -0,1 +1,5 @@ | ||
**<span style="color:red;">NOTE:</span> I am no longer maintaining this project. Let me know if you'd like to take it on, and I'll give you publishing rights for it on NPM.** | ||
--- | ||
Express Form provides data filtering and validation as route middleware to your Express applications. | ||
@@ -7,4 +11,3 @@ | ||
var form = require("express-form"), | ||
filter = form.filter, | ||
validate = form.validate; | ||
field = form.field; | ||
@@ -25,8 +28,5 @@ var app = express.createServer(); | ||
form( | ||
filter("username").trim(), | ||
validate("username").required().is(/^[a-z]+$/), | ||
filter("password").trim(), | ||
validate("password").required().is(/^[0-9]+$/), | ||
filter("email").trim(), | ||
validate("email").isEmail() | ||
field("username").trim().required().is(/^[a-z]+$/), | ||
field("password").trim().required().is(/^[0-9]+$/), | ||
field("email").trim().isEmail() | ||
), | ||
@@ -62,3 +62,3 @@ | ||
// the `username` field. | ||
form(form.filter("username").trim()), | ||
form(form.field("username").trim()), | ||
@@ -72,14 +72,20 @@ // standard Express handler | ||
### Filters | ||
### Fields | ||
The `filter` property of the module creates a filter object tied to a specific field. | ||
The `field` property of the module creates a filter/validator object tied to a specific field. | ||
filter(fieldname); | ||
// -> Filter | ||
field(fieldname[, label]); | ||
The API is chainable, so you can keep calling filter methods one after the other: | ||
You can access nested properties with either dot or square-bracket notation. | ||
field("post.content").minLength(50), | ||
field("post[user][id]").isInt(), | ||
field("post.super.nested.property").required() | ||
filter("username").trim().toLower().truncate(5) | ||
Simply specifying a property like this, makes sure it exists. So, even if `req.body.post` was undefined, `req.form.post.content` would be defined. This helps avoid any unwanted errors in your code. | ||
The API is chainable, so you can keep calling filter/validator methods one after the other: | ||
filter("username").trim().toLower().truncate(5).required().isAlphanumeric() | ||
#### Filter API: | ||
@@ -122,29 +128,2 @@ | ||
Custom Filters | ||
custom(function) | ||
Filters the field value using custom logic. | ||
Example: | ||
If the `name` field has a value of "hello there", this would | ||
transform it to "hello-there". | ||
filter("name").custom(function(value) { | ||
return value.replace(/\s+/g, "-"); | ||
}); | ||
### Validators | ||
The `validate` property of the module creates a validator object tied to a specific field. | ||
validate(fieldname[, label]); | ||
// -> Validator | ||
The API is chainable, so you can keep calling validator methods one after the other: | ||
validate("username").required().isAlphanumeric() | ||
#### Validator API: | ||
@@ -266,12 +245,45 @@ | ||
### Array Method | ||
array() | ||
Using the array() flag means that field always gives an array. If the field value is an array, but there is no flag, then the first value in that array is used instead. | ||
This means that you don't have to worry about unexpected post data that might break your code. Eg/ when you call an array method on what is actually a string. | ||
field("project.users").array(), | ||
// undefined => [], "" => [], "q" => ["q"], ["a", "b"] => ["a", "b"] | ||
field("project.block"), | ||
// project.block: ["a", "b"] => "a". No "array()", so only first value used. | ||
In addition, any other methods called with the array method, are applied to every value within the array. | ||
field("post.users").array().toUpper() | ||
// post.users: ["one", "two", "three"] => ["ONE", "TWO", "THREE"] | ||
### Custom Methods | ||
custom(function[, message]) | ||
- function (Function): A custom validation function. | ||
- function (Function): A custom filter or validation function. | ||
This method can be utilised as either a filter or validator method. | ||
If the function throws an error, then an error is added to the form. (If `message` is not provided, the thrown error message is used.) | ||
If the function returns a value, then it is considered a filter method, with the field then becoming the returned value. | ||
If the function returns undefined, then the method has no effect on the field. | ||
Validates the field using a custom validation function. If the function | ||
throws, and `message` is not provided, the thrown error message is used. | ||
Examples: | ||
If the `name` field has a value of "hello there", this would | ||
transform it to "hello-there". | ||
field("name").custom(function(value) { | ||
return value.replace(/\s+/g, "-"); | ||
}); | ||
Throws an error if `username` field does not have value "admin". | ||
Example: | ||
validate("username").custom(function(value) { | ||
field("username").custom(function(value) { | ||
if (value !== "admin") { | ||
@@ -281,5 +293,4 @@ throw new Error("%s must be 'admin'."); | ||
}); | ||
### http.ServerRequest.prototype.form | ||
@@ -296,4 +307,4 @@ | ||
Flashes all errors. Configurable, enabled by default. | ||
getErrors(name) -> Array | ||
getErrors(name) -> Array or Object if no name given | ||
- fieldname (String): The name of the field | ||
@@ -303,12 +314,34 @@ | ||
You can also call this method with no parameters to get a map of errors for all of the fields. | ||
Example request handler: | ||
function(req, res) { | ||
if (req.isValid == false) { | ||
if (!req.form.isValid) { | ||
console.log(req.errors); | ||
console.log(req.getErrors("username")) | ||
console.log(req.getErrors("username")); | ||
console.log(req.getErrors()); | ||
} | ||
} | ||
### Configuration | ||
Express Form has various configuration options, but aims for sensible defaults for a typical Express application. | ||
form.configure(options) -> self | ||
- options (Object): An object with configuration options. | ||
flashErrors (Boolean): If validation errors should be automatically passed to Express’ flash() method. Default: true. | ||
autoLocals (Boolean): If field values from Express’ request.body should be passed into Express’ response.locals object. This is helpful when a form is invalid an you want to repopulate the form elements with their submitted values. Default: true. | ||
Note: if a field name dash-separated, the name used for the locals object will be in camelCase. | ||
dataSources (Array): An array of Express request properties to use as data sources when filtering and validating data. Default: ["body", "query", "params"]. | ||
autoTrim (Boolean): If true, all fields will be automatically trimmed. Default: false. | ||
passThrough (Boolean): If true, all data sources will be merged with `req.form`. Default: false. | ||
Installation: | ||
@@ -315,0 +348,0 @@ ------------- |
@@ -271,2 +271,23 @@ var assert = require("assert"), | ||
assert.equal(request.form.errors.length, 0); | ||
// Failure with nested values | ||
var request = { | ||
body: { | ||
field1: { deep: "value1"}, | ||
field2: { deeper: "value2"} | ||
} | ||
}; | ||
form(validate("field1.deep").equals("field::field2[deeper]"))(request, {}); | ||
assert.equal(request.form.errors.length, 1); | ||
assert.equal(request.form.errors[0], "field1.deep does not equal value2"); | ||
// Success with nested values | ||
var request = { | ||
body: { | ||
field1: { deep: "value"}, | ||
field2: { deeper: "value"} | ||
} | ||
}; | ||
form(validate("field1[deep]").equals("field::field2.deeper"))(request, {}); | ||
assert.equal(request.form.errors.length, 0); | ||
}, | ||
@@ -273,0 +294,0 @@ |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
1
348
0
0
1
66794
15
1473