objectid.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.ObjectId = void 0;
  4. var buffer_1 = require("buffer");
  5. var ensure_buffer_1 = require("./ensure_buffer");
  6. var utils_1 = require("./parser/utils");
  7. // Regular expression that checks for hex value
  8. var checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
  9. // Unique sequence for the current process (initialized on first use)
  10. var PROCESS_UNIQUE = null;
  11. var kId = Symbol('id');
  12. /**
  13. * A class representation of the BSON ObjectId type.
  14. * @public
  15. */
  16. var ObjectId = /** @class */ (function () {
  17. /**
  18. * Create an ObjectId type
  19. *
  20. * @param id - Can be a 24 character hex string, 12 byte binary Buffer, or a number.
  21. */
  22. function ObjectId(id) {
  23. if (!(this instanceof ObjectId))
  24. return new ObjectId(id);
  25. // Duck-typing to support ObjectId from different npm packages
  26. if (id instanceof ObjectId) {
  27. this[kId] = id.id;
  28. this.__id = id.__id;
  29. }
  30. if (typeof id === 'object' && id && 'id' in id) {
  31. if ('toHexString' in id && typeof id.toHexString === 'function') {
  32. this[kId] = buffer_1.Buffer.from(id.toHexString(), 'hex');
  33. }
  34. else {
  35. this[kId] = typeof id.id === 'string' ? buffer_1.Buffer.from(id.id) : id.id;
  36. }
  37. }
  38. // The most common use case (blank id, new objectId instance)
  39. if (id == null || typeof id === 'number') {
  40. // Generate a new id
  41. this[kId] = ObjectId.generate(typeof id === 'number' ? id : undefined);
  42. // If we are caching the hex string
  43. if (ObjectId.cacheHexString) {
  44. this.__id = this.id.toString('hex');
  45. }
  46. }
  47. if (ArrayBuffer.isView(id) && id.byteLength === 12) {
  48. this[kId] = ensure_buffer_1.ensureBuffer(id);
  49. }
  50. if (typeof id === 'string') {
  51. if (id.length === 12) {
  52. var bytes = buffer_1.Buffer.from(id);
  53. if (bytes.byteLength === 12) {
  54. this[kId] = bytes;
  55. }
  56. }
  57. else if (id.length === 24 && checkForHexRegExp.test(id)) {
  58. this[kId] = buffer_1.Buffer.from(id, 'hex');
  59. }
  60. else {
  61. throw new TypeError('Argument passed in must be a Buffer or string of 12 bytes or a string of 24 hex characters');
  62. }
  63. }
  64. if (ObjectId.cacheHexString) {
  65. this.__id = this.id.toString('hex');
  66. }
  67. }
  68. Object.defineProperty(ObjectId.prototype, "id", {
  69. /**
  70. * The ObjectId bytes
  71. * @readonly
  72. */
  73. get: function () {
  74. return this[kId];
  75. },
  76. set: function (value) {
  77. this[kId] = value;
  78. if (ObjectId.cacheHexString) {
  79. this.__id = value.toString('hex');
  80. }
  81. },
  82. enumerable: false,
  83. configurable: true
  84. });
  85. Object.defineProperty(ObjectId.prototype, "generationTime", {
  86. /**
  87. * The generation time of this ObjectId instance
  88. * @deprecated Please use getTimestamp / createFromTime which returns an int32 epoch
  89. */
  90. get: function () {
  91. return this.id.readInt32BE(0);
  92. },
  93. set: function (value) {
  94. // Encode time into first 4 bytes
  95. this.id.writeUInt32BE(value, 0);
  96. },
  97. enumerable: false,
  98. configurable: true
  99. });
  100. /** Returns the ObjectId id as a 24 character hex string representation */
  101. ObjectId.prototype.toHexString = function () {
  102. if (ObjectId.cacheHexString && this.__id) {
  103. return this.__id;
  104. }
  105. var hexString = this.id.toString('hex');
  106. if (ObjectId.cacheHexString && !this.__id) {
  107. this.__id = hexString;
  108. }
  109. return hexString;
  110. };
  111. /**
  112. * Update the ObjectId index
  113. * @privateRemarks
  114. * Used in generating new ObjectId's on the driver
  115. * @internal
  116. */
  117. ObjectId.getInc = function () {
  118. return (ObjectId.index = (ObjectId.index + 1) % 0xffffff);
  119. };
  120. /**
  121. * Generate a 12 byte id buffer used in ObjectId's
  122. *
  123. * @param time - pass in a second based timestamp.
  124. */
  125. ObjectId.generate = function (time) {
  126. if ('number' !== typeof time) {
  127. time = ~~(Date.now() / 1000);
  128. }
  129. var inc = ObjectId.getInc();
  130. var buffer = buffer_1.Buffer.alloc(12);
  131. // 4-byte timestamp
  132. buffer.writeUInt32BE(time, 0);
  133. // set PROCESS_UNIQUE if yet not initialized
  134. if (PROCESS_UNIQUE === null) {
  135. PROCESS_UNIQUE = utils_1.randomBytes(5);
  136. }
  137. // 5-byte process unique
  138. buffer[4] = PROCESS_UNIQUE[0];
  139. buffer[5] = PROCESS_UNIQUE[1];
  140. buffer[6] = PROCESS_UNIQUE[2];
  141. buffer[7] = PROCESS_UNIQUE[3];
  142. buffer[8] = PROCESS_UNIQUE[4];
  143. // 3-byte counter
  144. buffer[11] = inc & 0xff;
  145. buffer[10] = (inc >> 8) & 0xff;
  146. buffer[9] = (inc >> 16) & 0xff;
  147. return buffer;
  148. };
  149. /**
  150. * Converts the id into a 24 character hex string for printing
  151. *
  152. * @param format - The Buffer toString format parameter.
  153. * @internal
  154. */
  155. ObjectId.prototype.toString = function (format) {
  156. // Is the id a buffer then use the buffer toString method to return the format
  157. if (format)
  158. return this.id.toString(format);
  159. return this.toHexString();
  160. };
  161. /**
  162. * Converts to its JSON the 24 character hex string representation.
  163. * @internal
  164. */
  165. ObjectId.prototype.toJSON = function () {
  166. return this.toHexString();
  167. };
  168. /**
  169. * Compares the equality of this ObjectId with `otherID`.
  170. *
  171. * @param otherId - ObjectId instance to compare against.
  172. */
  173. ObjectId.prototype.equals = function (otherId) {
  174. if (otherId === undefined || otherId === null) {
  175. return false;
  176. }
  177. if (otherId instanceof ObjectId) {
  178. return this.toString() === otherId.toString();
  179. }
  180. if (typeof otherId === 'string' &&
  181. ObjectId.isValid(otherId) &&
  182. otherId.length === 12 &&
  183. utils_1.isUint8Array(this.id)) {
  184. return otherId === buffer_1.Buffer.prototype.toString.call(this.id, 'latin1');
  185. }
  186. if (typeof otherId === 'string' && ObjectId.isValid(otherId) && otherId.length === 24) {
  187. return otherId.toLowerCase() === this.toHexString();
  188. }
  189. if (typeof otherId === 'string' && ObjectId.isValid(otherId) && otherId.length === 12) {
  190. return buffer_1.Buffer.from(otherId).equals(this.id);
  191. }
  192. if (typeof otherId === 'object' &&
  193. 'toHexString' in otherId &&
  194. typeof otherId.toHexString === 'function') {
  195. return otherId.toHexString() === this.toHexString();
  196. }
  197. return false;
  198. };
  199. /** Returns the generation date (accurate up to the second) that this ID was generated. */
  200. ObjectId.prototype.getTimestamp = function () {
  201. var timestamp = new Date();
  202. var time = this.id.readUInt32BE(0);
  203. timestamp.setTime(Math.floor(time) * 1000);
  204. return timestamp;
  205. };
  206. /** @internal */
  207. ObjectId.createPk = function () {
  208. return new ObjectId();
  209. };
  210. /**
  211. * Creates an ObjectId from a second based number, with the rest of the ObjectId zeroed out. Used for comparisons or sorting the ObjectId.
  212. *
  213. * @param time - an integer number representing a number of seconds.
  214. */
  215. ObjectId.createFromTime = function (time) {
  216. var buffer = buffer_1.Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
  217. // Encode time into first 4 bytes
  218. buffer.writeUInt32BE(time, 0);
  219. // Return the new objectId
  220. return new ObjectId(buffer);
  221. };
  222. /**
  223. * Creates an ObjectId from a hex string representation of an ObjectId.
  224. *
  225. * @param hexString - create a ObjectId from a passed in 24 character hexstring.
  226. */
  227. ObjectId.createFromHexString = function (hexString) {
  228. // Throw an error if it's not a valid setup
  229. if (typeof hexString === 'undefined' || (hexString != null && hexString.length !== 24)) {
  230. throw new TypeError('Argument passed in must be a single String of 12 bytes or a string of 24 hex characters');
  231. }
  232. return new ObjectId(buffer_1.Buffer.from(hexString, 'hex'));
  233. };
  234. /**
  235. * Checks if a value is a valid bson ObjectId
  236. *
  237. * @param id - ObjectId instance to validate.
  238. */
  239. ObjectId.isValid = function (id) {
  240. if (id == null)
  241. return false;
  242. if (typeof id === 'number') {
  243. return true;
  244. }
  245. if (typeof id === 'string') {
  246. return id.length === 12 || (id.length === 24 && checkForHexRegExp.test(id));
  247. }
  248. if (id instanceof ObjectId) {
  249. return true;
  250. }
  251. if (utils_1.isUint8Array(id) && id.length === 12) {
  252. return true;
  253. }
  254. // Duck-Typing detection of ObjectId like objects
  255. if (typeof id === 'object' && 'toHexString' in id && typeof id.toHexString === 'function') {
  256. if (typeof id.id === 'string') {
  257. return id.id.length === 12;
  258. }
  259. return id.toHexString().length === 24 && checkForHexRegExp.test(id.id.toString('hex'));
  260. }
  261. return false;
  262. };
  263. /** @internal */
  264. ObjectId.prototype.toExtendedJSON = function () {
  265. if (this.toHexString)
  266. return { $oid: this.toHexString() };
  267. return { $oid: this.toString('hex') };
  268. };
  269. /** @internal */
  270. ObjectId.fromExtendedJSON = function (doc) {
  271. return new ObjectId(doc.$oid);
  272. };
  273. /**
  274. * Converts to a string representation of this Id.
  275. *
  276. * @returns return the 24 character hex string representation.
  277. * @internal
  278. */
  279. ObjectId.prototype[Symbol.for('nodejs.util.inspect.custom')] = function () {
  280. return this.inspect();
  281. };
  282. ObjectId.prototype.inspect = function () {
  283. return "new ObjectId(\"" + this.toHexString() + "\")";
  284. };
  285. /** @internal */
  286. ObjectId.index = ~~(Math.random() * 0xffffff);
  287. return ObjectId;
  288. }());
  289. exports.ObjectId = ObjectId;
  290. // Deprecated methods
  291. Object.defineProperty(ObjectId.prototype, 'generate', {
  292. value: utils_1.deprecate(function (time) { return ObjectId.generate(time); }, 'Please use the static `ObjectId.generate(time)` instead')
  293. });
  294. Object.defineProperty(ObjectId.prototype, 'getInc', {
  295. value: utils_1.deprecate(function () { return ObjectId.getInc(); }, 'Please use the static `ObjectId.getInc()` instead')
  296. });
  297. Object.defineProperty(ObjectId.prototype, 'get_inc', {
  298. value: utils_1.deprecate(function () { return ObjectId.getInc(); }, 'Please use the static `ObjectId.getInc()` instead')
  299. });
  300. Object.defineProperty(ObjectId, 'get_inc', {
  301. value: utils_1.deprecate(function () { return ObjectId.getInc(); }, 'Please use the static `ObjectId.getInc()` instead')
  302. });
  303. Object.defineProperty(ObjectId.prototype, '_bsontype', { value: 'ObjectID' });
  304. //# sourceMappingURL=objectid.js.map