Change endpoint from persons to people

This commit is contained in:
xfarrow
2025-03-23 21:00:08 +01:00
parent 4ae263662c
commit d005193f63
7158 changed files with 700476 additions and 735 deletions

View File

@ -0,0 +1,13 @@
import { ContextBuilder } from '../context-builder';
import { CustomValidator } from '../base';
import { BailOptions, ContextHandler, OptionalOptions } from './context-handler';
import { ContextRunner } from './context-runner';
export declare class ContextHandlerImpl<Chain> implements ContextHandler<Chain> {
private readonly builder;
private readonly chain;
constructor(builder: ContextBuilder, chain: Chain);
bail(opts?: BailOptions): Chain;
if(condition: CustomValidator | ContextRunner): Chain;
optional(options?: OptionalOptions | boolean): Chain;
hide(hiddenValue?: string): Chain;
}

View File

@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextHandlerImpl = void 0;
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(opts) {
if (opts?.level === 'request') {
this.builder.setRequestBail();
}
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) {
let value;
if (typeof options === 'boolean') {
value = options ? 'undefined' : false;
}
else {
value = options.values
? options.values
: options.checkFalsy
? 'falsy'
: options.nullable
? 'null'
: 'undefined';
}
this.builder.setOptional(value);
return this.chain;
}
hide(hiddenValue) {
this.builder.setHidden(true, hiddenValue);
return this.chain;
}
}
exports.ContextHandlerImpl = ContextHandlerImpl;

View File

@ -0,0 +1,110 @@
import { CustomValidator } from '../base';
import { Optional } from '../context';
import { ContextRunner } from './context-runner';
export interface BailOptions {
/**
* Defines the level at which to stop running further validations:
* - When set to `chain`, further validations won't be run for this validation chain if there
* are any errors.
* - When set to `request`, no further validations on the same request will be run either if
* there are any errors.
*
* @default 'chain'
*/
level?: 'chain' | 'request';
}
export interface OptionalOptions {
/**
* Defines which kind of value makes a field optional.
*
* - `undefined`: only `undefined` values; equivalent to `value === undefined`
* - `null`: only `undefined` and `null` values; equivalent to `value == null`
* - `falsy`: all falsy values; equivalent to `!value`
*
* @default 'undefined'
*/
values?: Exclude<Optional, false>;
/**
* Whether a field whose value is `null` or `undefined` is to be considered optional.
* @default false
* @deprecated Use `values` instead.
*/
nullable?: boolean;
/**
* Whether a field whose value is falsy (that is, `0`, `false`, `null`, `undefined` or an empty
* string) is to be considered optional.
* @default false
* @deprecated Use `values` instead.
*/
checkFalsy?: boolean;
}
export interface ContextHandler<Chain> {
/**
* 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.
*
* May be used multiple times in the same validation chain if desired.
*
* @example
* check('username')
* .isEmail()
* // If not an email, stop here
* .bail()
* .custom(checkDenylistDomain)
* // If domain is not allowed, don't go check if it already exists
* .bail()
* .custom(checkEmailExists)
*
* @returns the current validation chain
*/
bail(opts?: BailOptions): Chain;
/**
* Adds a condition on whether the validation should continue on a field or not.
* @param condition may be either
* - a custom validator-like function, which must truthy or a promise that resolves to continue
* validation. If the return value is falsy, a promise that rejects, or if it throws, validation
* will stop.
* - a validation chain which if it would produce errors, the validation chain stops.
* @example
* check('newPassword')
* // Only validate if the old password has been provided
* .if((value, { req }) => req.body.oldPassword)
* // Or, use it with a a validation chain
* .if(body('oldPassword').notEmpty())
* @returns the current validation chain
*/
if(condition: CustomValidator | ContextRunner): Chain;
/**
* Marks the field(s) of the validation chain as optional.
* By default, only fields with an `undefined` value are considered optional and will be ignored
* when validating.
*
* @param options an object of options to customize the behavior of optional.
* @returns the current validation chain
*/
optional(options?: {
values?: Optional;
/**
* @deprecated use `values` instead
*/
checkFalsy?: boolean;
/**
* @deprecated use `values` instead
*/
nullable?: boolean;
} | boolean): Chain;
/**
* Hide the field's value in errors returned by `validationResult()`.
*
* If the value is confidential information (such as api key),
* you might want to call this method to prevent exposing it.
*
* @param hiddenValue? String to replace the field's value with.
* If it's not set, the field value is removed from errors.
*
* @returns the current validation chain
*/
hide(hiddenValue?: string): Chain;
}

