import { ClassDeclarationStructure , PropertyDeclarationStructure , StructureKind } from 'ts-morph' ; import { prependPrefix } from '../internal-prefix' ; import { getEntityDescription , getNavPropertyDescription , getPropertyDescription , addLeadingNewline } from '../typedoc' ; import { VdmEntity , VdmNavigationProperty , VdmProperty , VdmServiceMetadata } from '../vdm-types' ; internal export function entityClass ( entity , service ) { return { kind : StructureKind . Class , name : `${ entity . className }<T extends DeSerializers = DefaultDeSerializers>` , extends : 'Entity' , implements : [ `${ entity . className }Type<T>` ] , properties : [ ... staticProperties ( entity , service ) , ... properties ( entity ) , ... navProperties ( entity , service ) ] , isExported : true , docs : [ addLeadingNewline ( getEntityDescription ( entity , service ) ) ] } ; } function staticProperties ( entity , service ) { return [ entityName ( entity ) , defaultServicePath ( service ) , keys ( entity ) ] ; } function entityName ( entity ) { return { kind : StructureKind . Property , name : prependPrefix ( 'entityName' ) , isStatic : true , initializer : `'${ entity . entitySetName }'` , docs : [ addLeadingNewline ( `Technical entity name for ${ entity . className }.` ) ] } ; } function defaultServicePath ( service ) { return { kind : StructureKind . Property , name : prependPrefix ( 'defaultServicePath' ) , isStatic : true , initializer : `'${ service . servicePath }'` , docs : [ addLeadingNewline ( 'Default url path for the according service.' ) ] } ; } function keys ( entity ) { return { kind : StructureKind . Property , name : prependPrefix ( 'keys' ) , isStatic : true , initializer : `[${ entity . keys . map ( key => `'${ key . originalName }'` ) . join ( ',' ) }]` , docs : [ addLeadingNewline ( `All key fields of the ${ entity . className } entity` ) ] } ; } function properties ( entity ) { return entity . properties . map ( prop => property ( prop ) ) ; } function property ( prop ) { return { kind : StructureKind . Property , name : prop . instancePropertyName + ( prop . nullable ? '?' : '!' ) , type : getPropertyType ( prop ) , docs : [ addLeadingNewline ( getPropertyDescription ( prop , { nullable : prop . nullable , maxLength : prop . maxLength } ) ) ] } ; } internal param prop returns export function getPropertyType ( prop ) { if ( prop . isCollection ) { if ( prop . isComplex ) { return `${ prop . jsType }<T>[]` + getNullableSuffix ( prop ) ; } if ( prop . isEnum ) { return `${ prop . jsType }[]` + getNullableSuffix ( prop ) ; } return `DeserializedType<T, '${ prop . edmType }'>[]` + getNullableSuffix ( prop ) ; } if ( prop . isComplex ) { return `${ prop . jsType }<T>` + getNullableSuffix ( prop ) ; } if ( prop . isEnum ) { return `${ prop . jsType }` + getNullableSuffix ( prop ) ; } return `DeserializedType<T, '${ prop . edmType }'>` + getNullableSuffix ( prop ) ; } function getNullableSuffix ( prop ) { return prop . nullable ? ' | null' : '' ; } function navProperties ( entity , service ) { return entity . navigationProperties . map ( navProp => navProperty ( navProp , service ) ) ; } function navProperty ( navProp , service ) { const entity = service . entities . find ( e => e . entitySetName === navProp . to ) ; if ( ! entity ) { throw Error ( `Failed to find the entity from the service: ${ JSON . stringify ( service ) } for nav property ${ navProp }` ) ; } return { kind : StructureKind . Property , name : navProp . instancePropertyName + ( navProp . isCollection ? '!' : '?' ) , type : entity . className + '<T>' + ( navProp . isCollection ? '[]' : ' | null' ) , docs : [ addLeadingNewline ( getNavPropertyDescription ( navProp ) ) ] } ; }