158158// return doc;
159159// }
160160
161- function is_object_id ( id ) {
162- return typeof id === 'string' && ( / ^ [ 0 - 9 a - f ] { 24 } $ / i) . test ( id ) ;
161+ function is_object_id ( id , generate = false ) {
162+ const ERROR_MSG = 'Argument passed must be a single string of 12 bytes or a string of 24 hex characters' ;
163+
164+ if ( id === null || id === undefined ) {
165+ return generate ? mongoObjectId ( ) : false ;
166+ }
167+
168+ if ( typeof id === 'number' && Number . isInteger ( id ) && id > 0 ) {
169+ if ( ! generate ) return true ;
170+ return id . toString ( 16 ) . padStart ( 8 , '0' ) + mongoObjectId ( ) . substring ( 8 ) ;
171+ }
172+
173+ let hex_string = null ;
174+ if ( typeof id === 'string' ) {
175+ hex_string = id ;
176+ } else if ( id . _id && typeof id . _id === 'string' ) {
177+ hex_string = id . _id ;
178+ }
179+
180+ if ( hex_string && ( / ^ [ 0 - 9 a - f ] { 24 } $ / i) . test ( hex_string ) ) {
181+ return generate ? hex_string . toLowerCase ( ) : true ;
182+ }
183+
184+ if ( generate ) throw new Error ( ERROR_MSG ) ;
185+ return false ;
163186}
164187
188+
165189function mongoObjectId ( ) {
166190 // eslint-disable-next-line no-bitwise
167191 const timestamp = ( new Date ( ) . getTime ( ) / 1000 | 0 ) . toString ( 16 ) ;
@@ -232,15 +256,11 @@ function mongoObjectId() {
232256
233257/**
234258 * MongoDB ObjectId compatibility class
235- * Behaves like mongodb.ObjectId but returns strings
259+ * behaves like mongodb.ObjectId with minimal validations
236260 */
237261class ObjectID {
238262 constructor ( id_str ) {
239- if ( id_str === undefined || id_str === null ) {
240- this . _id = mongoObjectId ( ) ;
241- } else {
242- this . _id = String ( id_str ) ;
243- }
263+ this . _id = is_object_id ( id_str , true ) ;
244264 }
245265
246266 toString ( ) {
@@ -252,27 +272,21 @@ class ObjectID {
252272 }
253273
254274 valueOf ( ) {
255- return this . _id ;
275+ return this ;
256276 }
257277
258278 toJSON ( ) {
259279 return this . _id ;
260280 }
261281
262282 getTimestamp ( ) {
263- // Extract timestamp from first 4 bytes of ObjectId hex string
264- const timestampHex = this . _id . substring ( 0 , 8 ) ;
265- const timestamp = parseInt ( timestampHex , 16 ) ;
283+ const timestamp = parseInt ( this . _id . substring ( 0 , 8 ) , 16 ) ;
266284 return new Date ( timestamp * 1000 ) ;
267285 }
268286
269287 static isValid ( id ) {
270288 return is_object_id ( id ) ;
271289 }
272-
273- static [ Symbol . hasInstance ] ( instance ) {
274- return instance && typeof instance . _id === 'string' && is_object_id ( instance . _id ) ;
275- }
276290}
277291
278292// // EXPORTS
0 commit comments