markusbohl / fluent-ts-validator Goto Github PK
View Code? Open in Web Editor NEWFluent Validation in TypeScript
Fluent Validation in TypeScript
Consider this class with 3 properties which are optional:
export class SearchPlace {
property1: string | undefined = undefined;
property2: string | undefined = undefined;
property3: number | undefined = undefined;
}
I have a simple validator like this:
export class MyValidator extends AbstractValidator<MyObj> {
constructor() {
super();
this.validateIfString(dto => dto.property1)
.fulfills(new OtherValidator())
.whenDefined();
this.validateIfString(dto => dto.property2)
.isNotEmpty()
.withFailureMessage(`property2 is invalid`)
.whenDefined();
this.validateIfNumber(dto => dto.property3)
.isNotEqualTo(0)
.withFailureMessage(`property3 cannot be zero`)
.whenDefined();
}
}
Now this validator works fine when any of the properties are actually defined, and works fine if any property is not defined. But I also want to say you must define at least one of the properties. (i.e. I need a valid value of either property1, or property2 or property3. It is not OK to have them all undefined)
How would I do that?
When running npm run test
it reads out:
> jasmine-ts 'src/**/*.spec.ts'
>> Executing 0 defined specs...
Test Suites & Specs:
>> Done!
Summary:
No specs executed.
Finished in 0.033 seconds
When running npm run test:coverage
it errors with the following text:
> ts-node node_modules/.bin/istanbul cover -e .ts -x '*.spec.ts' node_modules/.bin/jasmine
C:\Development\fluent-ts-validator\node_modules\.bin\istanbul:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
^^^^^^^
SyntaxError: missing ) after argument list
(latest Version 2.1.0)
I have this dto:
export class ClassA{
name: string = ""; //<- notice the default value is empty string
}
and now its validator:
export class ClassAValidator extends AbstractValidator<ClassA> {
constructor() {
super();
this.validateIfString(dto => dto.name)
.hasLengthBetween(1, 200)
.whenNotEmpty() //<- not available here
.withFailureMessage(`name must be 1 to 200 characters`);
}
I only want to validate the name
if the value is: NOT undefined AND NOT null AND NOT empty
But the call to whenNotEmpty()
is no longer there, as per examples in documentation.
for example: startDate: Date
and endDate: Date
both need to be a Date
but also startDate < endDate
but I can't find anything like: this.validateIfDate((o) => o.startDate).isBefore((o) => o.endDate)
The method isBefore
needs a Date
, so maybe if I access to the current validating object, but I dont know how?
When property validation on a nested class fails, i'd expect:
In my case if the home address street property is failing, i'd expect:
Currently what i get:
NOTES:
Given the situation below using the validator gives me 2 failures, but unfortunately on the 2nd (nested) failure it just says: Home Address is invalid.
Although this statement is true, the detail that the home address Street property that's invalid get's missing.
Also i'd expect a path property that would contain the parent object's path property extended with then failed property to be present, like: homeAddress.location.lat property is missing. Given this property it would be possible to easily match the control on the UI and ensure that the error is displayed there
NOTE: If you remove the return statement from the pesronComponent's executeValidation fn, then there's a code which emulates such errors, everything rest is done by this "framework" of mine. The only thing I miss is a VALIDATION library that's able to provide the data in the format (with that path) - the only one I've found is not working in StackBlitz and it's not supported...
I have a model:
interface Person {
firstName: string;
lastName: string;
ssn: string;
homeAddress: Address;
mailingAddress: Address;
}
interface Address { /* usual street, city, zip, state ... ev. location with long/lat */ }
I have created a PersonValidator and an AddressValidator
export class PersonModelValidator extends AbstractValidator<PersonModel> {
constructor() {
super();
this.validateIfString((p) => p.LastName)
.isAlphanumeric()
.isUppercase();
this.validateIfString((p) => p.SSN).matches(
new RegExp('\\d{3}-\\d{2}-\\d{4}')
);
this.validateIf((p) => p.HomeAddress).fulfills(
new AddressModelValidatorLocationRequired()
);
}
}
export class AddressModelValidatorLocationRequired extends AbstractValidator<AddressModel> {
constructor() {
super();
this.validateIfString((a) => a.Street).isNotEmpty();
}
}
this.validateIf(customerAccount => customerAccount.userName)
.fulfills(async (userName) => {
// todo add request to api
return false;
})
.withFailureMessage("username already taken");
fails to compile with type error Type 'Promise<boolean>' is not assignable to type 'boolean'.
and I'm not seeing any other ways in the documentation to implement this functionality.
is there any support asynchronous custom validation?
Hi, first thanks for this tool
If I build a custom validator and use it in another one, how can I show the error messages of the first in the second?
export class SuperpowerValidator extends AbstractValidator<Superpower> {
constructor() {
super();
this.validateIf(superpower => superpower.type)
.isNotEmpty().withFailureMessage("Superpower Error");
}
}
export class SuperheroValidator extends AbstractValidator<Superhero> {
constructor() {
super();
this.validateIfEach(hero => hero.superpowers)
.fulfills(new SuperpowerValidator()); // <- How can I get "Superpower Error" here ?
}
}
The fulfills(validator: Validatable) keeps only the isValid() of the ValidationResult so the custom message of ValidationFailure returned from validator: Validatable is lost.
Lets say I have a DTO like this:
class Dto{
property1?:number
}
and a validator:
class MyValidator extends AbstractValidator<Dto>{
}
How would I write a rule that only validates the number if it is defined, since it is optional?
I tried:
this.validateIfNumber(dto => dto.property1)
.isPositive()
.whenDefined()
.withFailureMessage(`must be a number above zero`)
But compiler obviously complains that: Type 'number | undefined' is not assignable to type 'number'
because validateIfNumber()
must have a number
not a number | undefined
given an enum like this:
export enum species {
none = "",
cattle = "cattle",
deer = "deer"
}
and I have a DTO defined like this:
class AClass{
species: species = species.none;
}
I would love a validator to make sure I have one of the values in the enum, something like this perhaps?
this.validateIfString(dto => dto.species)
.isOneOf(species)
.whenNotEmpty()
isOneOf(enum)
or isIn(enum)
is that doable?
Feature request: It would be nice if there were some pre-built validation rules purpose-built for iterables.
For example:
Hey there,
We've just picked up version 2.1.1 and now I have quite a few compiler errors. Now given the version increase was at a patch level, I would not have expected compiler errors. Happy if this expectation is wrong - just trying to understand if it's our implementation or not. We trip errors in this pattern error TS2339: Property 'validate' does not exist on type <type>
We are also trpping a error TS2307: Cannot find module 'fluent-ts-validator'.
which cause an exception when running our tests.
Node 6.9.1
NPM 3.10.8
Typescript 2.4.1
If I revert to 2.1.0, everything works.
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.