import { createLogger , ErrorWithCause } from '@sap-cloud-sdk/util' ; import { BatchResponse , ErrorResponse , ReadResponse , WriteResponse , WriteResponses } from '../../batch-response' ; import { DeSerializers } from '../../de-serializers' ; import { EntityApi , EntityBase } from '../../entity-base' ; import { EntityDeserializer } from '../../entity-deserializer' ; import { ResponseDataAccessor } from '../../response-data-accessor' ; import { ResponseData , isHttpSuccessCode } from './batch-response-parser' ; const logger = createLogger ( { package : 'odata-common' , messageContext : 'batch-response-transformer' } ) ; internal export class BatchResponseDeserializer < DeSerializersT extends DeSerializers > { param entityToApi param responseDataAccessor param deserializer constructor ( private readonly entityToApi , private readonly responseDataAccessor , private readonly deserializer ) { } param parsedBatchResponse returns deserializeBatchResponse ( parsedBatchResponse ) { return parsedBatchResponse . map ( responseData => { if ( Array . isArray ( responseData ) ) { return this . deserializeChangeSet ( responseData ) ; } return isHttpSuccessCode ( responseData . httpCode ) ? this . deserializeRetrieveResponse ( responseData ) : this . deserializeErrorResponse ( responseData ) ; } ) ; } private deserializeRetrieveResponse ( responseData ) { return { ... responseData , responseType : 'ReadResponse' , type : this . getApi ( responseData . body ) ! , as : asReadResponse ( responseData . body , this . responseDataAccessor , this . deserializer ) , isSuccess : ( ) => true , isError : ( ) => false , isReadResponse : ( ) => true , isWriteResponses : ( ) => false } ; } private deserializeErrorResponse ( responseData ) { return { ... responseData , responseType : 'ErrorResponse' , isSuccess : ( ) => false , isError : ( ) => true , isReadResponse : ( ) => false , isWriteResponses : ( ) => false } ; } private deserializeChangeSetSubResponse ( responseData ) { return { ... responseData , responseType : 'WriteResponse' , type : this . getApi ( responseData . body ) , as : asWriteResponse ( responseData . body , this . responseDataAccessor , this . deserializer ) } ; } private deserializeChangeSet ( changesetData ) { return { responses : changesetData . map ( subResponseData => this . deserializeChangeSetSubResponse ( subResponseData ) ) , isSuccess : ( ) => true , isError : ( ) => false , isReadResponse : ( ) => false , isWriteResponses : ( ) => true } ; } param responseBody returns private getApi ( responseBody ) { const entityJson = this . responseDataAccessor . isCollectionResult ( responseBody ) ? this . responseDataAccessor . getCollectionResult ( responseBody ) [ 0 ] : this . responseDataAccessor . getSingleResult ( responseBody ) ; const entityUri = entityJson ?. __metadata ?. uri ; if ( entityUri ) { return this . entityToApi [ parseEntityNameFromMetadataUri ( entityUri ) ] ; } logger . warn ( 'Could not parse constructor from response body.' ) ; } } param parsedBatchResponse param entityToApi param responseDataAccessor param deserializer returns internal export function deserializeBatchResponse < DeSerializersT extends DeSerializers > ( parsedBatchResponse , entityToApi , responseDataAccessor , deserializer ) { return new BatchResponseDeserializer ( entityToApi , responseDataAccessor , deserializer ) . deserializeBatchResponse ( parsedBatchResponse ) ; } param body param responseDataAccessor param deserializer returns function asReadResponse ( body , responseDataAccessor , deserializer ) { return < EntityT extends EntityBase , DeSerializersT extends DeSerializers > ( entityApi ) : EntityT [ ] => { if ( body . error ) { throw new ErrorWithCause ( 'Could not parse read response.' , body . error ) ; } if ( responseDataAccessor . isCollectionResult ( body ) ) { return responseDataAccessor . getCollectionResult ( body ) . map ( r => deserializer . deserializeEntity ( r , entityApi ) ) ; } return [ deserializer . deserializeEntity ( responseDataAccessor . getSingleResult ( body ) , entityApi ) ] ; } ; } param body param responseDataAccessor param deserializer returns function asWriteResponse ( body , responseDataAccessor , deserializer ) { return < EntityT extends EntityBase , DeSerializersT extends DeSerializers > ( entityApi ) => deserializer . deserializeEntity ( responseDataAccessor . getSingleResult ( body ) , entityApi ) ; } param uri returns internal export function parseEntityNameFromMetadataUri ( uri ) { if ( ! uri ) { throw new Error ( `Could not retrieve entity name from metadata. URI was: '${ uri }'.` ) ; } const [ pathBeforeQuery ] = uri . split ( '?' ) ; const [ pathBeforeKeys ] = pathBeforeQuery . split ( '(' ) ; const uriParts = pathBeforeKeys . split ( '/' ) ; const entityName = uriParts . pop ( ) || uriParts . pop ( ) ; if ( ! entityName ) { throw Error ( `Could not retrieve entity name from metadata. Unknown URI format. URI was: '${ uri }'.` ) ; } return entityName ; }