View File

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

View File

@ -0,0 +1,18 @@
import { Request } from '../base';
import { Context, ReadonlyContext } from '../context';
import { ContextBuilder } from '../context-builder';
import { SelectFields } from '../field-selection';
import { Result } from '../validation-result';
import { ContextRunner, ResultWithContext } from './context-runner';
export declare class ResultWithContextImpl extends Result implements ResultWithContext {
readonly context: ReadonlyContext;
constructor(context: ReadonlyContext);
}
export declare class ContextRunnerImpl implements ContextRunner {
private readonly builderOrContext;
private readonly selectFields;
constructor(builderOrContext: ContextBuilder | Context, selectFields?: SelectFields);
run(req: Request, options?: {
dryRun?: boolean;
}): Promise<ResultWithContextImpl>;
}

View File

@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextRunnerImpl = exports.ResultWithContextImpl = void 0;
const _ = require("lodash");
const base_1 = require("../base");
const context_1 = require("../context");
const field_selection_1 = require("../field-selection");
const validation_result_1 = require("../validation-result");
class ResultWithContextImpl extends validation_result_1.Result {
constructor(context) {
super(error => error, context.errors);
this.context = context;
}
}
exports.ResultWithContextImpl = ResultWithContextImpl;
class ContextRunnerImpl {
constructor(builderOrContext, selectFields = field_selection_1.selectFields) {
this.builderOrContext = builderOrContext;
this.selectFields = selectFields;
}
async run(req, options = {}) {
const context = this.builderOrContext instanceof context_1.Context
? this.builderOrContext
: this.builderOrContext.build();
const internalReq = req;
const bail = internalReq[base_1.contextsKey]?.some(context => context.bail && context.errors.length > 0);
if (bail) {
return new ResultWithContextImpl(context);
}
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(async (instance) => {
const { location, path } = instance;
const instanceKey = `${location}:${path}`;
if (haltedInstances.has(instanceKey)) {
return;
}
try {
await contextItem.run(context, instance.value, {
req,
location,
path,
pathValues: instance.pathValues,
});
// An instance is mutable, so if an item changed its value, there's no need to call getData again
const newValue = instance.value;
// 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 (!options.dryRun && reqValue !== instance.value) {
path !== '' ? _.set(req[location], path, newValue) : _.set(req, location, newValue);
}
}
catch (e) {
if (e instanceof base_1.ValidationHalt) {
haltedInstances.add(instanceKey);
return;
}
throw e;
}
});
await Promise.all(promises);
}
if (!options.dryRun) {
internalReq[base_1.contextsKey] = (internalReq[base_1.contextsKey] || []).concat(context);
}
return new ResultWithContextImpl(context);
}
}
exports.ContextRunnerImpl = ContextRunnerImpl;

View File

@ -0,0 +1,22 @@
import { Request, ValidationError } from '../base';
import { ReadonlyContext } from '../context';
import { Result } from '../validation-result';
export type ContextRunningOptions = {
/**
* Defines whether errors and sanitization should be persisted to `req`.
* @default false
*/
dryRun?: boolean;
};
export interface ResultWithContext extends Result<ValidationError> {
readonly context: ReadonlyContext;
}
export interface ContextRunner {
/**
* Runs the current validation chain.
* @param req the express request to validate
* @param options an object of options to customize how the chain will be run
* @returns a promise for a {@link Result} that resolves when the validation chain has finished
*/
run(req: Request, options?: ContextRunningOptions): Promise<ResultWithContext>;
}

