Code Monkey home page Code Monkey logo

class-validator's Introduction

class-validator

Build Status codecov npm version install size

Allows use of decorator and non-decorator based validation. Internally uses validator.js to perform validation. Class-validator works on both browser and node.js platforms.

Table of Contents

Installation

npm install class-validator --save

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.

Usage

Create your class and put some validation decorators on the properties you want to validate:

import {
  validate,
  validateOrReject,
  Contains,
  IsInt,
  Length,
  IsEmail,
  IsFQDN,
  IsDate,
  Min,
  Max,
} from 'class-validator';

export class Post {
  @Length(10, 20)
  title: string;

  @Contains('hello')
  text: string;

  @IsInt()
  @Min(0)
  @Max(10)
  rating: number;

  @IsEmail()
  email: string;

  @IsFQDN()
  site: string;

  @IsDate()
  createDate: Date;
}

let post = new Post();
post.title = 'Hello'; // should not pass
post.text = 'this is a great post about hell world'; // should not pass
post.rating = 11; // should not pass
post.email = 'google.com'; // should not pass
post.site = 'googlecom'; // should not pass

validate(post).then(errors => {
  // errors is an array of validation errors
  if (errors.length > 0) {
    console.log('validation failed. errors: ', errors);
  } else {
    console.log('validation succeed');
  }
});

validateOrReject(post).catch(errors => {
  console.log('Promise rejected (validation failed). Errors: ', errors);
});
// or
async function validateOrRejectExample(input) {
  try {
    await validateOrReject(input);
  } catch (errors) {
    console.log('Caught promise rejection (validation failed). Errors: ', errors);
  }
}

Passing options

The validate function optionally expects a ValidatorOptions object as a second parameter:

export interface ValidatorOptions {
  skipMissingProperties?: boolean;
  whitelist?: boolean;
  forbidNonWhitelisted?: boolean;
  groups?: string[];
  dismissDefaultMessages?: boolean;
  validationError?: {
    target?: boolean;
    value?: boolean;
  };

  forbidUnknownValues?: boolean;
  stopAtFirstError?: boolean;
}

IMPORTANT The forbidUnknownValues value is set to true by default and it is highly advised to keep the default. Setting it to false will result unknown objects passing the validation!

Validation errors

The validate method returns an array of ValidationError objects. Each ValidationError is:

{
    target: Object; // Object that was validated.
    property: string; // Object's property that haven't pass validation.
    value: any; // Value that haven't pass a validation.
    constraints?: { // Constraints that failed validation with error messages.
        [type: string]: string;
    };
    children?: ValidationError[]; // Contains all nested validation errors of the property
}

In our case, when we validated a Post object, we have such an array of ValidationError objects:

[{
    target: /* post object */,
    property: "title",
    value: "Hello",
    constraints: {
        length: "$property must be longer than or equal to 10 characters"
    }
}, {
    target: /* post object */,
    property: "text",
    value: "this is a great post about hell world",
    constraints: {
        contains: "text must contain a hello string"
    }
},
// and other errors
]

If you don't want a target to be exposed in validation errors, there is a special option when you use validator:

validator.validate(post, { validationError: { target: false } });

This is especially useful when you send errors back over http, and you most probably don't want to expose the whole target object.

Validation messages

You can specify validation message in the decorator options and that message will be returned in the ValidationError returned by the validate method (in the case that validation for this field fails).

import { MinLength, MaxLength } from 'class-validator';

export class Post {
  @MinLength(10, {
    message: 'Title is too short',
  })
  @MaxLength(50, {
    message: 'Title is too long',
  })
  title: string;
}

There are few special tokens you can use in your messages:

  • $value - the value that is being validated
  • $property - name of the object's property being validated
  • $target - name of the object's class being validated
  • $constraint1, $constraint2, ... $constraintN - constraints defined by specific validation type

Example of usage:

import { MinLength, MaxLength } from 'class-validator';

export class Post {
  @MinLength(10, {
    // here, $constraint1 will be replaced with "10", and $value with actual supplied value
    message: 'Title is too short. Minimal length is $constraint1 characters, but actual is $value',
  })
  @MaxLength(50, {
    // here, $constraint1 will be replaced with "50", and $value with actual supplied value
    message: 'Title is too long. Maximal length is $constraint1 characters, but actual is $value',
  })
  title: string;
}

Also you can provide a function, that returns a message. This allows you to create more granular messages:

import { MinLength, MaxLength, ValidationArguments } from 'class-validator';

export class Post {
  @MinLength(10, {
    message: (args: ValidationArguments) => {
      if (args.value.length === 1) {
        return 'Too short, minimum length is 1 character';
      } else {
        return 'Too short, minimum length is ' + args.constraints[0] + ' characters';
      }
    },
  })
  title: string;
}

Message function accepts ValidationArguments which contains the following information:

  • value - the value that is being validated
  • constraints - array of constraints defined by specific validation type
  • targetName - name of the object's class being validated
  • object - object that is being validated
  • property - name of the object's property being validated

Validating arrays

If your field is an array and you want to perform validation of each item in the array you must specify a special each: true decorator option:

import { MinLength, MaxLength } from 'class-validator';

export class Post {
  @MaxLength(20, {
    each: true,
  })
  tags: string[];
}

This will validate each item in post.tags array.

Validating sets

If your field is a set and you want to perform validation of each item in the set you must specify a special each: true decorator option:

import { MinLength, MaxLength } from 'class-validator';

export class Post {
  @MaxLength(20, {
    each: true,
  })
  tags: Set<string>;
}

This will validate each item in post.tags set.

Validating maps

If your field is a map and you want to perform validation of each item in the map you must specify a special each: true decorator option:

import { MinLength, MaxLength } from 'class-validator';

export class Post {
  @MaxLength(20, {
    each: true,
  })
  tags: Map<string, string>;
}

