utils.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. 'use strict';
  2. const crypto = require('crypto');
  3. const requireOptional = require('require_optional');
  4. /**
  5. * Generate a UUIDv4
  6. */
  7. const uuidV4 = () => {
  8. const result = crypto.randomBytes(16);
  9. result[6] = (result[6] & 0x0f) | 0x40;
  10. result[8] = (result[8] & 0x3f) | 0x80;
  11. return result;
  12. };
  13. /**
  14. * Returns the duration calculated from two high resolution timers in milliseconds
  15. *
  16. * @param {Object} started A high resolution timestamp created from `process.hrtime()`
  17. * @returns {Number} The duration in milliseconds
  18. */
  19. const calculateDurationInMs = started => {
  20. const hrtime = process.hrtime(started);
  21. return (hrtime[0] * 1e9 + hrtime[1]) / 1e6;
  22. };
  23. /**
  24. * Relays events for a given listener and emitter
  25. *
  26. * @param {EventEmitter} listener the EventEmitter to listen to the events from
  27. * @param {EventEmitter} emitter the EventEmitter to relay the events to
  28. */
  29. function relayEvents(listener, emitter, events) {
  30. events.forEach(eventName => listener.on(eventName, event => emitter.emit(eventName, event)));
  31. }
  32. function retrieveKerberos() {
  33. let kerberos;
  34. try {
  35. kerberos = requireOptional('kerberos');
  36. } catch (err) {
  37. if (err.code === 'MODULE_NOT_FOUND') {
  38. throw new Error('The `kerberos` module was not found. Please install it and try again.');
  39. }
  40. throw err;
  41. }
  42. return kerberos;
  43. }
  44. // Throw an error if an attempt to use EJSON is made when it is not installed
  45. const noEJSONError = function() {
  46. throw new Error('The `mongodb-extjson` module was not found. Please install it and try again.');
  47. };
  48. // Facilitate loading EJSON optionally
  49. function retrieveEJSON() {
  50. let EJSON = null;
  51. try {
  52. EJSON = requireOptional('mongodb-extjson');
  53. } catch (error) {} // eslint-disable-line
  54. if (!EJSON) {
  55. EJSON = {
  56. parse: noEJSONError,
  57. deserialize: noEJSONError,
  58. serialize: noEJSONError,
  59. stringify: noEJSONError,
  60. setBSONModule: noEJSONError,
  61. BSON: noEJSONError
  62. };
  63. }
  64. return EJSON;
  65. }
  66. /**
  67. * A helper function for determining `maxWireVersion` between legacy and new topology
  68. * instances
  69. *
  70. * @private
  71. * @param {(Topology|Server)} topologyOrServer
  72. */
  73. function maxWireVersion(topologyOrServer) {
  74. if (topologyOrServer.ismaster) {
  75. return topologyOrServer.ismaster.maxWireVersion;
  76. }
  77. if (topologyOrServer.description) {
  78. return topologyOrServer.description.maxWireVersion;
  79. }
  80. return null;
  81. }
  82. /*
  83. * Checks that collation is supported by server.
  84. *
  85. * @param {Server} [server] to check against
  86. * @param {object} [cmd] object where collation may be specified
  87. * @param {function} [callback] callback function
  88. * @return true if server does not support collation
  89. */
  90. function collationNotSupported(server, cmd) {
  91. return cmd && cmd.collation && maxWireVersion(server) < 5;
  92. }
  93. /**
  94. * Checks if a given value is a Promise
  95. *
  96. * @param {*} maybePromise
  97. * @return true if the provided value is a Promise
  98. */
  99. function isPromiseLike(maybePromise) {
  100. return maybePromise && typeof maybePromise.then === 'function';
  101. }
  102. module.exports = {
  103. uuidV4,
  104. calculateDurationInMs,
  105. relayEvents,
  106. collationNotSupported,
  107. retrieveEJSON,
  108. retrieveKerberos,
  109. maxWireVersion,
  110. isPromiseLike
  111. };