View File

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

View File

@ -0,0 +1,9 @@
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 './validation-chain';

View File

@ -0,0 +1,25 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./sanitizers"), exports);
__exportStar(require("./sanitizers-impl"), exports);
__exportStar(require("./context-handler"), exports);
__exportStar(require("./context-handler-impl"), exports);
__exportStar(require("./context-runner"), exports);
__exportStar(require("./context-runner-impl"), exports);
__exportStar(require("./validators"), exports);
__exportStar(require("./validators-impl"), exports);
__exportStar(require("./validation-chain"), exports);

View File

@ -0,0 +1,29 @@
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;
default(default_value: any): Chain;
replace(values_to_replace: any, new_value: any): 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;
toLowerCase(): Chain;
toUpperCase(): Chain;
trim(chars?: string): Chain;
whitelist(chars: string): Chain;
}

View File

@ -0,0 +1,80 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SanitizersImpl = void 0;
const _ = require("lodash");
const validator = require("validator");
const sanitization_1 = require("../context-items/sanitization");
class SanitizersImpl {
constructor(builder, chain) {
this.builder = builder;
this.chain = chain;
}
// custom sanitizers
customSanitizer(sanitizer) {
this.builder.addItem(new sanitization_1.Sanitization(sanitizer, true));
return this.chain;
}
default(default_value) {
return this.customSanitizer(value => [undefined, null, NaN, ''].includes(value) ? _.cloneDeep(default_value) : value);
}
replace(values_to_replace, new_value) {
if (!Array.isArray(values_to_replace)) {
values_to_replace = [values_to_replace];
}
return this.customSanitizer(value => values_to_replace.includes(value) ? _.cloneDeep(new_value) : value);
}
// 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);
}
toLowerCase() {
return this.customSanitizer(value => (typeof value === 'string' ? value.toLowerCase() : value));
}
toUpperCase() {
return this.customSanitizer(value => (typeof value === 'string' ? value.toUpperCase() : value));
}
trim(chars) {
return this.addStandardSanitization(validator.trim, chars);
}
whitelist(chars) {
return this.addStandardSanitization(validator.whitelist, chars);
}
}
exports.SanitizersImpl = SanitizersImpl;

View File

@ -0,0 +1,42 @@
import { CustomSanitizer } from '../base';
import * as Options from '../options';
export interface Sanitizers<Return> {
/**
* Adds a custom sanitizer to the validation chain.
*
* @param sanitizer the custom sanitizer
* @returns the current validation chain
*/
customSanitizer(sanitizer: CustomSanitizer): Return;
/**
* Replaces the value of the field if it's one of `''`, `null`, `undefined` or `NaN`.
*
* @param default_value the value to replace with
* @returns the current validation chain
*/
default(default_value: any): Return;
/**
* Replaces a field's value with another value.
*
* @param values_to_replace one or more values that should be replaced
* @param new_value the value to replace with
* @returns the current validation chain
*/
replace(values_to_replace: any, new_value: any): 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;
toLowerCase(): Return;
toUpperCase(): 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,18 @@
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;
}
/**
* A copy of `ValidationChain` where methods that would return the chain itself can return any other
* value.
* Useful for typing functions which accept either standard or custom validation chains.
*/
export type ValidationChainLike = {
[K in keyof ValidationChain]: ValidationChain[K] extends (...args: infer A) => ValidationChain ? (...args: A) => any : ValidationChain[K];
};

View File

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

View File

