import { Normalizer , Rule , Error } from '../type' ; import { IBaseValidator , publicKey , privateKey , pathKey } from './proxy' ; import { IStatableValidator } from './validation-state' ; import { getByPath , noop , isPlainObject , isFunction } from './util' ; export const schemaKey = 'schema' ; interface ISchema { $params : { [ key ] : any ; } ; $normalizer : Normalizer ; $rules : { [ key ] : Rule ; } ; $errors : { [ key ] : Error ; } ; [ key ] : any ; } export interface ISchemaValidator extends IBaseValidator , IStatableValidator { [ key ] : any ; [ privateKey ] : { [ pathKey ] : string [ ] ; invalid : boolean ; validated : boolean ; pending : number ; dirty : boolean ; setValidated : ( value : boolean ) => void ; setInvalid : ( value : boolean ) => void ; setDirty : ( value : boolean ) => void ; setPending : ( value : boolean ) => void ; resetPending : ( ) => void ; [ key ] : any ; [ schemaKey ] : ISchema ; } ; [ publicKey ] : { [ key ] : any ; pending : boolean ; invalid : boolean ; dirty : boolean ; anyDirty : boolean ; error : boolean ; anyError : boolean ; errors : { [ key ] : any ; } ; } ; } const createDefaultSchema = ( ) : ISchema => { return { $params : { } , $normalizer : ( { value } ) => value , $rules : { } , $errors : { } , } ; } ; export const wrapSchema = ( { rootSchema , validator , } ) : void => { const path = validator [ privateKey ] [ pathKey ] ; const defaultSchema = createDefaultSchema ( ) ; validator [ privateKey ] [ schemaKey ] = ( validator [ privateKey ] [ schemaKey ] || { } ) as ISchemaValidator ; validator [ privateKey ] [ schemaKey ] . $params = defaultSchema . $params ; validator [ privateKey ] [ schemaKey ] . $normalizer = defaultSchema . $normalizer ; validator [ privateKey ] [ schemaKey ] . $rules = defaultSchema . $rules ; validator [ privateKey ] [ schemaKey ] . $errors = defaultSchema . $errors ; applyMostAppropriateSchema ( { rootSchema , validator , path : path . slice ( ) , startIndex : 0 } ) ; for ( const key in validator [ privateKey ] [ schemaKey ] . $rules ) { if ( validator [ privateKey ] [ schemaKey ] . $errors [ key ] === undefined ) { validator [ privateKey ] [ schemaKey ] . $errors [ key ] = noop ; } } } ; const applyMostAppropriateSchema = ( { rootSchema , validator , path , startIndex , } ) => { if ( startIndex === path . length ) { try { const schema = getByPath ( rootSchema , path ) ; if ( shouldUseSchema ( schema ) ) { if ( isPlainObject ( schema . $params ) ) validator [ privateKey ] [ schemaKey ] . $params = schema . $params ; if ( isFunction ( schema . $normalizer ) ) validator [ privateKey ] [ schemaKey ] . $normalizer = schema . $normalizer ; if ( isPlainObject ( schema . $rules ) ) validator [ privateKey ] [ schemaKey ] . $rules = schema . $rules ; if ( isPlainObject ( schema . $errors ) ) validator [ privateKey ] [ schemaKey ] . $errors = schema . $errors ; return true ; } } catch ( error ) { } return false ; } if ( applyMostAppropriateSchema ( { rootSchema , validator , path , startIndex : startIndex + 1 } ) ) return true ; const oldKey = path [ startIndex ] ; path [ startIndex ] = '$iter' ; if ( applyMostAppropriateSchema ( { rootSchema , validator , path , startIndex : startIndex + 1 } ) ) return true ; path [ startIndex ] = oldKey ; return false ; } ; const shouldUseSchema = ( schema ? ) => { if ( schema === undefined ) return false ; if ( schema . $params !== undefined ) return true ; if ( schema . $normalizer !== undefined ) return true ; if ( schema . $rules !== undefined ) return true ; if ( schema . $errors !== undefined ) return true ; return false ; } ;