UNPKG

39.3 kBMarkdownView Raw
1# class-validator
2
3![Build Status](https://github.com/typestack/class-validator/workflows/CI/badge.svg)
4[![codecov](https://codecov.io/gh/typestack/class-validator/branch/develop/graph/badge.svg)](https://codecov.io/gh/typestack/class-validator)
5[![npm version](https://badge.fury.io/js/class-validator.svg)](https://badge.fury.io/js/class-validator)
6[![install size](https://packagephobia.now.sh/badge?p=class-validator)](https://packagephobia.now.sh/result?p=class-validator)
7
8Allows use of decorator and non-decorator based validation.
9Internally uses [validator.js][1] to perform validation.
10Class-validator works on both browser and node.js platforms.
11
12## Table of Contents
13
14- [class-validator](#class-validator)
15 - [Table of Contents](#table-of-contents)
16 - [Installation](#installation)
17 - [Usage](#usage)
18 - [Passing options](#passing-options)
19 - [Validation errors](#validation-errors)
20 - [Validation messages](#validation-messages)
21 - [Validating arrays](#validating-arrays)
22 - [Validating sets](#validating-sets)
23 - [Validating maps](#validating-maps)
24 - [Validating nested objects](#validating-nested-objects)
25 - [Validating promises](#validating-promises)
26 - [Inheriting Validation decorators](#inheriting-validation-decorators)
27 - [Conditional validation](#conditional-validation)
28 - [Whitelisting](#whitelisting)
29 - [Passing context to decorators](#passing-context-to-decorators)
30 - [Skipping missing properties](#skipping-missing-properties)
31 - [Validation groups](#validation-groups)
32 - [Custom validation classes](#custom-validation-classes)
33 - [Custom validation decorators](#custom-validation-decorators)
34 - [Using service container](#using-service-container)
35 - [Synchronous validation](#synchronous-validation)
36 - [Manual validation](#manual-validation)
37 - [Validation decorators](#validation-decorators)
38 - [Defining validation schema without decorators](#defining-validation-schema-without-decorators)
39 - [Validating plain objects](#validating-plain-objects)
40 - [Samples](#samples)
41 - [Extensions](#extensions)
42 - [Release notes](#release-notes)
43
44## Installation
45
46```
47npm install class-validator --save
48```
49
50> Note: Please use at least npm@6 when using class-validator. From npm@6 the dependency tree is flattened, which is required by `class-validator` to function properly.
51
52## Usage
53
54Create your class and put some validation decorators on the properties you want to validate:
55
56```typescript
57import {
58 validate,
59 validateOrReject,
60 Contains,
61 IsInt,
62 Length,
63 IsEmail,
64 IsFQDN,
65 IsDate,
66 Min,
67 Max,
68} from 'class-validator';
69
70export class Post {
71 @Length(10, 20)
72 title: string;
73
74 @Contains('hello')
75 text: string;
76
77 @IsInt()
78 @Min(0)
79 @Max(10)
80 rating: number;
81
82 @IsEmail()
83 email: string;
84
85 @IsFQDN()
86 site: string;
87
88 @IsDate()
89 createDate: Date;
90}
91
92let post = new Post();
93post.title = 'Hello'; // should not pass
94post.text = 'this is a great post about hell world'; // should not pass
95post.rating = 11; // should not pass
96post.email = 'google.com'; // should not pass
97post.site = 'googlecom'; // should not pass
98
99validate(post).then(errors => {
100 // errors is an array of validation errors
101 if (errors.length > 0) {
102 console.log('validation failed. errors: ', errors);
103 } else {
104 console.log('validation succeed');
105 }
106});
107
108validateOrReject(post).catch(errors => {
109 console.log('Promise rejected (validation failed). Errors: ', errors);
110});
111// or
112async function validateOrRejectExample(input) {
113 try {
114 await validateOrReject(input);
115 } catch (errors) {
116 console.log('Caught promise rejection (validation failed). Errors: ', errors);
117 }
118}
119```
120
121### Passing options
122
123The `validate` function optionally expects a `ValidatorOptions` object as a second parameter:
124
125```ts
126export interface ValidatorOptions {
127 skipMissingProperties?: boolean;
128 whitelist?: boolean;
129 forbidNonWhitelisted?: boolean;
130 groups?: string[];
131 dismissDefaultMessages?: boolean;
132 validationError?: {
133 target?: boolean;
134 value?: boolean;
135 };
136
137 forbidUnknownValues?: boolean;
138 stopAtFirstError?: boolean;
139}
140```
141
142> It's highly advised to set `forbidUnknownValues: true` as it will prevent unknown objects from passing validation.
143
144## Validation errors
145
146The `validate` method returns an array of `ValidationError` objects. Each `ValidationError` is:
147
148```typescript
149{
150 target: Object; // Object that was validated.
151 property: string; // Object's property that haven't pass validation.
152 value: any; // Value that haven't pass a validation.
153 constraints?: { // Constraints that failed validation with error messages.
154 [type: string]: string;
155 };
156 children?: ValidationError[]; // Contains all nested validation errors of the property
157}
158```
159
160In our case, when we validated a Post object, we have such an array of `ValidationError` objects:
161
162```typescript
163[{
164 target: /* post object */,
165 property: "title",
166 value: "Hello",
167 constraints: {
168 length: "$property must be longer than or equal to 10 characters"
169 }
170}, {
171 target: /* post object */,
172 property: "text",
173 value: "this is a great post about hell world",
174 constraints: {
175 contains: "text must contain a hello string"
176 }
177},
178// and other errors
179]
180```
181
182If you don't want a `target` to be exposed in validation errors, there is a special option when you use validator:
183
184```typescript
185validator.validate(post, { validationError: { target: false } });
186```
187
188This is especially useful when you send errors back over http, and you most probably don't want to expose
189the whole target object.
190
191## Validation messages
192
193You can specify validation message in the decorator options and that message will be returned in the `ValidationError`
194returned by the `validate` method (in the case that validation for this field fails).
195
196```typescript
197import { MinLength, MaxLength } from 'class-validator';
198
199export class Post {
200 @MinLength(10, {
201 message: 'Title is too short',
202 })
203 @MaxLength(50, {
204 message: 'Title is too long',
205 })
206 title: string;
207}
208```
209
210There are few special tokens you can use in your messages:
211
212- `$value` - the value that is being validated
213- `$property` - name of the object's property being validated
214- `$target` - name of the object's class being validated
215- `$constraint1`, `$constraint2`, ... `$constraintN` - constraints defined by specific validation type
216
217Example of usage:
218
219```typescript
220import { MinLength, MaxLength } from 'class-validator';
221
222export class Post {
223 @MinLength(10, {
224 // here, $constraint1 will be replaced with "10", and $value with actual supplied value
225 message: 'Title is too short. Minimal length is $constraint1 characters, but actual is $value',
226 })
227 @MaxLength(50, {
228 // here, $constraint1 will be replaced with "50", and $value with actual supplied value
229 message: 'Title is too long. Maximal length is $constraint1 characters, but actual is $value',
230 })
231 title: string;
232}
233```
234
235Also you can provide a function, that returns a message. This allows you to create more granular messages:
236
237```typescript
238import { MinLength, MaxLength, ValidationArguments } from 'class-validator';
239
240export class Post {
241 @MinLength(10, {
242 message: (args: ValidationArguments) => {
243 if (args.value.length === 1) {
244 return 'Too short, minimum length is 1 character';
245 } else {
246 return 'Too short, minimum length is ' + args.constraints[0] + ' characters';
247 }
248 },
249 })
250 title: string;
251}
252```
253
254Message function accepts `ValidationArguments` which contains the following information:
255
256- `value` - the value that is being validated
257- `constraints` - array of constraints defined by specific validation type
258- `targetName` - name of the object's class being validated
259- `object` - object that is being validated
260- `property` - name of the object's property being validated
261
262## Validating arrays
263
264If your field is an array and you want to perform validation of each item in the array you must specify a
265special `each: true` decorator option:
266
267```typescript
268import { MinLength, MaxLength } from 'class-validator';
269
270export class Post {
271 @MaxLength(20, {
272 each: true,
273 })
274 tags: string[];
275}
276```
277
278This will validate each item in `post.tags` array.
279
280## Validating sets
281
282If your field is a set and you want to perform validation of each item in the set you must specify a
283special `each: true` decorator option:
284
285```typescript
286import { MinLength, MaxLength } from 'class-validator';
287
288export class Post {
289 @MaxLength(20, {
290 each: true,
291 })
292 tags: Set<string>;
293}
294```
295
296This will validate each item in `post.tags` set.
297
298## Validating maps
299
300If your field is a map and you want to perform validation of each item in the map you must specify a
301special `each: true` decorator option:
302
303```typescript
304import { MinLength, MaxLength } from 'class-validator';
305
306export class Post {
307 @MaxLength(20, {
308 each: true,
309 })
310 tags: Map<string, string>;
311}
312```
313
314This will validate each item in `post.tags` map.
315
316## Validating nested objects
317
318If your object contains nested objects and you want the validator to perform their validation too, then you need to
319use the `@ValidateNested()` decorator:
320
321```typescript
322import { ValidateNested } from 'class-validator';
323
324export class Post {
325 @ValidateNested()
326 user: User;
327}
328```
329
330Please note that nested object _must_ be an instance of a class, otherwise `@ValidateNested` won't know what class is target of validation. Check also [Validating plain objects](#validating-plain-objects).
331
332It also works with multi-dimensional array, like :
333
334```typescript
335import { ValidateNested } from 'class-validator';
336
337export class Plan2D {
338 @ValidateNested()
339 matrix: Point[][];
340}
341```
342
343## Validating promises
344
345If your object contains property with `Promise`-returned value that should be validated, then you need to use the `@ValidatePromise()` decorator:
346
347```typescript
348import { ValidatePromise, Min } from 'class-validator';
349
350export class Post {
351 @Min(0)
352 @ValidatePromise()
353 userId: Promise<number>;
354}
355```
356
357It also works great with `@ValidateNested` decorator:
358
359```typescript
360import { ValidateNested, ValidatePromise } from 'class-validator';
361
362export class Post {
363 @ValidateNested()
364 @ValidatePromise()
365 user: Promise<User>;
366}
367```
368
369## Inheriting Validation decorators
370
371When you define a subclass which extends from another one, the subclass will automatically inherit the parent's decorators. If a property is redefined in the descendant class decorators will be applied on it both from that and the base class.
372
373```typescript
374import { validate } from 'class-validator';
375
376class BaseContent {
377 @IsEmail()
378 email: string;
379
380 @IsString()
381 password: string;
382}
383
384class User extends BaseContent {
385 @MinLength(10)
386 @MaxLength(20)
387 name: string;
388
389 @Contains('hello')
390 welcome: string;
391
392 @MinLength(20)
393 password: string;
394}
395
396let user = new User();
397
398user.email = 'invalid email'; // inherited property
399user.password = 'too short'; // password wil be validated not only against IsString, but against MinLength as well
400user.name = 'not valid';
401user.welcome = 'helo';
402
403validate(user).then(errors => {
404 // ...
405}); // it will return errors for email, title and text properties
406```
407
408## Conditional validation
409
410The conditional validation decorator (`@ValidateIf`) can be used to ignore the validators on a property when the provided condition function returns false. The condition function takes the object being validated and must return a `boolean`.
411
412```typescript
413import { ValidateIf, IsNotEmpty } from 'class-validator';
414
415export class Post {
416 otherProperty: string;
417
418 @ValidateIf(o => o.otherProperty === 'value')
419 @IsNotEmpty()
420 example: string;
421}
422```
423
424In the example above, the validation rules applied to `example` won't be run unless the object's `otherProperty` is `"value"`.
425
426Note that when the condition is false all validation decorators are ignored, including `isDefined`.
427
428## Whitelisting
429
430Even if your object is an instance of a validation class it can contain additional properties that are not defined.
431If you do not want to have such properties on your object, pass special flag to `validate` method:
432
433```typescript
434import { validate } from 'class-validator';
435// ...
436validate(post, { whitelist: true });
437```
438
439This will strip all properties that don't have any decorators. If no other decorator is suitable for your property,
440you can use @Allow decorator:
441
442```typescript
443import {validate, Allow, Min} from "class-validator";
444
445export class Post {
446
447 @Allow()
448 title: string;
449
450 @Min(0)
451 views: number;
452
453 nonWhitelistedProperty: number;
454}
455
456let post = new Post();
457post.title = 'Hello world!';
458post.views = 420;
459
460post.nonWhitelistedProperty = 69;
461(post as any).anotherNonWhitelistedProperty = "something";
462
463validate(post).then(errors => {
464 // post.nonWhitelistedProperty is not defined
465 // (post as any).anotherNonWhitelistedProperty is not defined
466 ...
467});
468```
469
470If you would rather to have an error thrown when any non-whitelisted properties are present, pass another flag to
471`validate` method:
472
473```typescript
474import { validate } from 'class-validator';
475// ...
476validate(post, { whitelist: true, forbidNonWhitelisted: true });
477```
478
479## Passing context to decorators
480
481It's possible to pass a custom object to decorators which will be accessible on the `ValidationError` instance of the property if validation failed.
482
483```ts
484import { validate } from 'class-validator';
485
486class MyClass {
487 @MinLength(32, {
488 message: 'EIC code must be at least 32 characters',
489 context: {
490 errorCode: 1003,
491 developerNote: 'The validated string must contain 32 or more characters.',
492 },
493 })
494 eicCode: string;
495}
496
497const model = new MyClass();
498
499validate(model).then(errors => {
500 //errors[0].contexts['minLength'].errorCode === 1003
501});
502```
503
504## Skipping missing properties
505
506Sometimes you may want to skip validation of the properties that do not exist in the validating object. This is
507usually desirable when you want to update some parts of the object, and want to validate only updated parts,
508but skip everything else, e.g. skip missing properties.
509In such situations you will need to pass a special flag to `validate` method:
510
511```typescript
512import { validate } from 'class-validator';
513// ...
514validate(post, { skipMissingProperties: true });
515```
516
517When skipping missing properties, sometimes you want not to skip all missing properties, some of them maybe required
518for you, even if skipMissingProperties is set to true. For such cases you should use `@IsDefined()` decorator.
519`@IsDefined()` is the only decorator that ignores `skipMissingProperties` option.
520
521## Validation groups
522
523In different situations you may want to use different validation schemas of the same object.
524In such cases you can use validation groups.
525
526```typescript
527import { validate, Min, Length } from 'class-validator';
528
529export class User {
530 @Min(12, {
531 groups: ['registration'],
532 })
533 age: number;
534
535 @Length(2, 20, {
536 groups: ['registration', 'admin'],
537 })
538 name: string;
539}
540
541let user = new User();
542user.age = 10;
543user.name = 'Alex';
544
545validate(user, {
546 groups: ['registration'],
547}); // this will not pass validation
548
549validate(user, {
550 groups: ['admin'],
551}); // this will pass validation
552
553validate(user, {
554 groups: ['registration', 'admin'],
555}); // this will not pass validation
556
557validate(user, {
558 groups: undefined, // the default
559}); // this will not pass validation since all properties get validated regardless of their groups
560
561validate(user, {
562 groups: [],
563}); // this will not pass validation, (equivalent to 'groups: undefined', see above)
564```
565
566There is also a special flag `always: true` in validation options that you can use. This flag says that this validation
567must be applied always no matter which group is used.
568
569## Custom validation classes
570
571If you have custom validation logic you can create a _Constraint class_:
572
5731. First create a file, lets say `CustomTextLength.ts`, and define a new class:
574
575 ```typescript
576 import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
577
578 @ValidatorConstraint({ name: 'customText', async: false })
579 export class CustomTextLength implements ValidatorConstraintInterface {
580 validate(text: string, args: ValidationArguments) {
581 return text.length > 1 && text.length < 10; // for async validations you must return a Promise<boolean> here
582 }
583
584 defaultMessage(args: ValidationArguments) {
585 // here you can provide default error message if validation failed
586 return 'Text ($value) is too short or too long!';
587 }
588 }
589 ```
590
591 We marked our class with `@ValidatorConstraint` decorator.
592 You can also supply a validation constraint name - this name will be used as "error type" in ValidationError.
593 If you will not supply a constraint name - it will be auto-generated.
594
595 Our class must implement `ValidatorConstraintInterface` interface and its `validate` method,
596 which defines validation logic. If validation succeeds, method returns true, otherwise false.
597 Custom validator can be asynchronous, if you want to perform validation after some asynchronous
598 operations, simply return a promise with boolean inside in `validate` method.
599
600 Also we defined optional method `defaultMessage` which defines a default error message,
601 in the case that the decorator's implementation doesn't set an error message.
602
6032) Then you can use your new validation constraint in your class:
604
605 ```typescript
606 import { Validate } from 'class-validator';
607 import { CustomTextLength } from './CustomTextLength';
608
609 export class Post {
610 @Validate(CustomTextLength, {
611 message: 'Title is too short or long!',
612 })
613 title: string;
614 }
615 ```
616
617 Here we set our newly created `CustomTextLength` validation constraint for `Post.title`.
618
6193) And use validator as usual:
620
621 ```typescript
622 import { validate } from 'class-validator';
623
624 validate(post).then(errors => {
625 // ...
626 });
627 ```
628
629You can also pass constraints to your validator, like this:
630
631```typescript
632import { Validate } from 'class-validator';
633import { CustomTextLength } from './CustomTextLength';
634
635export class Post {
636 @Validate(CustomTextLength, [3, 20], {
637 message: 'Wrong post title',
638 })
639 title: string;
640}
641```
642
643And use them from `validationArguments` object:
644
645```typescript
646import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
647
648@ValidatorConstraint()
649export class CustomTextLength implements ValidatorConstraintInterface {
650 validate(text: string, validationArguments: ValidationArguments) {
651 return text.length > validationArguments.constraints[0] && text.length < validationArguments.constraints[1];
652 }
653}
654```
655
656## Custom validation decorators
657
658You can also create a custom decorators. Its the most elegant way of using a custom validations.
659Lets create a decorator called `@IsLongerThan`:
660
6611. Create a decorator itself:
662
663 ```typescript
664 import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';
665
666 export function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
667 return function (object: Object, propertyName: string) {
668 registerDecorator({
669 name: 'isLongerThan',
670 target: object.constructor,
671 propertyName: propertyName,
672 constraints: [property],
673 options: validationOptions,
674 validator: {
675 validate(value: any, args: ValidationArguments) {
676 const [relatedPropertyName] = args.constraints;
677 const relatedValue = (args.object as any)[relatedPropertyName];
678 return typeof value === 'string' && typeof relatedValue === 'string' && value.length > relatedValue.length; // you can return a Promise<boolean> here as well, if you want to make async validation
679 },
680 },
681 });
682 };
683 }
684 ```
685
6862. Put it to use:
687
688 ```typescript
689 import { IsLongerThan } from './IsLongerThan';
690
691 export class Post {
692 title: string;
693
694 @IsLongerThan('title', {
695 /* you can also use additional validation options, like "groups" in your custom validation decorators. "each" is not supported */
696 message: 'Text must be longer than the title',
697 })
698 text: string;
699 }
700 ```
701
702In your custom decorators you can also use `ValidationConstraint`.
703Lets create another custom validation decorator called `IsUserAlreadyExist`:
704
7051. Create a ValidationConstraint and decorator:
706
707 ```typescript
708 import {
709 registerDecorator,
710 ValidationOptions,
711 ValidatorConstraint,
712 ValidatorConstraintInterface,
713 ValidationArguments,
714 } from 'class-validator';
715
716 @ValidatorConstraint({ async: true })
717 export class IsUserAlreadyExistConstraint implements ValidatorConstraintInterface {
718 validate(userName: any, args: ValidationArguments) {
719 return UserRepository.findOneByName(userName).then(user => {
720 if (user) return false;
721 return true;
722 });
723 }
724 }
725
726 export function IsUserAlreadyExist(validationOptions?: ValidationOptions) {
727 return function (object: Object, propertyName: string) {
728 registerDecorator({
729 target: object.constructor,
730 propertyName: propertyName,
731 options: validationOptions,
732 constraints: [],
733 validator: IsUserAlreadyExistConstraint,
734 });
735 };
736 }
737 ```
738
739 note that we marked our constraint that it will by async by adding `{ async: true }` in validation options.
740
7412. And put it to use:
742
743 ```typescript
744 import { IsUserAlreadyExist } from './IsUserAlreadyExist';
745
746 export class User {
747 @IsUserAlreadyExist({
748 message: 'User $value already exists. Choose another name.',
749 })
750 name: string;
751 }
752 ```
753
754## Using service container
755
756Validator supports service container in the case if want to inject dependencies into your custom validator constraint
757classes. Here is example how to integrate it with [typedi][2]:
758
759```typescript
760import { Container } from 'typedi';
761import { useContainer, Validator } from 'class-validator';
762
763// do this somewhere in the global application level:
764useContainer(Container);
765let validator = Container.get(Validator);
766
767// now everywhere you can inject Validator class which will go from the container
768// also you can inject classes using constructor injection into your custom ValidatorConstraint-s
769```
770
771## Synchronous validation
772
773If you want to perform a simple non async validation you can use `validateSync` method instead of regular `validate`
774method. It has the same arguments as `validate` method. But note, this method **ignores** all async validations
775you have.
776
777## Manual validation
778
779There are several method exist in the Validator that allows to perform non-decorator based validation:
780
781```typescript
782import { isEmpty, isBoolean } from 'class-validator';
783
784isEmpty(value);
785isBoolean(value);
786```
787
788## Validation decorators
789
790<!-- Disable table formatting because Prettier messing it up. -->
791<!-- prettier-ignore -->
792| Decorator | Description |
793| ------------------------------------------------| ----------- |
794| **Common validation decorators** | |
795| `@IsDefined(value: any)` | Checks if value is defined (!== undefined, !== null). This is the only decorator that ignores skipMissingProperties option. |
796| `@IsOptional()` | Checks if given value is empty (=== null, === undefined) and if so, ignores all the validators on the property. |
797| `@Equals(comparison: any)` | Checks if value equals ("===") comparison. |
798| `@NotEquals(comparison: any)` | Checks if value not equal ("!==") comparison. |
799| `@IsEmpty()` | Checks if given value is empty (=== '', === null, === undefined). |
800| `@IsNotEmpty()` | Checks if given value is not empty (!== '', !== null, !== undefined). |
801| `@IsIn(values: any[])` | Checks if value is in a array of allowed values. |
802| `@IsNotIn(values: any[])` | Checks if value is not in a array of disallowed values. |
803| **Type validation decorators** | |
804| `@IsBoolean()` | Checks if a value is a boolean. |
805| `@IsDate()` | Checks if the value is a date. |
806| `@IsString()` | Checks if the string is a string. |
807| `@IsNumber(options: IsNumberOptions)` | Checks if the value is a number. |
808| `@IsInt()` | Checks if the value is an integer number. |
809| `@IsArray()` | Checks if the value is an array |
810| `@IsEnum(entity: object)` | Checks if the value is an valid enum |
811| **Number validation decorators** |
812| `@IsDivisibleBy(num: number)` | Checks if the value is a number that's divisible by another. |
813| `@IsPositive()` | Checks if the value is a positive number greater than zero. |
814| `@IsNegative()` | Checks if the value is a negative number smaller than zero. |
815| `@Min(min: number)` | Checks if the given number is greater than or equal to given number. |
816| `@Max(max: number)` | Checks if the given number is less than or equal to given number. |
817| **Date validation decorators** |
818| `@MinDate(date: Date)` | Checks if the value is a date that's after the specified date. |
819| `@MaxDate(date: Date)` | Checks if the value is a date that's before the specified date. |
820| **String-type validation decorators** | |
821| `@IsBooleanString()` | Checks if a string is a boolean (e.g. is "true" or "false"). |
822| `@IsDateString()` | Alias for `@IsISO8601()`. |
823| `@IsNumberString(options?: IsNumericOptions)` | Checks if a string is a number. |
824| **String validation decorators** | |
825| `@Contains(seed: string)` | Checks if the string contains the seed. |
826| `@NotContains(seed: string)` | Checks if the string not contains the seed. |
827| `@IsAlpha()` | Checks if the string contains only letters (a-zA-Z). |
828| `@IsAlphanumeric()` | Checks if the string contains only letters and numbers. |
829| `@IsDecimal(options?: IsDecimalOptions)` | Checks if the string is a valid decimal value. Default IsDecimalOptions are `force_decimal=False`, `decimal_digits: '1,'`, `locale: 'en-US'` |
830| `@IsAscii()` | Checks if the string contains ASCII chars only. |
831| `@IsBase32()` | Checks if a string is base32 encoded. |
832| `@IsBase64()` | Checks if a string is base64 encoded. |
833| `@IsIBAN()` | Checks if a string is a IBAN (International Bank Account Number). |
834| `@IsBIC()` | Checks if a string is a BIC (Bank Identification Code) or SWIFT code. |
835| `@IsByteLength(min: number, max?: number)` | Checks if the string's length (in bytes) falls in a range. |
836| `@IsCreditCard()` | Checks if the string is a credit card. |
837| `@IsCurrency(options?: IsCurrencyOptions)` | Checks if the string is a valid currency amount. |
838| `@IsEthereumAddress()` | Checks if the string is an Ethereum address using basic regex. Does not validate address checksums. |
839| `@IsBtcAddress()` | Checks if the string is a valid BTC address. |
840| `@IsDataURI()` | Checks if the string is a data uri format. |
841| `@IsEmail(options?: IsEmailOptions)` | Checks if the string is an email.|
842| `@IsFQDN(options?: IsFQDNOptions)` | Checks if the string is a fully qualified domain name (e.g. domain.com). |
843| `@IsFullWidth()` | Checks if the string contains any full-width chars. |
844| `@IsHalfWidth()` | Checks if the string contains any half-width chars. |
845| `@IsVariableWidth()` | Checks if the string contains a mixture of full and half-width chars. |
846| `@IsHexColor()` | Checks if the string is a hexadecimal color. |
847| `@IsHSLColor()` | Checks if the string is an HSL color based on [CSS Colors Level 4 specification](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). |
848| `@IsRgbColor(options?: IsRgbOptions)` | Checks if the string is a rgb or rgba color. |
849| `@IsIdentityCard(locale?: string)` | Checks if the string is a valid identity card code. |
850| `@IsPassportNumber(countryCode?: string)` | Checks if the string is a valid passport number relative to a specific country code. |
851| `@IsPostalCode(locale?: string)` | Checks if the string is a postal code. |
852| `@IsHexadecimal()` | Checks if the string is a hexadecimal number. |
853| `@IsOctal()` | Checks if the string is a octal number. |
854| `@IsMACAddress(options?: IsMACAddressOptions)` | Checks if the string is a MAC Address. |
855| `@IsIP(version?: "4"\|"6")` | Checks if the string is an IP (version 4 or 6). |
856| `@IsPort()` | Checks if the string is a valid port number. |
857| `@IsISBN(version?: "10"\|"13")` | Checks if the string is an ISBN (version 10 or 13). |
858| `@IsEAN()` | Checks if the string is an if the string is an EAN (European Article Number). |
859| `@IsISIN()` | Checks if the string is an ISIN (stock/security identifier). |
860| `@IsISO8601(options?: IsISO8601Options)` | Checks if the string is a valid ISO 8601 date format. Use the option strict = true for additional checks for a valid date. |
861| `@IsJSON()` | Checks if the string is valid JSON. |
862| `@IsJWT()` | Checks if the string is valid JWT. |
863| `@IsObject()` | Checks if the object is valid Object (null, functions, arrays will return false). |
864| `@IsNotEmptyObject()` | Checks if the object is not empty. |
865| `@IsLowercase()` | Checks if the string is lowercase. |
866| `@IsLatLong()` | Checks if the string is a valid latitude-longitude coordinate in the format lat, long. |
867| `@IsLatitude()` | Checks if the string or number is a valid latitude coordinate. |
868| `@IsLongitude()` | Checks if the string or number is a valid longitude coordinate. |
869| `@IsMobilePhone(locale: string)` | Checks if the string is a mobile phone number. |
870| `@IsISO31661Alpha2()` | Checks if the string is a valid ISO 3166-1 alpha-2 officially assigned country code. |
871| `@IsISO31661Alpha3()` | Checks if the string is a valid ISO 3166-1 alpha-3 officially assigned country code. |
872| `@IsLocale()` | Checks if the string is a locale. |
873| `@IsPhoneNumber(region: string)` | Checks if the string is a valid phone numberusing libphonenumber-js. |
874| `@IsMongoId()` | Checks if the string is a valid hex-encoded representation of a MongoDB ObjectId. |
875| `@IsMultibyte()` | Checks if the string contains one or more multibyte chars. |
876| `@IsNumberString(options?: IsNumericOptions)` | Checks if the string is numeric. |
877| `@IsSurrogatePair()` | Checks if the string contains any surrogate pairs chars. |
878| `@IsUrl(options?: IsURLOptions)` | Checks if the string is an url. |
879| `@IsMagnetURI()` | Checks if the string is a [magnet uri format](https://en.wikipedia.org/wiki/Magnet_URI_scheme). |
880| `@IsUUID(version?: "3"\|"4"\|"5"\|"all")` | Checks if the string is a UUID (version 3, 4, 5 or all ). |
881| `@IsFirebasePushId()` | Checks if the string is a [Firebase Push ID](https://firebase.googleblog.com/2015/02/the-2120-ways-to-ensure-unique_68.html) |
882| `@IsUppercase()` | Checks if the string is uppercase. |
883| `@Length(min: number, max?: number)` | Checks if the string's length falls in a range. |
884| `@MinLength(min: number)` | Checks if the string's length is not less than given number. |
885| `@MaxLength(max: number)` | Checks if the string's length is not more than given number. |
886| `@Matches(pattern: RegExp, modifiers?: string)` | Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i'). |
887| `@IsMilitaryTime()` | Checks if the string is a valid representation of military time in the format HH:MM. |
888| `@IsHash(algorithm: string)` | Checks if the string is a hash The following types are supported:`md4`, `md5`, `sha1`, `sha256`, `sha384`, `sha512`, `ripemd128`, `ripemd160`, `tiger128`, `tiger160`, `tiger192`, `crc32`, `crc32b`. |
889| `@IsMimeType()` | Checks if the string matches to a valid [MIME type](https://en.wikipedia.org/wiki/Media_type) format |
890| `@IsSemVer()` | Checks if the string is a Semantic Versioning Specification (SemVer). |
891| `@IsISSN(options?: IsISSNOptions)` | Checks if the string is a ISSN. |
892| `@IsISRC()` | Checks if the string is a [ISRC](https://en.wikipedia.org/wiki/International_Standard_Recording_Code). |
893| `@IsRFC3339()` | Checks if the string is a valid [RFC 3339](https://tools.ietf.org/html/rfc3339) date. |
894| **Array validation decorators** | |
895| `@ArrayContains(values: any[])` | Checks if array contains all values from the given array of values. |
896| `@ArrayNotContains(values: any[])` | Checks if array does not contain any of the given values. |
897| `@ArrayNotEmpty()` | Checks if given array is not empty. |
898| `@ArrayMinSize(min: number)` | Checks if the array's length is greater than or equal to the specified number. |
899| `@ArrayMaxSize(max: number)` | Checks if the array's length is less or equal to the specified number. |
900| `@ArrayUnique(identifier?: (o) => any)` | Checks if all array's values are unique. Comparison for objects is reference-based. Optional function can be speciefied which return value will be used for the comparsion. |
901| **Object validation decorators** |
902| `@IsInstance(value: any)` | Checks if the property is an instance of the passed value. |
903| **Other decorators** | |
904| `@Allow()` | Prevent stripping off the property when no other constraint is specified for it. |
905
906## Defining validation schema without decorators
907
908You can define your validation schemas without decorators:
909
910- you can define it in the separate object
911- you can define it in the `.json` file
912
913This feature maybe useful in the cases if:
914
915- are using es5/es6 and don't have decorators available
916- you don't have a classes, and instead using interfaces
917- you don't want to use model at all
918- you want to have a validation schema separate of your model
919- you want beautiful json-schema based validation models
920- you simply hate decorators
921
922Here is an example of using it:
923
9241. Create a schema object:
925
926 ```typescript
927 import { ValidationSchema } from 'class-validator';
928 export let UserValidationSchema: ValidationSchema = {
929 // using interface here is not required, its just for type-safety
930 name: 'myUserSchema', // this is required, and must be unique
931 properties: {
932 firstName: [
933 {
934 type: 'minLength', // validation type. All validation types are listed in ValidationTypes class.
935 constraints: [2],
936 },
937 {
938 type: 'maxLength',
939 constraints: [20],
940 },
941 ],
942 lastName: [
943 {
944 type: 'minLength',
945 constraints: [2],
946 },
947 {
948 type: 'maxLength',
949 constraints: [20],
950 },
951 ],
952 email: [
953 {
954 type: 'isEmail',
955 },
956 ],
957 },
958 };
959 ```
960
961 Same schema can be provided in `.json` file, depend on your wish.
962
9632. Register your schema:
964
965 ```typescript
966 import { registerSchema } from 'class-validator';
967 import { UserValidationSchema } from './UserValidationSchema';
968 registerSchema(UserValidationSchema); // if schema is in .json file, then you can simply do registerSchema(require("path-to-schema.json"));
969 ```
970
971 Better to put this code in a global place, maybe when you bootstrap your application, for example in `app.ts`.
972
9733. Validate your object using validation schema:
974
975 ```typescript
976 import { validate } from 'class-validator';
977 const user = { firstName: 'Johny', secondName: 'Cage', email: 'johny@cage.com' };
978 validate('myUserSchema', user).then(errors => {
979 if (errors.length > 0) {
980 console.log('Validation failed: ', errors);
981 } else {
982 console.log('Validation succeed.');
983 }
984 });
985 ```
986
987 That's it. Here `"myUserSchema"` is the name of our validation schema.
988 `validate` method will perform validation based on this schema
989
990## Validating plain objects
991
992Due to nature of the decorators, the validated object has to be instantiated using `new Class()` syntax. If you have your class defined using class-validator decorators and you want to validate plain JS object (literal object or returned by JSON.parse), you need to transform it to the class instance via using [class-transformer](https://github.com/pleerock/class-transformer)).
993
994## Samples
995
996Take a look on samples in [./sample](https://github.com/pleerock/class-validator/tree/master/sample) for more examples of
997usages.
998
999## Extensions
1000
1001There are several extensions that simplify class-validator integration with other modules:
1002
1003- [class-validator integration](https://github.com/19majkel94/class-transformer-validator) with [class-transformer](https://github.com/pleerock/class-transformer)
1004- [class-validator-rule](https://github.com/yantrab/class-validator-rule)
1005- [ngx-dynamic-form-builder](https://github.com/EndyKaufman/ngx-dynamic-form-builder)
1006- [abarghoud/ngx-reactive-form-class-validator](https://github.com/abarghoud/ngx-reactive-form-class-validator)
1007
1008## Release notes
1009
1010See information about breaking changes and release notes [here][3].
1011
1012[1]: https://github.com/chriso/validator.js
1013[2]: https://github.com/pleerock/typedi
1014[3]: CHANGELOG.md
1015
\No newline at end of file