@ -0,0 +1,119 @@
import { CustomValidator, ErrorMessage, FieldMessageFactory } from '../base';
import { ContextBuilder } from '../context-builder';
import * as Options from '../options';
import { ExistsOptions, 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: FieldMessageFactory | ErrorMessage): Chain;
custom(validator: CustomValidator): Chain;
exists(options?: ExistsOptions): Chain;
isArray(options?: {
min?: number;
max?: number;
}): Chain;
isObject(options?: {
strict?: boolean;
}): Chain;
isString(): Chain;
isULID(): any;
notEmpty(options?: Options.IsEmptyOptions): Chain;
private addStandardValidation;
contains(elem: any, options?: Options.ContainsOptions): Chain;
equals(comparison: string): Chain;
isAbaRouting(): Chain;
isAfter(dateOrOptions?: string | Options.IsAfterOptions): Chain;
isAlpha(locale?: Options.AlphaLocale, options?: Options.IsAlphaOptions): Chain;
isAlphanumeric(locale?: Options.AlphanumericLocale, options?: Options.IsAlphanumericOptions): Chain;
isAscii(): Chain;
isBase32(options?: Options.IsBase32Options): Chain;
isBase58(): Chain;
isBase64(options?: Options.IsBase64Options): Chain;
isBefore(date?: string): Chain;
isBIC(): Chain;
/**
* There are basically three levels of strictness for this validator.
* Passing `{ strict: true }` as option only passes the validation if the value is a JS bool. (It also overrides the loose property of the options).
* Passing `{ loose: true|false }` along with no `strict` prop of with `strict` falsy follows the behaviour specified in validator.js docs.
*/
isBoolean(options?: Options.IsBooleanOptions): Chain;
isBtcAddress(): Chain;
isByteLength(options: Options.MinMaxOptions): Chain;
isCreditCard(): Chain;
isCurrency(options?: Options.IsCurrencyOptions): Chain;
isDataURI(): Chain;
isDate(options?: Options.IsDateOptions): Chain;
isDecimal(options?: Options.IsDecimalOptions): Chain;
isDivisibleBy(number: number): Chain;
isEAN(): Chain;
isEmail(options?: Options.IsEmailOptions): Chain;
isEmpty(options?: Options.IsEmptyOptions): Chain;
isEthereumAddress(): Chain;
isFQDN(options?: Options.IsFQDNOptions): Chain;
isFloat(options?: Options.IsFloatOptions): Chain;
isFreightContainerID(): Chain;
isFullWidth(): Chain;
isHalfWidth(): Chain;
isHash(algorithm: Options.HashAlgorithm): Chain;
isHexColor(): Chain;
isHexadecimal(): Chain;
isHSL(): Chain;
isIBAN(options?: Options.IsIBANOptions): Chain;
isIdentityCard(locale: Options.IdentityCardLocale): Chain;
isIMEI(options?: Options.IsIMEIOptions): Chain;
isIP(version?: Options.IPVersion): Chain;
isIPRange(version?: Options.IPVersion): Chain;
isISBN(versionOrOptions?: number | Options.IsISBNOptions): Chain;
isISSN(options?: Options.IsISSNOptions): Chain;
isISIN(): Chain;
isISO6346(): Chain;
isISO6391(): Chain;
isISO8601(options?: Options.IsISO8601Options): Chain;
isISO31661Alpha2(): Chain;
isISO31661Alpha3(): Chain;
isISO4217(): Chain;
isISRC(): Chain;
isIn(values: readonly any[]): Chain;
isInt(options?: Options.IsIntOptions): Chain;
isJSON(options?: Options.IsJSONOptions): Chain;
isJWT(): Chain;
isLatLong(options?: Options.IsLatLongOptions): Chain;
isLength(options: Options.MinMaxOptions): Chain;
isLicensePlate(locale: Options.IsLicensePlateLocale): Chain;
isLocale(): Chain;
isLowercase(): Chain;
isLuhnNumber(): Chain;
isMagnetURI(): Chain;
isMailtoURI(options?: Options.IsEmailOptions): Chain;
isMACAddress(options?: Options.IsMACAddressOptions): Chain;
isMD5(): Chain;
isMimeType(): Chain;
isMobilePhone(locale: Options.MobilePhoneLocale | readonly Options.MobilePhoneLocale[], options?: Options.IsMobilePhoneOptions): Chain;
isMongoId(): Chain;
isMultibyte(): Chain;
isNumeric(options?: Options.IsNumericOptions): Chain;
isOctal(): Chain;
isPassportNumber(countryCode?: Options.PassportCountryCode): Chain;
isPort(): Chain;
isPostalCode(locale: Options.PostalCodeLocale): Chain;
isRFC3339(): Chain;
isRgbColor(includePercentValues?: boolean): Chain;
isSemVer(): Chain;
isSlug(): Chain;
isStrongPassword(options?: Options.IsStrongPasswordOptions): Chain;
isSurrogatePair(): Chain;
isTaxID(locale: Options.TaxIDLocale): Chain;
isTime(options?: Options.IsTimeOptions): Chain;
isURL(options?: Options.IsURLOptions): Chain;
isUUID(version?: Options.UUIDVersion): Chain;
isUppercase(): Chain;
isVariableWidth(): Chain;
isVAT(countryCode: Options.VATCountryCode): Chain;
isWhitelisted(chars: string | readonly string[]): Chain;
matches(pattern: RegExp | string, modifiers?: string): any;
}

