import { first , last } from '@sap-cloud-sdk/util' ; import voca from 'voca' ; import { VdmActionImportReturnType , VdmComplexType , VdmEntity , VdmFunctionImportReturnType , VdmReturnTypeCategory , VdmUnsupportedReason } from '../../vdm-types' ; import { getTypeMappingActionFunction , isCollectionType , parseTypeName } from '../edmx-to-vdm-util' ; import { EdmxReturnType } from '../../edmx-parser/v4' ; import { isNullableProperty } from '../../generator-utils' ; import { getApiName } from '../../generator-without-ts-morph/service' ; internal export function parseFunctionImportReturnTypes ( returnType , entities , complexTypes , extractResponse , serviceName ) { return parseReturnTypes ( returnType , entities , complexTypes , extractResponse , serviceName ) as VdmFunctionImportReturnType ; } internal export function parseActionImportReturnTypes ( returnType , entities , complexTypes , extractResponse , serviceName ) { return parseReturnTypes ( returnType , entities , complexTypes , extractResponse , serviceName ) as VdmActionImportReturnType ; } function parseReturnTypes ( returnType , entities , complexTypes , extractResponse , serviceName ) { if ( ! returnType ) { return getVoidReturnType ( ) ; } const isCollection = isCollectionType ( returnType . Type ) ; const isNullable = typeof returnType === 'undefined' ? false : isNullableProperty ( returnType ) ; const edmType = findEdmType ( returnType . Type ) ; if ( edmType ) { return getEdmReturnType ( isCollection , isNullable , edmType , extractResponse ) ; } const filteredEntities = findEntityTypes ( returnType . Type , entities ) ; if ( filteredEntities . length ) { return getEntityReturnType ( isCollection , isNullable , filteredEntities , serviceName ) ; } const complexType = findComplexType ( returnType . Type , complexTypes ) ; if ( complexType ) { return getComplexReturnType ( isCollection , isNullable , complexType ) ; } throw Error ( `Unable to find a return type for name ${ returnType }.` ) ; } function findEdmType ( returnType ) { returnType = parseTypeName ( returnType ) ; if ( returnType . startsWith ( 'Edm.' ) ) { return returnType ; } } function findEntityTypes ( returnType , entities ) { returnType = parseTypeName ( returnType ) ; const entity = entities . filter ( e => `${ e . entityTypeNamespace }.${ e . entityTypeName }` === returnType ) ; if ( ! entity . length ) { const parsedReturnType = last ( returnType . split ( '.' ) ) ; return entities . filter ( e => e . entityTypeName === parsedReturnType ) ; } return entity ; } function findComplexType ( returnType , complexTypes ) { returnType = parseTypeName ( returnType ) ; const complexType = complexTypes . find ( e => `${ e . namespace }.${ e . originalName }` === returnType ) ; if ( ! complexType ) { const parsedReturnType = last ( returnType . split ( '.' ) ) ; return complexTypes . find ( c => c . originalName === parsedReturnType ) ; } return complexType ; } function getVoidReturnType ( ) { return { returnTypeCategory : VdmReturnTypeCategory . VOID , returnType : 'undefined' , builderFunction : '(val) => undefined' , isNullable : false , isCollection : false } ; } function getEdmReturnType ( isCollection , isNullable , edmType , extractResponse ) { const typeMapping = getTypeMappingActionFunction ( edmType ) ; const valueAlias = 'val' ; const extracted = isCollection ? valueAlias : extractResponse ( valueAlias ) ; return { returnTypeCategory : VdmReturnTypeCategory . EDM_TYPE , returnType : typeMapping . jsType , builderFunction : `(${ valueAlias }) => edmToTs(${ extracted }, '${ typeMapping . edmType }', deSerializers)` , isNullable , isCollection } ; } function getEntityReturnType ( isCollection , isNullable , entities , serviceName ) { if ( ! entities . length ) { throw Error ( 'Could not get entity return type for function import. No matching entity types found.' ) ; } return entities . length === 1 ? { returnTypeCategory : VdmReturnTypeCategory . ENTITY , returnType : first ( entities ) ! . className , builderFunction : `${ voca . decapitalize ( serviceName ) }(deSerializers).${ getApiName ( first ( entities ) ! . className ) }` , isNullable , isCollection } : { returnTypeCategory : VdmReturnTypeCategory . NEVER , returnType : 'never' , isNullable , isCollection , unsupportedReason : VdmUnsupportedReason . ENTITY_NOT_DESERIALIZABLE } ; } function getComplexReturnType ( isCollection , isNullable , complexType ) { return { returnTypeCategory : VdmReturnTypeCategory . COMPLEX_TYPE , returnType : complexType . typeName , builderFunction : `(data) => entityDeserializer(
          deSerializers
        ).deserializeComplexType(data, ${ complexType . typeName })` , isNullable , isCollection } ; } internal export function isEntityNotDeserializable ( returnType ) { return ( returnType . returnTypeCategory === VdmReturnTypeCategory . NEVER && returnType . unsupportedReason === VdmUnsupportedReason . ENTITY_NOT_DESERIALIZABLE ) ; } internal export type ExtractResponse = ( string ) => string ;