Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smaller bundle size #258

Closed
wants to merge 12 commits into from
1,953 changes: 993 additions & 960 deletions README.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "class-validator",
"private": true,
"version": "0.9.1",
"version": "1.0.0-rc1",
"description": "Class-based validation with Typescript / ES6 / ES5 using decorators or validation schemas. Supports both node.js and browser",
"license": "MIT",
"readmeFilename": "README.md",
Expand All @@ -23,7 +23,6 @@
"typescript-validator"
],
"dependencies": {
"@types/validator": "9.4.2",
"google-libphonenumber": "^3.1.6",
"validator": "10.4.0"
},
Expand All @@ -34,6 +33,7 @@
"@types/mocha": "^5.2.5",
"@types/node": "^10.5.2",
"@types/sinon": "^5.0.1",
"@types/validator": "^9.4.2",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"codecov": "^3.0.4",
Expand Down
12 changes: 11 additions & 1 deletion sample/sample1-simple-validation/Post.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import {Contains, IsInt, MinLength, MaxLength, IsEmail, IsFQDN, IsDate, ArrayNotEmpty, ArrayMinSize, ArrayMaxSize, IsEnum} from "../../src/decorator/decorators";
import {IsDate} from "../../src/decorator/typechecker/IsDate";
import {IsInt} from "../../src/decorator/typechecker/IsInt";
import {IsEnum} from "../../src/decorator/typechecker/IsEnum";
import {Contains} from "../../src/decorator/string/Contains";
import {IsEmail} from "../../src/decorator/string/IsEmail";
import {IsFQDN} from "../../src/decorator/string/IsFQDN";
import {MinLength} from "../../src/decorator/string/MinLength";
import {MaxLength} from "../../src/decorator/string/MaxLength";
import {ArrayNotEmpty} from "../../src/decorator/array/ArrayNotEmpty";
import {ArrayMinSize} from "../../src/decorator/array/ArrayMinSize";
import {ArrayMaxSize} from "../../src/decorator/array/ArrayMaxSize";

export enum PostType {
Public,
Expand Down
9 changes: 7 additions & 2 deletions sample/sample2-using-groups/Post.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import {Contains, IsInt, Length, IsEmail, IsFQDN, IsDate} from "../../src/decorator/decorators";
import {IsDate} from "../../src/decorator/typechecker/IsDate";
import {IsInt} from "../../src/decorator/typechecker/IsInt";
import {Contains} from "../../src/decorator/string/Contains";
import {IsEmail} from "../../src/decorator/string/IsEmail";
import {IsFQDN} from "../../src/decorator/string/IsFQDN";
import {Length} from "../../src/decorator/string/Length";

export class Post {

Expand Down Expand Up @@ -35,4 +40,4 @@ export class Post {
@IsDate()
createDate: Date;

}
}
5 changes: 3 additions & 2 deletions sample/sample3-nested-objects/Post.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Contains, IsInt, Length, IsEmail, IsFQDN, IsDate, ValidateNested} from "../../src/decorator/decorators";
import {Tag} from "./Tag";
import {Length} from "../../src/decorator/string/Length";
import {ValidateNested} from "../../src/decorator/system/ValidateNested";

export class Post {

Expand All @@ -11,4 +12,4 @@ export class Post {
@ValidateNested()
tags: Tag[];

}
}
4 changes: 2 additions & 2 deletions sample/sample3-nested-objects/Tag.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Contains, IsInt, Length, IsEmail, IsFQDN, IsDate} from "../../src/decorator/decorators";
import {Length} from "../../src/decorator/string/Length";

export class Tag {

Expand All @@ -7,4 +7,4 @@ export class Tag {
})
name: string;

}
}
4 changes: 2 additions & 2 deletions sample/sample4-custom-validator/CustomTextLength.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ValidatorConstraint} from "../../src/decorator/ValidatorConstraint";
import {ValidatorConstraintInterface} from "../../src/validation/ValidatorConstraintInterface";
import {ValidatorConstraint} from "../../src/decorator/decorators";

@ValidatorConstraint()
export class CustomTextLength implements ValidatorConstraintInterface {
Expand All @@ -8,4 +8,4 @@ export class CustomTextLength implements ValidatorConstraintInterface {
return text.length > 1 && text.length < 10;
}

}
}
5 changes: 2 additions & 3 deletions sample/sample4-custom-validator/Post.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {Contains, IsInt, MinLength, MaxLength, IsEmail, IsFQDN, IsDate, IsNotEmpty, ArrayNotEmpty, ArrayMinSize, ArrayMaxSize} from "../../src/decorator/decorators";
import {Validate} from "../../src/decorator/decorators";
import {CustomTextLength} from "./CustomTextLength";
import {Validate} from "../../src/decorator/Validate";