This will validate each item in post.tags map.

Validating nested objects

If your object contains nested objects and you want the validator to perform their validation too, then you need to use the @ValidateNested() decorator:

import { ValidateNested } from 'class-validator';

export class Post {
  @ValidateNested()
  user: User;
}

Please 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.

It also works with multi-dimensional array, like :

import { ValidateNested } from 'class-validator';

export class Plan2D {
  @ValidateNested()
  matrix: Point[][];
}

Validating promises

If your object contains property with Promise-returned value that should be validated, then you need to use the @ValidatePromise() decorator:

import { ValidatePromise, Min } from 'class-validator';

export class Post {
  @Min(0)
  @ValidatePromise()
  userId: Promise<number>;
}

It also works great with @ValidateNested decorator:

import { ValidateNested, ValidatePromise } from 'class-validator';

export class Post {
  @ValidateNested()
  @ValidatePromise()
  user: Promise<User>;
}

Inheriting Validation decorators

When 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 from both its own class and the base class.

import { validate } from 'class-validator';

class BaseContent {
  @IsEmail()
  email: string;

  @IsString()
  password: string;
}

class User extends BaseContent {
  @MinLength(10)
  @MaxLength(20)
  name: string;

  @Contains('hello')
  welcome: string;

  @MinLength(20)
  password: string;
}

let user = new User();

user.email = 'invalid email'; // inherited property
user.password = 'too short'; // password wil be validated not only against IsString, but against MinLength as well
user.name = 'not valid';
user.welcome = 'helo';

validate(user).then(errors => {
  // ...
}); // it will return errors for email, password, name and welcome properties

Conditional validation

The 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.

import { ValidateIf, IsNotEmpty } from 'class-validator';

export class Post {
  otherProperty: string;

  @ValidateIf(o => o.otherProperty === 'value')
  @IsNotEmpty()
  example: string;
}

In the example above, the validation rules applied to example won't be run unless the object's otherProperty is "value".

Note that when the condition is false all validation decorators are ignored, including isDefined.

Whitelisting

Even if your object is an instance of a validation class it can contain additional properties that are not defined. If you do not want to have such properties on your object, pass special flag to validate method:

import { validate } from 'class-validator';
// ...
validate(post, { whitelist: true });

This will strip all properties that don't have any decorators. If no other decorator is suitable for your property, you can use @Allow decorator:

import {validate, Allow, Min} from "class-validator";

export class Post {

    @Allow()
    title: string;

    @Min(0)
    views: number;

    nonWhitelistedProperty: number;
}

let post = new Post();
post.title = 'Hello world!';
post.views = 420;

post.nonWhitelistedProperty = 69;
(post as any).anotherNonWhitelistedProperty = "something";

validate(post).then(errors => {
  // post.nonWhitelistedProperty is not defined
  // (post as any).anotherNonWhitelistedProperty is not defined
  ...
});

If you would rather to have an error thrown when any non-whitelisted properties are present, pass another flag to validate method:

import { validate } from 'class-validator';
// ...
validate(post, { whitelist: true, forbidNonWhitelisted: true });

Passing context to decorators

It's possible to pass a custom object to decorators which will be accessible on the ValidationError instance of the property if validation failed.

import { validate } from 'class-validator';

class MyClass {
  @MinLength(32, {
    message: 'EIC code must be at least 32 characters',
    context: {
      errorCode: 1003,
      developerNote: 'The validated string must contain 32 or more characters.',
    },
  })
  eicCode: string;
}

const model = new MyClass();

validate(model).then(errors => {
  //errors[0].contexts['minLength'].errorCode === 1003
});

Skipping missing properties

Sometimes you may want to skip validation of the properties that do not exist in the validating object. This is usually desirable when you want to update some parts of the object, and want to validate only updated parts, but skip everything else, e.g. skip missing properties. In such situations you will need to pass a special flag to validate method:

import { validate } from 'class-validator';
// ...
validate(post, { skipMissingProperties: true });

When skipping missing properties, sometimes you want not to skip all missing properties, some of them maybe required for you, even if skipMissingProperties is set to true. For such cases you should use @IsDefined() decorator. @IsDefined() is the only decorator that ignores skipMissingProperties option.

Validation groups

In different situations you may want to use different validation schemas of the same object. In such cases you can use validation groups.

IMPORTANT Calling a validation with a group combination that would not result in a validation (eg: non existent group name) will result in a unknown value error. When validating with groups the provided group combination should match at least one decorator.

import { validate, Min, Length } from 'class-validator';

export class User {
  @Min(12, {
    groups: ['registration'],
  })
  age: number;

  @Length(2, 20, {
    groups: ['registration', 'admin'],
  })
  name: string;
}

let user = new User();
user.age = 10;
user.name = 'Alex';

validate(user, {
  groups: ['registration'],
}); // this will not pass validation

validate(user, {
  groups: ['admin'],
}); // this will pass validation

validate(user, {
  groups: ['registration', 'admin'],
}); // this will not pass validation

validate(user, {
  groups: undefined, // the default
}); // this will not pass validation since all properties get validated regardless of their groups

validate(user, {
  groups: [],
}); // this will not pass validation, (equivalent to 'groups: undefined', see above)

There is also a special flag always: true in validation options that you can use. This flag says that this validation must be applied always no matter which group is used.

Custom validation classes

