Skip to content

Commit f752cba

Browse files
authored
fix(shell-api): relax BSON type validation MONGOSH-865 (#983)
Since for the types that the BSON library itself provides, the only benefit of our wrappers is the extra type validation, we should ensure that it is accurate.
1 parent 01b8824 commit f752cba

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

packages/shell-api/src/shell-bson.spec.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ describe('Shell BSON', () => {
111111
expect(s._bsontype).to.equal('ObjectID');
112112
expect(s.toHexString()).to.equal('5ebbe8e2905bb493d6981b6b');
113113
});
114+
it('works with an integer argument', () => {
115+
const s = new (shellBson.ObjectId as any)(0x12345678);
116+
expect(s._bsontype).to.equal('ObjectID');
117+
expect(s.toHexString().slice(0, 8)).to.equal('12345678');
118+
});
114119
it('has help and other metadata', async() => {
115120
const s = shellBson.ObjectId();
116121
expect((await toShellResult(s.help)).type).to.equal('Help');
@@ -119,9 +124,9 @@ describe('Shell BSON', () => {
119124
});
120125
it('errors for wrong type of arg 1', () => {
121126
try {
122-
(shellBson.ObjectId as any)(1);
127+
(shellBson.ObjectId as any)(Symbol('foo'));
123128
} catch (e) {
124-
return expect(e.message).to.contain('string, got number');
129+
return expect(e.message).to.contain('object, got symbol');
125130
}
126131
expect.fail('Expecting error, nothing thrown');
127132
});
@@ -152,6 +157,11 @@ describe('Shell BSON', () => {
152157
const s = new (shellBson.Timestamp as any)(0, 100);
153158
expect(s._bsontype).to.equal('Timestamp');
154159
});
160+
it('with a long argument', () => {
161+
const s = shellBson.Timestamp(shellBson.Long(1, 2));
162+
expect(s._bsontype).to.equal('Timestamp');
163+
expect(s.toExtendedJSON()).to.deep.equal({ $timestamp: { t: 2, i: 1 } });
164+
});
155165
it('has help and other metadata', async() => {
156166
const s = shellBson.Timestamp(0, 100);
157167
expect((await toShellResult(s.help)).type).to.equal('Help');
@@ -162,7 +172,7 @@ describe('Shell BSON', () => {
162172
try {
163173
(shellBson.Timestamp as any)('1');
164174
} catch (e) {
165-
return expect(e.message).to.contain('number, got string');
175+
return expect(e.message).to.contain('object, got string');
166176
}
167177
expect.fail('Expecting error, nothing thrown');
168178
});
@@ -191,6 +201,12 @@ describe('Shell BSON', () => {
191201
expect(code.code).to.equal('code');
192202
expect(code.scope).to.deep.equal({ k: 'v' });
193203
});
204+
it('works with a function argument', () => {
205+
const fn = function() { expect.fail(); };
206+
const code = shellBson.Code(fn, { k: 'v' });
207+
expect(code.code).to.equal(fn);
208+
expect(code.scope).to.deep.equal({ k: 'v' });
209+
});
194210
it('has help and other metadata', async() => {
195211
const s = shellBson.Code('code', { k: 'v' });
196212
expect((await toShellResult(s.help)).type).to.equal('Help');
@@ -201,7 +217,7 @@ describe('Shell BSON', () => {
201217
try {
202218
(shellBson.Code as any)(1);
203219
} catch (e) {
204-
return expect(e.message).to.contain('string, got number');
220+
return expect(e.message).to.contain('function, got number');
205221
}
206222
expect.fail('Expecting error, nothing thrown');
207223
});

packages/shell-api/src/shell-bson.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,32 @@ export default function constructShellBson(bson: typeof BSON, printWarning: (msg
5151
(bson.BSONSymbol as any).prototype.deprecated = true;
5252

5353
const bsonPkg = {
54-
DBRef: Object.assign(function(namespace: string, oid: any, db?: string): any {
54+
DBRef: Object.assign(function(namespace: string, oid: any, db?: string): typeof bson.DBRef.prototype {
5555
assertArgsDefinedType([namespace, oid, db], ['string', true, [undefined, 'string']], 'DBRef');
5656
return new bson.DBRef(namespace, oid, db);
5757
}, { prototype: bson.DBRef.prototype }),
5858
// DBPointer not available in the bson 1.x library, but depreciated since 1.6
5959
Map: bson.Map,
60-
bsonsize: function(object: any): any {
60+
bsonsize: function(object: any): number {
6161
assertArgsDefinedType([object], ['object'], 'bsonsize');
6262
return bson.calculateObjectSize(object);
6363
},
64-
MaxKey: Object.assign(function(): any {
64+
MaxKey: Object.assign(function(): typeof bson.MaxKey.prototype {
6565
return new bson.MaxKey();
6666
}, { prototype: bson.MaxKey.prototype }),
67-
MinKey: Object.assign(function(): any {
67+
MinKey: Object.assign(function(): typeof bson.MinKey.prototype {
6868
return new bson.MinKey();
6969
}, { prototype: bson.MinKey.prototype }),
70-
ObjectId: Object.assign(function(id?: string): any {
71-
assertArgsDefinedType([id], [[undefined, 'string']], 'ObjectId');
70+
ObjectId: Object.assign(function(id?: string | number | typeof bson.ObjectId.prototype | Buffer): typeof bson.ObjectId.prototype {
71+
assertArgsDefinedType([id], [[undefined, 'string', 'number', 'object']], 'ObjectId');
7272
return new bson.ObjectId(id);
7373
}, { prototype: bson.ObjectId.prototype }),
74-
Timestamp: Object.assign(function(low = 0, high = 0): any {
75-
assertArgsDefinedType([low, high], ['number', 'number'], 'Timestamp');
76-
return new bson.Timestamp(low, high);
74+
Timestamp: Object.assign(function(low?: number | typeof bson.Long.prototype, high?: number): typeof bson.Timestamp.prototype {
75+
assertArgsDefinedType([low, high], [['number', 'object', undefined], [undefined, 'number']], 'Timestamp');
76+
return new bson.Timestamp(low as number, high as number);
7777
}, { prototype: bson.Timestamp.prototype }),
78-
Code: Object.assign(function(c: any = '', s?: any): any {
79-
assertArgsDefinedType([c, s], [[undefined, 'string'], [undefined, 'object']], 'Code');
78+
Code: Object.assign(function(c: string | Function = '', s?: any): typeof bson.Code.prototype {
79+
assertArgsDefinedType([c, s], [[undefined, 'string', 'function'], [undefined, 'object']], 'Code');
8080
return new bson.Code(c, s);
8181
}, { prototype: bson.Code.prototype }),
8282
NumberDecimal: Object.assign(function(s = '0'): any {

0 commit comments

Comments
 (0)