export class Post {

Expand All @@ -9,4 +8,4 @@ export class Post {
})
title: string;

}
}
6 changes: 3 additions & 3 deletions sample/sample6-custom-decorator/IsLongerThan.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {registerDecorator} from "../../src/index";
import {ValidationOptions} from "../../src/decorator/ValidationOptions";
import {ValidatorConstraintInterface} from "../../src/validation/ValidatorConstraintInterface";
import {ValidatorConstraint} from "../../src/decorator/decorators";
import {ValidatorConstraint} from "../../src/decorator/ValidatorConstraint";
import {ValidationArguments} from "../../src/validation/ValidationArguments";
import {registerDecorator} from "../../src/register-decorator";

export function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
Expand All @@ -27,4 +27,4 @@ export class IsLongerThanConstraint implements ValidatorConstraintInterface {
value.length > relatedValue.length;
}

}
}
4 changes: 2 additions & 2 deletions sample/sample6-custom-decorator/IsUserAlreadyExist.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {registerDecorator} from "../../src/index";
import {ValidationOptions} from "../../src/decorator/ValidationOptions";
import {ValidationArguments} from "../../src/validation/ValidationArguments";
import {registerDecorator} from "../../src/register-decorator";

export function IsUserAlreadyExist(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
Expand All @@ -23,4 +23,4 @@ export function IsUserAlreadyExist(validationOptions?: ValidationOptions) {
}
});
};
}
}
4 changes: 2 additions & 2 deletions sample/sample7-inheritance-support/BaseContent.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {IsEmail} from "../../src/decorator/decorators";
import {IsEmail} from "../../src/decorator/string/IsEmail";

export class BaseContent {

@IsEmail()
email: string;

}
}
7 changes: 5 additions & 2 deletions sample/sample7-inheritance-support/Post.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {Contains, IsInt, MinLength, MaxLength} from "../../src/decorator/decorators";
import {BaseContent} from "./BaseContent";
import {IsInt} from "../../src/decorator/typechecker/IsInt";
import {Contains} from "../../src/decorator/string/Contains";
import {MinLength} from "../../src/decorator/string/MinLength";
import {MaxLength} from "../../src/decorator/string/MaxLength";

export class Post extends BaseContent {

Expand All @@ -13,4 +16,4 @@ export class Post extends BaseContent {
@IsInt()
rating: number;

}
}
26 changes: 26 additions & 0 deletions src/decorator/Validate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {ValidationOptions} from "./ValidationOptions";
import {ValidationMetadataArgs} from "../metadata/ValidationMetadataArgs";
import {ValidationMetadata} from "../metadata/ValidationMetadata";
import {MetadataStorage} from "../metadata/MetadataStorage";
import {ValidationTypes} from "../validation/ValidationTypes";
import {getFromContainer} from "../container";

/**
* Performs validation based on the given custom validation class.
* Validation class must be decorated with ValidatorConstraint decorator.
*/
export function Validate(constraintClass: Function, validationOptions?: ValidationOptions): Function;
export function Validate(constraintClass: Function, constraints?: any[], validationOptions?: ValidationOptions): Function;
export function Validate(constraintClass: Function, constraintsOrValidationOptions?: any[] | ValidationOptions, maybeValidationOptions?: ValidationOptions): Function {
return function (object: Object, propertyName: string) {
const args: ValidationMetadataArgs = {
type: ValidationTypes.CUSTOM_VALIDATION,
target: object.constructor,
propertyName: propertyName,
constraintCls: constraintClass,
constraints: constraintsOrValidationOptions instanceof Array ? constraintsOrValidationOptions as any[] : undefined,
validationOptions: !(constraintsOrValidationOptions instanceof Array) ? constraintsOrValidationOptions as ValidationOptions : maybeValidationOptions
};
getFromContainer(MetadataStorage).addValidationMetadata(new ValidationMetadata(args));
};
}
33 changes: 33 additions & 0 deletions src/decorator/ValidateBy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {ValidationFunction} from "./ValidationFunction";
import {ValidationOptions} from "./ValidationOptions";
import {registerDecorator} from "../register-decorator";
import {ValidationArguments} from "../validation/ValidationArguments";
import {ValidatorConstraintInterface} from "../validation/ValidatorConstraintInterface";

export function buildMessage(
impl: (eachPrefix: string, args?: ValidationArguments) => string,
validationOptions?: ValidationOptions)
: (validationArguments?: ValidationArguments) => string {
return (validationArguments?: ValidationArguments) => {
const eachPrefix = validationOptions && validationOptions.each
? "each value in "
: "";
return impl(eachPrefix, validationArguments);
};
}

