diff --git a/packages/cli-repl/test/e2e-bson.spec.ts b/packages/cli-repl/test/e2e-bson.spec.ts index 8e8698a137..f220349054 100644 --- a/packages/cli-repl/test/e2e-bson.spec.ts +++ b/packages/cli-repl/test/e2e-bson.spec.ts @@ -576,5 +576,11 @@ describe('BSON e2e', function() { expect(result).to.match(/size: \d+/); }); }); + describe('inheritance', () => { + it('instanceof works for bson types', async() => { + expect(await shell.executeLine('ObjectId() instanceof ObjectId')).to.include('true'); + shell.assertNoErrors(); + }); + }); }); diff --git a/packages/shell-api/src/shell-bson.ts b/packages/shell-api/src/shell-bson.ts index e3ee2a7dac..c3d83d7634 100644 --- a/packages/shell-api/src/shell-bson.ts +++ b/packages/shell-api/src/shell-bson.ts @@ -49,57 +49,57 @@ export default function constructShellBson(bson: typeof BSON, printWarning: (msg (bson.BSONSymbol as any).prototype.deprecated = true; const bsonPkg = { - DBRef: function(namespace: string, oid: any, db?: string): any { + DBRef: Object.assign(function(namespace: string, oid: any, db?: string): any { assertArgsDefinedType([namespace, oid, db], ['string', true, [undefined, 'string']], 'DBRef'); return new bson.DBRef(namespace, oid, db); - }, + }, { prototype: bson.DBRef.prototype }), // DBPointer not available in the bson 1.x library, but depreciated since 1.6 Map: bson.Map, bsonsize: function(object: any): any { assertArgsDefinedType([object], ['object'], 'bsonsize'); return bson.calculateObjectSize(object); }, - MaxKey: function(): any { + MaxKey: Object.assign(function(): any { return new bson.MaxKey(); - }, - MinKey: function(): any { + }, { prototype: bson.MaxKey.prototype }), + MinKey: Object.assign(function(): any { return new bson.MinKey(); - }, - ObjectId: function(id?: string): any { + }, { prototype: bson.MinKey.prototype }), + ObjectId: Object.assign(function(id?: string): any { assertArgsDefinedType([id], [[undefined, 'string']], 'ObjectId'); return new bson.ObjectId(id); - }, - Symbol: function(value = ''): any { + }, { prototype: bson.ObjectId.prototype }), + Symbol: Object.assign(function(value = ''): any { return new bson.BSONSymbol(value); - }, - Timestamp: function(low = 0, high = 0): any { + }, { prototype: bson.BSONSymbol.prototype }), + Timestamp: Object.assign(function(low = 0, high = 0): any { assertArgsDefinedType([low, high], ['number', 'number'], 'Timestamp'); return new bson.Timestamp(low, high); - }, - Code: function(c: any = '', s?: any): any { + }, { prototype: bson.Timestamp.prototype }), + Code: Object.assign(function(c: any = '', s?: any): any { assertArgsDefinedType([c, s], [[undefined, 'string'], [undefined, 'object']], 'Code'); return new bson.Code(c, s); - }, - NumberDecimal: function(s = '0'): any { + }, { prototype: bson.Code.prototype }), + NumberDecimal: Object.assign(function(s = '0'): any { assertArgsDefinedType([s], [['string', 'number']], 'NumberDecimal'); if (typeof s === 'string') { return bson.Decimal128.fromString(s); } printWarning('NumberDecimal: specifying a number as argument is deprecated and may lead to loss of precision'); return bson.Decimal128.fromString(`${s}`); - }, - NumberInt: function(v = '0'): any { + }, { prototype: bson.Decimal128.prototype }), + NumberInt: Object.assign(function(v = '0'): any { assertArgsDefinedType([v], [['string', 'number']], 'NumberInt'); return new bson.Int32(parseInt(`${v}`, 10)); - }, - NumberLong: function(s: string | number = '0'): any { + }, { prototype: bson.Int32.prototype }), + NumberLong: Object.assign(function(s: string | number = '0'): any { assertArgsDefinedType([s], [['string', 'number']], 'NumberLong'); if (typeof s === 'string') { return bson.Long.fromString(s); } printWarning('NumberLong: specifying a number as argument is deprecated and may lead to loss of precision'); return bson.Long.fromInt(s); - }, + }, { prototype: bson.Long.prototype }), ISODate: function(input?: string): Date { if (!input) input = new Date().toISOString(); const isoDateRegex = @@ -119,17 +119,17 @@ export default function constructShellBson(bson: typeof BSON, printWarning: (msg } throw new MongoshInvalidInputError(`${JSON.stringify(input)} is not a valid ISODate`, CommonErrors.InvalidArgument); }, - BinData: function(subtype: number, b64string: string): BinaryType { // this from 'help misc' in old shell + BinData: Object.assign(function(subtype: number, b64string: string): BinaryType { // this from 'help misc' in old shell assertArgsDefinedType([subtype, b64string], ['number', 'string'], 'BinData'); const buffer = Buffer.from(b64string, 'base64'); return new bson.Binary(buffer, subtype); - }, - HexData: function(subtype: number, hexstr: string): BinaryType { + }, { prototype: bson.Binary.prototype }), + HexData: Object.assign(function(subtype: number, hexstr: string): BinaryType { assertArgsDefinedType([subtype, hexstr], ['number', 'string'], 'HexData'); const buffer = Buffer.from(hexstr, 'hex'); return new bson.Binary(buffer, subtype); - }, - UUID: function(hexstr?: string): BinaryType { + }, { prototype: bson.Binary.prototype }), + UUID: Object.assign(function(hexstr?: string): BinaryType { if (hexstr === undefined) { // Generate a version 4, variant 1 UUID, like the old shell did. const uuid = randomBytes(16); @@ -142,12 +142,12 @@ export default function constructShellBson(bson: typeof BSON, printWarning: (msg // (e.g. 01234567-89ab-cdef-0123-456789abcdef). const buffer = Buffer.from((hexstr as string).replace(/-/g, ''), 'hex'); return new bson.Binary(buffer, bson.Binary.SUBTYPE_UUID); - }, - MD5: function(hexstr: string): BinaryType { + }, { prototype: bson.Binary.prototype }), + MD5: Object.assign(function(hexstr: string): BinaryType { assertArgsDefinedType([hexstr], ['string'], 'MD5'); const buffer = Buffer.from(hexstr, 'hex'); return new bson.Binary(buffer, bson.Binary.SUBTYPE_MD5); - }, + }, { prototype: bson.Binary.prototype }), // Add the driver types to bsonPkg so we can deprecate the shell ones later Decimal128: bson.Decimal128, BSONSymbol: bson.BSONSymbol,