import reflect , { decorateProperty , decorate , mergeDecorator , TypeOverride } from "@plumier/reflect" ; import { VisitorInvocation } from './invocation' ; import { Result } from './visitor' ; import { Class } from './types' ; import { safeToString } from './converter' ; const RequiredValidator = Symbol ( "tc:required" ) ; const PartialValidator = Symbol ( "tc:partial" ) ; type Validator = ( val : any ) => string | undefined ; interface ValidatorDecorator { type : "tc:validator" ; validator : Validator | string | symbol ; } function createValidation ( validator ) { return decorateProperty ( < ValidatorDecorator > { type : "tc:validator" , validator } ) ; } function required ( ) { return createValidation ( RequiredValidator ) ; } function partial ( type ) { return mergeDecorator ( reflect . type ( type ) , createValidation ( PartialValidator ) ) ; } function isPartial ( i ) { return i . parent && i . parent . decorators . find ( ( x ) => x . validator === PartialValidator ) ; } function isEmpty ( result ) { return ( result . value === "" || result . value === undefined || result . value === null ) ; } function getValidators ( i ) { return i . decorators . filter ( ( x ) => x . validator !== PartialValidator && x . type === "tc:validator" ) ; } function validatorVisitor ( i ) { const validators = getValidators ( i ) ; const result = i . proceed ( ) ; if ( ! isPartial ( i ) && isEmpty ( result ) && validators . some ( x => x . validator === RequiredValidator ) ) return Result . error ( i . value , i . path , "Required" ) ; if ( isEmpty ( result ) || validators . length === 0 ) return result ; else { const messages = [ ] ; for ( const validator of validators ) { if ( typeof validator . validator === "function" ) { const msg = validator . validator ( safeToString ( i . value ) ) ; if ( msg ) messages . push ( msg ) ; } } return messages . length > 0 ? Result . error ( i . value , i . path , messages ) : result ; } } export { createValidation , required , partial , validatorVisitor , Validator , ValidatorDecorator , PartialValidator , RequiredValidator } ;