serializer.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.AsnSerializer = void 0;
  4. const asn1js = require("asn1js");
  5. const converters = require("./converters");
  6. const enums_1 = require("./enums");
  7. const helper_1 = require("./helper");
  8. const storage_1 = require("./storage");
  9. class AsnSerializer {
  10. static serialize(obj) {
  11. if (obj instanceof asn1js.BaseBlock) {
  12. return obj.toBER(false);
  13. }
  14. return this.toASN(obj).toBER(false);
  15. }
  16. static toASN(obj) {
  17. if (obj && typeof obj === "object" && (0, helper_1.isConvertible)(obj)) {
  18. return obj.toASN();
  19. }
  20. if (!(obj && typeof obj === "object")) {
  21. throw new TypeError("Parameter 1 should be type of Object.");
  22. }
  23. const target = obj.constructor;
  24. const schema = storage_1.schemaStorage.get(target);
  25. storage_1.schemaStorage.cache(target);
  26. let asn1Value = [];
  27. if (schema.itemType) {
  28. if (!Array.isArray(obj)) {
  29. throw new TypeError("Parameter 1 should be type of Array.");
  30. }
  31. if (typeof schema.itemType === "number") {
  32. const converter = converters.defaultConverter(schema.itemType);
  33. if (!converter) {
  34. throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`);
  35. }
  36. asn1Value = obj.map((o) => converter.toASN(o));
  37. }
  38. else {
  39. asn1Value = obj.map((o) => this.toAsnItem({ type: schema.itemType }, "[]", target, o));
  40. }
  41. }
  42. else {
  43. for (const key in schema.items) {
  44. const schemaItem = schema.items[key];
  45. const objProp = obj[key];
  46. if (objProp === undefined ||
  47. schemaItem.defaultValue === objProp ||
  48. (typeof schemaItem.defaultValue === "object" &&
  49. typeof objProp === "object" &&
  50. (0, helper_1.isArrayEqual)(this.serialize(schemaItem.defaultValue), this.serialize(objProp)))) {
  51. continue;
  52. }
  53. const asn1Item = AsnSerializer.toAsnItem(schemaItem, key, target, objProp);
  54. if (typeof schemaItem.context === "number") {
  55. if (schemaItem.implicit) {
  56. if (!schemaItem.repeated &&
  57. (typeof schemaItem.type === "number" || (0, helper_1.isConvertible)(schemaItem.type))) {
  58. const value = {};
  59. value.valueHex =
  60. asn1Item instanceof asn1js.Null
  61. ? asn1Item.valueBeforeDecodeView
  62. : asn1Item.valueBlock.toBER();
  63. asn1Value.push(new asn1js.Primitive({
  64. optional: schemaItem.optional,
  65. idBlock: {
  66. tagClass: 3,
  67. tagNumber: schemaItem.context,
  68. },
  69. ...value,
  70. }));
  71. }
  72. else {
  73. asn1Value.push(new asn1js.Constructed({
  74. optional: schemaItem.optional,
  75. idBlock: {
  76. tagClass: 3,
  77. tagNumber: schemaItem.context,
  78. },
  79. value: asn1Item.valueBlock.value,
  80. }));
  81. }
  82. }
  83. else {
  84. asn1Value.push(new asn1js.Constructed({
  85. optional: schemaItem.optional,
  86. idBlock: {
  87. tagClass: 3,
  88. tagNumber: schemaItem.context,
  89. },
  90. value: [asn1Item],
  91. }));
  92. }
  93. }
  94. else if (schemaItem.repeated) {
  95. asn1Value = asn1Value.concat(asn1Item);
  96. }
  97. else {
  98. asn1Value.push(asn1Item);
  99. }
  100. }
  101. }
  102. let asnSchema;
  103. switch (schema.type) {
  104. case enums_1.AsnTypeTypes.Sequence:
  105. asnSchema = new asn1js.Sequence({ value: asn1Value });
  106. break;
  107. case enums_1.AsnTypeTypes.Set:
  108. asnSchema = new asn1js.Set({ value: asn1Value });
  109. break;
  110. case enums_1.AsnTypeTypes.Choice:
  111. if (!asn1Value[0]) {
  112. throw new Error(`Schema '${target.name}' has wrong data. Choice cannot be empty.`);
  113. }
  114. asnSchema = asn1Value[0];
  115. break;
  116. }
  117. return asnSchema;
  118. }
  119. static toAsnItem(schemaItem, key, target, objProp) {
  120. let asn1Item;
  121. if (typeof schemaItem.type === "number") {
  122. const converter = schemaItem.converter;
  123. if (!converter) {
  124. throw new Error(`Property '${key}' doesn't have converter for type ${enums_1.AsnPropTypes[schemaItem.type]} in schema '${target.name}'`);
  125. }
  126. if (schemaItem.repeated) {
  127. if (!Array.isArray(objProp)) {
  128. throw new TypeError("Parameter 'objProp' should be type of Array.");
  129. }
  130. const items = Array.from(objProp, (element) => converter.toASN(element));
  131. const Container = schemaItem.repeated === "sequence" ? asn1js.Sequence : asn1js.Set;
  132. asn1Item = new Container({
  133. value: items,
  134. });
  135. }
  136. else {
  137. asn1Item = converter.toASN(objProp);
  138. }
  139. }
  140. else {
  141. if (schemaItem.repeated) {
  142. if (!Array.isArray(objProp)) {
  143. throw new TypeError("Parameter 'objProp' should be type of Array.");
  144. }
  145. const items = Array.from(objProp, (element) => this.toASN(element));
  146. const Container = schemaItem.repeated === "sequence" ? asn1js.Sequence : asn1js.Set;
  147. asn1Item = new Container({
  148. value: items,
  149. });
  150. }
  151. else {
  152. asn1Item = this.toASN(objProp);
  153. }
  154. }
  155. return asn1Item;
  156. }
  157. }
  158. exports.AsnSerializer = AsnSerializer;