import { FuncKeywordDefinition , JSONSchemaType , AnySchemaObject , AnySchema , SchemaCxt } from 'ajv' ; import * as createDebug from 'debug' ; import { DataValidateFunction , DataValidationCxt } from '../types' ; import { LiskValidationError } from '../errors' ; const debug = createDebug ( 'codec:keyword:fieldNumber' ) ; export const metaSchema = { title : 'Lisk Codec Field Number' , type : 'number' , minimum : 1 , maximum : 18999 , } ; const deepValue = ( obj , path ) : any => { const parts = path . split ( '.' ) ; const len = parts . length ; let result = obj ; for ( let i = 0 ; i < len ; i += 1 ) { result = result [ parts [ i ] ] ; } return result ; } ; const compile = ( value , parentSchema , it ) : DataValidateFunction => { debug ( 'compile: schema: %i' , value ) ; debug ( 'compile: parent schema: %j' , parentSchema ) ; const { schemaPath , schemaEnv : { root : { schema : rootSchema } , } , } = it ; const parentPath = schemaPath . str . split ( '.' ) ; parentPath . shift ( ) ; parentPath . pop ( ) ; const parentSchemaObject = deepValue ( rootSchema , parentPath . join ( '.' ) ) ; const fieldNumbers = Object . keys ( parentSchemaObject ) . map ( ( key ) => parentSchemaObject [ key ] . fieldNumber ) ; const uniqueFieldNumbers = [ ... new Set ( fieldNumbers ) ] ; if ( fieldNumbers . length !== uniqueFieldNumbers . length ) { throw new LiskValidationError ( [ { keyword : 'fieldNumber' , message : 'Value must be unique across all properties on same level' , params : { fieldNumbers } , dataPath : '' , schemaPath : schemaPath . str , } , ] ) ; } return ( _data , _dataCxt ? ) : boolean => true ; } ; export const fieldNumberKeyword = { keyword : 'fieldNumber' , compile , valid : true , errors : false , modifying : false , metaSchema , } ;