import { ValidationErrors } from './ValidationErrors' ; import { ValidationError , ValidatorFunction , ValidatorFunctionAsync } from './types' ; export { CreditCardValidations as CreditCard } from './creditCard' ; export { ValidationErrors , ValidationError , ValidatorFunction , ValidatorFunctionAsync } ; const RE = { name : /^[a-z,\.'-]+( +[a-z,\.'-]+)+$/i , englishLetters : /^([a-zA-Z\s]+)$/ , email : /^([a-zA-Z0-9_.-\\+])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/ , password : /^(?=.*?[a-zA-Z0-9]).{6,}$/ , url : /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/ , zipcode : /(^\d{5}$)|(^\d{5}-\d{4}$)/ , } ; export const Validators = { none : < T = any > ( val ) => ValidationErrors . None , notEmpty : < T = string > ( val ) => ! ! val ? ValidationErrors . None : ValidationErrors . ShouldBeNonEmpty , firstName : < T = string > ( val ) => ! ! val ? ValidationErrors . None : ValidationErrors . FirstName , lastName : < T = string > ( val ) => ! ! val ? ValidationErrors . None : ValidationErrors . LastName , occupation : < T = string > ( val ) => ! ! val ? ValidationErrors . None : ValidationErrors . Occupation , birthday : ( val ) => ! ! val && new Date ( val ) . getTime ( ) < new Date ( ) . getTime ( ) ? ValidationErrors . None : ValidationErrors . Birthday , relationship : < T = string > ( val ) => ! ! val ? ValidationErrors . None : ValidationErrors . Relationship , goal : < T = string > ( val ) => ! ! val ? ValidationErrors . None : ValidationErrors . Goal , fullName : ( val ) => RE . name . test ( val . trim ( ) ) ? ValidationErrors . None : ValidationErrors . InvalidNameFormat , onlyEnglish : ( val ) => RE . englishLetters . test ( val ) ? ValidationErrors . None : ValidationErrors . OnlyEnglishLetters , email : ( val ) => RE . email . test ( val ) ? ValidationErrors . None : ValidationErrors . InvalidEmailFormat , password : ( val ) => RE . password . test ( val ) ? ValidationErrors . None : ValidationErrors . InvalidPasswordFormat , url : ( val ) => RE . url . test ( val ) ? ValidationErrors . None : ValidationErrors . InvalidURLFormat , notEmptyArray : < T > ( val ) => ! ! val && val . length ? ValidationErrors . None : ValidationErrors . ShouldBeNonEmpty , arrayContains : < T > ( arr ) => ( ( val ) => arr . includes ( val ) ? ValidationErrors . None : ValidationErrors . ValueOutOfRange ) , notFutureDate : ( val ) => { if ( ! val || isNaN ( new Date ( val ) . getTime ( ) ) ) { return ValidationErrors . InvalidDate ; } return ! ! val && new Date ( val ) . getTime ( ) < new Date ( ) . getTime ( ) ? ValidationErrors . None : ValidationErrors . NotFutureDate ; } , dateInFuture : ( val , withoutTime = true ) => { const date = new Date ( val ) . getTime ( ) ; const now = new Date ( ) ; if ( ! val || isNaN ( date ) ) { return ValidationErrors . InvalidDate ; } if ( withoutTime ) { now . setHours ( 0 , 0 , 0 , 0 ) ; } return ! ! val && date >= now . getTime ( ) ? ValidationErrors . None : ValidationErrors . FutureDate ; } , textLength : ( val , length = 255 , required = true ) => { if ( ( ! val || ! val . replace ( /\s/g , '' ) . length ) && required ) { return ValidationErrors . ShouldBeNonEmpty ; } if ( val . length > length ) { return ValidationErrors . TextLength ; } return ValidationErrors . None ; } , maxIntegerValue : ( val , max = 60 ) => { const value = parseInt ( val , 10 ) ; if ( ! /^\+?(0|[1-9]\d*)$/ . test ( val ) ) { return ValidationErrors . InvalidInteger ; } if ( ! value ) { return ValidationErrors . ShouldBeNonEmpty ; } return value <= max ? ValidationErrors . None : ValidationErrors . MaxValue ; } , zipcode : ( val ) => RE . zipcode . test ( val ) ? ValidationErrors . None : ValidationErrors . Zipcode , } ; const isDocNameValid = ( name ) => { if ( ! name || ! name . replace ( /\s/g , '' ) . length ) { return ValidationErrors . ShouldBeNonEmpty ; } if ( name . length > 255 ) { return ValidationErrors . None ; } return ValidationErrors . None ; } ; export function createShouldBeEqualTo < T = string > ( getter ) { return ( val ) => getter ( ) === val ? ValidationErrors . None : ValidationErrors . ShouldBeEqualTo ; } export const Wrappers = { required < T = string > ( validator ) { return ( val ) : ValidationErrors => { return Validators . notEmpty ( val ) || validator ( val ) ; } ; } , notRequired < T = string > ( validator ) { return ( val ) : ValidationErrors => { return Validators . notEmpty ( val ) === ValidationErrors . ShouldBeNonEmpty ? ValidationErrors . None : validator ( val ) ; } ; } , thrower < T = string > ( validator ) { return ( val ) => { throwNotOk ( validator ( val ) ) ; } ; } , getter < T , TField extends keyof T > ( field , fn ) { return ( val ) => { const f = val && val [ field ] ; return fn ( f ) ; } ; } , } ; export function throwNotOk ( result , message = 'Validation error' ) { if ( result ) { throw new ValidationError ( message , result ) ; } } export function validateObject < T > ( obj , validators , atLeastOneValidField = false ) { const res = { } ; const keys = Object . keys ( obj ) ; let hasValidField = false ; for ( let i = 0 ; i < keys . length ; ++ i ) { const k = keys [ i ] ; const kk = k as keyof T ; const validator = validators [ kk ] ; if ( ! validator ) { continue ; } const v = obj [ k as keyof T ] ; const err = validator ( v ) ; if ( err ) { res [ kk ] = err ; } else { hasValidField = true ; } } if ( atLeastOneValidField && hasValidField ) { return { } ; } return res ; }