objectid.js 11 KB

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