export function ValidateBy(validator: ValidationFunction, validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
name: validator.name,
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
constraints: validator.constraints,
validator: <ValidatorConstraintInterface> {
validate: validator.validate,
defaultMessage: validator.defaultMessage
}
});
};
}
9 changes: 9 additions & 0 deletions src/decorator/ValidationFunction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {ValidationArguments} from "../validation/ValidationArguments";

export interface ValidationFunction {
name: string;
constraints?: any[];
validate: (value: any, validationArguments?: ValidationArguments) => Promise<boolean>|boolean;
defaultMessage: (validationArguments?: ValidationArguments) => string;
async?: boolean;
}
20 changes: 20 additions & 0 deletions src/decorator/ValidatorConstraint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {ConstraintMetadata} from "../metadata/ConstraintMetadata";
import {getFromContainer} from "../container";
import {MetadataStorage} from "../metadata/MetadataStorage";

/**
* Registers custom validator class.
*/
export function ValidatorConstraint(options?: { name?: string, async?: boolean }) {
return function (target: Function) {
const isAsync = options && options.async ? true : false;
let name = options && options.name ? options.name : "";
if (!name) {
name = (target as any).name;
if (!name) // generate name if it was not given
name = name.replace(/\.?([A-Z]+)/g, (x, y) => "_" + y.toLowerCase()).replace(/^_/, "");
}
const metadata = new ConstraintMetadata(target, name, isAsync);
getFromContainer(MetadataStorage).addConstraintMetadata(metadata);
};
}
30 changes: 30 additions & 0 deletions src/decorator/array/ArrayContains.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {ValidationOptions} from "../ValidationOptions";
import {buildMessage, ValidateBy} from "../ValidateBy";

export const ARRAY_CONTAINS = "arrayContains";

/**
* Checks if array contains all values from the given array of values.
* If null or undefined is given then this function returns false.
*/
export function arrayContains(array: any[], values: any[]) {
if (!(array instanceof Array)) {
return false;
}

return !array || values.every(value => array.indexOf(value) !== -1);
}

/**
* Checks if array contains all values from the given array of values.
*/
export function ArrayContains(values: any[], validationOptions?: ValidationOptions) {
return ValidateBy({
name: ARRAY_CONTAINS,
validate: (value, args) => arrayContains(value, args.constraints[0]),
constraints: [values],
defaultMessage: buildMessage((eachPrefix) => eachPrefix + "$property must contain $constraint1 values", validationOptions)
},
validationOptions
);
}
30 changes: 30 additions & 0 deletions src/decorator/array/ArrayMaxSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {ValidationOptions} from "../ValidationOptions";
import {buildMessage, ValidateBy} from "../ValidateBy";

export const ARRAY_MAX_SIZE = "arrayMaxSize";

/**
* Checks if array's length is as maximal this number.
* If null or undefined is given then this function returns false.
*/
export function arrayMaxSize(array: any[], max: number) {
if (!(array instanceof Array)) {
return false;
}

return array instanceof Array && array.length <= max;
}

/**
* Checks if array's length is as maximal this number.
*/
export function ArrayMaxSize(max: number, validationOptions?: ValidationOptions) {
return ValidateBy({
name: ARRAY_MAX_SIZE,
validate: (value, args) => arrayMaxSize(value, args.constraints[0]),
constraints: [max],
defaultMessage: buildMessage((eachPrefix) => eachPrefix + "$property must contain not more than $constraint1 elements", validationOptions)
},
validationOptions
);
}
30 changes: 30 additions & 0 deletions src/decorator/array/ArrayMinSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {ValidationOptions} from "../ValidationOptions";
import {buildMessage, ValidateBy} from "../ValidateBy";

export const ARRAY_MIN_SIZE = "arrayMinSize";

/**
* Checks if array's length is as minimal this number.
* If null or undefined is given then this function returns false.
*/
export function arrayMinSize(array: any[], min: number) {
if (!(array instanceof Array)) {
return false;
}

return array instanceof Array && array.length >= min;
}

/**
* Checks if array's length is as minimal this number.
*/
export function ArrayMinSize(min: number, validationOptions?: ValidationOptions) {
return ValidateBy({
name: ARRAY_MIN_SIZE,
validate: (value, args) => arrayMinSize(value, args.constraints[0]),
constraints: [min],
defaultMessage: buildMessage((eachPrefix) => eachPrefix + "$property must contain at least $constraint1 elements", validationOptions)
},
validationOptions
);
}
Loading