@depup/express-validator 7.3.1-depup.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +32 -0
  3. package/changes.json +14 -0
  4. package/lib/base.d.ts +187 -0
  5. package/lib/base.js +8 -0
  6. package/lib/chain/context-handler-impl.d.ts +13 -0
  7. package/lib/chain/context-handler-impl.js +52 -0
  8. package/lib/chain/context-handler.d.ts +110 -0
  9. package/lib/chain/context-handler.js +2 -0
  10. package/lib/chain/context-runner-impl.d.ts +18 -0
  11. package/lib/chain/context-runner-impl.js +72 -0
  12. package/lib/chain/context-runner.d.ts +22 -0
  13. package/lib/chain/context-runner.js +2 -0
  14. package/lib/chain/index.d.ts +9 -0
  15. package/lib/chain/index.js +25 -0
  16. package/lib/chain/sanitizers-impl.d.ts +29 -0
  17. package/lib/chain/sanitizers-impl.js +80 -0
  18. package/lib/chain/sanitizers.d.ts +42 -0
  19. package/lib/chain/sanitizers.js +2 -0
  20. package/lib/chain/validation-chain.d.ts +18 -0
  21. package/lib/chain/validation-chain.js +2 -0
  22. package/lib/chain/validators-impl.d.ts +121 -0
  23. package/lib/chain/validators-impl.js +353 -0
  24. package/lib/chain/validators.d.ts +181 -0
  25. package/lib/chain/validators.js +2 -0
  26. package/lib/context-builder.d.ts +20 -0
  27. package/lib/context-builder.js +52 -0
  28. package/lib/context-items/bail.d.ts +5 -0
  29. package/lib/context-items/bail.js +13 -0
  30. package/lib/context-items/chain-condition.d.ts +9 -0
  31. package/lib/context-items/chain-condition.js +16 -0
  32. package/lib/context-items/context-item.d.ts +5 -0
  33. package/lib/context-items/context-item.js +2 -0
  34. package/lib/context-items/custom-condition.d.ts +8 -0
  35. package/lib/context-items/custom-condition.js +24 -0
  36. package/lib/context-items/custom-validation.d.ts +10 -0
  37. package/lib/context-items/custom-validation.js +34 -0
  38. package/lib/context-items/index.d.ts +5 -0
  39. package/lib/context-items/index.js +21 -0
  40. package/lib/context-items/sanitization.d.ts +12 -0
  41. package/lib/context-items/sanitization.js +34 -0
  42. package/lib/context-items/standard-validation.d.ts +13 -0
  43. package/lib/context-items/standard-validation.js +25 -0
  44. package/lib/context.d.ts +61 -0
  45. package/lib/context.js +117 -0
  46. package/lib/express-validator.d.ts +153 -0
  47. package/lib/express-validator.js +125 -0
  48. package/lib/field-selection.d.ts +22 -0
  49. package/lib/field-selection.js +221 -0
  50. package/lib/index.d.ts +9 -0
  51. package/lib/index.js +25 -0
  52. package/lib/matched-data.d.ts +26 -0
  53. package/lib/matched-data.js +45 -0
  54. package/lib/middlewares/check.d.ts +3 -0
  55. package/lib/middlewares/check.js +23 -0
  56. package/lib/middlewares/exact.d.ts +29 -0
  57. package/lib/middlewares/exact.js +68 -0
  58. package/lib/middlewares/one-of.d.ts +28 -0
  59. package/lib/middlewares/one-of.js +91 -0
  60. package/lib/middlewares/schema.d.ts +108 -0
  61. package/lib/middlewares/schema.js +112 -0
  62. package/lib/middlewares/validation-chain-builders.d.ts +43 -0
  63. package/lib/middlewares/validation-chain-builders.js +49 -0
  64. package/lib/options.d.ts +377 -0
  65. package/lib/options.js +2 -0
  66. package/lib/utils.d.ts +12 -0
  67. package/lib/utils.js +56 -0
  68. package/lib/validation-result.d.ts +67 -0
  69. package/lib/validation-result.js +80 -0
  70. package/package.json +97 -0