View File

@ -0,0 +1,347 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidatorsImpl = void 0;
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 || options.values === 'falsy') {
validator = value => !!value;
}
else if (options.checkNull || options.values === 'null') {
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));
}
isObject(options = { strict: true }) {
return this.custom(value => typeof value === 'object' &&
(options.strict == null || options.strict ? value !== null && !Array.isArray(value) : true));
}
isString() {
return this.custom(value => typeof value === 'string');
}
isULID() {
return this.matches(/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/i);
}
notEmpty(options) {
this.not();
return this.isEmpty(options);
}
// Standard validators
addStandardValidation(validator, ...options) {
return this.addItem(new context_items_1.StandardValidation(validator, this.negateNext, options));
}
contains(elem, options) {
return this.addStandardValidation(validator.contains, elem, options);
}
equals(comparison) {
return this.addStandardValidation(validator.equals, comparison);
}
isAbaRouting() {
return this.addStandardValidation(validator.isAbaRouting);
}
isAfter(dateOrOptions) {
return this.addStandardValidation(validator.isAfter, dateOrOptions);
}
isAlpha(locale, options) {
// TODO(v7): remove string[] support
const ignore = Array.isArray(options?.ignore) ? options?.ignore.join('') : options?.ignore;
return this.addStandardValidation(validator.isAlpha, locale, { ...options, ignore });
}
isAlphanumeric(locale, options) {
return this.addStandardValidation(validator.isAlphanumeric, locale, options);
}
isAscii() {
return this.addStandardValidation(validator.isAscii);
}
isBase32(options) {
return this.addStandardValidation(validator.isBase32, options);
}
isBase58() {
return this.addStandardValidation(validator.isBase58);
}
isBase64(options) {
return this.addStandardValidation(validator.isBase64, options);
}
isBefore(date) {
return this.addStandardValidation(validator.isBefore, date);
}
isBIC() {
return this.addStandardValidation(validator.isBIC);
}
/**
* There are basically three levels of strictness for this validator.
* Passing `{ strict: true }` as option only passes the validation if the value is a JS bool. (It also overrides the loose property of the options).
* Passing `{ loose: true|false }` along with no `strict` prop of with `strict` falsy follows the behaviour specified in validator.js docs.
*/
isBoolean(options) {
if (options?.strict) {
return this.custom(value => {
return value === true || value === false;
});
}
return this.addStandardValidation(validator.isBoolean, options);
}
isBtcAddress() {
return this.addStandardValidation(validator.isBtcAddress);
}
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);
}
isDate(options) {
return this.addStandardValidation(validator.isDate, options);
}
isDecimal(options) {
return this.addStandardValidation(validator.isDecimal, options);
}
isDivisibleBy(number) {
return this.addStandardValidation(validator.isDivisibleBy, number);
}
isEAN() {
return this.addStandardValidation(validator.isEAN);
}
isEmail(options) {
return this.addStandardValidation(validator.isEmail, options);
}
isEmpty(options) {
return this.addStandardValidation(validator.isEmpty, options);
}
isEthereumAddress() {
return this.addStandardValidation(validator.isEthereumAddress);
}
isFQDN(options) {
return this.addStandardValidation(validator.isFQDN, options);
}
isFloat(options) {
return this.addStandardValidation(validator.isFloat, options);
}
isFreightContainerID() {
return this.addStandardValidation(validator.isFreightContainerID);
}
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);
}
isHSL() {
return this.addStandardValidation(validator.isHSL);
}
isIBAN(options) {
return this.addStandardValidation(validator.isIBAN, options);
}
isIdentityCard(locale) {
return this.addStandardValidation(validator.isIdentityCard, locale);
}
isIMEI(options) {
return this.addStandardValidation(validator.isIMEI, options);
}
isIP(version) {
return this.addStandardValidation(validator.isIP, version);
}
isIPRange(version) {
return this.addStandardValidation(validator.isIPRange, version);
}
isISBN(versionOrOptions) {
return this.addStandardValidation(validator.isISBN, versionOrOptions);
}
isISSN(options) {
return this.addStandardValidation(validator.isISSN, options);
}
isISIN() {
return this.addStandardValidation(validator.isISIN);
}
isISO6346() {
return this.addStandardValidation(validator.isISO6346);
}
isISO6391() {
return this.addStandardValidation(validator.isISO6391);
}
isISO8601(options) {
return this.addStandardValidation(validator.isISO8601, options);
}
isISO31661Alpha2() {
return this.addStandardValidation(validator.isISO31661Alpha2);
}
isISO31661Alpha3() {
return this.addStandardValidation(validator.isISO31661Alpha3);
}
isISO4217() {
return this.addStandardValidation(validator.isISO4217);
}
isISRC() {
return this.addStandardValidation(validator.isISRC);
}
isIn(values) {
return this.addStandardValidation(validator.isIn, values);
}
isInt(options) {
return this.addStandardValidation(validator.isInt, options);
}
isJSON(options) {
return this.addStandardValidation(validator.isJSON, options);
}
isJWT() {
return this.addStandardValidation(validator.isJWT);
}
isLatLong(options) {
return this.addStandardValidation(validator.isLatLong, options);
}
isLength(options) {
return this.addStandardValidation(validator.isLength, options);
}
isLicensePlate(locale) {
return this.addStandardValidation(validator.isLicensePlate, locale);
}
isLocale() {
return this.addStandardValidation(validator.isLocale);
}
isLowercase() {
return this.addStandardValidation(validator.isLowercase);
}
isLuhnNumber() {
return this.addStandardValidation(validator.isLuhnNumber);
}
isMagnetURI() {
return this.addStandardValidation(validator.isMagnetURI);
}
isMailtoURI(options) {
return this.addStandardValidation(validator.isMailtoURI, options);
}
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);
}
isOctal() {
return this.addStandardValidation(validator.isOctal);
}
isPassportNumber(countryCode) {
return this.addStandardValidation(validator.isPassportNumber, countryCode);
}
isPort() {
return this.addStandardValidation(validator.isPort);
}
isPostalCode(locale) {
return this.addStandardValidation(validator.isPostalCode, locale);
}
isRFC3339() {
return this.addStandardValidation(validator.isRFC3339);
}
isRgbColor(includePercentValues) {
return this.addStandardValidation(validator.isRgbColor, includePercentValues);
}
isSemVer() {
return this.addStandardValidation(validator.isSemVer);
}
isSlug() {
return this.addStandardValidation(validator.isSlug);
}
isStrongPassword(options) {
return this.addStandardValidation(validator.isStrongPassword, options);
}
isSurrogatePair() {
return this.addStandardValidation(validator.isSurrogatePair);
}
isTaxID(locale) {
return this.addStandardValidation(validator.isTaxID, locale);
}
isTime(options) {
return this.addStandardValidation(validator.isTime, options);
}
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);
}
isVAT(countryCode) {
return this.addStandardValidation(validator.isVAT, countryCode);
}
isWhitelisted(chars) {
return this.addStandardValidation(validator.isWhitelisted, chars);
}
matches(pattern, modifiers) {
return this.addStandardValidation.apply(this, [
validator.matches,
...(typeof pattern === 'string'
? [pattern, modifiers]
: [pattern.source, [...new Set((modifiers || '') + pattern.flags)].join('')]),
]);
}
}
exports.ValidatorsImpl = ValidatorsImpl;

