1
0

util.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. "use strict";
  2. /**
  3. * Various utility functions.
  4. * @namespace
  5. */
  6. var util = module.exports = require("./util/minimal");
  7. var roots = require("./roots");
  8. var Type, // cyclic
  9. Enum;
  10. util.codegen = require("@protobufjs/codegen");
  11. util.fetch = require("@protobufjs/fetch");
  12. util.path = require("@protobufjs/path");
  13. /**
  14. * Node's fs module if available.
  15. * @type {Object.<string,*>}
  16. */
  17. util.fs = util.inquire("fs");
  18. /**
  19. * Converts an object's values to an array.
  20. * @param {Object.<string,*>} object Object to convert
  21. * @returns {Array.<*>} Converted array
  22. */
  23. util.toArray = function toArray(object) {
  24. if (object) {
  25. var keys = Object.keys(object),
  26. array = new Array(keys.length),
  27. index = 0;
  28. while (index < keys.length)
  29. array[index] = object[keys[index++]];
  30. return array;
  31. }
  32. return [];
  33. };
  34. /**
  35. * Converts an array of keys immediately followed by their respective value to an object, omitting undefined values.
  36. * @param {Array.<*>} array Array to convert
  37. * @returns {Object.<string,*>} Converted object
  38. */
  39. util.toObject = function toObject(array) {
  40. var object = {},
  41. index = 0;
  42. while (index < array.length) {
  43. var key = array[index++],
  44. val = array[index++];
  45. if (val !== undefined)
  46. object[key] = val;
  47. }
  48. return object;
  49. };
  50. var safePropBackslashRe = /\\/g,
  51. safePropQuoteRe = /"/g;
  52. /**
  53. * Tests whether the specified name is a reserved word in JS.
  54. * @param {string} name Name to test
  55. * @returns {boolean} `true` if reserved, otherwise `false`
  56. */
  57. util.isReserved = function isReserved(name) {
  58. return /^(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$/.test(name);
  59. };
  60. /**
  61. * Returns a safe property accessor for the specified property name.
  62. * @param {string} prop Property name
  63. * @returns {string} Safe accessor
  64. */
  65. util.safeProp = function safeProp(prop) {
  66. if (!/^[$\w_]+$/.test(prop) || util.isReserved(prop))
  67. return "[\"" + prop.replace(safePropBackslashRe, "\\\\").replace(safePropQuoteRe, "\\\"") + "\"]";
  68. return "." + prop;
  69. };
  70. /**
  71. * Converts the first character of a string to upper case.
  72. * @param {string} str String to convert
  73. * @returns {string} Converted string
  74. */
  75. util.ucFirst = function ucFirst(str) {
  76. return str.charAt(0).toUpperCase() + str.substring(1);
  77. };
  78. var camelCaseRe = /_([a-z])/g;
  79. /**
  80. * Converts a string to camel case.
  81. * @param {string} str String to convert
  82. * @returns {string} Converted string
  83. */
  84. util.camelCase = function camelCase(str) {
  85. return str.substring(0, 1)
  86. + str.substring(1)
  87. .replace(camelCaseRe, function($0, $1) { return $1.toUpperCase(); });
  88. };
  89. /**
  90. * Compares reflected fields by id.
  91. * @param {Field} a First field
  92. * @param {Field} b Second field
  93. * @returns {number} Comparison value
  94. */
  95. util.compareFieldsById = function compareFieldsById(a, b) {
  96. return a.id - b.id;
  97. };
  98. /**
  99. * Decorator helper for types (TypeScript).
  100. * @param {Constructor<T>} ctor Constructor function
  101. * @param {string} [typeName] Type name, defaults to the constructor's name
  102. * @returns {Type} Reflected type
  103. * @template T extends Message<T>
  104. * @property {Root} root Decorators root
  105. */
  106. util.decorateType = function decorateType(ctor, typeName) {
  107. /* istanbul ignore if */
  108. if (ctor.$type) {
  109. if (typeName && ctor.$type.name !== typeName) {
  110. util.decorateRoot.remove(ctor.$type);
  111. ctor.$type.name = typeName;
  112. util.decorateRoot.add(ctor.$type);
  113. }
  114. return ctor.$type;
  115. }
  116. /* istanbul ignore next */
  117. if (!Type)
  118. Type = require("./type");
  119. var type = new Type(typeName || ctor.name);
  120. util.decorateRoot.add(type);
  121. type.ctor = ctor; // sets up .encode, .decode etc.
  122. Object.defineProperty(ctor, "$type", { value: type, enumerable: false });
  123. Object.defineProperty(ctor.prototype, "$type", { value: type, enumerable: false });
  124. return type;
  125. };
  126. var decorateEnumIndex = 0;
  127. /**
  128. * Decorator helper for enums (TypeScript).
  129. * @param {Object} object Enum object
  130. * @returns {Enum} Reflected enum
  131. */
  132. util.decorateEnum = function decorateEnum(object) {
  133. /* istanbul ignore if */
  134. if (object.$type)
  135. return object.$type;
  136. /* istanbul ignore next */
  137. if (!Enum)
  138. Enum = require("./enum");
  139. var enm = new Enum("Enum" + decorateEnumIndex++, object);
  140. util.decorateRoot.add(enm);
  141. Object.defineProperty(object, "$type", { value: enm, enumerable: false });
  142. return enm;
  143. };
  144. /**
  145. * Decorator root (TypeScript).
  146. * @name util.decorateRoot
  147. * @type {Root}
  148. * @readonly
  149. */
  150. Object.defineProperty(util, "decorateRoot", {
  151. get: function() {
  152. return roots["decorated"] || (roots["decorated"] = new (require("./root"))());
  153. }
  154. });