import assert from 'assert' ; import * as model from '../model/metamodel' ; import { JsonSpec } from '../model/json-spec' ; import chalk from 'chalk' ; /**
 * Verifies if "read" version of interface definitions
 * contains the same properties of their "write" version.
 * Then, it copies every model.Property from write to read but 'required'.
 */ export default async function readDefinitionValidation ( model , jsonSpec ) { for ( const type of model . types ) { if ( type . kind !== 'interface' ) continue ; const readBehavior = type . behaviors ?. find ( behavior => behavior . type . name === 'OverloadOf' ) ; if ( readBehavior == null ) continue ; assert ( Array . isArray ( readBehavior . generics ) ) ; assert ( readBehavior . generics [ 0 ] . kind === 'instance_of' ) ; for ( const parent of model . types ) { if ( parent . name . name === readBehavior . generics [ 0 ] . type . name && parent . name . namespace === readBehavior . generics [ 0 ] . type . namespace ) { assert ( parent . kind === 'interface' ) ; const readProperties = type . properties . map ( p => p . name ) ; for ( const property of parent . properties ) { if ( ! readProperties . includes ( property . name ) ) { console . log ( chalk . red `The property '${ property . name }' is present in ${ parent . name . namespace }.${ parent . name . name } but not in ${ type . name . namespace }.${ type . name . name }` ) ; process . exit ( 1 ) ; } const readProperty = type . properties . find ( p => p . name === property . name ) as model . Property ; if ( ! deepEqual ( readProperty . type , property . type ) ) { console . log ( chalk . red `The property '${ property . name }' present in ${ parent . name . namespace }.${ parent . name . name } does not have the same type in ${ type . name . namespace }.${ type . name . name }` ) ; process . exit ( 1 ) ; } for ( const key in property ) { if ( key === 'required' ) continue ; readProperty [ key ] = property [ key ] ; } } } } } return model ; } function deepEqual ( a , b ) { try { assert . deepStrictEqual ( a , b ) ; return true ; } catch ( err ) { return false ; } }