import ErrorCodes from '../errors/io-error-codes' ; import { isParserTree } from '../utils/is' ; import MemberDef from './memberdef' ; import TypeDef from './typedef' ; import KeyValueCollection from '../header/index' ; import { InternetObjectError } from '../errors/io-error' ; import { Token } from '../parser' ; import { Node , ParserTreeValue } from '../parser/index' ; import { TypedefRegistry } from './typedef-registry' ; import { doCommonTypeCheck } from './utils' ; /**
 * Represents the `array`, performs following validations.
 * - Value is an array
 * - Value is optional
 * - Value is nullable
 * - array is <= schema.maxLength
 * - array is >= schema.minLength
 * - Value is in choices
 */ class ArrayDef implements TypeDef { private _keys : any = null ; public getType ( ) { return 'array' ; } public parse = ( data , memberDef , vars ? ) : any => { if ( isParserTree ( data ) ) { return _process ( 'parse' , memberDef , data . values , data , vars ) ; } else if ( data === undefined ) { return _process ( 'parse' , memberDef , undefined , data , vars ) ; } throw new Error ( 'invalid-value' ) ; } ; public load = ( data , memberDef ) : any => { const value = data === undefined ? undefined : data ; return _process ( 'load' , memberDef , value , data ) ; } ; public serialize = ( data , memberDef ) : string => { if ( memberDef . type !== 'array' ) { throw new InternetObjectError ( ErrorCodes . invalidArray ) ; } const validatedData = doCommonTypeCheck ( memberDef , data ) ; if ( validatedData !== data ) { data = validatedData ; } else if ( validatedData === undefined ) { return '' ; } else if ( validatedData === null ) { return 'N' ; } const serialized = [ ] ; const schema = memberDef . schema ; const typeDef = TypedefRegistry . get ( schema . type ) ; data . forEach ( ( value ) => { serialized . push ( typeDef . serialize ( value , schema ) ) ; } ) ; return `[${ serialized . join ( ',' ) }]` ; } ; } function _process ( processingFnName , memberDef , value , node ? , vars ? ) { const validatedData = doCommonTypeCheck ( memberDef , value , node ) ; if ( validatedData !== value || value === undefined ) return validatedData ; if ( ! Array . isArray ( value ) ) throw new Error ( 'invalid-value' ) ; const schema = memberDef . schema ; let typeDef ; if ( schema . type ) { typeDef = TypedefRegistry . get ( schema . type ) ; } else { console . assert ( false , 'Invalid Case: Array schema must have a type attribute!' ) ; throw new Error ( 'Verify this case!' ) ; } const array = [ ] ; value . forEach ( ( item ) => { if ( typeDef !== undefined ) { const value = typeDef [ processingFnName ] ( item , schema , vars ) ; array . push ( value ) ; } else { throw ErrorCodes . invalidType ; } } ) ; return array ; } function _invlalidChoice ( key , token , min ) { return [ ErrorCodes . invalidMinValue , `The "${ key }" must be greater than or equal to ${ min }, Currently it is "${ token . value }".` , token ] ; } function _invlalidMinLength ( key , token , min ) { return [ ErrorCodes . invalidMinValue , `The "${ key }" must be greater than or equal to ${ min }, Currently it is "${ token . value }".` , token ] ; } function _invlalidMaxLength ( key , token , max ) { return [ ErrorCodes . invalidMaxValue , `The "${ key }" must be less than or equal to ${ max }, Currently it is "${ token . value }".` , token ] ; } export default ArrayDef ;