If you have custom validation logic you can create a Constraint class:

  1. First create a file, lets say CustomTextLength.ts, and define a new class:

    import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
    
    @ValidatorConstraint({ name: 'customText', async: false })
    export class CustomTextLength implements ValidatorConstraintInterface {
      validate(text: string, args: ValidationArguments) {
        return text.length > 1 && text.length < 10; // for async validations you must return a Promise<boolean> here
      }
    
      defaultMessage(args: ValidationArguments) {
        // here you can provide default error message if validation failed
        return 'Text ($value) is too short or too long!';
      }
    }

    We marked our class with @ValidatorConstraint decorator. You can also supply a validation constraint name - this name will be used as "error type" in ValidationError. If you will not supply a constraint name - it will be auto-generated.

    Our class must implement ValidatorConstraintInterface interface and its validate method, which defines validation logic. If validation succeeds, method returns true, otherwise false. Custom validator can be asynchronous, if you want to perform validation after some asynchronous operations, simply return a promise with boolean inside in validate method.

    Also we defined optional method defaultMessage which defines a default error message, in the case that the decorator's implementation doesn't set an error message.

  2. Then you can use your new validation constraint in your class:

    import { Validate } from 'class-validator';
    import { CustomTextLength } from './CustomTextLength';
    
    export class Post {
      @Validate(CustomTextLength, {
        message: 'Title is too short or long!',
      })
      title: string;
    }

    Here we set our newly created CustomTextLength validation constraint for Post.title.

  3. And use validator as usual:

    import { validate } from 'class-validator';
    
    validate(post).then(errors => {
      // ...
    });

You can also pass constraints to your validator, like this:

import { Validate } from 'class-validator';
import { CustomTextLength } from './CustomTextLength';

export class Post {
  @Validate(CustomTextLength, [3, 20], {
    message: 'Wrong post title',
  })
  title: string;
}

And use them from validationArguments object:

import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';

@ValidatorConstraint()
export class CustomTextLength implements ValidatorConstraintInterface {
  validate(text: string, validationArguments: ValidationArguments) {
    return text.length > validationArguments.constraints[0] && text.length < validationArguments.constraints[1];
  }
}

Custom validation decorators

You can also create a custom decorators. Its the most elegant way of using a custom validations. Lets create a decorator called @IsLongerThan:

  1. Create a decorator itself:

    import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';
    
    export function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
      return function (object: Object, propertyName: string) {
        registerDecorator({
          name: 'isLongerThan',
          target: object.constructor,
          propertyName: propertyName,
          constraints: [property],
          options: validationOptions,
          validator: {
            validate(value: any, args: ValidationArguments) {
              const [relatedPropertyName] = args.constraints;
              const relatedValue = (args.object as any)[relatedPropertyName];
              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
            },
          },
        });
      };
    }
  2. Put it to use:

    import { IsLongerThan } from './IsLongerThan';
    
    export class Post {
      title: string;
    
      @IsLongerThan('title', {
        /* you can also use additional validation options, like "groups" in your custom validation decorators. "each" is not supported */
        message: 'Text must be longer than the title',
      })
      text: string;
    }

In your custom decorators you can also use ValidationConstraint. Lets create another custom validation decorator called IsUserAlreadyExist:

  1. Create a ValidationConstraint and decorator:

    import {
      registerDecorator,
      ValidationOptions,
      ValidatorConstraint,
      ValidatorConstraintInterface,
      ValidationArguments,
    } from 'class-validator';
    
    @ValidatorConstraint({ async: true })
    export class IsUserAlreadyExistConstraint implements ValidatorConstraintInterface {
      validate(userName: any, args: ValidationArguments) {
        return UserRepository.findOneByName(userName).then(user => {
          if (user) return false;
          return true;
        });
      }
    }
    
    export function IsUserAlreadyExist(validationOptions?: ValidationOptions) {
      return function (object: Object, propertyName: string) {
        registerDecorator({
          target: object.constructor,
          propertyName: propertyName,
          options: validationOptions,
          constraints: [],
          validator: IsUserAlreadyExistConstraint,
        });
      };
    }

    note that we marked our constraint that it will by async by adding { async: true } in validation options.

  2. And put it to use:

    import { IsUserAlreadyExist } from './IsUserAlreadyExist';
    
    export class User {
      @IsUserAlreadyExist({
        message: 'User $value already exists. Choose another name.',
      })
      name: string;
    }

Using service container

Validator supports service container in the case if want to inject dependencies into your custom validator constraint classes. Here is example how to integrate it with typedi:

import { Container } from 'typedi';
import { useContainer, Validator } from 'class-validator';

// do this somewhere in the global application level:
useContainer(Container);
let validator = Container.get(Validator);

// now everywhere you can inject Validator class which will go from the container
// also you can inject classes using constructor injection into your custom ValidatorConstraint-s

Synchronous validation

If you want to perform a simple non async validation you can use validateSync method instead of regular validate method. It has the same arguments as validate method. But note, this method ignores all async validations you have.

Manual validation

There are several method exist in the Validator that allows to perform non-decorator based validation:

import { isEmpty, isBoolean } from 'class-validator';

isEmpty(value);
isBoolean(value);

Validation decorators