View File

@ -0,0 +1,184 @@
import { CustomValidator, ErrorMessage, FieldMessageFactory } from '../base';
import * as Options from '../options';
export type ExistsOptions = {
/**
* Defines which kind of value makes a field _NOT_ exist.
*
* - `undefined`: only `undefined` values; equivalent to `value !== undefined`
* - `null`: only `undefined` and `null` values; equivalent to `value != null`
* - `falsy`: all falsy values; equivalent to `!!value`
*
* @default 'undefined'
*/
values?: 'undefined' | 'null' | 'falsy';
/**
* Whether a field whose value is falsy should be considered non-existent.
* @default false
* @deprecated Use `values` instead
*/
checkFalsy?: boolean;
/**
* Whether a field whose value is `null` or `undefined` should be considered non-existent.
* @default false
* @deprecated Use `values` instead
*/
checkNull?: boolean;
};
export interface Validators<Return> {
/**
* Negates the result of the next validator.
*
* @example check('weekday').not().isIn(['sunday', 'saturday'])
* @returns the current validation chain
*/
not(): Return;
/**
* Sets the error message for the previous validator.
*
* @param message the message, which can be any value, or a function for dynamically creating the
* error message based on the field value
* @returns the current validation chain
*/
withMessage(message: FieldMessageFactory | ErrorMessage): Return;
/**
* Adds a custom validator to the validation chain.
*
* @param validator the custom validator
* @returns the current validation chain
*/
custom(validator: CustomValidator): Return;
/**
* Adds a validator to check that the fields exist in the request.
* By default, this means that the value of the fields may not be `undefined`;
* all other values are acceptable.
*
* @param options
* @returns the current validation chain
*/
exists(options?: ExistsOptions): Return;
/**
* Adds a validator to check if a value is an array.
*
* @param options
* @returns the current validation chain
*/
isArray(options?: {
min?: number;
max?: number;
}): Return;
/**
* Adds a validator to check if a value is an object.
*
* @param options
* @returns the current validation chain
*/
isObject(options?: {
strict?: boolean;
}): Return;
/**
* Adds a validator to check if a value is a string.
*
* @returns the current validation chain
*/
isString(): Return;
/**
* Adds a validator to check if a value is a ULID.
*
* @returns the current validation chain
*/
isULID(): Return;
/**
* Adds a validator to check if a value is not empty; that is, a string with length of 1 or more.
*
* @param options
* @returns the current validation chain
*/
notEmpty(options?: Options.IsEmptyOptions): Return;
contains(elem: any, options?: Options.ContainsOptions): Return;
equals(comparison: string): Return;
isAbaRouting(): Return;
isAfter(dateOrOptions?: string | Options.IsAfterOptions): Return;
isAlpha(locale?: Options.AlphaLocale, options?: Options.IsAlphaOptions): Return;
isAlphanumeric(locale?: Options.AlphanumericLocale, options?: Options.IsAlphanumericOptions): Return;
isAscii(): Return;
isBase32(options?: Options.IsBase32Options): Return;
isBase58(): Return;
isBase64(options?: Options.IsBase64Options): Return;
isBefore(date?: string): Return;
isBIC(): Return;
isBoolean(options?: Options.IsBooleanOptions): Return;
isBtcAddress(): Return;
isByteLength(options: Options.MinMaxExtendedOptions): Return;
isCreditCard(options?: Options.IsCreditCard): Return;
isCurrency(options?: Options.IsCurrencyOptions): Return;
isDataURI(): Return;
isDate(options?: Options.IsDateOptions): Return;
isDecimal(options?: Options.IsDecimalOptions): Return;
isDivisibleBy(number: number): Return;
isEAN(): Return;
isEmail(options?: Options.IsEmailOptions): Return;
isEmpty(options?: Options.IsEmptyOptions): Return;
isEthereumAddress(): Return;
isFQDN(options?: Options.IsFQDNOptions): Return;
isFloat(options?: Options.IsFloatOptions): Return;
isFreightContainerID(): Return;
isFullWidth(): Return;
isHalfWidth(): Return;
isHash(algorithm: Options.HashAlgorithm): Return;
isHexColor(): Return;
isHexadecimal(): Return;
isHSL(): Return;
isIBAN(options?: Options.IsIBANOptions): Return;
isIdentityCard(locale?: Options.IdentityCardLocale): Return;
isIMEI(options?: Options.IsIMEIOptions): Return;
isIP(version?: Options.IPVersion): Return;
isIPRange(version?: Options.IPVersion): Return;
isISBN(versionOrOptions?: number | Options.IsISBNOptions): Return;
isISSN(options?: Options.IsISSNOptions): Return;
isISIN(): Return;
isISO6346(): Return;
isISO6391(): Return;
isISO8601(options?: Options.IsISO8601Options): Return;
isISO31661Alpha2(): Return;
isISO31661Alpha3(): Return;
isISO4217(): Return;
isISRC(): Return;
isIn(values: readonly any[]): Return;
isInt(options?: Options.IsIntOptions): Return;
isJSON(options?: Options.IsJSONOptions): Return;
isJWT(): Return;
isLatLong(options?: Options.IsLatLongOptions): Return;
isLength(options: Options.MinMaxOptions): Return;
isLicensePlate(locale: Options.IsLicensePlateLocale): Return;
isLocale(): Return;
isLowercase(): Return;
isLuhnNumber(): Return;
isMagnetURI(): Return;
isMailtoURI(options?: Options.IsEmailOptions): Return;
isMACAddress(options?: Options.IsMACAddressOptions): Return;
isMD5(): Return;
isMimeType(): Return;
isMobilePhone(locale: Options.MobilePhoneLocale | readonly Options.MobilePhoneLocale[], options?: Options.IsMobilePhoneOptions): Return;
isMongoId(): Return;
isMultibyte(): Return;
isNumeric(options?: Options.IsNumericOptions): Return;
isOctal(): Return;
isPassportNumber(countryCode?: Options.PassportCountryCode): Return;
isPort(): Return;
isPostalCode(locale: Options.PostalCodeLocale): Return;
isRgbColor(includePercentValues?: boolean): Return;
isRFC3339(): Return;
isSemVer(): Return;
isSlug(): Return;
isStrongPassword(options?: Options.IsStrongPasswordOptions): Return;
isSurrogatePair(): Return;
isTaxID(locale: Options.TaxIDLocale): Return;
isTime(options: Options.IsTimeOptions): Return;
isURL(options?: Options.IsURLOptions): Return;
isUUID(version?: Options.UUIDVersion): Return;
isUppercase(): Return;
isVariableWidth(): Return;
isVAT(countryCode: Options.VATCountryCode): Return;
isWhitelisted(chars: string | readonly string[]): Return;
matches(pattern: RegExp | string, modifiers?: string): Return;
}

View File

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