@sap-cloud-sdk/odata-common
Version:
SAP Cloud SDK for JavaScript common functions of OData client generator and OpenAPI clint generator.
166 lines • 7.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BatchResponseDeserializer = void 0;
exports.deserializeBatchResponse = deserializeBatchResponse;
exports.parseEntityNameFromMetadataUri = parseEntityNameFromMetadataUri;
const util_1 = require("@sap-cloud-sdk/util");
const batch_response_parser_1 = require("./batch-response-parser");
const logger = (0, util_1.createLogger)({
package: 'odata-common',
messageContext: 'batch-response-transformer'
});
/**
* Represents the state needed to deserialize a parsed batch response using OData version specific deserialization data access.
* @internal
*/
class BatchResponseDeserializer {
/**
* Creates an instance of BatchResponseTransformer.
* @param entityToApi - A map that holds the entity type to constructor mapping.
* @param responseDataAccessor - Response data access module.
* @param deserializer - Entity deserializer.
*/
constructor(entityToApi, responseDataAccessor, deserializer) {
this.entityToApi = entityToApi;
this.responseDataAccessor = responseDataAccessor;
this.deserializer = deserializer;
}
/**
* Deserialize the parsed batch response.
* @param parsedBatchResponse - Two dimensional list of parsed batch sub responses.
* @returns An array of parsed sub responses of the batch response.
*/
deserializeBatchResponse(parsedBatchResponse) {
return parsedBatchResponse.map(responseData => {
if (Array.isArray(responseData)) {
return this.deserializeChangeSet(responseData);
}
return (0, batch_response_parser_1.isHttpSuccessCode)(responseData.httpCode)
? this.deserializeRetrieveResponse(responseData)
: this.deserializeErrorResponse(responseData);
});
}
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
};
}
deserializeErrorResponse(responseData) {
return {
...responseData,
responseType: 'ErrorResponse',
isSuccess: () => false,
isError: () => true,
isReadResponse: () => false,
isWriteResponses: () => false
};
}
deserializeChangeSetSubResponse(responseData) {
return {
...responseData,
responseType: 'WriteResponse',
type: this.getApi(responseData.body),
as: asWriteResponse(responseData.body, this.responseDataAccessor, this.deserializer)
};
}
deserializeChangeSet(changesetData) {
return {
responses: changesetData.map(subResponseData => this.deserializeChangeSetSubResponse(subResponseData)),
isSuccess: () => true,
isError: () => false,
isReadResponse: () => false,
isWriteResponses: () => true
};
}
/**
* Retrieve the constructor for a specific single response body.
* @param responseBody - The body of a single response as an object.
* @returns The constructor if found in the mapping, `undefined` otherwise.
*/
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.');
return undefined;
}
}
exports.BatchResponseDeserializer = BatchResponseDeserializer;
/**
* Deserialize the parsed batch response.
* @param parsedBatchResponse - Two dimensional list of parsed batch sub responses.
* @param entityToApi - A map that holds the entity type to constructor mapping.
* @param responseDataAccessor - Response data access module.
* @param deserializer - Entity deserializer.
* @returns An array of parsed sub responses of the batch response.
* @internal
*/
function deserializeBatchResponse(parsedBatchResponse, entityToApi, responseDataAccessor, deserializer) {
return new BatchResponseDeserializer(entityToApi, responseDataAccessor, deserializer).deserializeBatchResponse(parsedBatchResponse);
}
/**
* Create a function to transform the parsed response body to a list of entities of the given type or an error.
* @param body - The parsed JSON response body.
* @param responseDataAccessor - Response data access module.
* @param deserializer - Entity deserializer.
* @returns A function to be used for transformation of the read response.
*/
function asReadResponse(body, responseDataAccessor, deserializer) {
return (
// constructor: Constructable<EntityT>
entityApi) => {
if (body.error) {
throw new util_1.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)
];
};
}
/**
* Create a function to transform the parsed response body to an entity of the given type.
* @param body - The parsed JSON response body.
* @param responseDataAccessor - Response data access module.
* @param deserializer - Entity deserializer.
* @returns A function to be used for transformation of the write response.
*/
function asWriteResponse(body, responseDataAccessor, deserializer) {
return (entityApi) => deserializer.deserializeEntity(responseDataAccessor.getSingleResult(body), entityApi);
}
/**
* Parse the entity name from the metadata uri. This should be the `__metadata` property of a single entity in the response.
* @param uri - The URI to parse the entity name from
* @returns The entity name.
* @internal
*/
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('/');
// Remove another part in case of a trailing slash
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;
}
//# sourceMappingURL=batch-response-deserializer.js.map