Decorator Description
Common validation decorators
@IsDefined(value: any) Checks if value is defined (!== undefined, !== null). This is the only decorator that ignores skipMissingProperties option.
@IsOptional() Checks if given value is empty (=== null, === undefined) and if so, ignores all the validators on the property.
@Equals(comparison: any) Checks if value equals ("===") comparison.
@NotEquals(comparison: any) Checks if value not equal ("!==") comparison.
@IsEmpty() Checks if given value is empty (=== '', === null, === undefined).
@IsNotEmpty() Checks if given value is not empty (!== '', !== null, !== undefined).
@IsIn(values: any[]) Checks if value is in an array of allowed values.
@IsNotIn(values: any[]) Checks if value is not in an array of disallowed values.
Type validation decorators
@IsBoolean() Checks if a value is a boolean.
@IsDate() Checks if the value is a date.
@IsString() Checks if the value is a string.
@IsNumber(options: IsNumberOptions) Checks if the value is a number.
@IsInt() Checks if the value is an integer number.
@IsArray() Checks if the value is an array
@IsEnum(entity: object) Checks if the value is a valid enum
Number validation decorators
@IsDivisibleBy(num: number) Checks if the value is a number that's divisible by another.
@IsPositive() Checks if the value is a positive number greater than zero.
@IsNegative() Checks if the value is a negative number smaller than zero.
@Min(min: number) Checks if the given number is greater than or equal to given number.
@Max(max: number) Checks if the given number is less than or equal to given number.
Date validation decorators
@MinDate(date: Date | (() => Date)) Checks if the value is a date that's after the specified date.
@MaxDate(date: Date | (() => Date)) Checks if the value is a date that's before the specified date.
String-type validation decorators
@IsBooleanString() Checks if a string is a boolean (e.g. is "true" or "false" or "1", "0").
@IsDateString() Alias for @IsISO8601().
@IsNumberString(options?: IsNumericOptions) Checks if a string is a number.
String validation decorators
@Contains(seed: string) Checks if the string contains the seed.
@NotContains(seed: string) Checks if the string not contains the seed.
@IsAlpha() Checks if the string contains only letters (a-zA-Z).
@IsAlphanumeric() Checks if the string contains only letters and numbers.
@IsDecimal(options?: IsDecimalOptions) Checks if the string is a valid decimal value. Default IsDecimalOptions are force_decimal=False, decimal_digits: '1,', locale: 'en-US'
@IsAscii() Checks if the string contains ASCII chars only.
@IsBase32() Checks if a string is base32 encoded.
@IsBase58() Checks if a string is base58 encoded.
@IsBase64(options?: IsBase64Options) Checks if a string is base64 encoded.
@IsIBAN() Checks if a string is a IBAN (International Bank Account Number).
@IsBIC() Checks if a string is a BIC (Bank Identification Code) or SWIFT code.
@IsByteLength(min: number, max?: number) Checks if the string's length (in bytes) falls in a range.
@IsCreditCard() Checks if the string is a credit card.
@IsCurrency(options?: IsCurrencyOptions) Checks if the string is a valid currency amount.
@IsISO4217CurrencyCode() Checks if the string is an ISO 4217 currency code.
@IsEthereumAddress() Checks if the string is an Ethereum address using basic regex. Does not validate address checksums.
@IsBtcAddress() Checks if the string is a valid BTC address.
@IsDataURI() Checks if the string is a data uri format.
@IsEmail(options?: IsEmailOptions) Checks if the string is an email.
@IsFQDN(options?: IsFQDNOptions) Checks if the string is a fully qualified domain name (e.g. domain.com).
@IsFullWidth() Checks if the string contains any full-width chars.
@IsHalfWidth() Checks if the string contains any half-width chars.
@IsVariableWidth() Checks if the string contains a mixture of full and half-width chars.
@IsHexColor() Checks if the string is a hexadecimal color.
@IsHSL() Checks if the string is an HSL color based on CSS Colors Level 4 specification.
@IsRgbColor(options?: IsRgbOptions) Checks if the string is a rgb or rgba color.
@IsIdentityCard(locale?: string) Checks if the string is a valid identity card code.
@IsPassportNumber(countryCode?: string) Checks if the string is a valid passport number relative to a specific country code.
@IsPostalCode(locale?: string) Checks if the string is a postal code.
@IsHexadecimal() Checks if the string is a hexadecimal number.
@IsOctal() Checks if the string is a octal number.
@IsMACAddress(options?: IsMACAddressOptions) Checks if the string is a MAC Address.
@IsIP(version?: "4"|"6") Checks if the string is an IP (version 4 or 6).
@IsPort() Checks if the string is a valid port number.
@IsISBN(version?: "10"|"13") Checks if the string is an ISBN (version 10 or 13).
@IsEAN() Checks if the string is an if the string is an EAN (European Article Number).
@IsISIN() Checks if the string is an ISIN (stock/security identifier).
@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.
@IsJSON() Checks if the string is valid JSON.
@IsJWT() Checks if the string is valid JWT.
@IsObject() Checks if the object is valid Object (null, functions, arrays will return false).
@IsNotEmptyObject() Checks if the object is not empty.
@IsLowercase() Checks if the string is lowercase.
@IsLatLong() Checks if the string is a valid latitude-longitude coordinate in the format lat, long.
@IsLatitude() Checks if the string or number is a valid latitude coordinate.
@IsLongitude() Checks if the string or number is a valid longitude coordinate.
@IsMobilePhone(locale: string) Checks if the string is a mobile phone number.
@IsISO31661Alpha2() Checks if the string is a valid ISO 3166-1 alpha-2 officially assigned country code.
@IsISO31661Alpha3() Checks if the string is a valid ISO 3166-1 alpha-3 officially assigned country code.
@IsLocale() Checks if the string is a locale.
@IsPhoneNumber(region: string) Checks if the string is a valid phone number using libphonenumber-js.
@IsMongoId() Checks if the string is a valid hex-encoded representation of a MongoDB ObjectId.
@IsMultibyte() Checks if the string contains one or more multibyte chars.
@IsNumberString(options?: IsNumericOptions) Checks if the string is numeric.
@IsSurrogatePair() Checks if the string contains any surrogate pairs chars.
@IsTaxId() Checks if the string is a valid tax ID. Default locale is en-US.
@IsUrl(options?: IsURLOptions) Checks if the string is a URL.
@IsMagnetURI() Checks if the string is a magnet uri format.
@IsUUID(version?: UUIDVersion) Checks if the string is a UUID (version 3, 4, 5 or all ).
@IsFirebasePushId() Checks if the string is a Firebase Push ID
@IsUppercase() Checks if the string is uppercase.
@Length(min: number, max?: number) Checks if the string's length falls in a range.
@MinLength(min: number) Checks if the string's length is not less than given number.
@MaxLength(max: number) Checks if the string's length is not more than given number.
@Matches(pattern: RegExp, modifiers?: string) Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i').
@IsMilitaryTime() Checks if the string is a valid representation of military time in the format HH:MM.
@IsTimeZone() Checks if the string represents a valid IANA time-zone.
@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.
@IsMimeType() Checks if the string matches to a valid MIME type format
@IsSemVer() Checks if the string is a Semantic Versioning Specification (SemVer).
@IsISSN(options?: IsISSNOptions) Checks if the string is a ISSN.
@IsISRC() Checks if the string is a ISRC.
@IsRFC3339() Checks if the string is a valid RFC 3339 date.
@IsStrongPassword(options?: IsStrongPasswordOptions) Checks if the string is a strong password.
Array validation decorators
@ArrayContains(values: any[]) Checks if array contains all values from the given array of values.
@ArrayNotContains(values: any[]) Checks if array does not contain any of the given values.
@ArrayNotEmpty() Checks if given array is not empty.
@ArrayMinSize(min: number) Checks if the array's length is greater than or equal to the specified number.
@ArrayMaxSize(max: number) Checks if the array's length is less or equal to the specified number.
@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.
Object validation decorators
@IsInstance(value: any) Checks if the property is an instance of the passed value.
Other decorators
@Allow() Prevent stripping off the property when no other constraint is specified for it.

