deserializationPolicy.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See License.txt in the project root for license information.
  3. import * as tslib_1 from "tslib";
  4. import { isStreamOperation } from "../operationSpec";
  5. import { RestError } from "../restError";
  6. import { MapperType } from "../serializer";
  7. import * as utils from "../util/utils";
  8. import { parseXML } from "../util/xml";
  9. import { BaseRequestPolicy } from "./requestPolicy";
  10. /**
  11. * Create a new serialization RequestPolicyCreator that will serialized HTTP request bodies as they
  12. * pass through the HTTP pipeline.
  13. */
  14. export function deserializationPolicy(deserializationContentTypes) {
  15. return {
  16. create: function (nextPolicy, options) {
  17. return new DeserializationPolicy(nextPolicy, deserializationContentTypes, options);
  18. }
  19. };
  20. }
  21. export var defaultJsonContentTypes = ["application/json", "text/json"];
  22. export var defaultXmlContentTypes = ["application/xml", "application/atom+xml"];
  23. /**
  24. * A RequestPolicy that will deserialize HTTP response bodies and headers as they pass through the
  25. * HTTP pipeline.
  26. */
  27. var DeserializationPolicy = /** @class */ (function (_super) {
  28. tslib_1.__extends(DeserializationPolicy, _super);
  29. function DeserializationPolicy(nextPolicy, deserializationContentTypes, options) {
  30. var _this = _super.call(this, nextPolicy, options) || this;
  31. _this.jsonContentTypes = deserializationContentTypes && deserializationContentTypes.json || defaultJsonContentTypes;
  32. _this.xmlContentTypes = deserializationContentTypes && deserializationContentTypes.xml || defaultXmlContentTypes;
  33. return _this;
  34. }
  35. DeserializationPolicy.prototype.sendRequest = function (request) {
  36. return tslib_1.__awaiter(this, void 0, void 0, function () {
  37. var _this = this;
  38. return tslib_1.__generator(this, function (_a) {
  39. return [2 /*return*/, this._nextPolicy.sendRequest(request).then(function (response) { return deserializeResponseBody(_this.jsonContentTypes, _this.xmlContentTypes, response); })];
  40. });
  41. });
  42. };
  43. return DeserializationPolicy;
  44. }(BaseRequestPolicy));
  45. export { DeserializationPolicy };
  46. function getOperationResponse(parsedResponse) {
  47. var result;
  48. var request = parsedResponse.request;
  49. var operationSpec = request.operationSpec;
  50. if (operationSpec) {
  51. var operationResponseGetter = request.operationResponseGetter;
  52. if (!operationResponseGetter) {
  53. result = operationSpec.responses[parsedResponse.status];
  54. }
  55. else {
  56. result = operationResponseGetter(operationSpec, parsedResponse);
  57. }
  58. }
  59. return result;
  60. }
  61. function shouldDeserializeResponse(parsedResponse) {
  62. var shouldDeserialize = parsedResponse.request.shouldDeserialize;
  63. var result;
  64. if (shouldDeserialize === undefined) {
  65. result = true;
  66. }
  67. else if (typeof shouldDeserialize === "boolean") {
  68. result = shouldDeserialize;
  69. }
  70. else {
  71. result = shouldDeserialize(parsedResponse);
  72. }
  73. return result;
  74. }
  75. export function deserializeResponseBody(jsonContentTypes, xmlContentTypes, response) {
  76. return parse(jsonContentTypes, xmlContentTypes, response).then(function (parsedResponse) {
  77. var shouldDeserialize = shouldDeserializeResponse(parsedResponse);
  78. if (shouldDeserialize) {
  79. var operationSpec = parsedResponse.request.operationSpec;
  80. if (operationSpec && operationSpec.responses) {
  81. var statusCode = parsedResponse.status;
  82. var expectedStatusCodes = Object.keys(operationSpec.responses);
  83. var hasNoExpectedStatusCodes = (expectedStatusCodes.length === 0 || (expectedStatusCodes.length === 1 && expectedStatusCodes[0] === "default"));
  84. var responseSpec = getOperationResponse(parsedResponse);
  85. var isExpectedStatusCode = hasNoExpectedStatusCodes ? (200 <= statusCode && statusCode < 300) : !!responseSpec;
  86. if (!isExpectedStatusCode) {
  87. var defaultResponseSpec = operationSpec.responses.default;
  88. if (defaultResponseSpec) {
  89. var initialErrorMessage = isStreamOperation(operationSpec)
  90. ? "Unexpected status code: " + statusCode
  91. : parsedResponse.bodyAsText;
  92. var error = new RestError(initialErrorMessage);
  93. error.statusCode = statusCode;
  94. error.request = utils.stripRequest(parsedResponse.request);
  95. error.response = utils.stripResponse(parsedResponse);
  96. var parsedErrorResponse = parsedResponse.parsedBody;
  97. try {
  98. if (parsedErrorResponse) {
  99. var defaultResponseBodyMapper = defaultResponseSpec.bodyMapper;
  100. if (defaultResponseBodyMapper && defaultResponseBodyMapper.serializedName === "CloudError") {
  101. if (parsedErrorResponse.error) {
  102. parsedErrorResponse = parsedErrorResponse.error;
  103. }
  104. if (parsedErrorResponse.code) {
  105. error.code = parsedErrorResponse.code;
  106. }
  107. if (parsedErrorResponse.message) {
  108. error.message = parsedErrorResponse.message;
  109. }
  110. }
  111. else {
  112. var internalError = parsedErrorResponse;
  113. if (parsedErrorResponse.error) {
  114. internalError = parsedErrorResponse.error;
  115. }
  116. error.code = internalError.code;
  117. if (internalError.message) {
  118. error.message = internalError.message;
  119. }
  120. }
  121. if (defaultResponseBodyMapper) {
  122. var valueToDeserialize = parsedErrorResponse;
  123. if (operationSpec.isXML && defaultResponseBodyMapper.type.name === MapperType.Sequence) {
  124. valueToDeserialize = typeof parsedErrorResponse === "object"
  125. ? parsedErrorResponse[defaultResponseBodyMapper.xmlElementName]
  126. : [];
  127. }
  128. error.body = operationSpec.serializer.deserialize(defaultResponseBodyMapper, valueToDeserialize, "error.body");
  129. }
  130. }
  131. }
  132. catch (defaultError) {
  133. error.message = "Error \"" + defaultError.message + "\" occurred in deserializing the responseBody - \"" + parsedResponse.bodyAsText + "\" for the default response.";
  134. }
  135. return Promise.reject(error);
  136. }
  137. }
  138. else if (responseSpec) {
  139. if (responseSpec.bodyMapper) {
  140. var valueToDeserialize = parsedResponse.parsedBody;
  141. if (operationSpec.isXML && responseSpec.bodyMapper.type.name === MapperType.Sequence) {
  142. valueToDeserialize = typeof valueToDeserialize === "object" ? valueToDeserialize[responseSpec.bodyMapper.xmlElementName] : [];
  143. }
  144. try {
  145. parsedResponse.parsedBody = operationSpec.serializer.deserialize(responseSpec.bodyMapper, valueToDeserialize, "operationRes.parsedBody");
  146. }
  147. catch (error) {
  148. var restError = new RestError("Error " + error + " occurred in deserializing the responseBody - " + parsedResponse.bodyAsText);
  149. restError.request = utils.stripRequest(parsedResponse.request);
  150. restError.response = utils.stripResponse(parsedResponse);
  151. return Promise.reject(restError);
  152. }
  153. }
  154. else if (operationSpec.httpMethod === "HEAD") {
  155. // head methods never have a body, but we return a boolean to indicate presence/absence of the resource
  156. parsedResponse.parsedBody = response.status >= 200 && response.status < 300;
  157. }
  158. if (responseSpec.headersMapper) {
  159. parsedResponse.parsedHeaders = operationSpec.serializer.deserialize(responseSpec.headersMapper, parsedResponse.headers.rawHeaders(), "operationRes.parsedHeaders");
  160. }
  161. }
  162. }
  163. }
  164. return Promise.resolve(parsedResponse);
  165. });
  166. }
  167. function parse(jsonContentTypes, xmlContentTypes, operationResponse) {
  168. var errorHandler = function (err) {
  169. var msg = "Error \"" + err + "\" occurred while parsing the response body - " + operationResponse.bodyAsText + ".";
  170. var errCode = err.code || RestError.PARSE_ERROR;
  171. var e = new RestError(msg, errCode, operationResponse.status, operationResponse.request, operationResponse, operationResponse.bodyAsText);
  172. return Promise.reject(e);
  173. };
  174. if (!operationResponse.request.streamResponseBody && operationResponse.bodyAsText) {
  175. var text_1 = operationResponse.bodyAsText;
  176. var contentType = operationResponse.headers.get("Content-Type") || "";
  177. var contentComponents = !contentType ? [] : contentType.split(";").map(function (component) { return component.toLowerCase(); });
  178. if (contentComponents.length === 0 || contentComponents.some(function (component) { return jsonContentTypes.indexOf(component) !== -1; })) {
  179. return new Promise(function (resolve) {
  180. operationResponse.parsedBody = JSON.parse(text_1);
  181. resolve(operationResponse);
  182. }).catch(errorHandler);
  183. }
  184. else if (contentComponents.some(function (component) { return xmlContentTypes.indexOf(component) !== -1; })) {
  185. return parseXML(text_1)
  186. .then(function (body) {
  187. operationResponse.parsedBody = body;
  188. return operationResponse;
  189. })
  190. .catch(errorHandler);
  191. }
  192. }
  193. return Promise.resolve(operationResponse);
  194. }
  195. //# sourceMappingURL=deserializationPolicy.js.map