Initial commit

This commit is contained in:
Rodrigo Pinto 2020-02-18 22:53:38 -05:00
commit d7af9332c1
1674 changed files with 119641 additions and 0 deletions

21
node_modules/express-validator/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2010 Chris O'Hara <cohara87@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

32
node_modules/express-validator/README.md generated vendored Normal file
View file

@ -0,0 +1,32 @@
# express-validator
[![npm version](https://img.shields.io/npm/v/express-validator.svg)](https://www.npmjs.com/package/express-validator)
[![Build Status](https://img.shields.io/travis/express-validator/express-validator.svg)](http://travis-ci.org/express-validator/express-validator)
[![Dependency Status](https://img.shields.io/david/express-validator/express-validator.svg)](https://david-dm.org/express-validator/express-validator)
[![Coverage Status](https://img.shields.io/coveralls/express-validator/express-validator.svg)](https://coveralls.io/github/express-validator/express-validator?branch=master)
An [express.js]( https://github.com/visionmedia/express ) middleware for
[validator]( https://github.com/chriso/validator.js ).
- [Installation](#installation)
- [Documentation](#documentation)
- [Changelog](#changelog)
- [License](#license)
## Installation
```
npm install express-validator
```
Also make sure that you have Node.js 8 or newer in order to use it.
## Documentation
Please refer to the documentation website on https://express-validator.github.io.
## Changelog
Check the [GitHub Releases page](https://github.com/express-validator/express-validator/releases).
## License
MIT License

1
node_modules/express-validator/check/index.d.ts generated vendored Normal file
View file

@ -0,0 +1 @@
export { Location, Meta, CustomValidator, DynamicMessageCreator, ValidationError, ValidationChain, check, body, cookie, header, param, query, buildCheckFunction, checkSchema, Schema, ValidationSchema, ParamSchema, ValidationParamSchema, oneOf, OneOfCustomMessageBuilder, validationResult, ErrorFormatter, Result, ResultFactory, } from '../src';

20
node_modules/express-validator/check/index.js generated vendored Normal file
View file

@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var src_1 = require("../src");
// middleware/validation-chain-builders
exports.check = src_1.check;
exports.body = src_1.body;
exports.cookie = src_1.cookie;
exports.header = src_1.header;
exports.param = src_1.param;
exports.query = src_1.query;
exports.buildCheckFunction = src_1.buildCheckFunction;
// middleware/schema
exports.checkSchema = src_1.checkSchema;
// middleware/one-of
exports.oneOf = src_1.oneOf;
// validation-result
exports.validationResult = src_1.validationResult;
exports.Result = src_1.Result;
console.warn('express-validator: requires to express-validator/check are deprecated.' +
'You should just use require("express-validator") instead.');

110
node_modules/express-validator/docs/api-check.md generated vendored Normal file
View file

@ -0,0 +1,110 @@
---
id: check-api
title: Validation middlewares
---
These methods are all available via `require('express-validator')`.
## `check([field, message])`
- `field` *(optional)*: a string or an array of strings of field names to validate against.
- `message` *(optional)*: an error message to use when failed validators don't specify a message. Defaults to `Invalid value`; see also [Dynamic Messages](feature-error-messages.md#dynamic-messages).
> *Returns:* a [Validation Chain](api-validation-chain.md)
Creates a validation chain for one or more fields. They may be located in any of the following request objects:
- `req.body`
- `req.cookies`
- `req.headers`
- `req.params`
- `req.query`
If any of the fields are present in more than one location, then all instances of that field value must pass the validation.
**Note:** If `fields` is omitted, then the whole request location will be validated.
This is only useful for `req.body`, though; see [Whole Body Validation](feature-whole-body-validation.md) for examples.
The validators will always be executed serially for the same field.
This means that if the chain targets more than one field, those will run in parallel, but each of their validators are serial.
## `body([fields, message])`
Same as `check([fields, message])`, but only checking `req.body`.
## `cookie([fields, message])`
Same as `check([fields, message])`, but only checking `req.cookies`.
## `header([fields, message])`
Same as `check([fields, message])`, but only checking `req.headers`.
## `param([fields, message])`
Same as `check([fields, message])`, but only checking `req.params`.
## `query([fields, message])`
Same as `check([fields, message])`, but only checking `req.query`.
## `checkSchema(schema)`
- `schema`: the schema to validate. Must comply with the format described in [Schema Validation](feature-schema-validation.md).
> *Returns:* an array of validation chains
## `oneOf(validationChains[, message])`
- `validationChains`: an array of [validation chains](api-validation-chain.md) created with `check()` or any of its variations,
or an array of arrays containing validation chains.
- `message` *(optional)*: an error message to use when all chains failed. Defaults to `Invalid value(s)`; see also [Dynamic Messages](feature-error-messages.md#dynamic-messages).
> *Returns:* a middleware instance
Creates a middleware instance that will ensure at least one of the given chains passes the validation.
If none of the given chains passes, an error will be pushed to the `_error` pseudo-field,
using the given `message`, and the errors of each chain will be made available under a key `nestedErrors`.
Example:
```js
const { check, oneOf, validationResult } = require('express-validator');
app.post('/start-freelancing', oneOf([
check('programming_language').isIn(['javascript', 'java', 'php']),
check('design_tools').isIn(['canva', 'photoshop', 'gimp'])
]), (req, res, next) => {
try {
validationResult(req).throw();
// yay! we're good to start selling our skilled services :)))
res.json(...);
} catch (err) {
// Oh noes. This user doesn't have enough skills for this...
res.status(422).json(...);
}
});
```
If an item of the array is an array containing validation chains, then all of those must pass in order for this
group be considered valid:
```js
// This protected route must be accessed either by passing both username + password,
// or by passing an access token
app.post('/protected/route', oneOf([
[
check('username').exists(),
check('password').exists()
],
check('access_token').exists()
]), someRouteHandler);
```
The execution of those validation chains are made in parallel,
while the execution within a chain still respects the rule defined in the [`check()` function](#check-field-message).
## `buildCheckFunction(locations)`
- `locations`: an array of request locations to gather data from.
May include any of `body`, `cookies`, `headers`, `params` or `query`.
> *Returns:* a variant of [`check()`](#check-field-message) checking the given request locations.
Creates a variant of [`check()`](#check-field-message) that checks the given request locations.
```js
const { buildCheckFunction } = require('express-validator');
const checkBodyAndQuery = buildCheckFunction(['body', 'query']);
app.put('/update-product', [
// id must be either in req.body or req.query, and must be an UUID
checkBodyAndQuery('id').isUUID()
], productUpdateHandler)
```

49
node_modules/express-validator/docs/api-filter.md generated vendored Normal file
View file

@ -0,0 +1,49 @@
---
id: filter-api
title: Sanitization middlewares
---
These methods are all available via `require('express-validator')`.
## `sanitize(fields)`
- `field`: a string or an array of strings of field names to validate against.
> *Returns:* a [Sanitization Chain](api-sanitization-chain.md)
Creates a sanitization chain for one or more fields. They may be located in any of the following request objects:
- `req.body`
- `req.cookies`
- `req.params`
- `req.query`
_* `req.headers` is **not** supported at the moment._
If any of the fields are present in more than one location, then all instances of that field value will be sanitized.
## `sanitizeBody(fields)`
Same as `sanitize(fields)`, but only sanitizing `req.body`.
## `sanitizeCookie(fields)`
Same as `sanitize(fields)`, but only sanitizing `req.cookies`.
## `sanitizeParam(fields)`
Same as `sanitize(fields)`, but only sanitizing `req.params`.
## `sanitizeQuery(fields)`
Same as `sanitize(fields)`, but only sanitizing `req.query`.
## `buildSanitizeFunction(locations)`
- `locations`: an array of request locations to gather data from.
May include any of `body`, `cookies`, `params` or `query`.
> *Returns:* a variant of [`sanitize()`](#sanitizefields) sanitizing the given request locations.
Creates a variant of [`sanitize()`](#sanitizefields) that sanitizes the given request locations.
```js
const { buildSanitizeFunction } = require('express-validator');
const sanitizeBodyAndQuery = buildSanitizeFunction(['body', 'query']);
app.put('/update-product', [
// id being either in req.body or req.query will be converted to int
sanitizeBodyAndQuery('id').toInt()
], productUpdateHandler)
```

View file

@ -0,0 +1,62 @@
---
id: matched-data-api
title: matchedData()
---
These methods are all available via `require('express-validator')`.
## `matchedData(req[, options])`
- `req`: the express request object.
- `options` *(optional)*: an object which accepts the following options:
- `includeOptionals`: if set to `true`, the returned value includes optional data. Defaults to `false`.
- `onlyValidData`: if set to `false`, the returned value includes data from fields
that didn't pass their validations. Defaults to `true`.
- `locations`: an array of locations to extract the data from. The acceptable values include
`body`, `cookies`, `headers`, `params` and `query`. Defaults to `undefined`, which means all locations.
> *Returns:* an object of data that express-validator has validated or sanitized.
Extracts data validated or sanitized by express-validator from the request and builds
an object with them. Nested paths and wildcards are properly handled as well.
See examples below.
## Examples
### Gathering data from multiple locations
If data you validated or sanitized is spread across various request locations
(e.g. `req.body`, `req.query`, `req.params`, etc), then `matchedData` will gather it properly.
You can also customize which locations you want the data from.
```js
// Suppose the request looks like this:
// req.query = { from: '2017-01-12' }
// req.body = { to: '2017-31-12' }
app.post('/room-availability', check(['from', 'to']).isISO8601(), (req, res, next) => {
const queryData = matchedData(req, { locations: ['query'] });
const bodyData = matchedData(req, { locations: ['body'] });
const allData = matchedData(req);
console.log(queryData); // { from: '2017-01-12' }
console.log(bodyData); // { to: '2017-31-12' }
console.log(allData); // { from: '2017-01-12', to: '2017-31-12' }
});
```
### Including optional data
You may want to have [optional values](api-validation-chain.md#optionaloptions) among the required ones.
If they are not included, some databases might understand that you don't to update that value,
so it's useful to set them to `null` or an empty string.
```js
// Suppose the request looks like this:
// req.body = { name: 'John Doe', bio: '' }
app.post('/update-user', [
check('name').not().isEmpty(),
check('bio').optional({ checkFalsy: true }).escape(),
], (req, res, next) => {
const requiredData = matchedData(req, { includeOptionals: false });
const allData = matchedData(req, { includeOptionals: true });
console.log(requiredData); // { name: 'John Doe' }
console.log(allData); // { name: 'John Doe', bio: '' }
});
```

View file

@ -0,0 +1,74 @@
---
id: sanitization-chain-api
title: Sanitization Chain API
---
The sanitization chain is a middleware, and it _should_ be passed to an Express route handler.
You can add as many sanitizers to a chain as you need.
When the middleware runs, it will modify each field in place, applying each of the sanitizers in the order they were specified:
```js
app.get('/', sanitizeBody('trimMe').trim(), (req, res, next) => {
// If req.body.trimMe was originally " something ",
// its sanitized value will be "something"
console.log(req.body.trimMe);
});
```
## Standard sanitizers
All sanitizers listed by validator.js are made available within a Sanitization Chain,
and are called "standard sanitizers" in express-validator.
This means you can use any of those methods, e.g. `normalizeEmail`, `trim`, `toInt`, etc.
> **For a complete list of standard sanitizers and their options**,
> please check [validator.js' docs](https://github.com/chriso/validator.js#sanitizers).
## Additional methods
In addition to the standard sanitizers, the following methods are also available within a Sanitization Chain:
### `.customSanitizer(sanitizer)`
- `sanitizer(value, { req, location, path })`: the custom sanitizer function.
Receives the value of the field being sanitized, as well as the express request, the location and the field path.
> *Returns:* the current sanitization chain instance
Adds a custom sanitizer to the current sanitization chain. It must synchronously return the new value.
Example:
```js
app.get('/object/:id', sanitizeParam('id').customSanitizer((value, { req }) => {
return req.query.type === 'user' ? ObjectId(value) : Number(value);
}), objectHandler)
```
### `.run(req)`
> *Returns:* a promise that resolves when the sanitization chain ran.
Runs the current sanitization chain in an imperative way.
```js
app.post('/create-post', async (req, res, next) => {
// BEFORE:
// req.body.content = ' hey your forum is amazing! <script>runEvilFunction();</script> ';
await sanitize('content').escape().trim().run(req);
// AFTER:
// req.body.content = 'hey your forum is amazing! &lt;script&gt;runEvilFunction();&lt;/script&gt;';
});
```
### `.toArray()`
> *Returns:* the current sanitization chain instance
Converts the value to an array. `undefined` will result in an empty array.
```js
app.post('/', [body('checkboxes').toArray()], (req, res, next) => {
// ['foo', 'bar] => ['foo', 'bar']
// 'foo' => ['foo']
// undefined => []
console.log(req.body.checkboxes);
});
```

View file

@ -0,0 +1,183 @@
---
id: validation-chain-api
title: Validation Chain API
---
The validation chain is a middleware, and it _should_ be passed to an Express route handler.
You can add as many validators and sanitizers to a chain as you need.
When the middleware runs, it will run each validator or sanitizer in the order they were specified;
this means if a sanitizer is specified before a validator, the validator will run with the sanitized
value.
> **Note:** Chains are mutable. Every time you call one of its methods, you're adding more behavior to the same chain.
> Keep this in mind and note that you probably want to use a factory function when reusing some base chain.
## Standard validators
All validators listed by validator.js are made available within a Validation Chain,
and are called "standard validators" in express-validator.
This means you can use any of those methods, e.g. `isInt`, `isEmail`, `contains`, etc.
> **For a complete list of standard validators and their options**,
> please check [validator.js' docs](https://github.com/chriso/validator.js#validators).
## Sanitization Chain API
A validation chain also is a subset of the [Sanitization Chain](api-sanitization-chain.md), meaning
all standard sanitizers and its additional methods are available:
```js
app.post('/create-user', [
// normalizeEmail() and toDate() are sanitizers, also available in the Sanitization Chain
check('email').normalizeEmail().isEmail(),
check('date-of-birth').isISO8601().toDate()
]);
```
## Additional methods
In addition to the standard validators and the [Sanitization Chain API](api-sanitization-chain.md),
the following methods are also available within a Validation Chain:
### `.bail()`
> *Returns:* the current validation chain instance
Stops running validations if any of the previous ones have failed.
Useful to prevent a custom validator that touches a database or external API from running when you
know it will fail.
`.bail()` can be used multiple times in the same validation chain if needed:
```js
app.post('/', [
check('username')
.isEmail()
.bail()
// If username is not an email, checkBlacklistedDomain will never run
.custom(checkBlacklistedDomain)
// If username is not an email or has a blacklisted domain, checkEmailExists will never run
.custom(checkEmailExists);
]);
```
### `.custom(validator)`
- `validator(value, { req, location, path })`: the custom validator function.
Receives the value of the field being validated, as well as the express request, the location and the field path.
> *Returns:* the current validation chain instance
Adds a custom validator to the current validation chain.
The custom validator may return a promise to indicate an async validation task. In case it's rejected, the field is considered invalid.
The custom validator may also throw JavaScript exceptions (eg `throw new Error()`) and return falsy values to indicate the field is invalid.
Example:
```js
app.post('/create-user', [
check('password').exists(),
check('passwordConfirmation', 'passwordConfirmation field must have the same value as the password field')
.exists()
.custom((value, { req }) => value === req.body.password)
], loginHandler);
```
### `.exists(options)`
- `options` *(optional)*: an object of options to customize the behavior of exists.
> *Returns:* the current validation chain instance
Adds a validator to check for the existence of the current fields in the request.
This means the value of the fields may not be `undefined`; all other values are acceptable.
You can customize this behavior by passing an object with the following options:
- `checkNull`: if `true`, fields with `null` values will not exist
- `checkFalsy`: if `true`, fields with falsy values (eg `""`, `0`, `false`, `null`) will also not exist
### `.if(condition)`
- `condition`: the condition for this Validation Chain to continue validating.
> *Returns:* the current validation chain instance
Adds a condition for deciding if validation should continue on a field or not.
The condition can be either:
- A custom validator-like function: `condition(value, { req, path, location })`.
Receives the value of the field being validated, as well as the express request, the location and the field path.
If it returns truthy or a promise that resolves, the validation chain will continue
running. If it returns falsy, a promise that rejects or if it throws, the validation chain will stop.
- A validation chain [created through `check()` or similar functions](api-check.md#check-field-message).
If running that chain would produce errors, then the validation chain will stop.
```js
body('oldPassword')
// if the new password is provided...
.if((value, { req }) => req.body.newPassword)
// OR
.if(body('newPassword').exists())
// ...then the old password must be too...
.not().empty()
// ...and they must not be equal.
.custom((value, { req }) => value !== req.body.newPassword)
```
### `.isArray(options)`
- `options` *(optional)*: an object which accepts the following options:
- `min`: minimum array length.
- `max`: maximum array length.
> *Returns:* the current validation chain instance
Adds a validator to check if a value is an array.
### `.isString()`
> *Returns:* the current validation chain instance
Adds a validator to check if a value is a string.
### `.not()`
> *Returns:* the current validation chain instance
Negates the result of the next validator.
```js
check('weekday').not().isIn(['sunday', 'saturday'])
```
### `.optional(options)`
- `options` *(optional)*: an object of options to customize the behaviour of optional.
> *Returns:* the current validation chain instance
Marks the current validation chain as optional.
This is useful to remove values that are not essential to your business and that would cause validation failures in case they were not provided in the request.
By default, fields with `undefined` values will be ignored from the validation.
You can customize this behavior by passing an object with the following options:
- `nullable`: if `true`, fields with `null` values will be considered optional
- `checkFalsy`: if `true`, fields with falsy values (eg `""`, `0`, `false`, `null`) will also be considered optional
### `.run(req)`
> *Returns:* a promise that resolves when the validation chain ran.
Runs the current validation chain in an imperative way.
```js
app.post('/create-user', async (req, res, next) => {
await check('email').isEmail().run(req);
await check('password').isLength({ min: 6 }).run(req);
const result = validationResult(req);
if (!result.isEmpty()) {
return res.status(422).json({ errors: result.array() });
}
// user can be created now!
});
```
### `.withMessage(message)`
- `message`: the error message to use for the previous validator
> *Returns:* the current validation chain instance
Sets the error message for the previous validator.
This will have precedence over errors thrown by a custom validator.
To build dynamic messages, see also [Dynamic Messages](feature-error-messages.md#dynamic-messages).

View file

@ -0,0 +1,120 @@
---
id: validation-result-api
title: validationResult()
---
These methods are all available via `require('express-validator')`.
## `validationResult(req)`
- `req`: the express request object
> *Returns:* a [`Result`](#result) object
Extracts the validation errors from a request and makes them available in a [`Result`](#result) object.
Each error returned by [`.array()`](#array-options) and [`.mapped()`](#mapped) methods
have the following format _by default_:
```js
{
"msg": "The error message",
"param": "param.name.with.index[0]",
"value": "param value",
// Location of the param that generated this error.
// It's either body, query, params, cookies or headers.
"location": "body",
// nestedErrors only exist when using the oneOf function
"nestedErrors": [{ ... }]
}
```
### `.withDefaults(options)`
- `options` *(optional)*: an object of options. Defaults to `{ formatter: error => error }`
> *Returns:* a new [`validationResult`](#validationresultreq) function, using the provided options
Creates a new `validationResult()`-like function with default options passed to the generated
[`Result`](#result) instance.
Below is an example which sets a default error formatter:
```js
const { validationResult } = require('express-validator');
const myValidationResult = validationResult.withDefaults({
formatter: (error) => {
return {
myLocation: error.location,
};
}
});
app.post('/create-user', yourValidationChains, (req, res) => {
// errors will be like [{ myLocation: 'body' }, { myLocation: 'query' }], etc
const errors = myValidationResult(req).array();
});
```
## `Result`
An object that holds the current state of validation errors in a request and allows access to it in
a variety of ways.
### `.isEmpty()`
> *Returns:* a boolean indicating whether this result object contains no errors at all.
```js
app.post('/create-user', yourValidationChains, (req, res) => {
const result = validationResult(req);
const hasErrors = !result.isEmpty();
// do something if hasErrors is true
});
```
### `.formatWith(formatter)`
- `formatter(error)`: the function to use to format when returning errors.
The `error` argument is an object in the format of `{ location, msg, param, value, nestedErrors }`, as described above.
> *Returns:* a new `Result` instance
```js
app.post('/create-user', yourValidationChains, (req, res, next) => {
const errorFormatter = ({ location, msg, param, value, nestedErrors }) => {
// Build your resulting errors however you want! String, object, whatever - it works!
return `${location}[${param}]: ${msg}`;
};
const result = validationResult(req).formatWith(errorFormatter);
if (!result.isEmpty()) {
// Response will contain something like
// { errors: [ "body[password]: must be at least 10 chars long" ] }
return res.json({ errors: result.array() });
}
// Handle your request as if no errors happened
});
```
### `.array([options])`
- `options` *(optional)*: an object of options. Defaults to `{ onlyFirstError: false }`
> *Returns:* an array of validation errors.
Gets all validation errors contained in this result object.
If the option `onlyFirstError` is set to `true`, then only the first
error for each field will be included.
### `.mapped()`
> *Returns:* an object where the keys are the field names, and the values are the validation errors
Gets the first validation error of each failed field in the form of an object.
### `.throw()`
If this result object has errors, then this method will throw an exception
decorated with the same validation result API.
```js
try {
validationResult(req).throw();
// Oh look at ma' success! All validations passed!
} catch (err) {
console.log(err.mapped()); // Oh noes!
}
```

View file

@ -0,0 +1,66 @@
---
id: custom-validators-sanitizers
title: Custom validators/sanitizers
---
Although express-validator offers plenty of handy validators and sanitizers through its underlying
dependency [validator.js](https://github.com/chriso/validator.js), it doesn't always suffices when
building your application.
For these cases, you may consider writing a custom validator or a custom sanitizer.
## Custom validator
A custom validator may be implemented by using the chain method [`.custom()`](api-validation-chain.md#customvalidator).
It takes a validator function.
Custom validators may return Promises to indicate an async validation (which will be awaited upon),
or `throw` any value/reject a promise to [use a custom error message](feature-error-messages.md#custom-validator-level).
### Example: checking if e-mail is in use
```js
const { body } = require('express-validator');
app.post('/user', body('email').custom(value => {
return User.findUserByEmail(value).then(user => {
if (user) {
return Promise.reject('E-mail already in use');
}
});
}), (req, res) => {
// Handle the request
});
```
### Example: checking if password confirmation matches password
```js
const { body } = require('express-validator');
app.post('/user', body('passwordConfirmation').custom((value, { req }) => {
if (value !== req.body.password) {
throw new Error('Password confirmation does not match password');
}
// Indicates the success of this synchronous custom validator
return true;
}), (req, res) => {
// Handle the request
});
```
## Custom sanitizers
Custom sanitizers can be implemented by using the method `.customSanitizer()`, no matter if
the [validation chain one](api-validation-chain.md#customsanitizersanitizer) or
the [sanitization chain one](api-sanitization-chain.md#customsanitizersanitizer).
Just like with the validators, you specify the sanitizer function, which _must_ be synchronous at the
moment.
### Example: converting to MongoDB's ObjectID
```js
const { sanitizeParam } = require('express-validator');
app.post('/object/:id', sanitizeParam('id').customSanitizer(value => {
return ObjectId(value);
}), (req, res) => {
// Handle the request
});
```

View file

@ -0,0 +1,101 @@
---
id: custom-error-messages
title: Custom Error Messages
---
express-validator's default error message is a simple `Invalid value`.
That's enough to cover all fields without being too opinionated.
You can, however, specify meaningful error messages in a variety of ways.
## Error message levels
### Validator Level
When you want fine grained control over the error message of each validator,
you may specify them using the [`.withMessage()` method](api-validation-chain.md#withmessagemessage).
```js
const { check } = require('express-validator');
app.post('/user', [
// ...some other validations...
check('password')
.isLength({ min: 5 }).withMessage('must be at least 5 chars long')
.matches(/\d/).withMessage('must contain a number')
], (req, res) => {
// Handle the request somehow
});
```
In the example above, if the password is less than 5 characters long, an error with the message
`must be at least 5 chars long` will be reported.
If it also doesn't contain a number, then an error with the message `must contain a number` will be
reported.
### Custom Validator Level
If you're using a custom validator, then it may very well throw or reject promises to indicate an invalid value.
In these cases, the error gets reported with a message that's equal to what was thrown by the validator:
```js
const { check } = require('express-validator');
app.post('/user', [
check('email').custom(value => {
return User.findByEmail(value).then(user => {
if (user) {
return Promise.reject('E-mail already in use');
}
});
}),
check('password').custom((value, { req }) => {
if (value !== req.body.passwordConfirmation) {
throw new Error('Password confirmation is incorrect');
}
})
], (req, res) => {
// Handle the request somehow
});
```
### Field Level
Messages can be specified at the field level by using the second parameter of the
[validation middlewares](api-check.md#check-field-message).
These messages are used as fall backs when a validator doesn't specify its own message:
```js
const { check } = require('express-validator');
app.post('/user', [
// ...some other validations...
check('password', 'The password must be 5+ chars long and contain a number')
.not().isIn(['123', 'password', 'god']).withMessage('Do not use a common word as the password')
.isLength({ min: 5 })
.matches(/\d/)
], (req, res) => {
// Handle the request somehow
});
```
In the example above, when the `password` field is shorter than 5 characters, or doesn't contain a number,
it will be reported with the message `The password must be 5+ chars long and contain a number`,
as these validators didn't specify a message of their own.
## Dynamic messages
You can build dynamic validation messages by providing functions anywhere a validation message is supported.
This is specially useful if you use a translation library to provide tailored messages:
```js
// check(field, withMessage) and .withMessage() work the same
check('something').isInt().withMessage((value, { req, location, path }) => {
return req.translate('validation.message.path', { value, location, path });
}),
check('somethingElse', (value, { req, location, path }) => {
return req.translate('validation.message.path', { value, location, path });
}),
// oneOf is special though - it only receives the req object for now
oneOf([ someValidation, anotherValidation ], ({ req }) => {
return req.translate('validation.multiple_failures');
});
```

View file

@ -0,0 +1,55 @@
---
id: running-imperatively
title: Running validations 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 both
[validation chain](api-validation-chain.md#runreq) and [sanitization chains](api-sanitization-chain.md#runreq).
Check the examples below to understand how this method can help you:
## Example: standardized validation error response
```js
// can be reused by many routes
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(422).json({ errors: errors.array() });
};
};
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.
});
```

View file

@ -0,0 +1,42 @@
---
id: sanitization
title: Sanitization
---
Sometimes, receiving input in a HTTP request isn't only about making sure that
the data is in the right format, but also that **it is free of noise**.
[validator.js provides a handful of sanitizers](https://github.com/chriso/validator.js#sanitizers)
that can be used to take care of the data that comes in.
```js
const express = require('express');
const { body } = require('express-validator');
const { sanitizeBody } = require('express-validator');
const app = express();
app.use(express.json());
app.post('/comment', [
body('email')
.isEmail()
.normalizeEmail(),
body('text')
.not().isEmpty()
.trim()
.escape(),
sanitizeBody('notifyOnReply').toBoolean()
], (req, res) => {
// Handle the request somehow
});
```
In the example above, we are validating `email` and `text` fields,
so we may take advantage of the same chain to apply some sanitization,
like e-mail normalization and trimming/HTML escaping.
And because the `notifyOnReply` field isn't validated, we may use `sanitizeBody` function
from the [sanitization middlewares](api-filter.md) to convert it to a JavaScript boolean.
> **Important:** please note that sanitization mutates the request.
This means that if `req.body.text` was sent with the value ` Hello world :>)`, after the sanitization
its value will be `Hello world :&gt;)`.

View file

@ -0,0 +1,72 @@
---
id: schema-validation
title: Schema Validation
---
Schemas are a special, object-based way of defining validations or sanitizations on requests.
At the root-level, you specify the field paths as the keys, and an object as values -- which define
the error messages, locations and validations/sanitizations.
Its syntaxs looks like this:
```js
const { checkSchema } = require('express-validator');
app.put('/user/:id/password', checkSchema({
id: {
// The location of the field, can be one or more of body, cookies, headers, params or query.
// If omitted, all request locations will be checked
in: ['params', 'query'],
errorMessage: 'ID is wrong',
isInt: true,
// Sanitizers can go here as well
toInt: true
},
myCustomField: {
// Custom validators
custom: {
options: (value, { req, location, path }) => {
return value + req.body.foo + location + path;
}
},
// and sanitizers
customSanitizer: {
options: (value, { req, location, path }) => {
let sanitizedValue;
if (req.body.foo && location && path) {
sanitizedValue = parseInt(value);
} else {
sanitizedValue = 0;
}
return sanitizedValue;
}
},
},
password: {
isLength: {
errorMessage: 'Password should be at least 7 chars long',
// Multiple options would be expressed as an array
options: { min: 7 }
}
},
firstName: {
isUppercase: {
// To negate a validator
negated: true,
},
rtrim: {
// Options as an array
options: [[" ", "-"]],
},
},
// Wildcards/dots for nested fields work as well
'addresses.*.postalCode': {
// Make this field optional when undefined or null
optional: { options: { nullable: true } },
isPostalCode: true
}
}), (req, res, next) => {
// handle the request as usual
})
```

View file

@ -0,0 +1,35 @@
---
id: whole-body-validation
title: Whole Body Validation
---
Sometimes you need to validate requests whose body is a string, an array, or even a number!
That's why you can omit the field to validate and check `req.body` directly:
```js
const bodyParser = require('body-parser');
const express = require('express');
const { body } = require('express-validator');
const app = express();
// Will handle text/plain requests
app.use(bodyParser.text());
app.post('/recover-password', body().isEmail(), (req, res) => {
// Assume the validity of the request was already checked
User.recoverPassword(req.body).then(() => {
res.send('Password recovered!');
});
});
```
This setup should be able to handle the following request:
```http
POST /recover-password HTTP/1.1
Host: localhost:3000
Content-Type: text/plain
my@email.com
```

View file

@ -0,0 +1,47 @@
---
id: wildcards
title: Wildcards
---
Sometimes you will want to apply the same rules to all items of an array or all keys of some object.
That's what the `*` character - also known as a wildcard -- is for.
For example, imagine you want to validate that all addresses have a valid postal code,
and that the number of each address is sanitized as an integer number.
We can do this with the following code:
```js
const express = require('express');
const { check, sanitize } = require('express-validator');
const app = express();
app.use(express.json());
app.post('/addresses', [
check('addresses.*.postalCode').isPostalCode(),
sanitize('addresses.*.number').toInt()
], (req, res) => {
// Handle the request
});
```
This will handle cases where you send an array of addresses:
```json
{
"addresses": [
{ "postalCode": "2010", "number": "500" },
{ "postalCode": "", "number": "501" },
]
}
```
...or even cases where you want a predefined set of addresses:
```json
{
"addresses": {
"home": { "postalCode": "", "number": "501" },
"work": { "postalCode": "2010", "number": "500" }
}
}
```

83
node_modules/express-validator/docs/index.md generated vendored Normal file
View file

@ -0,0 +1,83 @@
---
id: index
title: Getting Started
---
express-validator is a set of [express.js](http://expressjs.com/) middlewares that wraps
[validator.js](https://github.com/chriso/validator.js) validator and sanitizer functions.
## Installation
Install it using npm (make sure that you have Node.js 6 or newer):
```
npm install --save express-validator
```
## Basic guide
> It's recommended that you have basic knowledge of the express.js module before you go on with
this guide.
Let's get started by writing a basic route to create a user in the database:
```js
const express = require('express');
const app = express();
app.use(express.json());
app.post('/user', (req, res) => {
User.create({
username: req.body.username,
password: req.body.password
}).then(user => res.json(user));
});
```
Then, you'll want to make sure that you validate the input and report any errors before creating the user:
```js
// ...rest of the initial code omitted for simplicity.
const { check, validationResult } = require('express-validator');
app.post('/user', [
// username must be an email
check('username').isEmail(),
// password must be at least 5 chars long
check('password').isLength({ min: 5 })
], (req, res) => {
// Finds the validation errors in this request and wraps them in an object with handy functions
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
User.create({
username: req.body.username,
password: req.body.password
}).then(user => res.json(user));
});
```
*Voila!* Now, whenever a request that includes invalid `username` or `password` fields
is submitted, your server will respond like this:
```json
{
"errors": [{
"location": "body",
"msg": "Invalid value",
"param": "username"
}]
}
```
For all the available validators in express-validator (just like its options),
take a look at validator.js docs [here](https://github.com/chriso/validator.js#validators).
## What's next
This completes the basic guide on getting started with express-validator.
You might want to continue reading about some of the more advanced features available:
- [Sanitization](feature-sanitization.md)
- [Custom validators/sanitizers](feature-custom-validators-sanitizers.md)
- [Custom error messages](feature-error-messages.md)
- [Wildcards](feature-wildcards.md)
- [Schema validation](feature-schema-validation.md)

1
node_modules/express-validator/filter/index.d.ts generated vendored Normal file
View file

@ -0,0 +1 @@
export { Location, Meta, CustomSanitizer, SanitizationChain, sanitize, sanitizeBody, sanitizeCookie, sanitizeParam, sanitizeQuery, buildSanitizeFunction, matchedData, MatchedDataOptions, } from '../src';

14
node_modules/express-validator/filter/index.js generated vendored Normal file
View file

@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var src_1 = require("../src");
// middleware/sanitization-chain-builders
exports.sanitize = src_1.sanitize;
exports.sanitizeBody = src_1.sanitizeBody;
exports.sanitizeCookie = src_1.sanitizeCookie;
exports.sanitizeParam = src_1.sanitizeParam;
exports.sanitizeQuery = src_1.sanitizeQuery;
exports.buildSanitizeFunction = src_1.buildSanitizeFunction;
// matched-data
exports.matchedData = src_1.matchedData;
console.warn('express-validator: requires to express-validator/filter are deprecated.' +
'You should just use require("express-validator") instead.');

109
node_modules/express-validator/package.json generated vendored Normal file
View file

@ -0,0 +1,109 @@
{
"_from": "express-validator",
"_id": "express-validator@6.2.0",
"_inBundle": false,
"_integrity": "sha512-892cPistoSPzMuoG2p1W+2ZxBi0bAvPaaYgXK1E1C8/QncLo2d1HbiDDWkXUtTthjGEzEmwiELLJHu1Ez2hOEg==",
"_location": "/express-validator",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "express-validator",
"name": "express-validator",
"escapedName": "express-validator",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.2.0.tgz",
"_shasum": "294409468ee78e90e908c6a77ea3629bae41fd85",
"_spec": "express-validator",
"_where": "/Users/rodrigopinto/Documents/Development/Tutorials/myserver",
"author": {
"name": "Christoph Tavan",
"email": "dev@tavan.de"
},
"bugs": {
"url": "https://github.com/express-validator/express-validator/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Rusty Bailey",
"email": "rustylbailey@gmail.com"
},
{
"name": "Gustavo Henke",
"email": "guhenke@gmail.com"
}
],
"dependencies": {
"lodash": "^4.17.15",
"validator": "^11.1.0"
},
"deprecated": false,
"description": "Express middleware for the validator module.",
"devDependencies": {
"@types/jest": "^24.0.15",
"@types/lodash": "^4.14.136",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"coveralls": "^3.0.5",
"docusaurus": "^1.12.0",
"eslint": "^5.16.0",
"eslint-config-prettier": "^4.3.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.0",
"jest": "^24.8.0",
"prettier": "^1.18.2",
"ts-jest": "^24.0.2",
"typescript": "^3.5.3"
},
"engines": {
"node": ">= 8.0.0"
},
"files": [
"docs",
"src",
"check",
"filter",
"!*.spec.ts",
"!*.ts",
"*.d.ts"
],
"homepage": "https://express-validator.github.io",
"keywords": [
"express",
"validator",
"validation",
"validate",
"sanitize",
"sanitization",
"xss"
],
"license": "MIT",
"main": "./src/index.js",
"name": "express-validator",
"repository": {
"type": "git",
"url": "git://github.com/express-validator/express-validator.git"
},
"scripts": {
"clean": "git clean -Xf src check filter",
"docs:build": "npm --prefix ./website run build",
"docs:publish": "USE_SSH=true CURRENT_BRANCH=master npm --prefix ./website run publish-gh-pages",
"docs:start": "npm --prefix ./website start",
"docs:version": "npm --prefix ./website run version",
"lint": "eslint 'src/**/*.ts'",
"prepublishOnly": "tsc",
"report-coverage": "cat coverage/lcov.info | coveralls",
"test": "jest",
"version": "npm run docs:version -- $npm_package_version && git add -A website"
},
"types": "./src/index.d.ts",
"version": "6.2.0"
}

45
node_modules/express-validator/src/base.d.ts generated vendored Normal file
View file

@ -0,0 +1,45 @@
import { ReadonlyContext } from './context';
export declare type Location = 'body' | 'cookies' | 'headers' | 'params' | 'query';
export declare type Meta = {
req: Request;
location: Location;
path: string;
};
export declare type CustomValidator = (input: any, meta: Meta) => any;
export declare type StandardValidator = (input: string, ...options: any[]) => boolean;
export declare type CustomSanitizer = (input: any, meta: Meta) => any;
export declare type StandardSanitizer = (input: string, ...options: any[]) => any;
export declare type DynamicMessageCreator = (value: any, meta: Meta) => any;
export interface FieldInstance {
path: string;
originalPath: string;
location: Location;
value: any;
originalValue: any;
}
export declare type ValidationError = {
location?: undefined;
param: '_error';
msg: any;
nestedErrors: ValidationError[];
} | {
location: Location;
param: string;
value: any;
msg: any;
};
export interface Request {
[k: string]: any;
body?: any;
cookies?: Record<string, any>;
headers?: Record<string, any>;
params?: Record<string, any>;
query?: Record<string, any>;
}
export declare const contextsSymbol: unique symbol;
export interface InternalRequest extends Request {
[contextsSymbol]?: ReadonlyContext[];
}
export declare type Middleware = (req: Request, res: any, next: (err?: any) => void) => void;
export declare class ValidationHalt extends Error {
}

6
node_modules/express-validator/src/base.js generated vendored Normal file
View file

@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.contextsSymbol = Symbol('express-validator#contexts');
class ValidationHalt extends Error {
}
exports.ValidationHalt = ValidationHalt;

View file

@ -0,0 +1,13 @@
import { ContextBuilder } from '../context-builder';
import { Optional } from '../context';
import { CustomValidator } from '../base';
import { ContextHandler } from './context-handler';
import { ValidationChain } from './validation-chain';
export declare class ContextHandlerImpl<Chain> implements ContextHandler<Chain> {
private readonly builder;
private readonly chain;
constructor(builder: ContextBuilder, chain: Chain);
bail(): Chain;
if(condition: CustomValidator | ValidationChain): Chain;
optional(options?: Optional | true): Chain;
}

View file

@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const context_items_1 = require("../context-items");
const bail_1 = require("../context-items/bail");
class ContextHandlerImpl {
constructor(builder, chain) {
this.builder = builder;
this.chain = chain;
}
bail() {
this.builder.addItem(new bail_1.Bail());
return this.chain;
}
if(condition) {
if ('run' in condition) {
this.builder.addItem(new context_items_1.ChainCondition(condition));
}
else if (typeof condition === 'function') {
this.builder.addItem(new context_items_1.CustomCondition(condition));
}
else {
throw new Error('express-validator: condition is not a validation chain nor a function');
}
return this.chain;
}
optional(options = true) {
if (typeof options === 'boolean') {
this.builder.setOptional(options ? { checkFalsy: false, nullable: false } : false);
}
else {
this.builder.setOptional({
checkFalsy: !!options.checkFalsy,
nullable: !!options.nullable,
});
}
return this.chain;
}
}
exports.ContextHandlerImpl = ContextHandlerImpl;

View file

@ -0,0 +1,8 @@
import { CustomValidator } from '../base';
import { Optional } from '../context';
import { ValidationChain } from './validation-chain';
export interface ContextHandler<Chain> {
bail(): Chain;
if(condition: CustomValidator | ValidationChain): Chain;
optional(options?: Partial<Optional> | true): Chain;
}

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,12 @@
import { SelectFields } from '../select-fields';
import { Request } from '../base';
import { ContextBuilder } from '../context-builder';
import { ContextRunner } from './context-runner';
export declare class ContextRunnerImpl implements ContextRunner {
private readonly builder;
private readonly selectFields;
constructor(builder: ContextBuilder, selectFields?: SelectFields);
run(req: Request, options?: {
saveContext?: boolean;
}): Promise<import("../context").Context>;
}

View file

@ -0,0 +1,55 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const select_fields_1 = require("../select-fields");
const base_1 = require("../base");
class ContextRunnerImpl {
constructor(builder, selectFields = select_fields_1.selectFields) {
this.builder = builder;
this.selectFields = selectFields;
}
run(req, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
const context = this.builder.build();
const instances = this.selectFields(req, context.fields, context.locations);
context.addFieldInstances(instances);
const haltedInstances = new Set();
for (const contextItem of context.stack) {
const promises = context.getData({ requiredOnly: true }).map((instance) => __awaiter(this, void 0, void 0, function* () {
const instanceKey = `${instance.location}:${instance.path}`;
if (haltedInstances.has(instanceKey)) {
return;
}
try {
yield contextItem.run(context, instance.value, {
req,
location: instance.location,
path: instance.path,
});
}
catch (e) {
if (e instanceof base_1.ValidationHalt) {
haltedInstances.add(instanceKey);
return;
}
throw e;
}
}));
yield Promise.all(promises);
}
if (options.saveContext === undefined || options.saveContext) {
const internalReq = req;
internalReq[base_1.contextsSymbol] = (internalReq[base_1.contextsSymbol] || []).concat(context);
}
return context;
});
}
}
exports.ContextRunnerImpl = ContextRunnerImpl;

View file

@ -0,0 +1,7 @@
import { Request } from '../base';
import { Context } from '../context';
export interface ContextRunner {
run(req: Request, options?: {
saveContext?: boolean;
}): Promise<Context>;
}

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

10
node_modules/express-validator/src/chain/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,10 @@
export * from './sanitizers';
export * from './sanitizers-impl';
export * from './context-handler';
export * from './context-handler-impl';
export * from './context-runner';
export * from './context-runner-impl';
export * from './validators';
export * from './validators-impl';
export * from './sanitization-chain';
export * from './validation-chain';

9
node_modules/express-validator/src/chain/index.js generated vendored Normal file
View file

@ -0,0 +1,9 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./sanitizers-impl"));
__export(require("./context-handler-impl"));
__export(require("./context-runner-impl"));
__export(require("./validators-impl"));

View file

@ -0,0 +1,8 @@
import { Request } from '../base';
import { ContextBuilder } from '../context-builder';
import { Sanitizers } from './sanitizers';
import { ContextRunner } from './context-runner';
export interface SanitizationChain extends Sanitizers<SanitizationChain>, ContextRunner {
(req: Request, res: any, next: (errors?: any) => void): void;
builder: ContextBuilder;
}

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,25 @@
import { CustomSanitizer } from '../base';
import { ContextBuilder } from '../context-builder';
import * as Options from '../options';
import { Sanitizers } from './sanitizers';
export declare class SanitizersImpl<Chain> implements Sanitizers<Chain> {
private readonly builder;
private readonly chain;
constructor(builder: ContextBuilder, chain: Chain);
customSanitizer(sanitizer: CustomSanitizer): Chain;
private addStandardSanitization;
blacklist(chars: string): Chain;
escape(): Chain;
unescape(): Chain;
ltrim(chars?: string): Chain;
normalizeEmail(options?: Options.NormalizeEmailOptions): Chain;
rtrim(chars?: string): Chain;
stripLow(keep_new_lines?: boolean): Chain;
toArray(): Chain;
toBoolean(strict?: boolean): Chain;
toDate(): Chain;
toFloat(): Chain;
toInt(radix?: number): Chain;
trim(chars?: string): Chain;
whitelist(chars: string): Chain;
}

View file

@ -0,0 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const validator = require("validator");
const sanitization_1 = require("../context-items/sanitization");
class SanitizersImpl {
constructor(builder, chain) {
this.builder = builder;
this.chain = chain;
}
customSanitizer(sanitizer) {
this.builder.addItem(new sanitization_1.Sanitization(sanitizer, true));
return this.chain;
}
// Standard sanitizers
addStandardSanitization(sanitizer, ...options) {
this.builder.addItem(new sanitization_1.Sanitization(sanitizer, false, options));
return this.chain;
}
blacklist(chars) {
return this.addStandardSanitization(validator.blacklist, chars);
}
escape() {
return this.addStandardSanitization(validator.escape);
}
unescape() {
return this.addStandardSanitization(validator.unescape);
}
ltrim(chars) {
return this.addStandardSanitization(validator.ltrim, chars);
}
normalizeEmail(options) {
return this.addStandardSanitization(validator.normalizeEmail, options);
}
rtrim(chars) {
return this.addStandardSanitization(validator.rtrim, chars);
}
stripLow(keep_new_lines) {
return this.addStandardSanitization(validator.stripLow, keep_new_lines);
}
toArray() {
return this.customSanitizer(value => (value !== undefined && ((Array.isArray(value) && value) || [value])) || []);
}
toBoolean(strict) {
return this.addStandardSanitization(validator.toBoolean, strict);
}
toDate() {
return this.addStandardSanitization(validator.toDate);
}
toFloat() {
return this.addStandardSanitization(validator.toFloat);
}
toInt(radix) {
return this.addStandardSanitization(validator.toInt, radix);
}
trim(chars) {
return this.addStandardSanitization(validator.trim, chars);
}
whitelist(chars) {
return this.addStandardSanitization(validator.whitelist, chars);
}
}
exports.SanitizersImpl = SanitizersImpl;

View file

@ -0,0 +1,19 @@
import { CustomSanitizer } from '../base';
import * as Options from '../options';
export interface Sanitizers<Return> {
customSanitizer(sanitizer: CustomSanitizer): Return;
blacklist(chars: string): Return;
escape(): Return;
unescape(): Return;
ltrim(chars?: string): Return;
normalizeEmail(options?: Options.NormalizeEmailOptions): Return;
rtrim(chars?: string): Return;
stripLow(keep_new_lines?: boolean): Return;
toArray(): Return;
toBoolean(strict?: boolean): Return;
toDate(): Return;
toFloat(): Return;
toInt(radix?: number): Return;
trim(chars?: string): Return;
whitelist(chars: string): Return;
}

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,10 @@
import { Request } from '../base';
import { ContextBuilder } from '../context-builder';
import { Sanitizers } from './sanitizers';
import { Validators } from './validators';
import { ContextHandler } from './context-handler';
import { ContextRunner } from './context-runner';
export interface ValidationChain extends Validators<ValidationChain>, Sanitizers<ValidationChain>, ContextHandler<ValidationChain>, ContextRunner {
(req: Request, res: any, next: (error?: any) => void): void;
builder: ContextBuilder;
}

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,85 @@
import { CustomValidator } from '../base';
import { ContextBuilder } from '../context-builder';
import * as Options from '../options';
import { Validators } from './validators';
export declare class ValidatorsImpl<Chain> implements Validators<Chain> {
private readonly builder;
private readonly chain;
private lastValidator;
private negateNext;
constructor(builder: ContextBuilder, chain: Chain);
private addItem;
not(): Chain;
withMessage(message: any): Chain;
custom(validator: CustomValidator): Chain;
exists(options?: {
checkFalsy?: boolean;
checkNull?: boolean;
}): Chain;
isArray(options?: {
min?: number;
max?: number;
}): Chain;
isString(): Chain;
private addStandardValidation;
contains(elem: any): Chain;
equals(comparison: string): Chain;
isAfter(date?: string): Chain;
isAlpha(locale?: Options.AlphaLocale): Chain;
isAlphanumeric(locale?: Options.AlphanumericLocale): Chain;
isAscii(): Chain;
isBase32(): Chain;
isBase64(): Chain;
isBefore(date?: string): Chain;
isBoolean(): Chain;
isByteLength(options: Options.MinMaxOptions): Chain;
isCreditCard(): Chain;
isCurrency(options?: Options.IsCurrencyOptions): Chain;
isDataURI(): Chain;
isDecimal(options?: Options.IsDecimalOptions): Chain;
isDivisibleBy(number: number): Chain;
isEmail(options?: Options.IsEmailOptions): Chain;
isEmpty(options?: Options.IsEmptyOptions): Chain;
isFQDN(options?: Options.IsFQDNOptions): Chain;
isFloat(options?: Options.IsFloatOptions): Chain;
isFullWidth(): Chain;
isHalfWidth(): Chain;
isHash(algorithm: Options.HashAlgorithm): Chain;
isHexColor(): Chain;
isHexadecimal(): Chain;
isIdentityCard(locale: ['ES'] | 'any'): Chain;
isIP(version?: Options.IPVersion): Chain;
isIPRange(): Chain;
isISBN(version?: number): Chain;
isISSN(options?: Options.IsISSNOptions): Chain;
isISIN(): Chain;
isISO8601(options?: Options.IsISO8601Options): Chain;
isISO31661Alpha2(): Chain;
isISO31661Alpha3(): Chain;
isISRC(): Chain;
isIn(values: any[]): Chain;
isInt(options?: Options.IsIntOptions): Chain;
isJSON(): Chain;
isJWT(): Chain;
isLatLong(): Chain;
isLength(options: Options.MinMaxOptions): Chain;
isLowercase(): Chain;
isMagnetURI(): Chain;
isMACAddress(options?: Options.IsMACAddressOptions): Chain;
isMD5(): Chain;
isMimeType(): Chain;
isMobilePhone(locale: Options.MobilePhoneLocale, options?: Options.IsMobilePhoneOptions): Chain;
isMongoId(): Chain;
isMultibyte(): Chain;
isNumeric(options?: Options.IsNumericOptions): Chain;
isPort(): Chain;
isPostalCode(locale: Options.PostalCodeLocale): Chain;
isRFC3339(): Chain;
isSurrogatePair(): Chain;
isURL(options?: Options.IsURLOptions): Chain;
isUUID(version?: Options.UUIDVersion): Chain;
isUppercase(): Chain;
isVariableWidth(): Chain;
isWhitelisted(chars: string | string[]): Chain;
matches(pattern: RegExp | string, modifiers?: string): Chain;
}

View file

@ -0,0 +1,237 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const validator = require("validator");
const context_items_1 = require("../context-items");
class ValidatorsImpl {
constructor(builder, chain) {
this.builder = builder;
this.chain = chain;
this.negateNext = false;
}
addItem(item) {
this.builder.addItem(item);
this.lastValidator = item;
// Reset this.negateNext so that next validation isn't negated too
this.negateNext = false;
return this.chain;
}
// validation manipulation
not() {
this.negateNext = true;
return this.chain;
}
withMessage(message) {
this.lastValidator.message = message;
return this.chain;
}
// custom validators
custom(validator) {
return this.addItem(new context_items_1.CustomValidation(validator, this.negateNext));
}
exists(options = {}) {
let validator;
if (options.checkFalsy) {
validator = value => !!value;
}
else if (options.checkNull) {
validator = value => value != null;
}
else {
validator = value => value !== undefined;
}
return this.custom(validator);
}
isArray(options = {}) {
return this.custom(value => Array.isArray(value) &&
(typeof options.min === 'undefined' || value.length >= options.min) &&
(typeof options.max === 'undefined' || value.length <= options.max));
}
isString() {
return this.custom(value => typeof value === 'string');
}
// Standard validators
addStandardValidation(validator, ...options) {
return this.addItem(new context_items_1.StandardValidation(validator, this.negateNext, options));
}
contains(elem) {
return this.addStandardValidation(validator.contains, elem);
}
equals(comparison) {
return this.addStandardValidation(validator.equals, comparison);
}
isAfter(date) {
return this.addStandardValidation(validator.isAfter, date);
}
isAlpha(locale) {
return this.addStandardValidation(validator.isAlpha, locale);
}
isAlphanumeric(locale) {
return this.addStandardValidation(validator.isAlphanumeric, locale);
}
isAscii() {
return this.addStandardValidation(validator.isAscii);
}
isBase32() {
return this.addStandardValidation(validator.isBase32);
}
isBase64() {
return this.addStandardValidation(validator.isBase64);
}
isBefore(date) {
return this.addStandardValidation(validator.isBefore, date);
}
isBoolean() {
return this.addStandardValidation(validator.isBoolean);
}
isByteLength(options) {
return this.addStandardValidation(validator.isByteLength, options);
}
isCreditCard() {
return this.addStandardValidation(validator.isCreditCard);
}
isCurrency(options) {
return this.addStandardValidation(validator.isCurrency, options);
}
isDataURI() {
return this.addStandardValidation(validator.isDataURI);
}
isDecimal(options) {
return this.addStandardValidation(validator.isDecimal, options);
}
isDivisibleBy(number) {
return this.addStandardValidation(validator.isDivisibleBy, number);
}
isEmail(options) {
return this.addStandardValidation(validator.isEmail, options);
}
isEmpty(options) {
return this.addStandardValidation(validator.isEmpty, options);
}
isFQDN(options) {
return this.addStandardValidation(validator.isFQDN, options);
}
isFloat(options) {
return this.addStandardValidation(validator.isFloat, options);
}
isFullWidth() {
return this.addStandardValidation(validator.isFullWidth);
}
isHalfWidth() {
return this.addStandardValidation(validator.isHalfWidth);
}
isHash(algorithm) {
return this.addStandardValidation(validator.isHash, algorithm);
}
isHexColor() {
return this.addStandardValidation(validator.isHexColor);
}
isHexadecimal() {
return this.addStandardValidation(validator.isHexadecimal);
}
isIdentityCard(locale) {
return this.addStandardValidation(validator.isIdentityCard, locale);
}
isIP(version) {
return this.addStandardValidation(validator.isIP, version);
}
isIPRange() {
return this.addStandardValidation(validator.isIPRange);
}
isISBN(version) {
return this.addStandardValidation(validator.isISBN, version);
}
isISSN(options) {
return this.addStandardValidation(validator.isISSN, options);
}
isISIN() {
return this.addStandardValidation(validator.isISIN);
}
isISO8601(options) {
return this.addStandardValidation(validator.isISO8601, options);
}
isISO31661Alpha2() {
return this.addStandardValidation(validator.isISO31661Alpha2);
}
isISO31661Alpha3() {
return this.addStandardValidation(validator.isISO31661Alpha3);
}
isISRC() {
return this.addStandardValidation(validator.isISRC);
}
isIn(values) {
return this.addStandardValidation(validator.isIn, values);
}
isInt(options) {
return this.addStandardValidation(validator.isInt, options);
}
isJSON() {
return this.addStandardValidation(validator.isJSON);
}
isJWT() {
return this.addStandardValidation(validator.isJWT);
}
isLatLong() {
return this.addStandardValidation(validator.isLatLong);
}
isLength(options) {
return this.addStandardValidation(validator.isLength, options);
}
isLowercase() {
return this.addStandardValidation(validator.isLowercase);
}
isMagnetURI() {
return this.addStandardValidation(validator.isMagnetURI);
}
isMACAddress(options) {
return this.addStandardValidation(validator.isMACAddress, options);
}
isMD5() {
return this.addStandardValidation(validator.isMD5);
}
isMimeType() {
return this.addStandardValidation(validator.isMimeType);
}
isMobilePhone(locale, options) {
return this.addStandardValidation(validator.isMobilePhone, locale, options);
}
isMongoId() {
return this.addStandardValidation(validator.isMongoId);
}
isMultibyte() {
return this.addStandardValidation(validator.isMultibyte);
}
isNumeric(options) {
return this.addStandardValidation(validator.isNumeric, options);
}
isPort() {
return this.addStandardValidation(validator.isPort);
}
isPostalCode(locale) {
return this.addStandardValidation(validator.isPostalCode, locale);
}
isRFC3339() {
return this.addStandardValidation(validator.isRFC3339);
}
isSurrogatePair() {
return this.addStandardValidation(validator.isSurrogatePair);
}
isURL(options) {
return this.addStandardValidation(validator.isURL, options);
}
isUUID(version) {
return this.addStandardValidation(validator.isUUID, version);
}
isUppercase() {
return this.addStandardValidation(validator.isUppercase);
}
isVariableWidth() {
return this.addStandardValidation(validator.isVariableWidth);
}
isWhitelisted(chars) {
return this.addStandardValidation(validator.isWhitelisted, chars);
}
matches(pattern, modifiers) {
return this.addStandardValidation(validator.matches, pattern, modifiers);
}
}
exports.ValidatorsImpl = ValidatorsImpl;

View file

@ -0,0 +1,77 @@
import { CustomValidator, DynamicMessageCreator } from '../base';
import * as Options from '../options';
export interface Validators<Return> {
not(): Return;
withMessage(message: DynamicMessageCreator): Return;
withMessage(message: any): Return;
custom(validator: CustomValidator): Return;
exists(options?: {
checkFalsy?: boolean;
checkNull?: boolean;
}): Return;
isArray(options?: {
min?: number;
max?: number;
}): Return;
isString(): Return;
contains(elem: any): Return;
equals(comparison: string): Return;
isAfter(date?: string): Return;
isAlpha(locale?: Options.AlphaLocale): Return;
isAlphanumeric(locale?: Options.AlphanumericLocale): Return;
isAscii(): Return;
isBase32(): Return;
isBase64(): Return;
isBefore(date?: string): Return;
isBoolean(): Return;
isByteLength(options: Options.MinMaxExtendedOptions): Return;
isCreditCard(): Return;
isCurrency(options?: Options.IsCurrencyOptions): Return;
isDataURI(): Return;
isDecimal(options?: Options.IsDecimalOptions): Return;
isDivisibleBy(number: number): Return;
isEmail(options?: Options.IsEmailOptions): Return;
isEmpty(options?: Options.IsEmptyOptions): Return;
isFQDN(options?: Options.IsFQDNOptions): Return;
isFloat(options?: Options.IsFloatOptions): Return;
isFullWidth(): Return;
isHalfWidth(): Return;
isHash(algorithm: Options.HashAlgorithm): Return;
isHexColor(): Return;
isHexadecimal(): Return;
isIdentityCard(locale?: ['ES'] | 'any'): Return;
isIP(version?: Options.IPVersion): Return;
isIPRange(): Return;
isISBN(version?: number): Return;
isISSN(options?: Options.IsISSNOptions): Return;
isISIN(): Return;
isISO8601(options?: Options.IsISO8601Options): Return;
isISO31661Alpha2(): Return;
isISO31661Alpha3(): Return;
isISRC(): Return;
isIn(values: any[]): Return;
isInt(options?: Options.IsIntOptions): Return;
isJSON(): Return;
isJWT(): Return;
isLatLong(): Return;
isLength(options: Options.MinMaxOptions): Return;
isLowercase(): Return;
isMagnetURI(): Return;
isMACAddress(options?: Options.IsMACAddressOptions): Return;
isMD5(): Return;
isMimeType(): Return;
isMobilePhone(locale: Options.MobilePhoneLocale, options?: Options.IsMobilePhoneOptions): Return;
isMongoId(): Return;
isMultibyte(): Return;
isNumeric(options?: Options.IsNumericOptions): Return;
isPort(): Return;
isPostalCode(locale: Options.PostalCodeLocale): Return;
isRFC3339(): Return;
isSurrogatePair(): Return;
isURL(options?: Options.IsURLOptions): Return;
isUUID(version?: Options.UUIDVersion): Return;
isUppercase(): Return;
isVariableWidth(): Return;
isWhitelisted(chars: string | string[]): Return;
matches(pattern: RegExp | string, modifiers?: string): Return;
}

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,16 @@
import { ContextItem } from './context-items';
import { Context, Optional } from './context';
import { Location } from './base';
export declare class ContextBuilder {
private readonly stack;
private fields;
private locations;
private message;
private optional;
setFields(fields: string[]): this;
setLocations(locations: Location[]): this;
setMessage(message: any): this;
addItem(...items: ContextItem[]): this;
setOptional(options: Optional): this;
build(): Context;
}

35
node_modules/express-validator/src/context-builder.js generated vendored Normal file
View file

@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const context_1 = require("./context");
class ContextBuilder {
constructor() {
this.stack = [];
this.fields = [];
this.locations = [];
this.optional = false;
}
setFields(fields) {
this.fields = fields;
return this;
}
setLocations(locations) {
this.locations = locations;
return this;
}
setMessage(message) {
this.message = message;
return this;
}
addItem(...items) {
this.stack.push(...items);
return this;
}
setOptional(options) {
this.optional = options;
return this;
}
build() {
return new context_1.Context(this.fields, this.locations, this.stack, this.optional, this.message);
}
}
exports.ContextBuilder = ContextBuilder;

View file

@ -0,0 +1,5 @@
import { Context } from '../context';
import { ContextItem } from './context-item';
export declare class Bail implements ContextItem {
run(context: Context): Promise<void>;
}

View file

@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = require("../base");
class Bail {
run(context) {
if (context.errors.length > 0) {
throw new base_1.ValidationHalt();
}
return Promise.resolve();
}
}
exports.Bail = Bail;

View file

@ -0,0 +1,9 @@
import { ValidationChain } from '../chain';
import { Meta } from '../base';
import { Context } from '../context';
import { ContextItem } from './context-item';
export declare class ChainCondition implements ContextItem {
private readonly chain;
constructor(chain: ValidationChain);
run(_context: Context, _value: any, meta: Meta): Promise<void>;
}

View file

@ -0,0 +1,25 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = require("../base");
class ChainCondition {
constructor(chain) {
this.chain = chain;
}
run(_context, _value, meta) {
return __awaiter(this, void 0, void 0, function* () {
const otherContext = yield this.chain.run(meta.req, { saveContext: false });
if (otherContext.errors.length) {
throw new base_1.ValidationHalt();
}
});
}
}
exports.ChainCondition = ChainCondition;

View file

@ -0,0 +1,5 @@
import { Meta } from '../base';
import { Context } from '../context';
export interface ContextItem {
run(context: Context, value: any, meta: Meta): Promise<void>;
}

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,8 @@
import { CustomValidator, Meta } from '../base';
import { Context } from '../context';
import { ContextItem } from './context-item';
export declare class CustomCondition implements ContextItem {
private readonly condition;
constructor(condition: CustomValidator);
run(_context: Context, value: any, meta: Meta): Promise<void>;
}

View file

@ -0,0 +1,33 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = require("../base");
class CustomCondition {
constructor(condition) {
this.condition = condition;
}
run(_context, value, meta) {
return __awaiter(this, void 0, void 0, function* () {
try {
const result = this.condition(value, meta);
yield result;
// if the promise resolved or the result is truthy somehow, then there's no validation halt.
if (!result) {
// the error thrown here is symbolic, it will be re-thrown in the catch clause anyway.
throw new Error();
}
}
catch (e) {
throw new base_1.ValidationHalt();
}
});
}
}
exports.CustomCondition = CustomCondition;

View file

@ -0,0 +1,10 @@
import { CustomValidator, Meta } from '../base';
import { Context } from '../context';
import { ContextItem } from './context-item';
export declare class CustomValidation implements ContextItem {
private readonly validator;
private readonly negated;
message: any;
constructor(validator: CustomValidator, negated: boolean);
run(context: Context, value: any, meta: Meta): Promise<void>;
}

View file

@ -0,0 +1,38 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
class CustomValidation {
constructor(validator, negated) {
this.validator = validator;
this.negated = negated;
}
run(context, value, meta) {
return __awaiter(this, void 0, void 0, function* () {
try {
const result = this.validator(value, meta);
const actualResult = yield result;
const isPromise = result && result.then;
const failed = this.negated ? actualResult : !actualResult;
// A promise that was resolved only adds an error if negated.
// Otherwise it always suceeds
if ((!isPromise && failed) || (isPromise && this.negated)) {
context.addError(this.message, value, meta);
}
}
catch (err) {
if (this.negated) {
return;
}
context.addError((err instanceof Error ? err.message : err) || this.message, value, meta);
}
});
}
}
exports.CustomValidation = CustomValidation;

View file

@ -0,0 +1,5 @@
export * from './chain-condition';
export * from './context-item';
export * from './custom-condition';
export * from './custom-validation';
export * from './standard-validation';

View file

@ -0,0 +1,9 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./chain-condition"));
__export(require("./custom-condition"));
__export(require("./custom-validation"));
__export(require("./standard-validation"));

View file

@ -0,0 +1,10 @@
import { Context } from '../context';
import { CustomSanitizer, Meta, StandardSanitizer } from '../base';
import { ContextItem } from './context-item';
export declare class Sanitization implements ContextItem {
private readonly sanitizer;
private readonly custom;
private readonly options;
constructor(sanitizer: StandardSanitizer | CustomSanitizer, custom: boolean, options?: any[]);
run(context: Context, value: any, meta: Meta): Promise<void>;
}

View file

@ -0,0 +1,35 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const utils_1 = require("../utils");
class Sanitization {
constructor(sanitizer, custom, options = []) {
this.sanitizer = sanitizer;
this.custom = custom;
this.options = options;
}
run(context, value, meta) {
return __awaiter(this, void 0, void 0, function* () {
const { req, path, location } = meta;
const newValue = this.custom
? this.sanitizer(value, meta)
: this.sanitizer(utils_1.toString(value), ...this.options);
context.setData(path, newValue, location);
// Checks whether the value changed.
// Avoids e.g. undefined values being set on the request if it didn't have the key initially.
const reqValue = path !== '' ? _.get(req[location], path) : req[location];
if (reqValue !== newValue) {
path !== '' ? _.set(req[location], path, newValue) : _.set(req, location, newValue);
}
});
}
}
exports.Sanitization = Sanitization;

View file

@ -0,0 +1,11 @@
import { Meta, StandardValidator } from '../base';
import { Context } from '../context';
import { ContextItem } from './context-item';
export declare class StandardValidation implements ContextItem {
private readonly validator;
private readonly negated;
private readonly options;
message: any;
constructor(validator: StandardValidator, negated: boolean, options?: any[]);
run(context: Context, value: any, meta: Meta): Promise<void>;
}

View file

@ -0,0 +1,27 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../utils");
class StandardValidation {
constructor(validator, negated, options = []) {
this.validator = validator;
this.negated = negated;
this.options = options;
}
run(context, value, meta) {
return __awaiter(this, void 0, void 0, function* () {
const result = this.validator(utils_1.toString(value), ...this.options);
if (this.negated ? result : !result) {
context.addError(this.message, value, meta);
}
});
}
}
exports.StandardValidation = StandardValidation;

25
node_modules/express-validator/src/context.d.ts generated vendored Normal file
View file

@ -0,0 +1,25 @@
import { FieldInstance, Location, Meta, ValidationError } from './base';
import { ContextItem } from './context-items';
export declare type Optional = {
nullable: boolean;
checkFalsy: boolean;
} | false;
export declare class Context {
readonly fields: string[];
readonly locations: Location[];
readonly stack: ReadonlyArray<ContextItem>;
readonly optional: Optional;
readonly message?: any;
private readonly _errors;
readonly errors: ReadonlyArray<ValidationError>;
private readonly dataMap;
constructor(fields: string[], locations: Location[], stack: ReadonlyArray<ContextItem>, optional: Optional, message?: any);
getData(options?: {
requiredOnly: boolean;
}): FieldInstance[];
addFieldInstances(instances: FieldInstance[]): void;
setData(path: string, value: any, location: Location): void;
addError(message: any, value: any, meta: Meta): void;
addError(message: any, nestedErrors: ValidationError[]): void;
}
export declare type ReadonlyContext = Pick<Context, Exclude<keyof Context, 'setData' | 'addFieldInstances' | 'addError'>>;

79
node_modules/express-validator/src/context.js generated vendored Normal file
View file

@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
function getDataMapKey(path, location) {
return `${location}:${path}`;
}
class Context {
constructor(fields, locations, stack, optional, message) {
this.fields = fields;
this.locations = locations;
this.stack = stack;
this.optional = optional;
this.message = message;
this._errors = [];
this.dataMap = new Map();
}
get errors() {
return this._errors;
}
getData(options = { requiredOnly: false }) {
// Have to store this.optional in a const otherwise TS thinks the value could have changed
// when the functions below run
const { optional } = this;
const checks = options.requiredOnly && optional
? [
(value) => value !== undefined,
(value) => (optional.nullable ? value != null : true),
(value) => (optional.checkFalsy ? value : true),
]
: [];
return _([...this.dataMap.values()])
.groupBy('originalPath')
.flatMap((instances, group) => {
const locations = _.uniqBy(instances, 'location');
// #331 - When multiple locations are involved, all of them must pass the validation.
// If none of the locations contain the field, we at least include one for error reporting.
// #458, #531 - Wildcards are an exception though: they may yield 0..* instances with different
// paths, so we may want to skip this filtering.
if (instances.length > 1 && locations.length > 1 && !group.includes('*')) {
const withValue = instances.filter(instance => instance.value !== undefined);
return withValue.length ? withValue : [instances[0]];
}
return instances;
})
.filter(instance => checks.every(check => check(instance.value)))
.valueOf();
}
addFieldInstances(instances) {
instances.forEach(instance => {
this.dataMap.set(getDataMapKey(instance.path, instance.location), Object.assign({}, instance));
});
}
setData(path, value, location) {
const instance = this.dataMap.get(getDataMapKey(path, location));
if (!instance) {
throw new Error('Attempt to write data that did not pre-exist in context');
}
instance.value = value;
}
addError(message, valueOrNestedErrors, meta) {
const msg = message || this.message || 'Invalid value';
if (meta) {
this._errors.push({
value: valueOrNestedErrors,
msg: typeof msg === 'function' ? msg(valueOrNestedErrors, meta) : msg,
param: meta.path,
location: meta.location,
});
}
else {
this._errors.push({
msg,
param: '_error',
nestedErrors: valueOrNestedErrors,
});
}
}
}
exports.Context = Context;

9
node_modules/express-validator/src/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,9 @@
export { Location, Meta, CustomValidator, CustomSanitizer, DynamicMessageCreator, ValidationError, } from './base';
export { SanitizationChain, ValidationChain } from './chain';
export * from './middlewares/one-of';
export * from './middlewares/sanitization-chain-builders';
export * from './middlewares/validation-chain-builders';
export { checkSchema, Schema, ValidationSchema, // Deprecated
ParamSchema, ValidationParamSchema, } from './middlewares/schema';
export * from './matched-data';
export * from './validation-result';

12
node_modules/express-validator/src/index.js generated vendored Normal file
View file

@ -0,0 +1,12 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./middlewares/one-of"));
__export(require("./middlewares/sanitization-chain-builders"));
__export(require("./middlewares/validation-chain-builders"));
var schema_1 = require("./middlewares/schema");
exports.checkSchema = schema_1.checkSchema;
__export(require("./matched-data"));
__export(require("./validation-result"));

7
node_modules/express-validator/src/matched-data.d.ts generated vendored Normal file
View file

@ -0,0 +1,7 @@
import { Location, Request } from './base';
export declare type MatchedDataOptions = {
includeOptionals: boolean;
locations: Location[];
onlyValidData: boolean;
};
export declare function matchedData(req: Request, options?: Partial<MatchedDataOptions>): Record<string, any>;

37
node_modules/express-validator/src/matched-data.js generated vendored Normal file
View file

@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const base_1 = require("./base");
function matchedData(req, options = {}) {
const internalReq = req;
const fieldExtractor = createFieldExtractor(options.includeOptionals !== true);
const validityFilter = createValidityFilter(options.onlyValidData);
const locationFilter = createLocationFilter(options.locations);
return _(internalReq[base_1.contextsSymbol])
.flatMap(fieldExtractor)
.filter(validityFilter)
.map(field => field.instance)
.filter(locationFilter)
.reduce((state, instance) => _.set(state, instance.path, instance.value), {})
.valueOf();
}
exports.matchedData = matchedData;
function createFieldExtractor(removeOptionals) {
return (context) => {
const instances = context.getData({ requiredOnly: removeOptionals });
return instances.map((instance) => ({ instance, context }));
};
}
function createValidityFilter(onlyValidData = true) {
return !onlyValidData
? () => true
: (field) => {
const hasError = field.context.errors.some(error => error.location === field.instance.location && error.param === field.instance.path);
return !hasError;
};
}
function createLocationFilter(locations = []) {
// No locations mean all locations
const allLocations = locations.length === 0;
return allLocations ? () => true : (field) => locations.includes(field.location);
}

View file

@ -0,0 +1,3 @@
import { ValidationChain } from '../chain';
import { Location } from '../base';
export declare function check(fields?: string | string[], locations?: Location[], message?: any): ValidationChain;

View file

@ -0,0 +1,31 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const chain_1 = require("../chain");
const utils_1 = require("../utils");
const context_builder_1 = require("../context-builder");
function check(fields = '', locations = [], message) {
const builder = new context_builder_1.ContextBuilder()
.setFields(Array.isArray(fields) ? fields : [fields])
.setLocations(locations)
.setMessage(message);
const runner = new chain_1.ContextRunnerImpl(builder);
const middleware = (req, _res, next) => __awaiter(this, void 0, void 0, function* () {
try {
yield runner.run(req);
next();
}
catch (e) {
next(e);
}
});
return Object.assign(middleware, utils_1.bindAll(runner), utils_1.bindAll(new chain_1.SanitizersImpl(builder, middleware)), utils_1.bindAll(new chain_1.ValidatorsImpl(builder, middleware)), utils_1.bindAll(new chain_1.ContextHandlerImpl(builder, middleware)), { builder });
}
exports.check = check;

View file

@ -0,0 +1,7 @@
import { ValidationChain } from '../chain';
import { Middleware, Request } from '../base';
export declare type OneOfCustomMessageBuilder = (options: {
req: Request;
}) => any;
export declare function oneOf(chains: (ValidationChain | ValidationChain[])[], message?: OneOfCustomMessageBuilder): Middleware;
export declare function oneOf(chains: (ValidationChain | ValidationChain[])[], message?: any): Middleware;

View file

@ -0,0 +1,46 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const base_1 = require("../base");
const context_builder_1 = require("../context-builder");
function oneOf(chains, message) {
return (req, _res, next) => __awaiter(this, void 0, void 0, function* () {
const surrogateContext = new context_builder_1.ContextBuilder().build();
// Run each group of chains in parallel, and within each group, run each chain in parallel too.
const promises = chains.map((chain) => __awaiter(this, void 0, void 0, function* () {
const group = Array.isArray(chain) ? chain : [chain];
const contexts = yield Promise.all(group.map(chain => chain.run(req, { saveContext: false })));
const groupErrors = _.flatMap(contexts, 'errors');
// #536: The data from a chain within oneOf() can only be made available to e.g. matchedData()
// if its entire group is valid.
if (!groupErrors.length) {
contexts.forEach(context => {
surrogateContext.addFieldInstances(context.getData());
});
}
return groupErrors;
}));
req[base_1.contextsSymbol] = (req[base_1.contextsSymbol] || []).concat(surrogateContext);
try {
const allErrors = yield Promise.all(promises);
const success = allErrors.some(groupErrors => groupErrors.length === 0);
if (!success) {
// Only add an error to the context if no group of chains had success.
surrogateContext.addError(typeof message === 'function' ? message({ req }) : message || 'Invalid value(s)', _.flatMap(allErrors));
}
next();
}
catch (e) {
next(e);
}
});
}
exports.oneOf = oneOf;

View file

@ -0,0 +1,7 @@
import { Location } from '../base';
export declare function buildSanitizeFunction(locations: Location[]): (fields?: string | string[] | undefined) => import("..").SanitizationChain;
export declare const sanitize: (fields?: string | string[] | undefined) => import("..").SanitizationChain;
export declare const sanitizeBody: (fields?: string | string[] | undefined) => import("..").SanitizationChain;
export declare const sanitizeCookie: (fields?: string | string[] | undefined) => import("..").SanitizationChain;
export declare const sanitizeParam: (fields?: string | string[] | undefined) => import("..").SanitizationChain;
export declare const sanitizeQuery: (fields?: string | string[] | undefined) => import("..").SanitizationChain;

View file

@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sanitize_1 = require("./sanitize");
function buildSanitizeFunction(locations) {
return (fields) => sanitize_1.sanitize(fields, locations);
}
exports.buildSanitizeFunction = buildSanitizeFunction;
exports.sanitize = buildSanitizeFunction(['body', 'cookies', 'params', 'query']);
exports.sanitizeBody = buildSanitizeFunction(['body']);
exports.sanitizeCookie = buildSanitizeFunction(['cookies']);
exports.sanitizeParam = buildSanitizeFunction(['params']);
exports.sanitizeQuery = buildSanitizeFunction(['query']);

View file

@ -0,0 +1,3 @@
import { SanitizationChain } from '../chain';
import { Location } from '../base';
export declare function sanitize(fields?: string | string[], locations?: Location[]): SanitizationChain;

View file

@ -0,0 +1,30 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const chain_1 = require("../chain");
const utils_1 = require("../utils");
const context_builder_1 = require("../context-builder");
function sanitize(fields = '', locations = []) {
const builder = new context_builder_1.ContextBuilder()
.setFields(Array.isArray(fields) ? fields : [fields])
.setLocations(locations);
const runner = new chain_1.ContextRunnerImpl(builder);
const middleware = (req, _res, next) => __awaiter(this, void 0, void 0, function* () {
try {
yield runner.run(req);
next();
}
catch (e) {
next(e);
}
});
return Object.assign(middleware, utils_1.bindAll(runner), utils_1.bindAll(new chain_1.SanitizersImpl(builder, middleware)), { builder });
}
exports.sanitize = sanitize;

View file

@ -0,0 +1,44 @@
import { Sanitizers } from '../chain/sanitizers';
import { Validators } from '../chain/validators';
import { DynamicMessageCreator, Location } from '../base';
import { Optional } from '../context';
declare type ValidatorSchemaOptions<K extends keyof Validators<any>> = true | {
options?: Parameters<Validators<any>[K]> | Parameters<Validators<any>[K]>[0];
errorMessage?: DynamicMessageCreator | any;
negated?: boolean;
};
export declare type ValidatorsSchema = {
[K in keyof Validators<any>]?: ValidatorSchemaOptions<K>;
};
declare type SanitizerSchemaOptions<K extends keyof Sanitizers<any>> = true | {
options?: Parameters<Sanitizers<any>[K]> | Parameters<Sanitizers<any>[K]>[0];
};
export declare type SanitizersSchema = {
[K in keyof Sanitizers<any>]?: SanitizerSchemaOptions<K>;
};
declare type InternalParamSchema = ValidatorsSchema & SanitizersSchema;
/**
* Defines a schema of validations/sanitizations plus a general validation error message
* and possible field locations.
*/
export declare type ParamSchema = InternalParamSchema & {
in?: Location | Location[];
errorMessage?: DynamicMessageCreator | any;
optional?: true | {
options?: Partial<Optional>;
};
};
/**
* @deprecated Only here for v5 compatibility. Please use ParamSchema instead.
*/
export declare type ValidationParamSchema = ParamSchema;
/**
* Defines a mapping from field name to a validations/sanitizations schema.
*/
export declare type Schema = Record<string, ParamSchema>;
/**
* @deprecated Only here for v5 compatibility. Please use Schema instead.
*/
export declare type ValidationSchema = Schema;
export declare function checkSchema(schema: Schema, defaultLocations?: Location[]): import("../chain").ValidationChain[];
export {};

View file

@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chain_1 = require("../chain");
const check_1 = require("./check");
const validLocations = ['body', 'cookies', 'headers', 'params', 'query'];
const protectedNames = ['errorMessage', 'in'];
function checkSchema(schema, defaultLocations = validLocations) {
return Object.keys(schema).map(field => {
const config = schema[field];
const chain = check_1.check(field, ensureLocations(config, defaultLocations), config.errorMessage);
Object.keys(config)
.filter((method) => {
return config[method] && !protectedNames.includes(method);
})
.forEach(method => {
if (typeof chain[method] !== 'function') {
console.warn(`express-validator: a validator/sanitizer with name ${method} does not exist`);
return;
}
// Using "!" because typescript doesn't know it isn't undefined.
const methodCfg = config[method];
let options = methodCfg === true ? [] : methodCfg.options || [];
if (options != null && !Array.isArray(options)) {
options = [options];
}
if (isValidatorOptions(method, methodCfg) && methodCfg.negated) {
chain.not();
}
chain[method](...options);
if (isValidatorOptions(method, methodCfg) && methodCfg.errorMessage) {
chain.withMessage(methodCfg.errorMessage);
}
});
return chain;
});
}
exports.checkSchema = checkSchema;
function isValidatorOptions(method, methodCfg) {
return methodCfg !== true && method in chain_1.ValidatorsImpl.prototype;
}
function ensureLocations(config, defaults) {
// .filter(Boolean) is done because in can be undefined -- which is not going away from the type
// See https://github.com/Microsoft/TypeScript/pull/29955 for details
const locations = Array.isArray(config.in)
? config.in
: [config.in].filter(Boolean);
const actualLocations = locations.length ? locations : defaults;
return actualLocations.filter(location => validLocations.includes(location));
}

View file

@ -0,0 +1,8 @@
import { Location } from '../base';
export declare function buildCheckFunction(locations: Location[]): (fields?: string | string[] | undefined, message?: any) => import("..").ValidationChain;
export declare const check: (fields?: string | string[] | undefined, message?: any) => import("..").ValidationChain;
export declare const body: (fields?: string | string[] | undefined, message?: any) => import("..").ValidationChain;
export declare const cookie: (fields?: string | string[] | undefined, message?: any) => import("..").ValidationChain;
export declare const header: (fields?: string | string[] | undefined, message?: any) => import("..").ValidationChain;
export declare const param: (fields?: string | string[] | undefined, message?: any) => import("..").ValidationChain;
export declare const query: (fields?: string | string[] | undefined, message?: any) => import("..").ValidationChain;

View file

@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const check_1 = require("./check");
function buildCheckFunction(locations) {
return (fields, message) => check_1.check(fields, locations, message);
}
exports.buildCheckFunction = buildCheckFunction;
exports.check = buildCheckFunction(['body', 'cookies', 'headers', 'params', 'query']);
exports.body = buildCheckFunction(['body']);
exports.cookie = buildCheckFunction(['cookies']);
exports.header = buildCheckFunction(['headers']);
exports.param = buildCheckFunction(['params']);
exports.query = buildCheckFunction(['query']);

165
node_modules/express-validator/src/options.d.ts generated vendored Normal file
View file

@ -0,0 +1,165 @@
export declare type URLProtocol = 'http' | 'https' | 'ftp';
export declare type UUIDVersion = 3 | 4 | 5 | '3' | '4' | '5' | 'all';
export declare type IPVersion = 4 | 6;
export declare type AlphaLocale = 'ar' | 'ar-AE' | 'ar-BH' | 'ar-DZ' | 'ar-EG' | 'ar-IQ' | 'ar-JO' | 'ar-KW' | 'ar-LB' | 'ar-LY' | 'ar-MA' | 'ar-QA' | 'ar-QM' | 'ar-SA' | 'ar-SD' | 'ar-SY' | 'ar-TN' | 'ar-YE' | 'bg-BG' | 'cs-CZ' | 'da-DK' | 'de-DE' | 'el-GR' | 'en-AU' | 'en-GB' | 'en-HK' | 'en-IN' | 'en-NZ' | 'en-US' | 'en-ZA' | 'en-ZM' | 'es-ES' | 'fr-FR' | 'hu-HU' | 'it-IT' | 'ku-IQ' | 'nb-NO' | 'nl-NL' | 'nn-NO' | 'pl-PL' | 'pt-BR' | 'pt-PT' | 'ru-RU' | 'sk-SK' | 'sl-SI' | 'sr-RS' | 'sr-RS@latin' | 'sv-SE' | 'tr-TR' | 'uk-UA';
export declare type AlphanumericLocale = 'ar' | 'ar-AE' | 'ar-BH' | 'ar-DZ' | 'ar-EG' | 'ar-IQ' | 'ar-JO' | 'ar-KW' | 'ar-LB' | 'ar-LY' | 'ar-MA' | 'ar-QA' | 'ar-QM' | 'ar-SA' | 'ar-SD' | 'ar-SY' | 'ar-TN' | 'ar-YE' | 'bg-BG' | 'cs-CZ' | 'da-DK' | 'de-DE' | 'el-GR' | 'en-AU' | 'en-GB' | 'en-HK' | 'en-IN' | 'en-NZ' | 'en-US' | 'en-ZA' | 'en-ZM' | 'es-ES' | 'fr-FR' | 'fr-BE' | 'hu-HU' | 'it-IT' | 'ku-IQ' | 'nb-NO' | 'nl-BE' | 'nl-NL' | 'nn-NO' | 'pl-PL' | 'pt-BR' | 'pt-PT' | 'ru-RU' | 'sk-SK' | 'sl-SI' | 'sr-RS' | 'sr-RS@latin' | 'sv-SE' | 'tr-TR' | 'uk-UA';
export declare type MobilePhoneLocale = 'any' | 'ar-AE' | 'ar-BH' | 'ar-DZ' | 'ar-EG' | 'ar-JO' | 'ar-IQ' | 'ar-KW' | 'ar-SA' | 'ar-SY' | 'ar-TN' | 'be-BY' | 'bg-BG' | 'bn-BD' | 'cs-CZ' | 'de-DE' | 'da-DK' | 'el-GR' | 'en-AU' | 'en-CA' | 'en-GB' | 'en-GH' | 'en-HK' | 'en-IE' | 'en-IN' | 'en-KE' | 'en-MT' | 'en-MU' | 'en-NG' | 'en-NZ' | 'en-PK' | 'en-RW' | 'en-SG' | 'en-TZ' | 'en-UG' | 'en-US' | 'en-ZA' | 'en-ZM' | 'es-CL' | 'es-ES' | 'es-MX' | 'es-PY' | 'es-UY' | 'et-EE' | 'fa-IR' | 'fi-FI' | 'fj-FJ' | 'fo-FO' | 'fr-FR' | 'he-IL' | 'hu-HU' | 'id-ID' | 'it-IT' | 'ja-JP' | 'kk-KZ' | 'kl-GL' | 'lt-LT' | 'ms-MY' | 'nb-NO' | 'nl-NL' | 'nn-NO' | 'pl-PL' | 'pt-PT' | 'ro-RO' | 'ru-RU' | 'sk-SK' | 'sl-SI' | 'sr-RS' | 'sv-SE' | 'th-TH' | 'tr-TR' | 'uk-UA' | 'vi-VN' | 'zh-CN' | 'zh-HK' | 'zh-TW';
export declare type PostalCodeLocale = 'any' | 'AD' | 'AT' | 'AU' | 'BE' | 'BG' | 'BR' | 'CA' | 'CH' | 'CZ' | 'DE' | 'DK' | 'DZ' | 'EE' | 'ES' | 'FI' | 'FR' | 'GB' | 'GR' | 'HR' | 'HU' | 'ID' | 'IL' | 'IN' | 'IS' | 'IT' | 'JP' | 'KE' | 'LI' | 'LT' | 'LU' | 'LV' | 'MT' | 'MX' | 'NL' | 'NO' | 'NZ' | 'PL' | 'PR' | 'PT' | 'RO' | 'RU' | 'SA' | 'SE' | 'SI' | 'TN' | 'TW' | 'UA' | 'US' | 'ZA' | 'ZM';
export declare type HashAlgorithm = 'md4' | 'md5' | 'sha1' | 'sha256' | 'sha384' | 'sha512' | 'ripemd128' | 'ripemd160' | 'tiger128' | 'tiger160' | 'tiger192' | 'crc32' | 'crc32b';
export declare type IdentityCard = 'any' | 'ES' | 'he-IL' | 'zh-TW';
export interface MinMaxOptions {
min?: number;
max?: number;
}
export interface MinMaxExtendedOptions extends MinMaxOptions {
lt?: number;
gt?: number;
}
/**
* defaults to
* {
* symbol: '$',
* require_symbol: false,
* allow_space_after_symbol: false,
* symbol_after_digits: false,
* allow_negatives: true,
* parens_for_negatives: false,
* negative_sign_before_digits: false,
* negative_sign_after_digits: false,
* allow_negative_sign_placeholder: false,
* thousands_separator: ',',
* decimal_separator: '.',
* allow_space_after_digits: false
* }
*/
export interface IsCurrencyOptions {
symbol?: string;
require_symbol?: boolean;
allow_space_after_symbol?: boolean;
symbol_after_digits?: boolean;
allow_negatives?: boolean;
parens_for_negatives?: boolean;
negative_sign_before_digits?: boolean;
negative_sign_after_digits?: boolean;
allow_negative_sign_placeholder?: boolean;
thousands_separator?: string;
decimal_separator?: string;
allow_decimal?: boolean;
require_decimal?: boolean;
digits_after_decimal?: number[];
allow_space_after_digits?: boolean;
}
export interface IsDecimalOptions {
decimal_digits?: string;
force_decimal?: boolean;
locale?: AlphanumericLocale;
}
export interface IsEmailOptions {
allow_display_name?: boolean;
allow_utf8_local_part?: boolean;
require_tld?: boolean;
}
/**
* defaults to
* {
* ignore_whitespace: false
* }
*/
export interface IsEmptyOptions {
ignore_whitespace: boolean;
}
export interface IsFloatOptions extends MinMaxExtendedOptions {
locale?: AlphanumericLocale;
}
/**
* defaults to
* {
* require_tld: true,
* allow_underscores: false,
* allow_trailing_dot: false
* }
*/
export interface IsFQDNOptions {
require_tld?: boolean;
allow_underscores?: boolean;
allow_trailing_dot?: boolean;
}
export interface IsIntOptions extends MinMaxExtendedOptions {
allow_leading_zeroes?: boolean;
}
export interface IsISO8601Options {
strict: boolean;
}
/**
* defaults to
* {
* case_sensitive: false,
* require_hyphen: false
* }
*/
export interface IsISSNOptions {
case_sensitive?: boolean;
require_hyphen?: boolean;
}
/**
* defaults to
* {
* no_colons: false
* }
*/
export interface IsMACAddressOptions {
no_colons?: boolean;
}
export interface IsMobilePhoneOptions {
strictMode?: boolean;
}
/**
* defaults to
* {
* no_symbols: false
* }
*/
export interface IsNumericOptions {
no_symbols: boolean;
}
/**
* defaults to
* {
* protocols: ['http','https','ftp'],
* require_tld: true,
* require_protocol: false,
* require_host: true,
* require_valid_protocol: true,
* allow_underscores: false,
* host_whitelist: false,
* host_blacklist: false,
* allow_trailing_dot: false,
* allow_protocol_relative_urls: false
* }
*/
export interface IsURLOptions {
protocols?: URLProtocol[];
require_tld?: boolean;
require_protocol?: boolean;
require_host?: boolean;
require_valid_protocol?: boolean;
allow_underscores?: boolean;
host_whitelist?: (string | RegExp)[];
host_blacklist?: (string | RegExp)[];
allow_trailing_dot?: boolean;
allow_protocol_relative_urls?: boolean;
disallow_auth?: boolean;
}
export interface NormalizeEmailOptions {
all_lowercase?: boolean;
gmail_lowercase?: boolean;
gmail_remove_dots?: boolean;
gmail_remove_subaddress?: boolean;
gmail_convert_googlemaildotcom?: boolean;
outlookdotcom_lowercase?: boolean;
outlookdotcom_remove_subaddress?: boolean;
yahoo_lowercase?: boolean;
yahoo_remove_subaddress?: boolean;
icloud_lowercase?: boolean;
icloud_remove_subaddress?: boolean;
}

2
node_modules/express-validator/src/options.js generated vendored Normal file
View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,3 @@
import { FieldInstance, Location, Request } from './base';
export declare type SelectFields = (req: Request, fields: string[], locations: Location[]) => FieldInstance[];
export declare const selectFields: SelectFields;

71
node_modules/express-validator/src/select-fields.js generated vendored Normal file
View file

@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
exports.selectFields = (req, fields, locations) => _(fields)
.flatMap(field => _.flatMap(locations, location => {
return expandField(req, field, location);
}))
// Avoid duplicates if multiple field selections would return the same field twice.
// E.g. with fields = ['*.foo', 'bar.foo'] and req.body = { bar: { foo: 1 }, baz: { foo: 2 } },
// the instance bla.foo would appear twice, and baz.foo once.
.uniqWith(isSameFieldInstance)
.value();
function isSameFieldInstance(a, b) {
return a.path === b.path && a.location === b.location;
}
function expandField(req, field, location) {
const originalPath = field;
const pathToExpand = location === 'headers' ? field.toLowerCase() : field;
const paths = [];
expandPath(req[location], pathToExpand, paths);
return paths.map(path => {
const value = path === '' ? req[location] : _.get(req[location], path);
return {
location,
path,
originalPath,
value,
originalValue: value,
};
});
}
function expandPath(object, path, accumulator) {
const segments = _.toPath(path);
const wildcardPos = segments.indexOf('*');
if (wildcardPos > -1) {
const subObject = wildcardPos === 0 ? object : _.get(object, segments.slice(0, wildcardPos));
if (!subObject || !_.isObjectLike(subObject)) {
return;
}
Object.keys(subObject)
.map(key => segments
// Before the *
.slice(0, wildcardPos)
// The part that the * matched
.concat(key)
// After the *
.concat(segments.slice(wildcardPos + 1)))
.forEach(subPath => {
expandPath(object, subPath, accumulator);
});
}
else {
const reconstructedPath = segments.reduce((prev, segment) => {
let part = '';
if (/^\d+$/.test(segment)) {
// Index access
part = `[${segment}]`;
}
else if (prev) {
// Object key access
part = `.${segment}`;
}
else {
// Top level key
part = segment;
}
return prev + part;
}, '');
accumulator.push(reconstructedPath);
}
}

2
node_modules/express-validator/src/utils.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
export declare const bindAll: <T>(object: T) => { [K in keyof T]: T[K]; };
export declare function toString(value: any, deep?: boolean): string;

28
node_modules/express-validator/src/utils.js generated vendored Normal file
View file

@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bindAll = (object) => {
const protoKeys = Object.getOwnPropertyNames(Object.getPrototypeOf(object));
protoKeys.forEach(key => {
const maybeFn = object[key];
if (typeof maybeFn === 'function') {
object[key] = maybeFn.bind(object);
}
});
return object;
};
function toString(value, deep = true) {
if (Array.isArray(value) && value.length && deep) {
return toString(value[0], false);
}
else if (value instanceof Date) {
return value.toISOString();
}
else if (value && typeof value === 'object' && value.toString) {
return value.toString();
}
else if (value == null || (isNaN(value) && !value.length)) {
return '';
}
return String(value);
}
exports.toString = toString;

View file

@ -0,0 +1,23 @@
import { Request, ValidationError } from './base';
export declare type ErrorFormatter<T = any> = (error: ValidationError) => T;
export declare type ResultFactory<T> = (req: Request) => Result<T>;
interface ResultFactoryBuilderOptions<T = any> {
formatter: ErrorFormatter<T>;
}
export declare const validationResult: ResultFactory<ValidationError> & {
withDefaults: typeof withDefaults;
};
export declare class Result<T = any> {
private formatter;
private readonly errors;
constructor(formatter: ErrorFormatter<T>, errors: ValidationError[]);
array(options?: {
onlyFirstError?: boolean;
}): T[];
mapped(): Record<string, T>;
formatWith<T2>(formatter: ErrorFormatter<T2>): Result<T2>;
isEmpty(): boolean;
throw(): void;
}
declare function withDefaults<T = any>(options?: Partial<ResultFactoryBuilderOptions<T>>): ResultFactory<T>;
export {};

View file

@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const base_1 = require("./base");
const utils_1 = require("./utils");
// Assign to a variable so that TS doesn't use its catch all overload, which returns any
const withWithDefaults = { withDefaults };
exports.validationResult = Object.assign(withDefaults(), withWithDefaults);
class Result {
constructor(formatter, errors) {
this.formatter = formatter;
this.errors = errors;
}
array(options) {
return options && options.onlyFirstError
? Object.values(this.mapped())
: this.errors.map(this.formatter);
}
mapped() {
return this.errors.reduce((mapping, error) => {
if (!mapping[error.param]) {
mapping[error.param] = this.formatter(error);
}
return mapping;
}, {});
}
formatWith(formatter) {
return new Result(formatter, this.errors);
}
isEmpty() {
return this.errors.length === 0;
}
throw() {
if (!this.isEmpty()) {
throw Object.assign(new Error(), utils_1.bindAll(this));
}
}
}
exports.Result = Result;
function withDefaults(options = {}) {
const defaults = {
formatter: error => error,
};
const actualOptions = _.defaults(options, defaults);
return (req) => {
const contexts = req[base_1.contextsSymbol] || [];
const errors = _.flatMap(contexts, 'errors');
return new Result(actualOptions.formatter, errors);
};
}