Defining validation schema without decorators

Schema-based validation without decorators is no longer supported by class-validator. This feature was broken in version 0.12 and it will not be fixed. If you are interested in schema-based validation, you can find several such frameworks in the zod readme's comparison section.

Validating plain objects

Due 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).

Samples

Take a look on samples in ./sample for more examples of usages.

Extensions

There are several extensions that simplify class-validator integration with other modules or add additional validations:

Release notes

See information about breaking changes and release notes here.

Contributing

For information about how to contribute to this project, see TypeStack's general contribution guide.

class-validator's People

Contributors

0xflotus avatar adnan-kamili avatar braaar avatar christophercr avatar clashsoft avatar cyri-l avatar dependabot[bot] avatar dystopianprogrammer avatar edcarroll avatar felipesabino avatar greenkeeper[bot] avatar henrikra avatar honoluluhenk avatar iliyazelenko avatar jerradpatch avatar jucrouzet avatar kiancross avatar kiliandeca avatar mheironimus avatar michallytek avatar neilime avatar nonameprovided avatar pleerock avatar rmuchall avatar rubiin avatar salimlou avatar snyk-bot avatar vincent-chapron avatar vlapo avatar ytetsuro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

class-validator's Issues

Use custom validations with json-schema file

Hi,

Currently, it is not possible to use custom validations with json-schemas in a JSON file.

Eventhough you can specify this in your schema file:

{
"name": "mySchema",
  "properties": {
      "myProperty": [
       { "type": "customValidation", "constraintCls": "myConstraintClass" }
      ],
  }
}

The custom constraint class is not picked up so the custom validation is not performed.

This does work when you use an schema object rather than a json file. so it seems that the mechanism that picks up the metadatas, expects an actual class in the "constraintCls" field of the schema, but for obvious reasons you can't provide such class instance in a JSON file.

ValidatidationError .toString()

It would be nice to define .toString() method for ValidationError which will return ValidationError.constraints messages as string.

if (errors.length) {
    for (let error of errors) {
         console.log(error.toString());
    }
}

Format for message something like (formatted string with new lines):

PROPERTY_NAME errors
    length: "PROPERTY_NAME must be shorter than 10 characters"
    contains: "PROPERTY_NAME must contain a hello string"

or

PROPERTY_NAME errors
    - PROPERTY_NAME must be shorter than 10 characters
    - PROPERTY_NAME must contain a hello string

Rename package name

Looks like for some users (@amcdnl) its confusing to have a .ts postfix in the package name. What are suggestions for a new package name?

  • validator.ts (old name)
  • validator-ts
  • constraint-validator
  • .... ?

Synchronous validation

Is it possible with v0.4 to reproduce the validateOrThrow functionality that was present in v0.3?

We have been using this lib to validate options passed into the constructors of modules/classes where we need to be synchronous. Unfortunately we can't target ES6 yet to get async/await support due to being pinned to node v4 and it'd be a non-trivial amount of work to rewrite the all of our bootstrapping to be asynchronous.

IsInt validator syntax

The syntax has changed but i did not figure out how i could assign this without getting an error like this:
error TS2346: Supplied parameters do not match any signature of call target.

@IsInt({ min: 0, max: 20 }, { each: true })
public q4h: Number[];

I get also errors with

