serializer.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  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 base64 from "./util/base64";
  4. import * as utils from "./util/utils";
  5. var Serializer = /** @class */ (function () {
  6. function Serializer(modelMappers, isXML) {
  7. if (modelMappers === void 0) { modelMappers = {}; }
  8. this.modelMappers = modelMappers;
  9. this.isXML = isXML;
  10. }
  11. Serializer.prototype.validateConstraints = function (mapper, value, objectName) {
  12. var failValidation = function (constraintName, constraintValue) {
  13. throw new Error("\"" + objectName + "\" with value \"" + value + "\" should satisfy the constraint \"" + constraintName + "\": " + constraintValue + ".");
  14. };
  15. if (mapper.constraints && (value != undefined)) {
  16. var _a = mapper.constraints, ExclusiveMaximum = _a.ExclusiveMaximum, ExclusiveMinimum = _a.ExclusiveMinimum, InclusiveMaximum = _a.InclusiveMaximum, InclusiveMinimum = _a.InclusiveMinimum, MaxItems = _a.MaxItems, MaxLength = _a.MaxLength, MinItems = _a.MinItems, MinLength = _a.MinLength, MultipleOf = _a.MultipleOf, Pattern = _a.Pattern, UniqueItems = _a.UniqueItems;
  17. if (ExclusiveMaximum != undefined && value >= ExclusiveMaximum) {
  18. failValidation("ExclusiveMaximum", ExclusiveMaximum);
  19. }
  20. if (ExclusiveMinimum != undefined && value <= ExclusiveMinimum) {
  21. failValidation("ExclusiveMinimum", ExclusiveMinimum);
  22. }
  23. if (InclusiveMaximum != undefined && value > InclusiveMaximum) {
  24. failValidation("InclusiveMaximum", InclusiveMaximum);
  25. }
  26. if (InclusiveMinimum != undefined && value < InclusiveMinimum) {
  27. failValidation("InclusiveMinimum", InclusiveMinimum);
  28. }
  29. if (MaxItems != undefined && value.length > MaxItems) {
  30. failValidation("MaxItems", MaxItems);
  31. }
  32. if (MaxLength != undefined && value.length > MaxLength) {
  33. failValidation("MaxLength", MaxLength);
  34. }
  35. if (MinItems != undefined && value.length < MinItems) {
  36. failValidation("MinItems", MinItems);
  37. }
  38. if (MinLength != undefined && value.length < MinLength) {
  39. failValidation("MinLength", MinLength);
  40. }
  41. if (MultipleOf != undefined && value % MultipleOf !== 0) {
  42. failValidation("MultipleOf", MultipleOf);
  43. }
  44. if (Pattern && value.match(Pattern) === null) {
  45. failValidation("Pattern", Pattern);
  46. }
  47. if (UniqueItems && value.some(function (item, i, ar) { return ar.indexOf(item) !== i; })) {
  48. failValidation("UniqueItems", UniqueItems);
  49. }
  50. }
  51. };
  52. /**
  53. * Serialize the given object based on its metadata defined in the mapper
  54. *
  55. * @param {Mapper} mapper The mapper which defines the metadata of the serializable object
  56. *
  57. * @param {object|string|Array|number|boolean|Date|stream} object A valid Javascript object to be serialized
  58. *
  59. * @param {string} objectName Name of the serialized object
  60. *
  61. * @returns {object|string|Array|number|boolean|Date|stream} A valid serialized Javascript object
  62. */
  63. Serializer.prototype.serialize = function (mapper, object, objectName) {
  64. var payload = {};
  65. var mapperType = mapper.type.name;
  66. if (!objectName) {
  67. objectName = mapper.serializedName;
  68. }
  69. if (mapperType.match(/^Sequence$/ig) !== null) {
  70. payload = [];
  71. }
  72. if (object == undefined && (mapper.defaultValue != undefined || mapper.isConstant)) {
  73. object = mapper.defaultValue;
  74. }
  75. // This table of allowed values should help explain
  76. // the mapper.required and mapper.nullable properties.
  77. // X means "neither undefined or null are allowed".
  78. // || required
  79. // || true | false
  80. // nullable || ==========================
  81. // true || null | undefined/null
  82. // false || X | undefined
  83. // undefined || X | undefined/null
  84. var required = mapper.required, nullable = mapper.nullable;
  85. if (required && nullable && object === undefined) {
  86. throw new Error(objectName + " cannot be undefined.");
  87. }
  88. if (required && !nullable && object == undefined) {
  89. throw new Error(objectName + " cannot be null or undefined.");
  90. }
  91. if (!required && nullable === false && object === null) {
  92. throw new Error(objectName + " cannot be null.");
  93. }
  94. if (object == undefined) {
  95. payload = object;
  96. }
  97. else {
  98. // Validate Constraints if any
  99. this.validateConstraints(mapper, object, objectName);
  100. if (mapperType.match(/^any$/ig) !== null) {
  101. payload = object;
  102. }
  103. else if (mapperType.match(/^(Number|String|Boolean|Object|Stream|Uuid)$/ig) !== null) {
  104. payload = serializeBasicTypes(mapperType, objectName, object);
  105. }
  106. else if (mapperType.match(/^Enum$/ig) !== null) {
  107. var enumMapper = mapper;
  108. payload = serializeEnumType(objectName, enumMapper.type.allowedValues, object);
  109. }
  110. else if (mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123|UnixTime)$/ig) !== null) {
  111. payload = serializeDateTypes(mapperType, object, objectName);
  112. }
  113. else if (mapperType.match(/^ByteArray$/ig) !== null) {
  114. payload = serializeByteArrayType(objectName, object);
  115. }
  116. else if (mapperType.match(/^Base64Url$/ig) !== null) {
  117. payload = serializeBase64UrlType(objectName, object);
  118. }
  119. else if (mapperType.match(/^Sequence$/ig) !== null) {
  120. payload = serializeSequenceType(this, mapper, object, objectName);
  121. }
  122. else if (mapperType.match(/^Dictionary$/ig) !== null) {
  123. payload = serializeDictionaryType(this, mapper, object, objectName);
  124. }
  125. else if (mapperType.match(/^Composite$/ig) !== null) {
  126. payload = serializeCompositeType(this, mapper, object, objectName);
  127. }
  128. }
  129. return payload;
  130. };
  131. /**
  132. * Deserialize the given object based on its metadata defined in the mapper
  133. *
  134. * @param {object} mapper The mapper which defines the metadata of the serializable object
  135. *
  136. * @param {object|string|Array|number|boolean|Date|stream} responseBody A valid Javascript entity to be deserialized
  137. *
  138. * @param {string} objectName Name of the deserialized object
  139. *
  140. * @returns {object|string|Array|number|boolean|Date|stream} A valid deserialized Javascript object
  141. */
  142. Serializer.prototype.deserialize = function (mapper, responseBody, objectName) {
  143. if (responseBody == undefined) {
  144. if (this.isXML && mapper.type.name === "Sequence" && !mapper.xmlIsWrapped) {
  145. // Edge case for empty XML non-wrapped lists. xml2js can't distinguish
  146. // between the list being empty versus being missing,
  147. // so let's do the more user-friendly thing and return an empty list.
  148. responseBody = [];
  149. }
  150. return responseBody;
  151. }
  152. var payload;
  153. var mapperType = mapper.type.name;
  154. if (!objectName) {
  155. objectName = mapper.serializedName;
  156. }
  157. if (mapperType.match(/^Composite$/ig) !== null) {
  158. payload = deserializeCompositeType(this, mapper, responseBody, objectName);
  159. }
  160. else {
  161. if (this.isXML) {
  162. /**
  163. * If the mapper specifies this as a non-composite type value but the responseBody contains
  164. * both header ("$") and body ("_") properties, then just reduce the responseBody value to
  165. * the body ("_") property.
  166. */
  167. if (responseBody["$"] != undefined && responseBody["_"] != undefined) {
  168. responseBody = responseBody["_"];
  169. }
  170. }
  171. if (mapperType.match(/^Number$/ig) !== null) {
  172. payload = parseFloat(responseBody);
  173. if (isNaN(payload)) {
  174. payload = responseBody;
  175. }
  176. }
  177. else if (mapperType.match(/^Boolean$/ig) !== null) {
  178. if (responseBody === "true") {
  179. payload = true;
  180. }
  181. else if (responseBody === "false") {
  182. payload = false;
  183. }
  184. else {
  185. payload = responseBody;
  186. }
  187. }
  188. else if (mapperType.match(/^(String|Enum|Object|Stream|Uuid|TimeSpan|any)$/ig) !== null) {
  189. payload = responseBody;
  190. }
  191. else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/ig) !== null) {
  192. payload = new Date(responseBody);
  193. }
  194. else if (mapperType.match(/^UnixTime$/ig) !== null) {
  195. payload = unixTimeToDate(responseBody);
  196. }
  197. else if (mapperType.match(/^ByteArray$/ig) !== null) {
  198. payload = base64.decodeString(responseBody);
  199. }
  200. else if (mapperType.match(/^Base64Url$/ig) !== null) {
  201. payload = base64UrlToByteArray(responseBody);
  202. }
  203. else if (mapperType.match(/^Sequence$/ig) !== null) {
  204. payload = deserializeSequenceType(this, mapper, responseBody, objectName);
  205. }
  206. else if (mapperType.match(/^Dictionary$/ig) !== null) {
  207. payload = deserializeDictionaryType(this, mapper, responseBody, objectName);
  208. }
  209. }
  210. if (mapper.isConstant) {
  211. payload = mapper.defaultValue;
  212. }
  213. return payload;
  214. };
  215. return Serializer;
  216. }());
  217. export { Serializer };
  218. function trimEnd(str, ch) {
  219. var len = str.length;
  220. while ((len - 1) >= 0 && str[len - 1] === ch) {
  221. --len;
  222. }
  223. return str.substr(0, len);
  224. }
  225. function bufferToBase64Url(buffer) {
  226. if (!buffer) {
  227. return undefined;
  228. }
  229. if (!(buffer instanceof Uint8Array)) {
  230. throw new Error("Please provide an input of type Uint8Array for converting to Base64Url.");
  231. }
  232. // Uint8Array to Base64.
  233. var str = base64.encodeByteArray(buffer);
  234. // Base64 to Base64Url.
  235. return trimEnd(str, "=").replace(/\+/g, "-").replace(/\//g, "_");
  236. }
  237. function base64UrlToByteArray(str) {
  238. if (!str) {
  239. return undefined;
  240. }
  241. if (str && typeof str.valueOf() !== "string") {
  242. throw new Error("Please provide an input of type string for converting to Uint8Array");
  243. }
  244. // Base64Url to Base64.
  245. str = str.replace(/\-/g, "+").replace(/\_/g, "/");
  246. // Base64 to Uint8Array.
  247. return base64.decodeString(str);
  248. }
  249. function splitSerializeName(prop) {
  250. var classes = [];
  251. var partialclass = "";
  252. if (prop) {
  253. var subwords = prop.split(".");
  254. for (var _i = 0, subwords_1 = subwords; _i < subwords_1.length; _i++) {
  255. var item = subwords_1[_i];
  256. if (item.charAt(item.length - 1) === "\\") {
  257. partialclass += item.substr(0, item.length - 1) + ".";
  258. }
  259. else {
  260. partialclass += item;
  261. classes.push(partialclass);
  262. partialclass = "";
  263. }
  264. }
  265. }
  266. return classes;
  267. }
  268. function dateToUnixTime(d) {
  269. if (!d) {
  270. return undefined;
  271. }
  272. if (typeof d.valueOf() === "string") {
  273. d = new Date(d);
  274. }
  275. return Math.floor(d.getTime() / 1000);
  276. }
  277. function unixTimeToDate(n) {
  278. if (!n) {
  279. return undefined;
  280. }
  281. return new Date(n * 1000);
  282. }
  283. function serializeBasicTypes(typeName, objectName, value) {
  284. if (value !== null && value !== undefined) {
  285. if (typeName.match(/^Number$/ig) !== null) {
  286. if (typeof value !== "number") {
  287. throw new Error(objectName + " with value " + value + " must be of type number.");
  288. }
  289. }
  290. else if (typeName.match(/^String$/ig) !== null) {
  291. if (typeof value.valueOf() !== "string") {
  292. throw new Error(objectName + " with value \"" + value + "\" must be of type string.");
  293. }
  294. }
  295. else if (typeName.match(/^Uuid$/ig) !== null) {
  296. if (!(typeof value.valueOf() === "string" && utils.isValidUuid(value))) {
  297. throw new Error(objectName + " with value \"" + value + "\" must be of type string and a valid uuid.");
  298. }
  299. }
  300. else if (typeName.match(/^Boolean$/ig) !== null) {
  301. if (typeof value !== "boolean") {
  302. throw new Error(objectName + " with value " + value + " must be of type boolean.");
  303. }
  304. }
  305. else if (typeName.match(/^Stream$/ig) !== null) {
  306. var objectType = typeof value;
  307. if (objectType !== "string" &&
  308. objectType !== "function" &&
  309. !(value instanceof ArrayBuffer) &&
  310. !ArrayBuffer.isView(value) &&
  311. !(typeof Blob === "function" && value instanceof Blob)) {
  312. throw new Error(objectName + " must be a string, Blob, ArrayBuffer, ArrayBufferView, or a function returning NodeJS.ReadableStream.");
  313. }
  314. }
  315. }
  316. return value;
  317. }
  318. function serializeEnumType(objectName, allowedValues, value) {
  319. if (!allowedValues) {
  320. throw new Error("Please provide a set of allowedValues to validate " + objectName + " as an Enum Type.");
  321. }
  322. var isPresent = allowedValues.some(function (item) {
  323. if (typeof item.valueOf() === "string") {
  324. return item.toLowerCase() === value.toLowerCase();
  325. }
  326. return item === value;
  327. });
  328. if (!isPresent) {
  329. throw new Error(value + " is not a valid value for " + objectName + ". The valid values are: " + JSON.stringify(allowedValues) + ".");
  330. }
  331. return value;
  332. }
  333. function serializeByteArrayType(objectName, value) {
  334. if (value != undefined) {
  335. if (!(value instanceof Uint8Array)) {
  336. throw new Error(objectName + " must be of type Uint8Array.");
  337. }
  338. value = base64.encodeByteArray(value);
  339. }
  340. return value;
  341. }
  342. function serializeBase64UrlType(objectName, value) {
  343. if (value != undefined) {
  344. if (!(value instanceof Uint8Array)) {
  345. throw new Error(objectName + " must be of type Uint8Array.");
  346. }
  347. value = bufferToBase64Url(value);
  348. }
  349. return value;
  350. }
  351. function serializeDateTypes(typeName, value, objectName) {
  352. if (value != undefined) {
  353. if (typeName.match(/^Date$/ig) !== null) {
  354. if (!(value instanceof Date ||
  355. (typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
  356. throw new Error(objectName + " must be an instanceof Date or a string in ISO8601 format.");
  357. }
  358. value = (value instanceof Date) ? value.toISOString().substring(0, 10) : new Date(value).toISOString().substring(0, 10);
  359. }
  360. else if (typeName.match(/^DateTime$/ig) !== null) {
  361. if (!(value instanceof Date ||
  362. (typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
  363. throw new Error(objectName + " must be an instanceof Date or a string in ISO8601 format.");
  364. }
  365. value = (value instanceof Date) ? value.toISOString() : new Date(value).toISOString();
  366. }
  367. else if (typeName.match(/^DateTimeRfc1123$/ig) !== null) {
  368. if (!(value instanceof Date ||
  369. (typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
  370. throw new Error(objectName + " must be an instanceof Date or a string in RFC-1123 format.");
  371. }
  372. value = (value instanceof Date) ? value.toUTCString() : new Date(value).toUTCString();
  373. }
  374. else if (typeName.match(/^UnixTime$/ig) !== null) {
  375. if (!(value instanceof Date ||
  376. (typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
  377. throw new Error(objectName + " must be an instanceof Date or a string in RFC-1123/ISO8601 format " +
  378. "for it to be serialized in UnixTime/Epoch format.");
  379. }
  380. value = dateToUnixTime(value);
  381. }
  382. else if (typeName.match(/^TimeSpan$/ig) !== null) {
  383. if (!utils.isDuration(value)) {
  384. throw new Error(objectName + " must be a string in ISO 8601 format. Instead was \"" + value + "\".");
  385. }
  386. value = value;
  387. }
  388. }
  389. return value;
  390. }
  391. function serializeSequenceType(serializer, mapper, object, objectName) {
  392. if (!Array.isArray(object)) {
  393. throw new Error(objectName + " must be of type Array.");
  394. }
  395. var elementType = mapper.type.element;
  396. if (!elementType || typeof elementType !== "object") {
  397. throw new Error("element\" metadata for an Array must be defined in the " +
  398. ("mapper and it must of type \"object\" in " + objectName + "."));
  399. }
  400. var tempArray = [];
  401. for (var i = 0; i < object.length; i++) {
  402. tempArray[i] = serializer.serialize(elementType, object[i], objectName);
  403. }
  404. return tempArray;
  405. }
  406. function serializeDictionaryType(serializer, mapper, object, objectName) {
  407. if (typeof object !== "object") {
  408. throw new Error(objectName + " must be of type object.");
  409. }
  410. var valueType = mapper.type.value;
  411. if (!valueType || typeof valueType !== "object") {
  412. throw new Error("\"value\" metadata for a Dictionary must be defined in the " +
  413. ("mapper and it must of type \"object\" in " + objectName + "."));
  414. }
  415. var tempDictionary = {};
  416. for (var _i = 0, _a = Object.keys(object); _i < _a.length; _i++) {
  417. var key = _a[_i];
  418. tempDictionary[key] = serializer.serialize(valueType, object[key], objectName + "." + key);
  419. }
  420. return tempDictionary;
  421. }
  422. /**
  423. * Resolves a composite mapper's modelProperties.
  424. * @param serializer the serializer containing the entire set of mappers
  425. * @param mapper the composite mapper to resolve
  426. */
  427. function resolveModelProperties(serializer, mapper, objectName) {
  428. var modelProps = mapper.type.modelProperties;
  429. if (!modelProps) {
  430. var className = mapper.type.className;
  431. if (!className) {
  432. throw new Error("Class name for model \"" + objectName + "\" is not provided in the mapper \"" + JSON.stringify(mapper, undefined, 2) + "\".");
  433. }
  434. var modelMapper = serializer.modelMappers[className];
  435. if (!modelMapper) {
  436. throw new Error("mapper() cannot be null or undefined for model \"" + className + "\".");
  437. }
  438. modelProps = modelMapper.type.modelProperties;
  439. if (!modelProps) {
  440. throw new Error("modelProperties cannot be null or undefined in the " +
  441. ("mapper \"" + JSON.stringify(modelMapper) + "\" of type \"" + className + "\" for object \"" + objectName + "\"."));
  442. }
  443. }
  444. return modelProps;
  445. }
  446. function serializeCompositeType(serializer, mapper, object, objectName) {
  447. var _a;
  448. if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) {
  449. mapper = getPolymorphicMapper(serializer, mapper, object, "clientName");
  450. }
  451. if (object != undefined) {
  452. var payload = {};
  453. var modelProps = resolveModelProperties(serializer, mapper, objectName);
  454. for (var _i = 0, _b = Object.keys(modelProps); _i < _b.length; _i++) {
  455. var key = _b[_i];
  456. var propertyMapper = modelProps[key];
  457. if (propertyMapper.readOnly) {
  458. continue;
  459. }
  460. var propName = void 0;
  461. var parentObject = payload;
  462. if (serializer.isXML) {
  463. if (propertyMapper.xmlIsWrapped) {
  464. propName = propertyMapper.xmlName;
  465. }
  466. else {
  467. propName = propertyMapper.xmlElementName || propertyMapper.xmlName;
  468. }
  469. }
  470. else {
  471. var paths = splitSerializeName(propertyMapper.serializedName);
  472. propName = paths.pop();
  473. for (var _c = 0, paths_1 = paths; _c < paths_1.length; _c++) {
  474. var pathName = paths_1[_c];
  475. var childObject = parentObject[pathName];
  476. if ((childObject == undefined) && (object[key] != undefined)) {
  477. parentObject[pathName] = {};
  478. }
  479. parentObject = parentObject[pathName];
  480. }
  481. }
  482. if (parentObject != undefined) {
  483. var propertyObjectName = propertyMapper.serializedName !== ""
  484. ? objectName + "." + propertyMapper.serializedName
  485. : objectName;
  486. var toSerialize = object[key];
  487. var polymorphicDiscriminator = getPolymorphicDiscriminatorRecursively(serializer, mapper);
  488. if (polymorphicDiscriminator && polymorphicDiscriminator.clientName === key && toSerialize == undefined) {
  489. toSerialize = mapper.serializedName;
  490. }
  491. var serializedValue = serializer.serialize(propertyMapper, toSerialize, propertyObjectName);
  492. if (serializedValue !== undefined && propName != undefined) {
  493. if (propertyMapper.xmlIsAttribute) {
  494. // $ is the key attributes are kept under in xml2js.
  495. // This keeps things simple while preventing name collision
  496. // with names in user documents.
  497. parentObject.$ = parentObject.$ || {};
  498. parentObject.$[propName] = serializedValue;
  499. }
  500. else if (propertyMapper.xmlIsWrapped) {
  501. parentObject[propName] = (_a = {}, _a[propertyMapper.xmlElementName] = serializedValue, _a);
  502. }
  503. else {
  504. parentObject[propName] = serializedValue;
  505. }
  506. }
  507. }
  508. }
  509. var additionalPropertiesMapper = mapper.type.additionalProperties;
  510. if (additionalPropertiesMapper) {
  511. var propNames = Object.keys(modelProps);
  512. var _loop_1 = function (clientPropName) {
  513. var isAdditionalProperty = propNames.every(function (pn) { return pn !== clientPropName; });
  514. if (isAdditionalProperty) {
  515. payload[clientPropName] = serializer.serialize(additionalPropertiesMapper, object[clientPropName], objectName + '["' + clientPropName + '"]');
  516. }
  517. };
  518. for (var clientPropName in object) {
  519. _loop_1(clientPropName);
  520. }
  521. }
  522. return payload;
  523. }
  524. return object;
  525. }
  526. function isSpecialXmlProperty(propertyName) {
  527. return ["$", "_"].includes(propertyName);
  528. }
  529. function deserializeCompositeType(serializer, mapper, responseBody, objectName) {
  530. if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) {
  531. mapper = getPolymorphicMapper(serializer, mapper, responseBody, "serializedName");
  532. }
  533. var modelProps = resolveModelProperties(serializer, mapper, objectName);
  534. var instance = {};
  535. var handledPropertyNames = [];
  536. for (var _i = 0, _a = Object.keys(modelProps); _i < _a.length; _i++) {
  537. var key = _a[_i];
  538. var propertyMapper = modelProps[key];
  539. var paths = splitSerializeName(modelProps[key].serializedName);
  540. handledPropertyNames.push(paths[0]);
  541. var serializedName = propertyMapper.serializedName, xmlName = propertyMapper.xmlName, xmlElementName = propertyMapper.xmlElementName;
  542. var propertyObjectName = objectName;
  543. if (serializedName !== "" && serializedName !== undefined) {
  544. propertyObjectName = objectName + "." + serializedName;
  545. }
  546. var headerCollectionPrefix = propertyMapper.headerCollectionPrefix;
  547. if (headerCollectionPrefix) {
  548. var dictionary = {};
  549. for (var _b = 0, _c = Object.keys(responseBody); _b < _c.length; _b++) {
  550. var headerKey = _c[_b];
  551. if (headerKey.startsWith(headerCollectionPrefix)) {
  552. dictionary[headerKey.substring(headerCollectionPrefix.length)] = serializer.deserialize(propertyMapper.type.value, responseBody[headerKey], propertyObjectName);
  553. }
  554. handledPropertyNames.push(headerKey);
  555. }
  556. instance[key] = dictionary;
  557. }
  558. else if (serializer.isXML) {
  559. if (propertyMapper.xmlIsAttribute && responseBody.$) {
  560. instance[key] = serializer.deserialize(propertyMapper, responseBody.$[xmlName], propertyObjectName);
  561. }
  562. else {
  563. var propertyName = xmlElementName || xmlName || serializedName;
  564. var unwrappedProperty = responseBody[propertyName];
  565. if (propertyMapper.xmlIsWrapped) {
  566. unwrappedProperty = responseBody[xmlName];
  567. unwrappedProperty = unwrappedProperty && unwrappedProperty[xmlElementName];
  568. var isEmptyWrappedList = unwrappedProperty === undefined;
  569. if (isEmptyWrappedList) {
  570. unwrappedProperty = [];
  571. }
  572. }
  573. instance[key] = serializer.deserialize(propertyMapper, unwrappedProperty, propertyObjectName);
  574. }
  575. }
  576. else {
  577. // deserialize the property if it is present in the provided responseBody instance
  578. var propertyInstance = void 0;
  579. var res = responseBody;
  580. // traversing the object step by step.
  581. for (var _d = 0, paths_2 = paths; _d < paths_2.length; _d++) {
  582. var item = paths_2[_d];
  583. if (!res)
  584. break;
  585. res = res[item];
  586. }
  587. propertyInstance = res;
  588. var polymorphicDiscriminator = mapper.type.polymorphicDiscriminator;
  589. if (polymorphicDiscriminator && propertyMapper.serializedName === polymorphicDiscriminator.serializedName && propertyInstance == undefined) {
  590. propertyInstance = mapper.serializedName;
  591. }
  592. var serializedValue = void 0;
  593. // paging
  594. if (Array.isArray(responseBody[key]) && modelProps[key].serializedName === "") {
  595. propertyInstance = responseBody[key];
  596. instance = serializer.deserialize(propertyMapper, propertyInstance, propertyObjectName);
  597. }
  598. else if (propertyInstance !== undefined) {
  599. serializedValue = serializer.deserialize(propertyMapper, propertyInstance, propertyObjectName);
  600. instance[key] = serializedValue;
  601. }
  602. }
  603. }
  604. var additionalPropertiesMapper = mapper.type.additionalProperties;
  605. if (additionalPropertiesMapper) {
  606. var isAdditionalProperty = function (responsePropName) {
  607. for (var clientPropName in modelProps) {
  608. var paths = splitSerializeName(modelProps[clientPropName].serializedName);
  609. if (paths[0] === responsePropName) {
  610. return false;
  611. }
  612. }
  613. return true;
  614. };
  615. for (var responsePropName in responseBody) {
  616. if (isAdditionalProperty(responsePropName)) {
  617. instance[responsePropName] = serializer.deserialize(additionalPropertiesMapper, responseBody[responsePropName], objectName + '["' + responsePropName + '"]');
  618. }
  619. }
  620. }
  621. else if (responseBody) {
  622. for (var _e = 0, _f = Object.keys(responseBody); _e < _f.length; _e++) {
  623. var key = _f[_e];
  624. if (instance[key] === undefined && !handledPropertyNames.includes(key) && !isSpecialXmlProperty(key)) {
  625. instance[key] = responseBody[key];
  626. }
  627. }
  628. }
  629. return instance;
  630. }
  631. function deserializeDictionaryType(serializer, mapper, responseBody, objectName) {
  632. /*jshint validthis: true */
  633. var value = mapper.type.value;
  634. if (!value || typeof value !== "object") {
  635. throw new Error("\"value\" metadata for a Dictionary must be defined in the " +
  636. ("mapper and it must of type \"object\" in " + objectName));
  637. }
  638. if (responseBody) {
  639. var tempDictionary = {};
  640. for (var _i = 0, _a = Object.keys(responseBody); _i < _a.length; _i++) {
  641. var key = _a[_i];
  642. tempDictionary[key] = serializer.deserialize(value, responseBody[key], objectName);
  643. }
  644. return tempDictionary;
  645. }
  646. return responseBody;
  647. }
  648. function deserializeSequenceType(serializer, mapper, responseBody, objectName) {
  649. /*jshint validthis: true */
  650. var element = mapper.type.element;
  651. if (!element || typeof element !== "object") {
  652. throw new Error("element\" metadata for an Array must be defined in the " +
  653. ("mapper and it must of type \"object\" in " + objectName));
  654. }
  655. if (responseBody) {
  656. if (!Array.isArray(responseBody)) {
  657. // xml2js will interpret a single element array as just the element, so force it to be an array
  658. responseBody = [responseBody];
  659. }
  660. var tempArray = [];
  661. for (var i = 0; i < responseBody.length; i++) {
  662. tempArray[i] = serializer.deserialize(element, responseBody[i], objectName + "[" + i + "]");
  663. }
  664. return tempArray;
  665. }
  666. return responseBody;
  667. }
  668. function getPolymorphicMapper(serializer, mapper, object, polymorphicPropertyName) {
  669. var polymorphicDiscriminator = getPolymorphicDiscriminatorRecursively(serializer, mapper);
  670. if (polymorphicDiscriminator) {
  671. var discriminatorName = polymorphicDiscriminator[polymorphicPropertyName];
  672. if (discriminatorName != undefined) {
  673. var discriminatorValue = object[discriminatorName];
  674. if (discriminatorValue != undefined) {
  675. var typeName = mapper.type.uberParent || mapper.type.className;
  676. var indexDiscriminator = discriminatorValue === typeName
  677. ? discriminatorValue
  678. : typeName + "." + discriminatorValue;
  679. var polymorphicMapper = serializer.modelMappers.discriminators[indexDiscriminator];
  680. if (polymorphicMapper) {
  681. mapper = polymorphicMapper;
  682. }
  683. }
  684. }
  685. }
  686. return mapper;
  687. }
  688. function getPolymorphicDiscriminatorRecursively(serializer, mapper) {
  689. return mapper.type.polymorphicDiscriminator
  690. || getPolymorphicDiscriminatorSafely(serializer, mapper.type.uberParent)
  691. || getPolymorphicDiscriminatorSafely(serializer, mapper.type.className);
  692. }
  693. function getPolymorphicDiscriminatorSafely(serializer, typeName) {
  694. return (typeName && serializer.modelMappers[typeName] && serializer.modelMappers[typeName].type.polymorphicDiscriminator);
  695. }
  696. // TODO: why is this here?
  697. export function serializeObject(toSerialize) {
  698. if (toSerialize == undefined)
  699. return undefined;
  700. if (toSerialize instanceof Uint8Array) {
  701. toSerialize = base64.encodeByteArray(toSerialize);
  702. return toSerialize;
  703. }
  704. else if (toSerialize instanceof Date) {
  705. return toSerialize.toISOString();
  706. }
  707. else if (Array.isArray(toSerialize)) {
  708. var array = [];
  709. for (var i = 0; i < toSerialize.length; i++) {
  710. array.push(serializeObject(toSerialize[i]));
  711. }
  712. return array;
  713. }
  714. else if (typeof toSerialize === "object") {
  715. var dictionary = {};
  716. for (var property in toSerialize) {
  717. dictionary[property] = serializeObject(toSerialize[property]);
  718. }
  719. return dictionary;
  720. }
  721. return toSerialize;
  722. }
  723. /**
  724. * Utility function to create a K:V from a list of strings
  725. */
  726. function strEnum(o) {
  727. var result = {};
  728. for (var _i = 0, o_1 = o; _i < o_1.length; _i++) {
  729. var key = o_1[_i];
  730. result[key] = key;
  731. }
  732. return result;
  733. }
  734. export var MapperType = strEnum([
  735. "Base64Url",
  736. "Boolean",
  737. "ByteArray",
  738. "Composite",
  739. "Date",
  740. "DateTime",
  741. "DateTimeRfc1123",
  742. "Dictionary",
  743. "Enum",
  744. "Number",
  745. "Object",
  746. "Sequence",
  747. "String",
  748. "Stream",
  749. "TimeSpan",
  750. "UnixTime"
  751. ]);
  752. //# sourceMappingURL=serializer.js.map