objectid.js 11 KB

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