@IsInt({ min: 0, max: 20 }

Validate Promise API

I like this library but the API could be better. I'm talking about this:

validate(post).then(errors => { // errors is an array of validation errors
    if (errors.length > 0) {
        console.log("validation failed. errors: ", errors);
    } else {
        console.log("validation succeed");
    }
});

It would be better if the validate() reject promise on errors. To do that, this line should be replaced with:

const errors = executor.stripEmptyErrors(validationErrors);
return errors.length ? Promise.reject(errors) : Promise.resolve();

Then we simply work with validate() in async&await:

try {
    await validate(post);
    console.log("validation succeed");
} catch (errors) {
    console.log("validation failed. errors: ", errors);
}

And if you don't want to handle the errors (like in routing-controllers), you can just simply do that and it will throw error on errors:

await validate(post);
await postRepository.persist(post);
...

What do you think about this? It might be a breaking change, so you should publish this as a major version (to prevent auto update on npm install for older users) or we have to create a new name for the validate function with promise rejection behavior.

IsEmpty and IsNotEmpty decorater mixed up?

Hello, I just tried to validate my class with the @isempty and @isnotempty , however I noticed, that these two decoraters do what the other should do. But when validating them manually, they show the correct result.

export function validObject(obj, groups, res): any {
    options.groups = groups;
    let valObj = validate(obj, options);
    valObj.then(errors => {
        if(errors.length > 0) {
            res.status(400).json(errors);
        }
    })
}

yields following result

[
  {
    "value": "test",
    "property": "_name",
    "children": [],
    "constraints": {
      "isEmpty": ""
    }
  },
  {
    "value": "",
    "property": "_accessCode",
    "children": [],
    "constraints": {
      "isNotEmpty": ""
    }
  }
]

With the same request I validated the class inside the constructor manually with new Validator() and printed the result.

         let val = new Validator();
        console.log(`Var name: '${this._name}'`);
        if(val.isEmpty(this._name)) { console.log("isEmpty")    }
        else                        { console.log("isNotEmpty") }

        console.log(`Var access: '${this._accessCode}'`);
        if(val.isNotEmpty(this._accessCode)) { console.log("isNotEmpty") }
        else                                 { console.log("isEmpty")    }

printed result:

Var name: 'test'
isNotEmpty
Var access: ''
isEmpty

Cannot find module 'validator.ts/Validator'

Hi,
I'm trying to use your library but I'm getting a strange compilation error.

Basically the compilation output message is Cannot find module 'validator.ts/Validator' for all files that have import * as Validator from "validator.ts/Validator";

All packages look in the right place and VSCode offers me the intellisense for your package, but the compilation doesn't work.

Any hint?
Thx

Proposal: @IsArray validator

It would be nice if you add @IsArray validator.

For example i have following code:

@IsString({
    each: true
})
public readonly reservedNames: string[];

with this rule validator will not throw an error with string value assigned to the reservedNames property.

@IsArray validator should check only for array type, no matter - empty array or not.

@length(), default message wording

with a length decorator of '@Length(0, 4)', with an field value of '12334', I get a error of 'XXXX must be shorter than 4 characters'. What the error means to me is XXXX < 4, but its actually XXXX<= 4 ?

Building into single .js

I'm having trouble building the build/package *.js files into a single .js file. I have cloned the repo, ran npm install, tsd install, gulp compile and gulp packageFiles in it's root and it compiled perfectly.

What's the best entry point for the package, is it decorators/Validator.js? I'm still trying to get my head around compiling, concatenating and minifying typescript projects and their dependancies so apologies for the novice question. How do you use this in production? I have the following in a model file:

import {Validator} from "validator.ts/Validator";
import {NotEmpty, IsInt} from "validator.ts/decorator/Validation";

And great work on the project by the way, thanks very much for sharing it. I'm really looking forward to putting it to use.

IsInstance validator

Is exists like isInstanse validator for run time checking?

class Post {
  @IsInstance(User);
  user: User;
}

Thanks a lot!

skipMissing:true and error.target:false

Tried this but it doesnt seem to work, ie, the errors thrown by validation failure still have the "target" field.

validate(modelTradeByPartnerCountry,
                    {
                        skipMissingProperties: true,
                        error: { target: false }
                    })

I downloaded it and it doesn't work

Hello, I'm new to Node, I need to use this validator in a project so I tried first to make it work in an example but it just doesn't.

I downloaded every thing, I place the cmd where I downloaded the stuff and I did 'npm install', then I put an html file inside class-validator-master\sample\sample1-simple-validation that contains the following:

<html>
<head>
	<title>Clases en TS</title>
</head>
<body>
<h1>Ejemplo JS</h1>
<section id="container"></section>
<script type="text/javascript" src="app.js"></script>
</body>
</html>

Then I go to the browser and I get the following error in the console:

VM147 app.js:2
Uncaught ReferenceError: require is not defined(…)(anonymous function) @ VM147 app.js:2

Thank you for your time.

Inheritance support

Hello,

I'm in front of a problem when using the validate method.

I have an abstract class User with fields annotated with class-validator.

`export abstract class User {
id: string;

@MaxLength(200)
@Matches(Regex.REGEX_MAIL)
@IsNotEmpty()
@IsDefined()
email: string;

@MaxLength(50)
lastName: string;

@MaxLength(50)
firstName: string;

lastModifiedHeader: string;

}`

And an other class Artisan which extends User.

export class Artisan extends User { enterprise: string; }

When, in a component, I'm trying to validate an Artisan like this

artisan: Artisan = new Artisan(); validate(this.artisan, {skipMissingProperties: true}).then(...)

I have no errors.

But if I move the annotated fields from User to Artisan then no problem.

So is there a way for the validate method to considerate the inheritance ?

Best regard and thank you in advance.

ts-node register?

In your gulp file you are doing some interesting evaluating to transform your typescript file on the fly, there is a project that is similar to babel/register for typescript called ts-node

In your gulpfile.js you would just do:

require('ts-node/register');
require('gulpfile')

@IsUrl options not works

It seems what @IsURL options not works at all.

   /**
     * @type {string}
     */
    @IsString()
    @ValidateIf((options: IOptions) => Boolean(options.sourceMapBaseUrl))
    @IsUrl({
        require_protocol: true,
        require_valid_protocol: true
    })
    public readonly sourceMapBaseUrl: string;

Input string google.ru -> validator does not trows any errors.

question: groups confusion

@isdefined({groups: ["createCollections","updateCollections"]})
@isin(AllCollections.allLanguages)
subtitleLanguage: string=null;

if I call validation on group 'createCollections' it doesnt call 'IsIn'. So I have to add it to the group. But now its not called if I pass no group to the validator. Is this desired functionality? B/c I would be nice if it called the no group validation even when a group is specified. Like, in all groups I need IsIn to be called, however I sometimes need it to be defined.

Integration with Routing-Controllers

Hi,

Do you have some examples on how to integrate your two great frameworks? What would be the best strategy? Perhaps using Middlewares to keep everything using decorators?

Thanks for the great work!

Async validators & model passing

Currently the signature for validator interface is

export interface ValidatorInterface {
    validate(value: any): boolean;
}

This is fine for trivial validation, but more complex validation needs to be able to access the whole object, and also return promised booleans for async.

Proposed signature

export interface ValidatorInterface {
    validate(value: any, meta:ValidationMetadata): boolean | Promise<boolean>;
}

This will allow for

  • context-aware validators like @IsLongerThan('propertyName'), @RequiredIf('propertyName', 'value')
  • async validators like @UsernameAvailable

Notes:

  • If skipMissingProperties == true then a context aware validator will fail. The passed ValidationMetadata should pass the skipMissingProperties value through so that the validator can act appropriately.
  • Allowing promised validation will require a significant refactor to the Validator.validate method
    • It's probably best to refactor everything to be promise based - wrapping all calls with Promise.resolve() will allow both promised and basic validators to run
    • validateOrThrow would need a timeout(() => throw new ValidationError()) in the promise chain so the thrown errors escape. (for backwards compatibility).
    • validate would need a call signature of validate(object: any, validatorOptions?: ValidatorOptions): Promise<ValidationErrorInterface[]>. This would have to be a breaking change.

Throwing an error if a field is null or undefined

the example using validation decorators,

e.g.

    @Field()
    @MinLength(125)
    @MaxLength(2000)
    mission: string;
TypeError: This library (validator.js) validates strings only
    at assertString (/var/www/demo-app/node_modules/validator/lib/util/assertString.js:9:11)
    at Object.isLength (/var/www/demo-app/node_modules/validator/lib/isLength.js:19:30)
    at Validator.isLength (/var/www/demo-app/node_modules/validator.ts/Validator.js:345:30)
    at Validator.performValidation (/var/www/demo-app/node_modules/validator.ts/Validator.js:586:29)
    at /var/www/demo-app/node_modules/validator.ts/Validator.js:47:37
    at Array.map (native)
    at /var/www/demo-app/node_modules/validator.ts/Validator.js:40:45
    at Array.map (native)
    at Validator.validate (/var/www/demo-app/node_modules/validator.ts/Validator.js:35:26)
    at /var/www/demo-app/node_modules/validator.ts/Validator.js:90:32

@Length minimum validation off by 1

Sorry, to give keep lodging issues, I am just using this validation lib a lot recently.

so I have this,

  @Length(2, 40)
  @IsString()
  BRIEF_DESCRIPTION : string =null;

when I enter '1' I get no validation error. When I have this

  @Length(2, 40)
  @IsString()
  BRIEF_DESCRIPTION : string =null;

and enter '1' I get an error 'BRIEF_DESCRIPTION must be longer than or equal to 2 characters'.

In addition, it seems @minlength(min: number), has the same issue? Where a validation error isn't returned unless @minlength(2) or greater?

using version 0.6.0

0.4.0

Im going to release next 0.4.0 version. There are a lot of changes and improvements, and breaking changes too. Last breaking change I made today - I've changed ValidationError signature. Before releasing I wanted to ask you guys @zakhenry @DominicBoettger if there is something you think is wrong in this release, or something should be added/changed before this release.

Thank you

Improvement: isRequired

It would be helpful to have a isRequired decorator for some stuff.

In the meantime i will solve this with a custom validator

"options" in ValidationDecoratorOptions interface should be optional

Hi,

I'm using this awesome library in my project and now I enabled the strictNullChecks option from TS to have more explicit types. Then I noticed that the "options" property in the ValidationDecoratorOptions interface is required. However, digging a bit in the source code I noticed that it is used ValidationMetadata class but only if is defined. This class implements the corresponding ValidationMetadataArgs interface where indeed the "options" (alias "validationOptions") are optional.

Therefore I think that the "options" property should be marked as optional in the ValidationDecoratorOptions.

It's an easy and quick fix...

More information needed on Manual Validation parameters

I come from a php background, where the validation libraries I’m used to, just return true or false (which is awesome), then I do whatever I want from there. So, I opted to use the “Manual validation” here (isEmail precisely), and it worked as expected. (I’m using in a Nativescript application BTW)
Problem is with the second parameter, “options”, whose properties are not mentioned at all in the documentation.
I just ended up setting allow_display_name, allow_utf8_local_part and require_tld to true without even knowing what they mean.
I’d appreciate if these properties (and others like allow_negative_sign_placeholder, host_whitelist and host_blacklist) are explained.

EDIT::
I tried to use the decorators way as shown in the first example, and it worked. BUT console.log("validation failed. errors: ", errors) just outputs 'validation failed. errors: [object Object]' in the terminal. So, I really want to stick with the “Manual validation"

ValidationErrorInterface and ValidationError cannot be typehinted

With the following snippet

import { validateAsync, ValidationOptions, ValidationError} from 'class-validator';
[...]

public validate(model:T, validationOptions?:ValidationOptions):Promise<T> {

    try {
      return validateAsync(model, validationOptions);
    } catch (e){
      if (e instanceof ValidationError){
        throw new ValidationException(null, e.errors);
      }
      throw e;
    }
  }

I get

src/common/stores/store.ts(37,24): error TS2304: Cannot find name 'ValidationError'.

Same issue elsewhere for the ValidationErrorInterface

Error "Validation.js Error: This library (validator.js) validates strings only" on number field

Hello,

I'm getting this error on a number field on my class:

Some model class...

@IsIn([
      Difficulties.EASY,
      Difficulties.MEDIUM,
      Difficulties.DIFFICULT
    ])
    public difficulty:number;
export class Difficulties {
  static EASY:number=0;
  static MEDIUM:number=1;
  static DIFFICULT:number=2;
};

According to this post looks like the validator.js library doesn't work anymore with fields that are not STRING: validatorjs/validator.js#505

Thanks, F.

Property 'matches' does not exist on type 'typeof Validator'.

I have the following snippets

import {Validator} from 'class-validator/Validator'

console.log(Validator.matches('Tom', '[a-z]+', 'i'))

However, I keep getting the following error:

Property 'matches' does not exist on type 'typeof Validator'.

I am uncertain what is causing this. It seems simple enough.

Thanks

Travis CI installation error: `typings: not found`

I got error during Travis CI building.

> [email protected] postinstall /home/travis/build/sanex3339/javascript-obfuscator/node_modules/class-validator
> typings install
sh: 1: typings: not found

This error comes after i removed typings package from package.json of my package.

Looks like "typings": "^1.3.1" must be in dependencies instead of devDependencies.

add complete es5/es6 support

Right now its possible to use validator with es5/es6, but we can provide more features to make this experience smoother. List of todos:

  • add support of registering validation schema for target class
  • add support of registering custom validations without using decorators
  • make schema validation better
  • cover schema validation with tests
  • add samples with javascript, or javascript + babel + decorators?
  • add docs how to use class-validator with javascript
  • add docs how to use class-validator with system-js

How to do an OR

Case:

if number = 9999.99 or is less than 1

how to do this, with two predefined annotations?

Nested validation skipmissing

I get the error:
[Error: Only objects and arrays are supported to nested validation]

I think it happens when nesting more than one hyrachie (and having no data in some objects).

What i tried to skip this error:

class subOptions implements ValidatorOptions {
public skipMissingProperties: boolean;
public groups: string[];
constructor() {
this.skipMissingProperties = true;
}
}
@ValidateNested(new subOptions())
public beforeRent: myclass;

Any ideas?

Thanks
Dominic

http://localhost:4200/validator 404 (Not Found)

I have the following

import {
  IsNotEmpty,
  Matches,
  MinLength
} from "class-validator";

export class Language {
  @IsNotEmpty({
    message: 'Cannot be empty'
  })
  @MinLength(2, {
    message: "Minimum characters arg[0]"
  })
  first: string = ''

  second: string = ''
}

Running my angular-cli application always throws the console error

zone.js:101 GET http://localhost:4200/validator 404 (Not Found)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM5846:3fetchTextFromURL @ system.src.js:1154(anonymous function) @ system.src.js:1735ZoneAwarePromise @ zone.js:584(anonymous function) @ system.src.js:1734(anonymous function) @ system.src.js:2759(anonymous function) @ system.src.js:3333(anonymous function) @ system.src.js:3600(anonymous function) @ system.src.js:3985(anonymous function) @ system.src.js:4448(anonymous function) @ system.src.js:4700(anonymous function) @ system.src.js:406ZoneDelegate.invoke @ zone.js:323Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426
zone.js:461 Unhandled Promise rejection: Error: XHR error (404 Not Found) loading http://localhost:4200/validator
at XMLHttpRequest.wrapFn as _onreadystatechange
at ZoneDelegate.invokeTask (http://localhost:4200/vendor/zone.js/dist/zone.js:356:38)
at Zone.runTask (http://localhost:4200/vendor/zone.js/dist/zone.js:256:48)
at XMLHttpRequest.ZoneTask.invoke (http://localhost:4200/vendor/zone.js/dist/zone.js:423:34)
Error loading http://localhost:4200/validator as "validator" from http://localhost:4200/vendor/class-validator/validation/Validator.js ; Zone: ; Task: Promise.then ; Value: Error: Error: XHR error (404 Not Found) loading http://localhost:4200/validator(…)consoleError @ zone.js:461_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
zone.js:463 Error: Uncaught (in promise): Error: Error: XHR error (404 Not Found) loading http://localhost:4200/validator(…)consoleError @ zone.js:463_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
zone.js:101 GET http://localhost:4200/validator 404 (Not Found)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM5846:3fetchTextFromURL @ system.src.js:1154(anonymous function) @ system.src.js:1735ZoneAwarePromise @ zone.js:584(anonymous function) @ system.src.js:1734(anonymous function) @ system.src.js:2759(anonymous function) @ system.src.js:3333(anonymous function) @ system.src.js:3600(anonymous function) @ system.src.js:3985(anonymous function) @ system.src.js:4448(anonymous function) @ system.src.js:4700(anonymous function) @ system.src.js:406ZoneDelegate.invoke @ zone.js:323Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426

This is the only place in my small app that I am importing 'class-validator'.
Removing the import the cosole error goes away and the application is displayed.

When I comment the annotations as shown below - the console errors disappear:

import {
  IsNotEmpty,
  Matches,
  MinLength
} from "class-validator";

export class Language {
  // @IsNotEmpty({
  //   message: 'Cannot be empty'
  // })
  // @MinLength(2, {
  //     message: "Minimum characters arg[0]"
  //   })
  // @Matches(nounRegex, {
  //   message: 'Only letters, space, - and \' allowed'
  // })
  first: string = ''

  // @Matches(nounRegexOptional, {
  //   message: 'Only letters, space, - and \' allowed'
  // })
  second: string = ''
}

So it appears that the annotations are causing this issue.

Hope you can help.

$value not resolving in message templates

Hi,

  @MinLength(
      2, {
        message: (args: ValidationArguments) => {
          if (args.value.length < 2) {
            return "$value is too short, minimum length is $constraint1 characters $property";
          }
        }
      })
  first: string = ''

The $value interpolation is not being resolved in the returned messages. $constraint1 and $property are resolved.

Cheers

Joi?

Joi support would be cool :)

Comparing password fields

I am using class-validator to validate my incoming requests in an express application and I am very happy with it.

Currently I am implementing a registration service, my request has two password fields, password and password2. I would like to compare them to each other but it seems that this functionality is lacking in class-validator.

Is class-validator able to handle this scenario already or is this a feature request?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.