Skip to content

Commit

Permalink
Merge branch 'master' into schema-multi-custom
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavohenke committed Jan 22, 2023
2 parents 095ae80 + 4be387a commit e739941
Show file tree
Hide file tree
Showing 295 changed files with 36,650 additions and 22,274 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Expand Up @@ -9,7 +9,7 @@
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "import", "prettier"],
"extends": ["prettier", "prettier/@typescript-eslint", "plugin:prettier/recommended"],
"extends": ["prettier"],
"globals": {},
"rules": {
// Possible errors
Expand Down
9 changes: 8 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Expand Up @@ -12,7 +12,13 @@ assignees: ''

## To Reproduce

<!-- Steps to reproduce the behavior -->
<!--
Steps to reproduce the behavior.
If possible, please include a link to a Runkit notebook.
You can use the following template to get started:
https://runkit.com/gustavohenke/express-validator-issue-template
-->

1. <!-- Go to '...' -->
2. <!-- Click on '...' -->
Expand All @@ -29,3 +35,4 @@ assignees: ''

- Express-validator version: <!-- [e.g. 6.6.1] -->
- Express version: <!-- [e.g. 4.17.1] -->
- Node.js version: <!-- [e.g. 14.20.1] -->
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Expand Up @@ -11,9 +11,9 @@ jobs:
node: [12, 14, 16]
steps:
- name: Check out
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: npm
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Expand Up @@ -17,5 +17,4 @@ npm-debug.log*

# Misc
/coverage
/website/build
.DS_Store
1 change: 1 addition & 0 deletions .prettierignore
Expand Up @@ -10,6 +10,7 @@
/filter/**/*.d.ts

# Docs
/website/.docusaurus
/website/build
/website/versioned_docs
/website/versioned_sidebars
Expand Down
4 changes: 3 additions & 1 deletion docs/api-check.md
Expand Up @@ -22,8 +22,10 @@ Creates a validation chain for one or more fields. They may be located in any of

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.
:::tip
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.
Expand Down
8 changes: 5 additions & 3 deletions docs/api-filter.md
Expand Up @@ -5,9 +5,11 @@ title: Sanitization middlewares

These methods are all available via `require('express-validator')`.

> These sanitization-only middlewares have been deprecated, as **the [validation middlewares](api-check.md)
> offer the same functionality**, and much more.
> They will be removed eventually.
:::caution
These sanitization-only middlewares have been deprecated, as **the [validation middlewares](api-check.md)
offer the same functionality**, and much more.
They will be removed eventually.
:::

## `sanitize(fields)`

Expand Down
16 changes: 12 additions & 4 deletions docs/api-sanitization-chain.md
Expand Up @@ -24,10 +24,18 @@ 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/validatorjs/validator.js#sanitizers).
:::info

> **Note:** Since validator.js only accepts `string` as input, any value (including arrays and objects) that needs to be sanitized by a Standard Sanitizer [is first converted to such type](faq.md#why-arrays-are-not-validatedsanitized-correctly).
**For a complete list of standard sanitizers and their options**,
please check [validator.js' docs](https://github.com/validatorjs/validator.js#sanitizers).

:::

:::note

Since validator.js only accepts `string` as input, any value (including arrays and objects) that needs to be sanitized by a Standard Sanitizer [is first converted to such type](faq.md#why-arrays-are-not-validatedsanitized-correctly).

:::

## Additional methods

Expand Down Expand Up @@ -112,7 +120,7 @@ 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', 'bar'] => ['foo', 'bar']
// 'foo' => ['foo']
// undefined => []
console.log(req.body.checkboxes);
Expand Down
45 changes: 30 additions & 15 deletions docs/api-validation-chain.md
Expand Up @@ -20,10 +20,18 @@ 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/validatorjs/validator.js#validators).
:::info

> **Note:** Since validator.js only accepts `string` as input, any value (including arrays and objects) that needs to be validated by a Standard Validator [is first converted to such type](faq.md#why-arrays-are-not-validatedsanitized-correctly).
**For a complete list of standard validators and their options**,
please check [validator.js' docs](https://github.com/validatorjs/validator.js#validators).

:::

:::note

Since validator.js only accepts `string` as input, any value (including arrays and objects) that needs to be validated by a Standard Validator [is first converted to such type](faq.md#why-arrays-are-not-validatedsanitized-correctly).

:::

## Sanitization Chain API

Expand Down Expand Up @@ -127,7 +135,11 @@ The condition can be either:
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.

> _Note:_ async functions must return a resolved or rejected `Promise` because `truthy` or `falsy` values won't stop the chain ([#1028](https://github.com/express-validator/express-validator/issues/1028#issuecomment-830561518)).
:::note

Async functions must return a resolved or rejected `Promise` because `truthy` or `falsy` values won't stop the chain ([#1028](https://github.com/express-validator/express-validator/issues/1028#issuecomment-830561518)).

:::

- A validation chain [created through `check()` or similar functions](api-check.md#check-field-message).

Expand Down Expand Up @@ -190,16 +202,19 @@ Adds a validator to check if a value is not empty; that is, a string with a leng
check('username').notEmpty();
```

> **Note:** This is not intended to check that the length of an array is greater than zero, as `.notEmpty()` will only validate the first element of it.
> To require a minimum array length use `.isArray({ min: 1 })`.
>
> ```js
> // weekdays: ['sunday', 'monday']
> check('weekdays').notEmpty(); // Passes validation
>
> // names: ['', 'John']
> check('names').notEmpty(); // Does not pass validation because names[0] is empty.
> ```
:::note
This is not intended to check that the length of an array is greater than zero, as `.notEmpty()` will only validate the first element of it.
To require a minimum array length use `.isArray({ min: 1 })`.

```js
// weekdays: ['sunday', 'monday']
check('weekdays').notEmpty(); // Passes validation

// names: ['', 'John']
check('names').notEmpty(); // Does not pass validation because names[0] is empty.
```

:::

### `.optional(options)`

Expand All @@ -223,7 +238,7 @@ You can customize this behavior by passing an object with the following options:
- `options` _(optional)_: an object of options to customize how the chain will be run:
- `dryRun`: defines whether errors and sanitizations won't be persisted to `req`. Defaults to `false`.

> _Returns:_ a promise for a [`Result`](api-validation-result.md#result) that resolves when the validation chain ran.
> _Returns:_ a promise for a [`Result`](api-validation-result.mdx#result) that resolves when the validation chain ran.
Runs the current validation chain in an imperative way.

Expand Down
162 changes: 162 additions & 0 deletions docs/api-validation-result.mdx
@@ -0,0 +1,162 @@
---
id: validation-result-api
title: validationResult()
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

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
has 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
<Tabs>
<TabItem value="js" label="JavaScript">

```js
const { validationResult } = require('express-validator');
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
});
```

</TabItem>
<TabItem value="ts" label="TypeScript">

```typescript
import { value validationResult, value ValidationError } from 'express-validator';
app.post('/create-user', yourValidationChains, (req, res, next) => {
const errorFormatter = ({ location, msg, param, value, nestedErrors }: ValidationError) => {
// 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
});
```

</TabItem>
</Tabs>

### `.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!
}
```

0 comments on commit e739941

Please sign in to comment.