typestack / class-validator Goto Github PK
View Code? Open in Web Editor NEWDecorator-based property validation for classes.
License: MIT License
Decorator-based property validation for classes.
License: MIT License
Do custom validators not support a default message?
It would be nice to have a json-schema converter like this: https://github.com/lightsofapollo/joi-to-json-schema
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.
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.
Is exists like isInstanse validator for run time checking?
class Post {
@IsInstance(User);
user: User;
}
Thanks a lot!
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.
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
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
There is a way to avoid writing all the rules again?
There could be an option to emit a validation error if the object contains a property it shouldn't (e.g. the property isn't declared and decorated in the class).
There's related issue in validator.js: validatorjs/validator.js#311
They recommend to do
validator.isInt(number) && number > 0
The question is how quickly to do that with annotations without creating custom ValidatorConstraint?
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
@IsLongerThan('propertyName')
, @RequiredIf('propertyName', 'value')
@UsernameAvailable
Notes:
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.Promise.resolve()
will allow both promised and basic validators to runtimeout(() => throw new ValidationError())
in the promise chain so the thrown errors escape. (for backwards compatibility).validate(object: any, validatorOptions?: ValidatorOptions): Promise<ValidationErrorInterface[]>
. This would have to be a breaking change.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 ?
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?
Hi,
As in the question above.
"Constraints" shouldn't since many validators don't require it (like IS_EMPTY)
"Options" because you don't need to provide any options most of the time
I'm happy to fix it, just need your voice here.
Good job BTW.
When the property is null or undefined, it shall return error message not throw an error
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!
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"
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
Not sure if this is because I am behind a firewall at my company (have a feeling its not), but I am getting a 403 when trying to download this dep
https://node-zopfli.s3.amazonaws.com/Release/zopfli-v2.0.2-node-v48-linux-x64.tar.gz
looks like badges complaining
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
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
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
.
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?
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
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.
Case:
if number = 9999.99 or is less than 1
how to do this, with two predefined annotations?
With typings https://github.com/typings/typings.
Thanks!
There is a class-sanitizer in a separate library right now. Should it stay separate or be a part of the class-validator library?
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...
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
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.
Joi support would be cool :)
For example, when I use @isurl, I wanted it test every string except ""
, null
and undefined
. If I need test on empty values I will add @IsNotEmpty
.But now I need add @ValidateIf(o=>o)
on many nullable properties.
Not only @IsUrl
, like @IsEmail
, @IsUUID
and etc have the same problem.
Is it possible to validate only a specific property?
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.
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
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 }
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
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.
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.
Right now its possible to use validator with es5/es6, but we can provide more features to make this experience smoother. List of todos:
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.
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')
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.
It would be helpful to have a isRequired decorator for some stuff.
In the meantime i will solve this with a custom validator
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
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 }
})
@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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.