diff --git a/package-lock.json b/package-lock.json index 192e6b89..efcb2126 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "express-validator", - "version": "6.12.0", + "version": "6.12.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "6.12.0", + "version": "6.12.1", "license": "MIT", "dependencies": { "lodash": "^4.17.21", diff --git a/package.json b/package.json index 6b9757df..85f2b613 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "Gustavo Henke ", "Federico Ciardi " ], - "version": "6.12.0", + "version": "6.12.1", "homepage": "https://express-validator.github.io", "license": "MIT", "repository": { diff --git a/website/i18n/en.json b/website/i18n/en.json index ff4edba6..bcd7741d 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -197,6 +197,9 @@ "version-6.12.0/version-6.12.0-custom-error-messages": { "title": "Custom Error Messages" }, + "version-6.12.1/version-6.12.1-running-imperatively": { + "title": "Running validations imperatively" + }, "version-6.2.0/version-6.2.0-validation-chain-api": { "title": "Validation Chain API" }, diff --git a/website/versioned_docs/version-6.12.1/feature-running-imperatively.md b/website/versioned_docs/version-6.12.1/feature-running-imperatively.md new file mode 100644 index 00000000..e97565e5 --- /dev/null +++ b/website/versioned_docs/version-6.12.1/feature-running-imperatively.md @@ -0,0 +1,128 @@ +--- +id: version-6.12.1-running-imperatively +title: Running validations imperatively +original_id: running-imperatively +--- + +express-validator favors the declarative way of doing things that express middlewares bring. +This means most of the APIs _look and work better_ when simply passed into an express route handler. + +You can, however, give control of running these validations to your own middleware/route handler. +This is possible with the use of the declarative method `run(req)`, available on +[validation chain](api-validation-chain.md#runreq-options), [sanitization chain](api-sanitization-chain.md#runreq), [`checkSchema`](api-check.md#checkschemaschema) and [`oneOf`](api-check.md#oneofvalidationchains-message). + +Check the examples below to understand how this method can help you: + +## Example: standardized validation error response + + + + +```js +const express = require('express'); +const { validationResult, ValidationChain } = require('express-validator'); +// can be reused by many routes + +// parallel processing +const validate = validations => { + return async (req, res, next) => { + await Promise.all(validations.map(validation => validation.run(req))); + + const errors = validationResult(req); + if (errors.isEmpty()) { + return next(); + } + + res.status(400).json({ errors: errors.array() }); + }; +}; + +// sequential processing, stops running validations chain if the previous one have failed. +const validate = validations => { + return async (req, res, next) => { + for (let validation of validations) { + const result = await validation.run(req); + if (result.errors.length) break; + } + + const errors = validationResult(req); + if (errors.isEmpty()) { + return next(); + } + + res.status(400).json({ errors: errors.array() }); + }; +}; +``` + + + +```typescript +import express from 'express'; +import { validationResult, ValidationChain } from 'express-validator'; +// can be reused by many routes + +// parallel processing +const validate = (validations: ValidationChain[]) => { + return async (req: express.Request, res: express.Response, next: express.NextFunction) => { + await Promise.all(validations.map(validation => validation.run(req))); + + const errors = validationResult(req); + if (errors.isEmpty()) { + return next(); + } + + res.status(400).json({ errors: errors.array() }); + }; +}; + +// sequential processing, stops running validations chain if the previous one have failed. +const validate = (validations: ValidationChain[]) => { + return async (req: express.Request, res: express.Response, next: express.NextFunction) => { + for (let validation of validations) { + const result = await validation.run(req); + if (result.errors.length) break; + } + + const errors = validationResult(req); + if (errors.isEmpty()) { + return next(); + } + + res.status(400).json({ errors: errors.array() }); + }; +}; +``` + + + +```js +app.post('/api/create-user', validate([ + body('email').isEmail(), + body('password').isLength({ min: 6 }) +]), async (req, res, next) => { + // request is guaranteed to not have any validation errors. + const user = await User.create({ ... }); +}); +``` + +## Example: validating with a condition + +```js +app.post( + '/update-settings', + body('email').isEmail(), + body('password').optional().isLength({ min: 6 }), + async (req, res, next) => { + // if a password has been provided, then a confirmation must also be provided. + if (req.body.password) { + await body('passwordConfirmation') + .equals(req.body.password) + .withMessage('passwords do not match') + .run(req); + } + + // Check the validation errors, and update the user's settings. + }, +); +``` diff --git a/website/versions.json b/website/versions.json index 3549eb94..63383759 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,4 +1,5 @@ [ + "6.12.1", "6.12.0", "6.11.1", "6.11.0",