import { CommonValidatorBuilder , CommonValidatorBuilderImpl , DateValidatorBuilder , DateValidatorBuilderImpl , IterableValidatorBuilder , SizedIterableValidatorBuilderImpl , NumberValidatorBuilder , NumberValidatorBuilderImpl , SizedIterableValidatorBuilder , StringValidatorBuilder , StringValidatorBuilderImpl , TypeValidatorBuilder , TypeValidatorBuilderImpl } from "./builder" ; import { Validatable , ValidationResult } from "./shared" ; import { SizedIterable } from "./shared/SizedIterable" ; import { CollectionValidationRule , RuleApplicationOutcome , ValidationRule } from "./validation" ; import { StringValidationOptionsBuilder } from "./builder/StringValidationOptionsBuilder" ; import { IterableValidationOptionsBuilder } from "./builder/IterableValidationOptionsBuilder" ; export abstract class template T export abstract class AbstractValidator < T > implements Validatable < T > { private rules : ValidationRule < T , any > [ ] = [ ] ; param lambdaExpression returns { CommonValidatorBuilder } protected validateIf < TProperty > ( lambdaExpression ) { const rule = this . registerRule ( new ValidationRule ( lambdaExpression ) ) ; return new CommonValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { TypeValidatorBuilder } protected validateIfAny ( lambdaExpression ) { const rule = this . registerRule ( new ValidationRule ( lambdaExpression ) ) ; return new TypeValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { NumberValidatorBuilder } protected validateIfNumber ( lambdaExpression ) { const rule = this . registerRule ( new ValidationRule ( lambdaExpression ) ) ; return new NumberValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { DateValidatorBuilder } protected validateIfDate ( lambdaExpression ) { const rule = this . registerRule ( new ValidationRule ( lambdaExpression ) ) ; return new DateValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { StringValidatorBuilder } protected validateIfString ( lambdaExpression ) { const rule = this . registerRule ( new ValidationRule ( lambdaExpression ) ) ; return new StringValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { CommonValidatorBuilder } protected validateIfEach < TProperty > ( lambdaExpression ) { const rule = this . registerRule ( new CollectionValidationRule ( lambdaExpression ) ) ; return new CommonValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { TypeValidatorBuilder } protected validateIfEachAny ( lambdaExpression ) { const rule = this . registerRule ( new CollectionValidationRule ( lambdaExpression ) ) ; return new TypeValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { NumberValidatorBuilder } protected validateIfEachNumber ( lambdaExpression ) { const rule = this . registerRule ( new CollectionValidationRule ( lambdaExpression ) ) ; return new NumberValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { DateValidatorBuilder } protected validateIfEachDate ( lambdaExpression ) { const rule = this . registerRule ( new CollectionValidationRule ( lambdaExpression ) ) ; return new DateValidatorBuilderImpl ( rule ) ; } param lambdaExpression returns { StringValidatorBuilder } protected validateIfEachString ( lambdaExpression ) { const rule = this . registerRule ( new CollectionValidationRule ( lambdaExpression ) ) ; return new StringValidatorBuilderImpl ( rule ) ; } param lambdaExpression protected validateIfIterable < TProperty > ( lambdaExpression ) ; protected validateIfIterable < TProperty > ( lambdaExpression ) ; protected validateIfIterable < TProperty > ( lambdaExpression ) { const rule = this . registerRule ( new ValidationRule ( lambdaExpression ) ) ; return new SizedIterableValidatorBuilderImpl ( rule ) ; } private registerRule < TProperty > ( validationRule ) { this . rules . push ( validationRule ) ; return validationRule ; } param input returns { ValidationResult } validate ( input ) { const result = new ValidationResult ( ) ; this . rules . forEach ( ( rule ) => { const outcome = rule . apply ( input ) ; if ( outcome . isFailure ( ) ) { result . addFailures ( outcome . getValidationFailures ( ) ) ; } } ) ; return result ; } param input returns { Promise < ValidationResult > } validateAsync ( input ) { return new Promise < ValidationResult > ( ( resolve ) => { const promises = this . createPromiseForEachRule ( input , this . rules ) ; Promise . all ( promises ) . then ( ( outcomes ) => { resolve ( this . buildValidationResultFrom ( outcomes ) ) ; } ) ; } ) ; } private createPromiseForEachRule ( input , rules ) { const promises = [ ] ; rules . forEach ( ( rule ) => { promises . push ( this . applyRuleAsync ( rule , input ) ) ; } ) ; return promises ; } private applyRuleAsync ( rule , input ) { return new Promise ( ( resolve ) => { resolve ( rule . apply ( input ) ) ; } ) ; } private buildValidationResultFrom ( outcomes ) { const result = new ValidationResult ( ) ; outcomes . forEach ( ( outcome ) => { if ( outcome . isFailure ( ) ) { result . addFailures ( outcome . getValidationFailures ( ) ) ; } } ) ; return result ; } }