Skip to content

Commit

Permalink
feat(checkSchema): run imperatively (#977)
Browse files Browse the repository at this point in the history
* feat(checkSchema): run imperatively

* docs: update docs

* feat: apply code review suggestions
  • Loading branch information
fedeci committed Jan 9, 2021
1 parent a377870 commit 7f15d2d
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/api-check.md
Expand Up @@ -52,7 +52,7 @@ Same as `check([fields, message])`, but only checking `req.query`.

- `schema`: the schema to validate. Must comply with the format described in [Schema Validation](feature-schema-validation.md).

> _Returns:_ an array of validation chains
> _Returns:_ an array of validation chains and `{ run: (req) => Promise<unknown[]> }`
## `oneOf(validationChains[, message])`

Expand Down
3 changes: 1 addition & 2 deletions docs/feature-running-imperatively.md
Expand Up @@ -7,8 +7,7 @@ express-validator favors the declarative way of doing things that express middle
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-options) and [sanitization chains](api-sanitization-chain.md#runreq).
This is possible with the use of the declarative method `run(req)`, available on [validation chain](api-validation-chain.md#runreq-options), [sanitization chain](api-sanitization-chain.md#runreq) and [`checkSchema`](api-check.md#checkschemaschema).

Check the examples below to understand how this method can help you:

Expand Down
14 changes: 14 additions & 0 deletions src/middlewares/schema.spec.ts
Expand Up @@ -263,3 +263,17 @@ describe('on schema that contains fields with bail methods', () => {
expect(context.errors).toHaveLength(1);
});
});

it('run checkSchema imperatively', async () => {
const req = {
body: { foo: 'foo' },
};
const schema = checkSchema({
foo: {
exists: true,
isString: true,
},
});

return expect(schema.run(req)).resolves;
});
19 changes: 15 additions & 4 deletions src/middlewares/schema.ts
@@ -1,7 +1,7 @@
import { Sanitizers } from '../chain/sanitizers';
import { Validators } from '../chain/validators';
import { DynamicMessageCreator, Location } from '../base';
import { ValidatorsImpl } from '../chain';
import { DynamicMessageCreator, Location, Request } from '../base';
import { ValidationChain, ValidatorsImpl } from '../chain';
import { Optional } from '../context';
import { check } from './check';

Expand Down Expand Up @@ -58,8 +58,13 @@ export type ValidationSchema = Schema;
const validLocations: Location[] = ['body', 'cookies', 'headers', 'params', 'query'];
const protectedNames = ['errorMessage', 'in'];

export function checkSchema(schema: Schema, defaultLocations: Location[] = validLocations) {
return Object.keys(schema).map(field => {
export function checkSchema(
schema: Schema,
defaultLocations: Location[] = validLocations,
): ValidationChain[] & {
run: (req: Request) => Promise<unknown[]>;
} {
const chains = Object.keys(schema).map(field => {
const config = schema[field];
const chain = check(field, ensureLocations(config, defaultLocations), config.errorMessage);

Expand Down Expand Up @@ -100,6 +105,12 @@ export function checkSchema(schema: Schema, defaultLocations: Location[] = valid

return chain;
});

const run = async (req: Request) => {
return await Promise.all(chains.map(chain => chain.run(req)));
};

return Object.assign(chains, { run });
}

function isValidatorOptions(
Expand Down

0 comments on commit 7f15d2d

Please sign in to comment.