@@ -0,0 +1,26 @@
1
+ import { Location, Request } from './base';
2
+ export type MatchedDataOptions = {
3
+ /**
4
+ * Whether the value returned by `matchedData()` should include data deemed optional.
5
+ * @default false
6
+ */
7
+ includeOptionals: boolean;
8
+ /**
9
+ * An array of locations in the request to extract the data from.
10
+ */
11
+ locations: Location[];
12
+ /**
13
+ * Whether the value returned by `matchedData()` should include only values that have passed
14
+ * validation.
15
+ * @default true
16
+ */
17
+ onlyValidData: boolean;
18
+ };
19
+ /**
20
+ * Extracts data validated or sanitized from the request, and builds an object with them.
21
+ *
22
+ * @param req the express request object
23
+ * @param options
24
+ * @returns an object of data that's been validated or sanitized in the passed request
25
+ */
26
+ export declare function matchedData<T extends object = Record<string, any>>(req: Request, options?: Partial<MatchedDataOptions>): T;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.matchedData = matchedData;
4
+ const _ = require("lodash");
5
+ const base_1 = require("./base");
6
+ /**
7
+ * Extracts data validated or sanitized from the request, and builds an object with them.
8
+ *
9
+ * @param req the express request object
10
+ * @param options
11
+ * @returns an object of data that's been validated or sanitized in the passed request
12
+ */
13
+ function matchedData(req, options = {}) {
14
+ const internalReq = req;
15
+ const fieldExtractor = createFieldExtractor(options.includeOptionals !== true);
16
+ const validityFilter = createValidityFilter(options.onlyValidData);
17
+ const locationFilter = createLocationFilter(options.locations);
18
+ return _(internalReq[base_1.contextsKey])
19
+ .flatMap(fieldExtractor)
20
+ .filter(validityFilter)
21
+ .map(field => field.instance)
22
+ .filter(locationFilter)
23
+ .reduce((state, instance) => _.set(state, instance.path, instance.value), {});
24
+ }
25
+ function createFieldExtractor(removeOptionals) {
26
+ return (context) => {
27
+ const instances = context.getData({ requiredOnly: removeOptionals });
28
+ return instances.map((instance) => ({ instance, context }));
29
+ };
30
+ }
31
+ function createValidityFilter(onlyValidData = true) {
32
+ return !onlyValidData
33
+ ? () => true
34
+ : (field) => {
35
+ const hasError = field.context.errors.some(error => error.type === 'field' &&
36
+ error.location === field.instance.location &&
37
+ error.path === field.instance.path);
38
+ return !hasError;
39
+ };
40
+ }
41
+ function createLocationFilter(locations = []) {
42
+ // No locations mean all locations
43
+ const allLocations = locations.length === 0;
44
+ return allLocations ? () => true : (field) => locations.includes(field.location);
45
+ }
@@ -0,0 +1,3 @@
1
+ import { ErrorMessage, FieldMessageFactory, Location } from '../base';
2
+ import { ValidationChain } from '../chain';
3
+ export declare function check(fields?: string | string[], locations?: Location[], message?: FieldMessageFactory | ErrorMessage): ValidationChain;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.check = check;
4
+ const chain_1 = require("../chain");
5
+ const context_builder_1 = require("../context-builder");
6
+ const utils_1 = require("../utils");
7
+ function check(fields = '', locations = [], message) {
8
+ const builder = new context_builder_1.ContextBuilder()
9
+ .setFields(Array.isArray(fields) ? fields : [fields])
10
+ .setLocations(locations)
11
+ .setMessage(message);
12
+ const runner = new chain_1.ContextRunnerImpl(builder);
13
+ const middleware = async (req, _res, next) => {
14
+ try {
15
+ await runner.run(req);
16
+ next();
17
+ }
18
+ catch (e) {
19
+ next(e);
20
+ }
21
+ };
22
+ return Object.assign(middleware, (0, utils_1.bindAll)(runner), (0, utils_1.bindAll)(new chain_1.SanitizersImpl(builder, middleware)), (0, utils_1.bindAll)(new chain_1.ValidatorsImpl(builder, middleware)), (0, utils_1.bindAll)(new chain_1.ContextHandlerImpl(builder, middleware)), { builder });
23
+ }
@@ -0,0 +1,29 @@
1
+ import { ErrorMessage, Location, Middleware, UnknownFieldMessageFactory } from '../base';
2
+ import { ContextRunner, ValidationChain } from '../chain';
3
+ type CheckExactOptions = {
4
+ /**
5
+ * The list of locations which `checkExact()` should check.
6
+ * @default ['body', 'params', 'query']
7
+ */
8
+ locations?: readonly Location[];
9
+ message?: UnknownFieldMessageFactory | ErrorMessage;
10
+ };
11
+ type CheckExactInput = ValidationChain | ValidationChain[] | (ValidationChain | ValidationChain[])[];
12
+ /**
13
+ * Checks whether the request contains exactly only those fields that have been validated.
14
+ *
15
+ * Unknown fields, if found, will generate an error of type `unknown_fields`.
16
+ *
17
+ * @param chains either a single chain, an array of chains, or a mixed array of chains and array of chains.
18
+ * This means that all of the below are valid:
19
+ * ```
20
+ * checkExact(check('foo'))
21
+ * checkExact([check('foo'), check('bar')])
22
+ * checkExact([check('foo'), check('bar')])
23
+ * checkExact(checkSchema({ ... }))
24
+ * checkExact([checkSchema({ ... }), check('foo')])
25
+ * ```
26
+ * @param opts
27
+ */
28
+ export declare function checkExact(chains?: CheckExactInput, opts?: CheckExactOptions): Middleware & ContextRunner;
29
+ export {};
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkExact = checkExact;
4
+ const base_1 = require("../base");
5
+ const chain_1 = require("../chain");
6
+ const context_1 = require("../context");
7
+ const field_selection_1 = require("../field-selection");
8
+ const utils_1 = require("../utils");
9
+ /**
10
+ * Checks whether the request contains exactly only those fields that have been validated.
11
+ *
12
+ * Unknown fields, if found, will generate an error of type `unknown_fields`.
13
+ *
14
+ * @param chains either a single chain, an array of chains, or a mixed array of chains and array of chains.
15
+ * This means that all of the below are valid:
16
+ * ```
17
+ * checkExact(check('foo'))
18
+ * checkExact([check('foo'), check('bar')])
19
+ * checkExact([check('foo'), check('bar')])
20
+ * checkExact(checkSchema({ ... }))
21
+ * checkExact([checkSchema({ ... }), check('foo')])
22
+ * ```
23
+ * @param opts
24
+ */
25
+ function checkExact(chains, opts) {
26
+ // Don't include all locations by default. Browsers will add cookies and headers that the user
27
+ // might not want to validate, which would be a footgun.
28
+ const locations = opts?.locations || ['body', 'params', 'query'];
29
+ const chainsArr = Array.isArray(chains) ? chains.flat() : chains ? [chains] : [];
30
+ const run = async (req) => {
31
+ const internalReq = req;
32
+ const fieldsByLocation = new Map();
33
+ await (0, utils_1.runAllChains)(req, chainsArr);
34
+ // The chains above will have added contexts to the request
35
+ (internalReq[base_1.contextsKey] || []).forEach(context => {
36
+ context.locations.forEach(location => {
37
+ if (!locations.includes(location)) {
38
+ return;
39
+ }
40
+ const locationFields = fieldsByLocation.get(location) || [];
41
+ locationFields.push(...context.fields);
42
+ fieldsByLocation.set(location, locationFields);
43
+ });
44
+ });
45
+ // when none of the chains matched anything, then everything is unknown.
46
+ if (!fieldsByLocation.size) {
47
+ locations.forEach(location => fieldsByLocation.set(location, []));
48
+ }
49
+ let unknownFields = [];
50
+ for (const [location, fields] of fieldsByLocation.entries()) {
51
+ unknownFields = unknownFields.concat((0, field_selection_1.selectUnknownFields)(req, fields, [location]));
52
+ }
53
+ const context = new context_1.Context([], [], [], false, false);
54
+ if (unknownFields.length) {
55
+ context.addError({
56
+ type: 'unknown_fields',
57
+ req,
58
+ message: opts?.message || 'Unknown field(s)',
59
+ fields: unknownFields,
60
+ });
61
+ }
62
+ internalReq[base_1.contextsKey] = internalReq[base_1.contextsKey] || [];
63
+ internalReq[base_1.contextsKey].push(context);
64
+ return new chain_1.ResultWithContextImpl(context);
65
+ };
66
+ const middleware = (req, _res, next) => run(req).then(() => next(), next);
67
+ return Object.assign(middleware, { run });
68
+ }
@@ -0,0 +1,28 @@
1
+ import { AlternativeMessageFactory, ErrorMessage, GroupedAlternativeMessageFactory, Middleware } from '../base';
2
+ import { ContextRunner, ValidationChain } from '../chain';
3
+ export type OneOfErrorType = 'grouped' | 'least_errored' | 'flat';
4
+ export type OneOfOptions = {
5
+ /**
6
+ * The error message to use in case none of the chains are valid.
7
+ */
8
+ message?: AlternativeMessageFactory | ErrorMessage;
9
+ errorType?: Exclude<OneOfErrorType, 'grouped'>;
10
+ } | {
11
+ /**
12
+ * The error message to use in case none of the chain groups are valid.
13
+ */
14
+ message?: GroupedAlternativeMessageFactory | ErrorMessage;
15
+ errorType?: 'grouped';
16
+ };
17
+ /**
18
+ * Creates a middleware that will ensure that at least one of the given validation chains
19
+ * or validation chain groups are valid.
20
+ *
21
+ * If none are, a single `AlternativeValidationError` or `GroupedAlternativeValidationError`
22
+ * is added to the request, with the errors of each chain made available under the `nestedErrors` property.
23
+ *
24
+ * @param chains an array of validation chains to check if are valid.
25
+ * If any of the items of `chains` is an array of validation chains, then all of them
26
+ * must be valid together for the request to be considered valid.
27
+ */
28
+ export declare function oneOf(chains: (ValidationChain | ValidationChain[])[], options?: OneOfOptions): Middleware & ContextRunner;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oneOf = oneOf;
4
+ const _ = require("lodash");
5
+ const chain_1 = require("../chain");
6
+ const context_builder_1 = require("../context-builder");
7
+ const utils_1 = require("../utils");
8
+ // A dummy context item that gets added to surrogate contexts just to make them run
9
+ const dummyItem = { async run() { } };
10
+ /**
11
+ * Creates a middleware that will ensure that at least one of the given validation chains
12
+ * or validation chain groups are valid.
13
+ *
14
+ * If none are, a single `AlternativeValidationError` or `GroupedAlternativeValidationError`
15
+ * is added to the request, with the errors of each chain made available under the `nestedErrors` property.
16
+ *
17
+ * @param chains an array of validation chains to check if are valid.
18
+ * If any of the items of `chains` is an array of validation chains, then all of them
19
+ * must be valid together for the request to be considered valid.
20
+ */
21
+ function oneOf(chains, options = {}) {
22
+ const run = async (req, opts) => {
23
+ const surrogateContext = new context_builder_1.ContextBuilder().addItem(dummyItem).build();
24
+ // Run each group of chains in parallel
25
+ const promises = chains.map(async (chain) => {
26
+ const group = Array.isArray(chain) ? chain : [chain];
27
+ const results = await (0, utils_1.runAllChains)(req, group, { dryRun: true });
28
+ const { contexts, groupErrors } = results.reduce(({ contexts, groupErrors }, result) => {
29
+ const { context } = result;
30
+ contexts.push(context);
31
+ const fieldErrors = context.errors.filter((error) => error.type === 'field');
32
+ groupErrors.push(...fieldErrors);
33
+ return { contexts, groupErrors };
34
+ }, {
35
+ contexts: [],
36
+ groupErrors: [],
37
+ });
38
+ // #536: The data from a chain within oneOf() can only be made available to e.g. matchedData()
39
+ // if its entire group is valid.
40
+ if (!groupErrors.length) {
41
+ contexts.forEach(context => {
42
+ surrogateContext.addFieldInstances(context.getData());
43
+ });
44
+ }
45
+ return groupErrors;
46
+ });
47
+ const allErrors = await Promise.all(promises);
48
+ const success = allErrors.some(groupErrors => groupErrors.length === 0);
49
+ if (!success) {
50
+ const message = options.message || 'Invalid value(s)';
51
+ switch (options.errorType) {
52
+ case 'flat':
53
+ surrogateContext.addError({
54
+ type: 'alternative',
55
+ req,
56
+ message,
57
+ nestedErrors: _.flatMap(allErrors),
58
+ });
59
+ break;
60
+ case 'least_errored':
61
+ let leastErroredIndex = 0;
62
+ for (let i = 1; i < allErrors.length; i++) {
63
+ if (allErrors[i].length < allErrors[leastErroredIndex].length) {
64
+ leastErroredIndex = i;
65
+ }
66
+ }
67
+ surrogateContext.addError({
68
+ type: 'alternative',
69
+ req,
70
+ message,
71
+ nestedErrors: allErrors[leastErroredIndex],
72
+ });
73
+ break;
74
+ case 'grouped':
75
+ default:
76
+ // grouped
77
+ surrogateContext.addError({
78
+ type: 'alternative_grouped',
79
+ req,
80
+ message,
81
+ nestedErrors: allErrors,
82
+ });
83
+ break;
84
+ }
85
+ }
86
+ // Final context running pass to ensure contexts are added and values are modified properly
87
+ return await new chain_1.ContextRunnerImpl(surrogateContext).run(req, opts);
88
+ };
89
+ const middleware = (req, _res, next) => run(req).then(() => next(), next);
90
+ return Object.assign(middleware, { run });
91
+ }
@@ -0,0 +1,108 @@
1
+ import { CustomSanitizer, CustomValidator, ErrorMessage, FieldMessageFactory, Location, Request } from '../base';
2
+ import { BailOptions, OptionalOptions, ValidationChain, ValidationChainLike } from '../chain';
3
+ import { ResultWithContext } from '../chain/context-runner';
4
+ import { Sanitizers } from '../chain/sanitizers';
5
+ import { Validators } from '../chain/validators';
6
+ type BaseValidatorSchemaOptions = {
7
+ /**
8
+ * The error message if there's a validation error,
9
+ * or a function for creating an error message dynamically.
10
+ */
11
+ errorMessage?: FieldMessageFactory | ErrorMessage;
12
+ /**
13
+ * Whether the validation should be reversed.
14
+ */
15
+ negated?: boolean;
16
+ /**
17
+ * Whether the validation should bail after running this validator
18
+ */
19
+ bail?: boolean | BailOptions;
20
+ /**
21
+ * Specify a condition upon which this validator should run.
22
+ * Can either be a validation chain, or a custom validator function.
23
+ */
24
+ if?: CustomValidator | ValidationChain;
25
+ };
26
+ type ValidatorSchemaOptions<K extends keyof Validators<any>> = boolean | (BaseValidatorSchemaOptions & {
27
+ /**
28
+ * Options to pass to the validator.
29
+ */
30
+ options?: Parameters<Validators<any>[K]> | Parameters<Validators<any>[K]>[0];
31
+ });
32
+ type CustomValidatorSchemaOptions = BaseValidatorSchemaOptions & {
33
+ /**
34
+ * The implementation of a custom validator.
35
+ */
36
+ custom: CustomValidator;
37
+ };
38
+ export type ExtensionValidatorSchemaOptions = boolean | BaseValidatorSchemaOptions;
39
+ export type ValidatorsSchema = {
40
+ [K in Exclude<keyof Validators<any>, 'not' | 'withMessage'>]?: ValidatorSchemaOptions<K>;
41
+ };
42
+ type SanitizerSchemaOptions<K extends keyof Sanitizers<any>> = boolean | {
43
+ /**
44
+ * Options to pass to the sanitizer.
45
+ */
46
+ options?: Parameters<Sanitizers<any>[K]> | Parameters<Sanitizers<any>[K]>[0];
47
+ };
48
+ type CustomSanitizerSchemaOptions = {
49
+ /**
50
+ * The implementation of a custom sanitizer.
51
+ */
52
+ customSanitizer: CustomSanitizer;
53
+ };
54
+ export type ExtensionSanitizerSchemaOptions = true;
55
+ export type SanitizersSchema = {
56
+ [K in keyof Sanitizers<any>]?: SanitizerSchemaOptions<K>;
57
+ };
58
+ type BaseParamSchema = {
59
+ /**
60
+ * Which request location(s) the field to validate is.
61
+ * If unset, the field will be checked in every request location.
62
+ */
63
+ in?: Location | Location[];
64
+ /**
65
+ * The general error message in case a validator doesn't specify one,
66
+ * or a function for creating the error message dynamically.
67
+ */
68
+ errorMessage?: FieldMessageFactory | any;
69
+ /**
70
+ * Whether this field should be considered optional
71
+ */
72
+ optional?: boolean | {
73
+ options?: OptionalOptions;
74
+ };
75
+ };
76
+ export type DefaultSchemaKeys = keyof BaseParamSchema | keyof ValidatorsSchema | keyof SanitizersSchema;
77
+ /**
78
+ * Defines a schema of validations/sanitizations for a field
79
+ */
80
+ export type ParamSchema<T extends string = DefaultSchemaKeys> = BaseParamSchema & ValidatorsSchema & SanitizersSchema & {
81
+ [K in T]?: K extends keyof BaseParamSchema ? BaseParamSchema[K] : K extends keyof ValidatorsSchema ? ValidatorsSchema[K] : K extends keyof SanitizersSchema ? SanitizersSchema[K] : CustomValidatorSchemaOptions | CustomSanitizerSchemaOptions;
82
+ };
83
+ /**
84
+ * Defines a mapping from field name to a validations/sanitizations schema.
85
+ */
86
+ export type Schema<T extends string = DefaultSchemaKeys> = Record<string, ParamSchema<T>>;
87
+ /**
88
+ * Shortcut type for the return of a {@link checkSchema()}-like function.
89
+ */
90
+ export type RunnableValidationChains<C extends ValidationChainLike> = C[] & {
91
+ run(req: Request): Promise<ResultWithContext[]>;
92
+ };
93
+ /**
94
+ * Factory for a {@link checkSchema()} function which can have extension validators and sanitizers.
95
+ *
96
+ * @see {@link checkSchema()}
97
+ */
98
+ export declare function createCheckSchema<C extends ValidationChainLike>(createChain: (fields?: string | string[], locations?: Location[], errorMessage?: any) => C, extraValidators?: (keyof C)[], extraSanitizers?: (keyof C)[]): <T extends string = DefaultSchemaKeys>(schema: Schema<T>, defaultLocations?: Location[]) => RunnableValidationChains<C>;
99
+ /**
100
+ * Creates an express middleware with validations for multiple fields at once in the form of
101
+ * a schema object.
102
+ *
103
+ * @param schema the schema to validate.
104
+ * @param defaultLocations
105
+ * @returns
106
+ */
107
+ export declare const checkSchema: <T extends string = DefaultSchemaKeys>(schema: Schema<T>, defaultLocations?: Location[]) => RunnableValidationChains<ValidationChain>;
108
+ export {};
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkSchema = void 0;
4
+ exports.createCheckSchema = createCheckSchema;
5
+ const _ = require("lodash");
6
+ const chain_1 = require("../chain");
7
+ const utils_1 = require("../utils");
8
+ const check_1 = require("./check");
9
+ const validLocations = ['body', 'cookies', 'headers', 'params', 'query'];
10
+ const protectedNames = ['errorMessage', 'in', 'optional'];
11
+ /**
12
+ * Factory for a {@link checkSchema()} function which can have extension validators and sanitizers.
13
+ *
14
+ * @see {@link checkSchema()}
15
+ */
16
+ function createCheckSchema(createChain, extraValidators = [], extraSanitizers = []) {
17
+ /** Type guard for an object entry for a standard validator. */
18
+ function isStandardValidator(entry) {
19
+ return (
20
+ // #664 - explicitly exclude properties which should be set per validator
21
+ !['not', 'withMessage'].includes(entry[0]) &&
22
+ (entry[0] in chain_1.ValidatorsImpl.prototype || extraValidators.includes(entry[0])) &&
23
+ entry[1]);
24
+ }
25
+ /** Type guard for an object entry for a standard sanitizer. */
26
+ function isStandardSanitizer(entry) {
27
+ return ((entry[0] in chain_1.SanitizersImpl.prototype || extraSanitizers.includes(entry[0])) &&
28
+ entry[1]);
29
+ }
30
+ /** Type guard for an object entry for a custom validator. */
31
+ function isCustomValidator(entry) {
32
+ return (!isStandardValidator(entry) &&
33
+ !isStandardSanitizer(entry) &&
34
+ typeof entry[1] === 'object' &&
35
+ entry[1] &&
36
+ typeof entry[1].custom === 'function');
37
+ }
38
+ /** Type guard for an object entry for a custom sanitizer. */
39
+ function isCustomSanitizer(entry) {
40
+ return (!isStandardValidator(entry) &&
41
+ !isStandardSanitizer(entry) &&
42
+ typeof entry[1] === 'object' &&
43
+ entry[1] &&
44
+ typeof entry[1].customSanitizer === 'function');
45
+ }
46
+ return (schema, defaultLocations = validLocations) => {
47
+ const chains = Object.keys(schema).map(field => {
48
+ const config = schema[field];
49
+ const chain = createChain(field, ensureLocations(config, defaultLocations), config.errorMessage);
50
+ // optional doesn't matter where it happens in the chain
51
+ if (config.optional) {
52
+ chain.optional(config.optional === true ? true : config.optional.options);
53
+ }
54
+ for (const entry of Object.entries(config)) {
55
+ if (protectedNames.includes(entry[0]) || !entry[1]) {
56
+ continue;
57
+ }
58
+ if (!isStandardValidator(entry) &&
59
+ !isStandardSanitizer(entry) &&
60
+ !isCustomValidator(entry) &&
61
+ !isCustomSanitizer(entry)) {
62
+ console.warn(`express-validator: schema of "${field}" has unknown validator/sanitizer "${entry[0]}"`);
63
+ continue;
64
+ }
65
+ // For validators, stuff that must come _before_ the validator itself in the chain.
66
+ if ((isStandardValidator(entry) || isCustomValidator(entry)) && entry[1] !== true) {
67
+ const [, validatorConfig] = entry;
68
+ validatorConfig.if && chain.if(validatorConfig.if);
69
+ validatorConfig.negated && chain.not();
70
+ }
71
+ if (isStandardValidator(entry) || isStandardSanitizer(entry)) {
72
+ const options = entry[1] ? (entry[1] === true ? [] : _.castArray(entry[1].options)) : [];
73
+ chain[entry[0]](...options);
74
+ }
75
+ if (isCustomValidator(entry)) {
76
+ chain.custom(entry[1].custom);
77
+ }
78
+ if (isCustomSanitizer(entry)) {
79
+ chain.customSanitizer(entry[1].customSanitizer);
80
+ }
81
+ // For validators, stuff that must come _after_ the validator itself in the chain.
82
+ if ((isStandardValidator(entry) || isCustomValidator(entry)) && entry[1] !== true) {
83
+ const [, validatorConfig] = entry;
84
+ validatorConfig.bail &&
85
+ chain.bail(validatorConfig.bail === true ? {} : validatorConfig.bail);
86
+ validatorConfig.errorMessage && chain.withMessage(validatorConfig.errorMessage);
87
+ }
88
+ }
89
+ return chain;
90
+ });
91
+ const run = async (req) => (0, utils_1.runAllChains)(req, chains);
92
+ return Object.assign(chains, { run });
93
+ };
94
+ }
95
+ /**
96
+ * Creates an express middleware with validations for multiple fields at once in the form of
97
+ * a schema object.
98
+ *
99
+ * @param schema the schema to validate.
100
+ * @param defaultLocations
101
+ * @returns
102
+ */
103
+ exports.checkSchema = createCheckSchema(check_1.check);
104
+ function ensureLocations(config, defaults) {
105
+ // .filter(Boolean) is done because in can be undefined -- which is not going away from the type
106
+ // See https://github.com/Microsoft/TypeScript/pull/29955 for details
107
+ const locations = Array.isArray(config.in)
108
+ ? config.in
109
+ : [config.in].filter(Boolean);
110
+ const actualLocations = locations.length ? locations : defaults;
111
+ return actualLocations.filter(location => validLocations.includes(location));
112
+ }
@@ -0,0 +1,43 @@
1
+ import { ErrorMessage, FieldMessageFactory, Location } from '../base';
2
+ /**
3
+ * Creates a variant of `check()` that checks the given request locations.
4
+ *
5
+ * @example
6
+ * const checkBodyAndQuery = buildCheckFunction(['body', 'query']);
7
+ */
8
+ export declare function buildCheckFunction(locations: Location[]): (fields?: string | string[], message?: FieldMessageFactory | ErrorMessage) => import("..").ValidationChain;
9
+ /**
10
+ * Creates a middleware/validation chain for one or more fields that may be located in
11
+ * any of the following:
12
+ *
13
+ * - `req.body`
14
+ * - `req.cookies`
15
+ * - `req.headers`
16
+ * - `req.params`
17
+ * - `req.query`
18
+ *
19
+ * @param fields a string or array of field names to validate/sanitize
20
+ * @param message an error message to use when failed validations don't specify a custom message.
21
+ * Defaults to `Invalid Value`.
22
+ */
23
+ export declare const check: (fields?: string | string[], message?: FieldMessageFactory | ErrorMessage) => import("..").ValidationChain;
24
+ /**
25
+ * Same as {@link check()}, but only validates `req.body`.
26
+ */
27
+ export declare const body: (fields?: string | string[], message?: FieldMessageFactory | ErrorMessage) => import("..").ValidationChain;
28
+ /**
29
+ * Same as {@link check()}, but only validates `req.cookies`.
30
+ */
31
+ export declare const cookie: (fields?: string | string[], message?: FieldMessageFactory | ErrorMessage) => import("..").ValidationChain;
32
+ /**
33
+ * Same as {@link check()}, but only validates `req.headers`.
34
+ */
35
+ export declare const header: (fields?: string | string[], message?: FieldMessageFactory | ErrorMessage) => import("..").ValidationChain;
36
+ /**
37
+ * Same as {@link check()}, but only validates `req.params`.
38
+ */
39
+ export declare const param: (fields?: string | string[], message?: FieldMessageFactory | ErrorMessage) => import("..").ValidationChain;
40
+ /**
41
+ * Same as {@link check()}, but only validates `req.query`.
42
+ */
43
+ export declare const query: (fields?: string | string[], message?: FieldMessageFactory | ErrorMessage) => import("..").ValidationChain;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.query = exports.param = exports.header = exports.cookie = exports.body = exports.check = void 0;
4
+ exports.buildCheckFunction = buildCheckFunction;
5
+ const check_1 = require("./check");
6
+ /**
7
+ * Creates a variant of `check()` that checks the given request locations.
8
+ *
9
+ * @example
10
+ * const checkBodyAndQuery = buildCheckFunction(['body', 'query']);
11
+ */
12
+ function buildCheckFunction(locations) {
13
+ return (fields, message) => (0, check_1.check)(fields, locations, message);
14
+ }
15
+ /**
16
+ * Creates a middleware/validation chain for one or more fields that may be located in
17
+ * any of the following:
18
+ *
19
+ * - `req.body`
20
+ * - `req.cookies`
21
+ * - `req.headers`
22
+ * - `req.params`
23
+ * - `req.query`
24
+ *
25
+ * @param fields a string or array of field names to validate/sanitize
26
+ * @param message an error message to use when failed validations don't specify a custom message.
27
+ * Defaults to `Invalid Value`.
28
+ */
29
+ exports.check = buildCheckFunction(['body', 'cookies', 'headers', 'params', 'query']);
30
+ /**
31
+ * Same as {@link check()}, but only validates `req.body`.
32
+ */
33
+ exports.body = buildCheckFunction(['body']);
34
+ /**
35
+ * Same as {@link check()}, but only validates `req.cookies`.
36
+ */
37
+ exports.cookie = buildCheckFunction(['cookies']);
38
+ /**
39
+ * Same as {@link check()}, but only validates `req.headers`.
40
+ */
41
+ exports.header = buildCheckFunction(['headers']);
42
+ /**
43
+ * Same as {@link check()}, but only validates `req.params`.
44
+ */
45
+ exports.param = buildCheckFunction(['params']);
46
+ /**
47
+ * Same as {@link check()}, but only validates `req.query`.
48
+ */
49
+ exports.query = buildCheckFunction(['query']);